diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 400349f15..000000000 --- a/.clang-format +++ /dev/null @@ -1,75 +0,0 @@ ---- -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 deleted file mode 100644 index cd9c5e1db..000000000 --- a/.clangd +++ /dev/null @@ -1,9 +0,0 @@ -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" - - "-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 deleted file mode 100644 index 4acef401c..000000000 --- a/.dockerignore +++ /dev/null @@ -1,2 +0,0 @@ -.git/ -workspace/ diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index dbe5330ba..000000000 --- a/.gitattributes +++ /dev/null @@ -1,4 +0,0 @@ -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 deleted file mode 100644 index 92e6978c2..000000000 --- a/.github/ISSUE_TEMPLATE/bugs-and-issues.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -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 deleted file mode 100644 index 5a1e094c3..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -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 deleted file mode 100644 index d7b3a9b2d..000000000 --- a/.github/ISSUE_TEMPLATE/game-connection-issue.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -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 deleted file mode 100644 index fee6dd338..000000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,126 +0,0 @@ -on: - pull_request: - push: - workflow_dispatch: - -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 deleted file mode 100755 index a661f6f6c..000000000 --- a/.github/workflows/validate-linux.sh +++ /dev/null @@ -1,497 +0,0 @@ -#!/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 deleted file mode 100755 index 3ae4e1a16..000000000 --- a/.github/workflows/validate-report.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/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 deleted file mode 100644 index bbc107660..000000000 --- a/.github/workflows/validate.yml +++ /dev/null @@ -1,57 +0,0 @@ -on: - pull_request: - 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 update && 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@v4 - 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 index 04a7d1eac..498119e3c 100755 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,10 @@ # Main binaries created in *nix builds -/zerotier-one -/zerotier-idtool -/zerotier-cli -/zerotier-selftest -/zerotier -/nltest - -# IDE stuff -/.idea -/.nova -/compile_commands.json +/zerotier-* # OS-created garbage files from various platforms .DS_Store .Apple* Thumbs.db -@eaDir -._* # Windows build droppings /windows/ZeroTierOne.sdf @@ -33,58 +21,46 @@ Thumbs.db /windows/Release /windows/WebUIWrapper/bin /windows/WebUIWrapper/obj -/windows/lib /ext/installfiles/windows/ZeroTier One-SetupFiles +/ext/installfiles/windows/Prerequisites /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. +# Miscellaneous file types that we don't want to check in *.log *.opensdf *.user *.cache +*.obj *.tlog *.pid *.pkg *.o -/*.a -*.dylib -*.so -*.so.* -*.o-* *.core *.deb *.rpm *.autosave *.tmp -.depend + +# Root topology build files, temporaries, and never check in secrets +/root-topology/bin2c +/root-topology/mktopology +/root-topology/*.secret +/root-topology/test/supernodes +/root-topology/test/test-root-topology + +# MacGap wrapper build files +/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcuserdata/* +/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/xcuserdata/* +/ext/mac-ui-macgap1-wrapper/src/build + +# Web UI dev temporaries +/ui/.module-cache 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/ @@ -95,49 +71,3 @@ 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/ -tcp-proxy/target - -#snapcraft specifics -/parts/ -/stage/ -/prime/ - -*.snap - -.snapcraft -__pycache__ -*.pyc -*_source.tar.bz2 -snap/.snapcraft -tcp-proxy/tcp-proxy -rustybits/target -ext/installfiles/windows/*.back*.aip diff --git a/AUTHORS.md b/AUTHORS.md new file mode 100644 index 000000000..b286e7ca3 --- /dev/null +++ b/AUTHORS.md @@ -0,0 +1,44 @@ +## Authors + + * ZeroTier protocol design and core network virtualization engine, ZeroTier One service, React web UI, packaging for most platforms, kitchen sink...
+ Adam Ierymenko / adam.ierymenko@zerotier.com + + * Java JNI Interface to enable Android application development, and Android app itself (code for that is elsewhere)
+ Grant Limberg / glimberg@gmail.com + +## 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 + + * Several others made smaller contributions, which GitHub tracks here:
+ https://github.com/zerotier/ZeroTierOne/graphs/contributors + +## Third Party Code + + * LZ4 compression algorithm by Yann Collet (BSD license)
+ http://code.google.com/p/lz4/ + + * http-parser by many authors (MIT license)
+ https://github.com/joyent/http-parser + + * json-parser by James McLaughlin (BSD license)
+ https://github.com/udp/json-parser + + * TunTapOSX by Mattias Nissler (BSD license)
+ http://tuntaposx.sourceforge.net + + * tap-windows and tap-windows6 by the OpenVPN project (GPL)
+ https://github.com/OpenVPN/tap-windows
+ https://github.com/OpenVPN/tap-windows6 + + * Salsa20 stream cipher, Curve25519 elliptic curve cipher, Ed25519 + digital signature algorithm, and Poly1305 MAC algorithm, all by + Daniel J. Bernstein (public domain)
+ http://cr.yp.to/ + + * MiniUPNPC by Thomas Bernard [BSD] + http://miniupnp.free.fr diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index fff7808e1..000000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# 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 deleted file mode 100644 index 7f0801e20..000000000 --- a/COPYING +++ /dev/null @@ -1,12 +0,0 @@ -ZeroTier One, an endpoint server for the ZeroTier virtual network layer. -Copyright © 2011–2019 ZeroTier, Inc. - -ZeroTier is released under the terms of the BUSL 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 deleted file mode 100644 index 9ff3b011a..000000000 --- a/Dockerfile.ci +++ /dev/null @@ -1,28 +0,0 @@ -# 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 deleted file mode 100644 index 2a289cead..000000000 --- a/Dockerfile.release +++ /dev/null @@ -1,23 +0,0 @@ -# vim: ft=dockerfile - -FROM debian:bookworm - -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/bookworm bookworm 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 libssl3 -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 index 06a3fad64..01c99074d 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,149 +1,13 @@ ------------------------------------------------------------------------------ +ZeroTier One is licensed under the terms of the GNU General Public License +version 3, which are available here: -Business Source License 1.1 +http://gplv3.fsf.org/ -License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. -"Business Source License" is a trademark of MariaDB Corporation Ab. +Modification and redistribution of ZeroTier One is permitted in source form. +Binary distribution is permitted provided all copyright notices remain +intact and any modifications to the source code are also distributed. ------------------------------------------------------------------------------ - -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. +ZeroTier One may not be embedded into any closed-source application (e.g. via +linking), nor may closed-source derivatives be created, without a separately +negotiated license from ZeroTier Networks LLC. See the terms of the GPLv3 for +details. diff --git a/Makefile b/Makefile index f77767fb8..5a5f6605e 100644 --- a/Makefile +++ b/Makefile @@ -11,26 +11,8 @@ ifeq ($(OSTYPE),Linux) endif ifeq ($(OSTYPE),FreeBSD) - CC=clang - CXX=clang++ - ZT_BUILD_PLATFORM=7 - include make-bsd.mk + include make-freebsd.mk endif ifeq ($(OSTYPE),OpenBSD) - CC=clang - CXX=clang++ - ZT_BUILD_PLATFORM=9 - include make-bsd.mk + include make-freebsd.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 - -clang-format: - find node osdep service tcp-proxy controller -iname '*.cpp' -o -iname '*.hpp' | xargs clang-format -i diff --git a/OFFICIAL-RELEASE-STEPS.md b/OFFICIAL-RELEASE-STEPS.md deleted file mode 100644 index 0c198bd68..000000000 --- a/OFFICIAL-RELEASE-STEPS.md +++ /dev/null @@ -1,33 +0,0 @@ -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, i386, and arm64 `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 deleted file mode 100644 index 5b046e320..000000000 --- a/README.docker.md +++ /dev/null @@ -1,73 +0,0 @@ -# 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. -- `ZEROTIER_LOCAL_CONF`: Sets the the `local.conf` file content for zerotier-one - -### 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 index e881ce810..248065047 100644 --- a/README.md +++ b/README.md @@ -1,197 +1,171 @@ -ZeroTier - Global Area Networking +ZeroTier One ====== -*This document is written for a software developer audience. For information on using ZeroTier, see the: [Website](https://www.zerotier.com), [Documentation Site](https://docs.zerotier.com), and [Discussion Forum](https://discuss.zerotier.com).* +ZeroTier is a software defined networking layer for Earth. -ZeroTier 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. +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 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. +ZeroTier One is our OS-level client service. It allows Mac, Linux, Windows, FreeBSD, and soon other types of clients to join ZeroTier virtual networks like conventional VPNs or VLANs. It can run on native systems, VMs, or containers (Docker, OpenVZ, etc.). -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. +Visit [ZeroTier's site](https://www.zerotier.com/) for more information. You can also download professionally packaged binary installers/packages for a variety of supported OSes there if you don't want to build ZeroTier One from source. -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." +### Building from Source -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. +For Mac, Linux, and BSD, just type "make" (or "gmake" on BSD). You won't need much installed; here are the requirements for various platforms: -ZeroTier is licensed under the [BSL version 1.1](https://mariadb.com/bsl11/). See [LICENSE.txt](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. + * Mac: Xcode command line tools, and [Packages](http://s.sudre.free.fr/Software/Packages/about.html) if you want to build an OSX .pkg installer ("make mac-dist-pkg"). It should build on OSX 10.7 or newer. + * Linux: gcc/g++ or clang/clang++ (Makefile will use clang by default if available.) + * FreeBSD (and other BSD): C++ compiler (G++ usually) and GNU make (gmake). -A small amount of third party code is also included in ZeroTier and is not subject to our BSL license. See [AUTHORS.md](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.). +Each supported platform has its own *make-XXX.mk* file that contains the actual make rules for the platform. The right .mk file is included by the main Makefile based on the GNU make *OSTYPE* variable. Take a look at the .mk file for your platform for other targets, debug build rules, etc. -### Getting Started +Windows, of course, is special. We build for Windows with Microsoft Visual Studio 2012 on Windows 7. A solution file is located in the *windows* subfolder. Newer versions of Visual Studio (and Windows) may work but haven't been tested. Older versions almost certainly will not, since they lack things like *stdint.h* and certain STL features. MinGW or other ports of gcc/clang to Windows should also work but haven't been tested. Build steps for Windows are a bit more complicated. For the moment you are on your own there. -Everything in the ZeroTier world is controlled by two types of identifier: 40-bit/10-digit *ZeroTier addresses* and 64-bit/16-digit *network IDs*. These identifiers are easily distinguished by their length. A ZeroTier address identifies a node or "device" (laptop, phone, server, VM, app, etc.) while a network ID identifies a virtual Ethernet network that can be joined by devices. +Mobile versions are in progress. They don't work yet, and in any case only the glue code will be included in this repository. The full mobile apps are in private repositories on our own git server. -ZeroTier addresses can be thought of as port numbers on an enormous planet-wide enterprise Ethernet smart switch supporting VLANs. Network IDs are VLAN IDs to which these ports may be assigned. A single port can be assigned to more than one VLAN. +### Supported Platforms -A ZeroTier address looks like `8056c2e21c` and a network ID looks like `8056c2e21c000001`. Network IDs are composed of the ZeroTier address of that network's primary controller and an arbitrary 24-bit ID that identifies the network on this controller. Network controllers are roughly analogous to SDN controllers in SDN protocols like [OpenFlow](https://en.wikipedia.org/wiki/OpenFlow), though as with the analogy between VXLAN and VL2 this should not be read to imply that the protocols or design are the same. You can use our convenient and inexpensive SaaS hosted controllers at [my.zerotier.com](https://my.zerotier.com/) or [run your own controller](controller/) if you don't mind messing around with JSON configuration files or writing scripts to do so. +CPU architecture shouldn't matter unless it's smaller than 32-bit or something really bizarre like a "middle-endian" processor. We have reports of ZeroTier One running on arm32, arm64, and MIPS. It builds and runs out of the box on Raspberry Pi, BeagleBone, BananaPi, and other ARM-based developer/hobbyist boards. -### Project Layout +ZeroTier is written in C and C++ (C++03 / ISO/IEC 14882:2003) and uses data structures and algorithms from the C++03 STL. We do not use any C++11 features (yet), since we want to support a few old and embedded platforms that don't have C++11 compilers. You *will* require a compiler and headers new enough to support 64-bit integers (long long) and the *stdint.h* header. The latter could also be faked by adding defines for things like *uint32\_t*, *int64\_t*, etc. -The base path contains the ZeroTier One service main entry point (`one.cpp`), self test code, makefiles, etc. - - - `artwork/`: icons, logos, etc. - - `attic/`: old stuff and experimental code that we want to keep around for reference. - - `controller/`: the reference network controller implementation, which is built and included by default on desktop and server build targets. - - `debian/`: files for building Debian packages on Linux. - - `doc/`: manual pages and other documentation. - - `ext/`: third party libraries, binaries that we ship for convenience on some platforms (Mac and Windows), and installation support files. - - `include/`: include files for the ZeroTier core. - - `java/`: a JNI wrapper used with our Android mobile app. (The whole Android app is not open source but may be made so in the future.) - - `node/`: the ZeroTier virtual Ethernet switch core, which is designed to be entirely separate from the rest of the code and able to be built as a stand-alone OS-independent library. Note to developers: do not use C++11 features in here, since we want this to build on old embedded platforms that lack C++11 support. C++11 can be used elsewhere. - - `osdep/`: code to support and integrate with OSes, including platform-specific stuff only built for certain targets. - - `rule-compiler/`: JavaScript rules language compiler for defining network-level rules. - - `service/`: the ZeroTier One service, which wraps the ZeroTier core and provides VPN-like connectivity to virtual networks for desktops, laptops, servers, VMs, and containers. - - `windows/`: Visual Studio solution files, Windows service code, and the Windows task bar app UI. - - `zeroidc/`: OIDC implementation used by ZeroTier service to log into SSO-enabled networks. (This part is written in Rust, and more Rust will be appearing in this repository in the future.) - -### Contributing - -Please do pull requests off of the `dev` branch. - -Releases are done by merging `dev` into `main` and then tagging and doing builds. - -### Build and Platform Notes - -To build on Mac and Linux just type `make`. On FreeBSD and OpenBSD `gmake` (GNU make) is required and can be installed from packages or ports. For Windows there is a Visual Studio solution in `windows/`. - - - **Mac** - - Xcode command line tools for macOS 10.13 or newer are required. - - Rust for x86_64 and ARM64 targets *if SSO is enabled in the build*. - - **Linux** - - The minimum compiler versions required are GCC/G++ 8.x or CLANG/CLANG++ 5.x. - - Linux makefiles automatically detect and prefer clang/clang++ if present as it produces smaller and slightly faster binaries in most cases. You can override by supplying CC and CXX variables on the make command line. - - Rust for x86_64 and ARM64 targets *if SSO is enabled in the build*. - - **Windows** - - Visual Studio 2022 on Windows 10 or newer. - - Rust for x86_64 and ARM64 targets *if SSO is enabled in the build*. - - **FreeBSD** - - GNU make is required. Type `gmake` to build. - - `binutils` is required. Type `pkg install binutils` to install. - - Rust for x86_64 and ARM64 targets *if SSO is enabled in the build*. - - **OpenBSD** - - There is a limit of four network memberships on OpenBSD as there are only four tap devices (`/dev/tap0` through `/dev/tap3`). - - GNU make is required. Type `gmake` to build. - - Rust for x86_64 and ARM64 targets *if SSO is enabled in the build*. - -Typing `make selftest` will build a *zerotier-selftest* binary which unit tests various internals and reports on a few aspects of the build environment. It's a good idea to try this on novel platforms or architectures. +Typing "make selftest" will build a *zerotier-selftest* binary which unit tests various internals and reports on a few aspects of the build environment. It's a good idea to try this on novel platforms or architectures. ### Running -Running *zerotier-one* with `-h` option will show help. +Running *zerotier-one* with -h will show help. -On Linux and BSD, if you built from source, you can start the service with: +On Linux and BSD you can start the service with: sudo ./zerotier-one -d -On most distributions, macOS, and Windows, the installer will start the service and set it up to start on boot. - A home folder for your system will automatically be created. -The service is controlled via the JSON API, which by default is available at `127.0.0.1:9993`. It also listens on `0.0.0.0:9993` which is only usable if `allowManagementFrom` is properly configured in `local.conf`. We include a *zerotier-cli* command line utility to make API calls for standard things like joining and leaving networks. The *authtoken.secret* file in the home folder contains the secret token for accessing this API. See [service/README.md](service/README.md) for API documentation. +The service is controlled via the JSON API, which by default is available at 127.0.0.1 port 9993. We include a *zerotier-cli* command line utility to make API calls for standard things like joining and leaving networks. The *authtoken.secret* file in the home folder contains the secret token for accessing this API. See README.md in [service/](service/) for API documentation. Here's where home folders live (by default) on each OS: - * **Linux**: `/var/lib/zerotier-one` - * **FreeBSD** / **OpenBSD**: `/var/db/zerotier-one` - * **Mac**: `/Library/Application Support/ZeroTier/One` - * **Windows**: `\ProgramData\ZeroTier\One` (That's the default. The base 'shared app data' folder might be different if Windows is installed with a non-standard drive letter assignment or layout.) + * Linux: /var/lib/zerotier-one + * BSD: /var/db/zerotier-one + * Mac: /Library/Application Support/ZeroTier/One + * Windows: \\ProgramData\\ZeroTier\\One (That's for Windows 7. The base 'shared app data' folder might be different on different Windows versions.) -### Basic Troubleshooting +Running ZeroTier One on a Mac is the same, but OSX requires a kernel extension. We ship a signed binary build of the ZeroTier tap device driver, which can be installed on Mac with: + + sudo make install-mac-tap + +This will create the home folder for Mac, place *tap.kext* there, and set its modes correctly to enable ZeroTier One to manage it with *kextload* and *kextunload*. + +We recommend using our binary packages on Windows, since there are several prerequisites such as a tap driver that must be installed on the system *and* in the home folder. + +### Joining A Network + +ZeroTier virtual networks are identified by 16-digit hexadecimal network IDs, while devices are identified by 10-digit addresses. To get your address run: + + sudo zerotier-cli status + +(Use ./zerotier-cli if you're running it right from your build folder.) + +You should see something like: + + 200 info ########## ONLINE #.#.# + +That 10-digit hex code is you. It's derived via a one-way proof of work function from your cryptographic public key. Your public key can be found in *identity.public* in ZeroTier's home folder, while *identity.secret* contains your full identity including the secret portion of the key pair. + +(The identity files define your device's *identity*. Moving them to another system will move that identity. Be careful when cloning virtual machines that have identities stored on them. If two devices have the same identity, they'll "fight" over it and you won't know which device will receive network packets.) + +If you want to do a quick test, you can join [Earth](https://www.zerotier.com/earth.html). It's a global public network that anyone can join. Type: + + sudo zerotier-cli join 8056c2e21c000001 + +Then: + + sudo zerotier-cli listnetworks + +At first it'll be in *REQUESTING\_CONFIGURATION* state. In a few seconds to a minute you should see something like: + + 200 listnetworks 8056c2e21c000001 earth.zerotier.net ##:##:##:##:##:## OK PUBLIC zt0 ##.##.##.##/## + +Earth will assign you an IP address in the "unofficially available" globally unrouted 28.0.0.0/7 IP block so as to avoid conflicts with local networks. (Your networks can use any IP scheme, or can even leave IP addresses unmanaged.) Once you get an IP, you should be able to ping something: + + ping earth.zerotier.net + +Go to [http://earth.zerotier.net/](http://earth.zerotier.net/) to see a short little welcome page that will tell you your IP and Ethernet MAC address. + +Earth is a public place. If you don't want to stick around run: + + sudo zerotier-cli leave 8056c2e21c000001 + +The network (and associated interface) should be gone. + +Networks are created and administrated by network controllers. Most users will want to use our hosted controllers. Visit [our web site](https://www.zerotier.com/) for more information. Later in this README there are brief instructions about building ZeroTier One with network controller support for those who want to try running their own. + +Macintosh and Windows installers also install a GUI application. + +### Installing + +We don't have a "make install" rule quite yet. On Linux you can type: + + make installer + +This will build a binary that, when run, will install ZeroTier One on most current Linux distributions. We also have RPM and DEB build files in *ext/installfiles/linux* that wrap this installer in packages for RedHat/CentOS and Debian/Ubuntu derived distributions. If *rpmbuild* is present on the system, the RPM will be built. If *dpkg-deb* is present, the DEB package will be built. + +On Mac the best way is to install [Packages](http://s.sudre.free.fr/Software/Packages/about.html) and use: + + make mac-dist-pkg + +This builds a .pkg file that can be installed. + +BSD has no installer yet. We're working on it. + +Linux/BSD and Mac installations have an *uninstall.sh* file in their ZeroTier home folder that cleanly removes ZeroTier One from the system. Run this with: + + sudo /path/to/ZeroTier/home/folder/uninstall.sh + +Windows installers are insane. We build our .MSI installers with [Advanced Installer Enterprise](http://www.advancedinstaller.com). The Advanced Installer project file is in *ext/installfiles/windows*. To avoid lasting psychological trauma we recommend leaving Windows installers alone and using the pre-built Windows binaries on our web site. + +### Using ZeroTier One in Docker Containers + +To run the ZeroTier One service in a Docker container, run it with "--device=/dev/net/tun --cap-add=NET_ADMIN". This will allow ZeroTier One to open a "tap" virtual network port inside the container. + +Alternately, you can use Ethernet bridging to bridge the *docker0* device on your system to a ZeroTier virtual network. This allows you to run ZeroTier One on the host and bridge the entire Docker network backplane to a virtual network or other hosts. + +We're working on better "official" Docker support. In the meantime there is a [user-contributed project here](https://github.com/davide/docker-zerotier). + +### Building with Network Controller Support + +**Warning: as of beta version 1.0.3 the new network controller is not heavily tested. We recommend waiting for 1.0.4 to deploy this in production.** + +Network controllers are nodes responsible for issuing configurations and certificates to members of ZeroTier virtual networks. Most users won't need to run their own, so this code is by default not included in the ZeroTier One binary. + +You can build a network controller on Linux or Mac with: + + make ZT_ENABLE_NETWORK_CONTROLLER=1 + +This will build a version that contains the Sqlite-backed network controller and associated extensions to the JSON local service control API. You will need the development headers for sqlite3 installed. On Mac these ship as part of Xcode, while on Linux they'll be found in packages for the various distributions. + +See the JSON API documentation in [service/](service/) for more information about how to control controllers. + +### Troubleshooting For most users, it just works. -If you are running a local system firewall, we recommend adding a rules permitting zerotier. If you installed binaries for Windows this should be done automatically. Other platforms might require manual editing of local firewall rules depending on your configuration. +If you are running a local system firewall, we recommend adding a rule permitting UDP port 9993 inbound and outbound. If you installed binaries for Windows this should be done automatically. Other platforms might require manual editing of local firewall rules depending on your configuration. -See the [documentation site](https://docs.zerotier.com/zerotier/troubleshooting) for more information. +The Mac firewall can be founder under "Security" in System Preferences. Linux has a variety of firewall configuration systems and tools. If you're using Ubuntu's *ufw*, you can do this: -The Mac firewall can be found under "Security" in System Preferences. Linux has a variety of firewall configuration systems and tools. + sudo ufw allow 9993/udp -On CentOS check `/etc/sysconfig/iptables` for IPTables rules. For other distributions consult your distribution's documentation. You'll also have to check the UIs or documentation for commercial third party firewall applications like Little Snitch (Mac), McAfee Firewall Enterprise (Windows), etc. if you are running any of those. Some corporate environments might have centrally managed firewall software, so you might also have to contact IT. +On CentOS check */etc/sysconfig/iptables* for IPTables rules. For other distributions consult your distribution's documentation. You'll also have to check the UIs or documentation for commercial third party firewall applications like Little Snitch (Mac), McAfee Firewall Enterprise (Windows), etc. if you are running any of those. Some corporate environments might have centrally managed firewall software, so you might also have to contact IT. ZeroTier One peers will automatically locate each other and communicate directly over a local wired LAN *if UDP port 9993 inbound is open*. If that port is filtered, they won't be able to see each others' LAN announcement packets. If you're experiencing poor performance between devices on the same physical network, check their firewall settings. Without LAN auto-location peers must attempt "loopback" NAT traversal, which sometimes fails and in any case requires that every packet traverse your external router twice. -Users behind certain types of firewalls and "symmetric" NAT devices may not be able to connect to external peers directly at all. ZeroTier has limited support for port prediction and will *attempt* to traverse symmetric NATs, but this doesn't always work. If P2P connectivity fails you'll be bouncing UDP packets off our relay servers resulting in slower performance. Some NAT router(s) have a configurable NAT mode, and setting this to "full cone" will eliminate this problem. If you do this you may also see a magical improvement for things like VoIP phones, Skype, BitTorrent, WebRTC, certain games, etc., since all of these use NAT traversal techniques similar to ours. +Users behind certain types of firewalls and "symmetric" NAT devices may not able able to connect to external peers directly at all. ZeroTier has limited support for port prediction and will *attempt* to traverse symmetric NATs, but this doesn't always work. If P2P connectivity fails you'll be bouncing UDP packets off our relay servers resulting in slower performance. Some NAT router(s) have a configurable NAT mode, and setting this to "full cone" will eliminate this problem. If you do this you may also see a magical improvement for things like VoIP phones, Skype, BitTorrent, WebRTC, certain games, etc., since all of these use NAT traversal techniques similar to ours. + +If you're interested, there's a [technical deep dive about NAT traversal on our blog](https://www.zerotier.com/blog/?p=226). A troubleshooting tool to help you diagnose NAT issues is planned for the future as are uPnP/IGD/NAT-PMP and IPv6 transport. If a firewall between you and the Internet blocks ZeroTier's UDP traffic, you will fall back to last-resort TCP tunneling to rootservers over port 443 (https impersonation). This will work almost anywhere but is *very slow* compared to UDP or direct peer to peer connectivity. -Additional help can be found in our [knowledge base](https://zerotier.atlassian.net/wiki/spaces/SD/overview). +### License -### Prometheus Metrics - -Prometheus Metrics are available at the `/metrics` API endpoint. This endpoint is protected by an API key stored in `metricstoken.secret` to prevent unwanted information leakage. Information that could be gleaned from the metrics include joined networks and peers your instance is talking to. - -Access control is via the ZeroTier control interface itself and `metricstoken.secret`. This can be sent as a bearer auth token, via the `X-ZT1-Auth` HTTP header field, or appended to the URL as `?auth=`. You can see the current metrics via `cURL` with the following command: - - // Linux - curl -H "X-ZT1-Auth: $(sudo cat /var/lib/zerotier-one/metricstoken.secret)" http://localhost:9993/metrics - - // macOS - curl -H "X-ZT1-Auth: $(sudo cat /Library/Application\ Support/ZeroTier/One/metricstoken.secret)" http://localhost:9993/metrics - - // Windows PowerShell (Admin) - Invoke-RestMethod -Headers @{'X-ZT1-Auth' = "$(Get-Content C:\ProgramData\ZeroTier\One\metricstoken.secret)"; } -Uri http://localhost:9993/metrics - -To configure a scrape job in Prometheus on the machine ZeroTier is running on, add this to your Prometheus `scrape_config`: - - - job_name: zerotier-one - honor_labels: true - scrape_interval: 15s - metrics_path: /metrics - static_configs: - - targets: - - 127.0.0.1:9993 - labels: - group: zerotier-one - node_id: $YOUR_10_CHARACTER_NODE_ID - authorization: - credentials: $YOUR_METRICS_TOKEN_SECRET - -If neither of these methods are desirable, it is probably possible to distribute metrics via [Prometheus Proxy](https://github.com/pambrose/prometheus-proxy) or some other tool. Note: We have not tested this internally, but will probably work with the correct configuration. - -Metrics are also available on disk in ZeroTier's working directory: - - // Linux - /var/lib/zerotier-one/metrics.prom - - // macOS - /Library/Application\ Support/ZeroTier/One/metrics.prom - - //Windows - C:\ProgramData\ZeroTier\One\metrics.prom - -#### Available Metrics - -| Metric Name | Labels | Metric Type | Description | -| --- | --- | --- | --- | -| zt_packet | packet_type, direction | Counter | ZeroTier packet type counts | -| zt_packet_error | error_type, direction | Counter | ZeroTier packet errors| -| zt_data | protocol, direction | Counter | number of bytes ZeroTier has transmitted or received | -| zt_num_networks | | Gauge | number of networks this instance is joined to | -| zt_network_multicast_groups_subscribed | network_id | Gauge | number of multicast groups networks are subscribed to | -| zt_network_packets | network_id, direction | Counter | number of incoming/outgoing packets per network | -| zt_peer_latency | node_id | Histogram | peer latency (ms) | -| zt_peer_path_count | node_id, status | Gauge | number of paths to peer | -| zt_peer_packets | node_id, direction | Counter | number of packets to/from a peer | -| zt_peer_packet_errors | node_id | Counter | number of incoming packet errors from a peer | - -If there are other metrics you'd like to see tracked, ask us in an Issue or send us a Pull Request! - -### HTTP / App server - -There is a static http file server suitable for hosting Single Page Apps at http://localhost:9993/app/ - -Use `zerotier-cli info -j` to find your zerotier-one service's homeDir - -``` sh -cd $ZT_HOME -sudo mkdir -p app/app1 -sudo mkdir -p app/appB -echo 'appA

hello world A' | sudo tee app/appA/index.html -echo 'app2

hello world 2' | sudo tee app/app2/index.html -curl -sL http://localhost:9993/app/appA http://localhost:9993/app/app2 -``` - -Then visit [http://localhost:9993/app/app1/](http://localhost:9993/app/app1/) and [http://localhost:9993/app/appB/](http://localhost:9993/app/appB/) - -Requests to paths don't exist return the app root index.html, as is customary for SPAs. -If you want, you can write some javascript that talks to the service or controller [api](https://docs.zerotier.com/service/v1). +The ZeroTier source code is open source and is licensed under the GNU GPL v3 (not LGPL). If you'd like to embed it in a closed-source commercial product or appliance, please e-mail [contact@zerotier.com](mailto:contact@zerotier.com) to discuss commercial licensing. Otherwise it can be used for free. diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md deleted file mode 100644 index e6582207e..000000000 --- a/RELEASE-NOTES.md +++ /dev/null @@ -1,506 +0,0 @@ -ZeroTier Release Notes -====== - -# 2024-10-23 -- Version 1.14.2 - - * Fix for missing entitlement on macOS Sequoia. - * Fix for a problem correctly parsing local.conf to enable low bandwidth mode. - * Increment versions of some dependent libraries. - * Other fixes. - -# 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 deleted file mode 100644 index c539ed6a2..000000000 --- a/SECURITY.md +++ /dev/null @@ -1,93 +0,0 @@ -# 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----- - -mQINBGQGOVIBEACalXTnNqaiSOVLFEiqHpDMg8N/OI5D5850Xy1ZEvx3B3rz7cbn -k30ozHtJKbh+vqpyItE7DjyQAuF19gP5Q64Yh0Y+MmLHq60q/GwOwAYz7cI+UzA3 -5x8YqcmTp32LAM1xJn+iMlMLBuAmJl4kULKmOXPlpqPiyTFs5saizvm7fgRmfgJJ -HpsnIrTkaDFJhAR+jvMJohVYwmhuydeI0DsHu7KGpG1ddcHDrUjOPNqXnnAPSPwx -llw4yfKlQb8GYErsv/G5QVyzd5+SxEuiI4MARRnrk8LlMQ33CR6pzIQ/Bk5AAmye -mHqfEAknkiOf++urYhRs9BL3Kz3MdV0cg92zr9EFOg0u56jxf5OnAiTOhGUUA0hn -dS7peVGl46R9Oy2JYIazNDGi+4NIsYDFXsnsss9xOQVygPyeQd71zFHfix0jct9w -j3o/kj7Egsnm9nc13354bYT6bbalqXiRWwGH1eAFpjueNWiVFwZS6NZUP3WeNDiY -BlPo1LodvolbXiJcTILTCyEkERJPCK2zoE2nTdVfvTLWsuehw1M6Yd2/q74TVYy/ -RY+KjHkrChEBQ9PqXsXRHj6opKbT8JLfZkvU5k+3IiqqxOpB+QXFI/whj493CxWW -so7QAmzOCyJq8GDVPxzkwUac22YIkXdiOmb8i/HWq+kLY/HjQE259Gx6KwARAQAB -tClaZXJvVGllciBTZWN1cml0eSA8c2VjdXJpdHlAemVyb3RpZXIuY29tPokCTAQT -AQoANhYhBH1HQGb+4jzl6mnFqf09m6uqADkABQJkBjlSAhsDBAsJCAcEFQoJCAUW -AgMBAAIeAQIXgAAKCRD9PZurqgA5ACqPD/sFt6SG6Tu0HwTY2ofJtYsa2GBLL0pf -dYlX4cWSs1PVB5+m5Oj18y+GB2umA9GnsVtmvaSfp3XEngt2zNWX27uUsVfL35b2 -/5TVVe8RjzOedqMN+lQWMvO+f/C1zmWYXjjpC+iGjgMMaRRrofkkn+7uL4N9y6gY -rcXtpACT1rYFC+i1AKnZfUO8Vr5ji7odq0f7bDkN/N38rB0kRRwEmO8wqdpQK6gK -nxf9vgJl5ggimDk5Xtz1sfd3y28bf5N4hdOCkXUbd10nUFY3wDNTM4VxozxTGJeG -imdcc19Wuw/1fGUZ5SIjgPanCdPLGYwSTr+M6Fuern9uTtlC1GOby3BUtmVGP6EU -1pSAJSRpmoBPHKKOYtSMwV8PCboXru9P1ab8y8STKM3SKyghUJrl17gdc0LaksZa -E54pJudGPIQMFRqZjMdV6jgMuaLTozjZ4mW8EThf4mkX4xDkO8l7cOn0225ZYJZC -lZKpdnwzk9owkJA80u4KBNJxTtB4ZAPzjBsD5hFzCZQTLNQp/psU3EjZsau28eXT -E/C1QjEQHgy4ohkgQlCm1H1+clKssCWcdmsVGXuS1u8gh4K6X9b0Z6LeCGRaQvH2 -+DB8oTAdqp9nUZv9rP4pbo+sR4fF67CFLriVuxjedAiFkbM4uHMFcL4tc/X9+DRo -YN5X7oEkZvO507kCDQRkBjlSARAAz58UMF7K1qKyQjzKTcutaYZ5SaIGky9lCLZn -/2vjpFCoBogkxS/6IKQcwZk8b4S9QstaaQZDFEkxqNeKC0GiFTAMAb6SmYcK495h -EZnHl0NA5Nc2dBlZk5E/ENzTCz2bXaxCcVESc2z+xCzu07brbhGrqvliKiwOUzt9 -JzqEsar6I95OutBcZvkFCs44/Uf9bS1qf1w4klE8w3vdMtGH23umrET4tFZ+sh6o -ZFtQx0u2eKjsRdn/RMtsxLNaJlcE1DdIAqBpQrcmuwMC8v5wUGfCGZjhClzmyQlq -akUkayir7UtbHbFT/mgO+YI77YGXWk5QrwPscqqT2l8KB/YMujNDmaWa/0KV1lIY -zr5s4dzVeiwqFLR9ANFIhzFwzf3JLi6XSx123Qix0TxZoYPZCHl7yoi9qi6qybz5 -0Od2LSz3jbApeKYymZ+zjE+YV5y9DI6Wzy1j2M1FogNvTO9fMk+6dLt4HhTdSNvH -cKya462YCcy+tnZTkhmh+FTebbJlV6D4wG7skE5KCdBhjm53xLwp6XW9L6n2CrkL -W1IDBcCz0oPd1sMkXbO3wnxdXprV2XurCfsg/R2nszSNzvdJ8/xj3cr9hpoJ714R -qqyoEDRZ1Ss9kGL166o5MpN5qb/EewdkqGgWP7YFXbhsdHQiW7Z7dAqzjoaybD4O -nakkwyUAEQEAAYkCNgQYAQoAIBYhBH1HQGb+4jzl6mnFqf09m6uqADkABQJkBjlS -AhsMAAoJEP09m6uqADkAax0P/Rh8EZYRqW6dPYTl1YQusAK10rAcRNq3ekjofXGk -oXK1S7HWGoFgl5++5nfSfNgFJ5VLcgIM56wtIf49zFjWe5oC6fw8k+ghh4d2chMP -hdDILx6e0c30Iq1+EvovGR9hWa0wJ4cKTdzlwhY9ZC09q0ia+bl2mwpie1JQDR0c -zXCjt+PldLeeK9z1/XT0Q7KowYC+U18oR+KFm+EaRV4QT85JVequnIeGkmaHJrHB -lH4T5A5ib7y8edon1c0Zx3GsaxJUojkEJ0SX7ffVDu6ztUZfkHfCVpMW4VzUeGA/ -m+CtFO9ciLRGZEkRa+zhIGoBvwEXU0GiwiF4nZ0F2C8UioeW0YIEV9zl3nXJctYE -ZKc2whSENQRTGgaYHVoVZhznt71LKWgFLshwBo81UCXVkzwAjMW1ActDnmPw5M7q -xR5Qp5G49Z1GmfSozazha0HVFPKNV5i3RlTzs4yLUnZyH0yC9IvtOefMHcLjG96L -N5miEV97gvJJjrn8rhRvpUwAWgmT/9IuYjBNQTtNN40arto5HxezR76WCjdKYxdL -p3dM1iiBDShHNm7LdyZlLFhTOMU0tNBxJJ7B09ar5gakeZjD+2aB1ODX9VuFtozL -onBjI2gIkry0UIkuznHfFw05lZAZAiqHEVgVi/WTk4C/bklDZNgE0lx+IWzEz2iS -L455 -=lheL ------END PGP PUBLIC KEY BLOCK----- -``` diff --git a/artwork/AppIcon.png b/artwork/AppIcon.png deleted file mode 100644 index b96076bea..000000000 Binary files a/artwork/AppIcon.png and /dev/null differ diff --git a/artwork/AppIcon@2x.png b/artwork/AppIcon@2x.png deleted file mode 100644 index 6f1952e03..000000000 Binary files a/artwork/AppIcon@2x.png and /dev/null differ diff --git a/artwork/AppIcon@3x.png b/artwork/AppIcon@3x.png deleted file mode 100644 index b32d3230f..000000000 Binary files a/artwork/AppIcon@3x.png and /dev/null differ diff --git a/artwork/AppIcon_1024x1024.png b/artwork/AppIcon_1024x1024.png deleted file mode 100644 index c423c4f73..000000000 Binary files a/artwork/AppIcon_1024x1024.png and /dev/null differ diff --git a/artwork/AppIcon_20x20.png b/artwork/AppIcon_20x20.png deleted file mode 100644 index bb10b4781..000000000 Binary files a/artwork/AppIcon_20x20.png and /dev/null differ diff --git a/artwork/AppIcon_29x29.png b/artwork/AppIcon_29x29.png deleted file mode 100644 index 762af5c7f..000000000 Binary files a/artwork/AppIcon_29x29.png and /dev/null differ diff --git a/artwork/AppIcon_40x40.png b/artwork/AppIcon_40x40.png deleted file mode 100644 index b0a44c4f3..000000000 Binary files a/artwork/AppIcon_40x40.png and /dev/null differ diff --git a/artwork/AppIcon_58x58.png b/artwork/AppIcon_58x58.png deleted file mode 100644 index 6778218ef..000000000 Binary files a/artwork/AppIcon_58x58.png and /dev/null differ diff --git a/artwork/AppIcon_60x60.png b/artwork/AppIcon_60x60.png deleted file mode 100644 index bb46ae750..000000000 Binary files a/artwork/AppIcon_60x60.png and /dev/null differ diff --git a/artwork/AppIcon_80x80.png b/artwork/AppIcon_80x80.png deleted file mode 100644 index 3d630d4e2..000000000 Binary files a/artwork/AppIcon_80x80.png and /dev/null differ diff --git a/artwork/AppIcon_87x87.png b/artwork/AppIcon_87x87.png deleted file mode 100644 index cd864eb99..000000000 Binary files a/artwork/AppIcon_87x87.png and /dev/null differ diff --git a/artwork/AppIcon_90x90.png b/artwork/AppIcon_90x90.png deleted file mode 100644 index 0a618bbbb..000000000 Binary files a/artwork/AppIcon_90x90.png and /dev/null differ diff --git a/artwork/AppIcon_iPad@2x.png b/artwork/AppIcon_iPad@2x.png deleted file mode 100644 index 0d3d7a7fe..000000000 Binary files a/artwork/AppIcon_iPad@2x.png and /dev/null differ diff --git a/artwork/AppIcon_iPadPro@2x.png b/artwork/AppIcon_iPadPro@2x.png deleted file mode 100644 index 9a8cfcfbd..000000000 Binary files a/artwork/AppIcon_iPadPro@2x.png and /dev/null differ diff --git a/artwork/ZeroTierIcon32x32.png b/artwork/ZeroTierIcon32x32.png deleted file mode 100644 index 24ff0a1cc..000000000 Binary files a/artwork/ZeroTierIcon32x32.png and /dev/null differ diff --git a/artwork/ZeroTierIcon512x512.png b/artwork/ZeroTierIcon512x512.png deleted file mode 100644 index d225c2e33..000000000 Binary files a/artwork/ZeroTierIcon512x512.png and /dev/null differ diff --git a/attic/BandwidthAccount.hpp b/attic/BandwidthAccount.hpp new file mode 100644 index 000000000..3a6432c44 --- /dev/null +++ b/attic/BandwidthAccount.hpp @@ -0,0 +1,153 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#ifndef ZT_BWACCOUNT_HPP +#define ZT_BWACCOUNT_HPP + +#include "Constants.hpp" + +#include + +#include +#include + +#include "Utils.hpp" + +#ifdef __WINDOWS__ +#define round(x) ((x-floor(x))>0.5 ? ceil(x) : floor(x)) +#endif + +namespace ZeroTier { + +/** + * Bandwidth account used for rate limiting multicast groups + * + * This is used to apply a bank account model to multicast groups. Each + * multicast packet counts against a balance, which accrues at a given + * rate in bytes per second. Debt is possible. These parameters are + * configurable. + * + * A bank account model permits bursting behavior, which correctly models + * how OSes and apps typically use multicast. It's common for things to + * spew lots of multicast messages at once, wait a while, then do it + * again. A consistent bandwidth limit model doesn't fit. + */ +class BandwidthAccount +{ +public: + /** + * Create an uninitialized account + * + * init() must be called before this is used. + */ + BandwidthAccount() throw() {} + + /** + * Create and initialize + * + * @param preload Initial balance to place in account + * @param maxb Maximum allowed balance (> 0) + * @param acc Rate of accrual in bytes per second + * @param now Current time + */ + BandwidthAccount(uint32_t preload,uint32_t maxb,uint32_t acc,uint64_t now) + throw() + { + init(preload,maxb,acc,now); + } + + /** + * Initialize or re-initialize account + * + * @param preload Initial balance to place in account + * @param maxb Maximum allowed balance (> 0) + * @param acc Rate of accrual in bytes per second + * @param now Current time + */ + inline void init(uint32_t preload,uint32_t maxb,uint32_t acc,uint64_t now) + throw() + { + _lastTime = ((double)now / 1000.0); + _balance = preload; + _maxBalance = maxb; + _accrual = acc; + } + + /** + * Update and retrieve balance of this account + * + * @param now Current time + * @return New balance updated from current clock + */ + inline uint32_t update(uint64_t now) + throw() + { + double lt = _lastTime; + double nowf = ((double)now / 1000.0); + _lastTime = nowf; + return (_balance = std::min(_maxBalance,(uint32_t)round((double)_balance + ((double)_accrual * (nowf - lt))))); + } + + /** + * Update balance and conditionally deduct + * + * If the deduction amount fits, it is deducted after update. Otherwise + * balance is updated and false is returned. + * + * @param amt Amount to deduct + * @param now Current time + * @return True if amount fit within balance and was deducted + */ + inline bool deduct(uint32_t amt,uint64_t now) + throw() + { + if (update(now) >= amt) { + _balance -= amt; + return true; + } + return false; + } + + /** + * @return Most recent balance without update + */ + inline uint32_t balance() const + throw() + { + return _balance; + } + +private: + double _lastTime; + uint32_t _balance; + uint32_t _maxBalance; + uint32_t _accrual; +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/Filter.cpp b/attic/Filter.cpp new file mode 100644 index 000000000..a701e8b70 --- /dev/null +++ b/attic/Filter.cpp @@ -0,0 +1,408 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#include +#include +#include +#include + +#include + +#include "RuntimeEnvironment.hpp" +#include "Logger.hpp" +#include "Filter.hpp" +#include "Utils.hpp" + +namespace ZeroTier { + +const char *const Filter::UNKNOWN_NAME = "(unknown)"; +const Range Filter::ANY; + +static inline Range __parseRange(char *r) + throw(std::invalid_argument) +{ + char *saveptr = (char *)0; + unsigned int a = 0; + unsigned int b = 0; + unsigned int fn = 0; + for(char *f=Utils::stok(r,"-",&saveptr);(f);f=Utils::stok((char *)0,"-",&saveptr)) { + if (*f) { + switch(fn++) { + case 0: + if (*f != '*') + a = b = (unsigned int)strtoul(f,(char **)0,10); + break; + case 1: + if (*f != '*') + b = (unsigned int)strtoul(f,(char **)0,10); + break; + default: + throw std::invalid_argument("rule range must be , -, or *"); + } + } + } + return Range(a,b); +} + +Filter::Rule::Rule(const char *s) + throw(std::invalid_argument) +{ + char *saveptr = (char *)0; + char tmp[256]; + if (!Utils::scopy(tmp,sizeof(tmp),s)) + throw std::invalid_argument("rule string too long"); + unsigned int fn = 0; + for(char *f=Utils::stok(tmp,";",&saveptr);(f);f=Utils::stok((char *)0,";",&saveptr)) { + if (*f) { + switch(fn++) { + case 0: + _etherType = __parseRange(f); + break; + case 1: + _protocol = __parseRange(f); + break; + case 2: + _port = __parseRange(f); + break; + default: + throw std::invalid_argument("rule string has unknown extra fields"); + } + } + } + if (fn != 3) + throw std::invalid_argument("rule string must contain 3 fields"); +} + +bool Filter::Rule::operator()(unsigned int etype,const void *data,unsigned int len) const + throw(std::invalid_argument) +{ + if ((!_etherType)||(_etherType(etype))) { // ethertype is ANY, or matches + // Ethertype determines meaning of protocol and port + switch(etype) { + case ZT_ETHERTYPE_IPV4: + if (len > 20) { + if ((!_protocol)||(_protocol(((const uint8_t *)data)[9]))) { // protocol is ANY or match + if (!_port) // port is ANY + return true; + + // Don't match on fragments beyond fragment 0. If we've blocked + // fragment 0, further fragments will fall on deaf ears anyway. + if ((Utils::ntoh(((const uint16_t *)data)[3]) & 0x1fff)) + return false; + + // Internet header length determines where data begins, in multiples of 32 bits + unsigned int ihl = 4 * (((const uint8_t *)data)[0] & 0x0f); + + switch(((const uint8_t *)data)[9]) { // port's meaning depends on IP protocol + case ZT_IPPROTO_ICMP: + // For ICMP, port is ICMP type + return _port(((const uint8_t *)data)[ihl]); + case ZT_IPPROTO_TCP: + case ZT_IPPROTO_UDP: + case ZT_IPPROTO_SCTP: + case ZT_IPPROTO_UDPLITE: + // For these, port is destination port. Protocol designers were + // nice enough to put the field in the same place. + return _port(((const uint16_t *)data)[(ihl / 2) + 1]); + default: + // port has no meaning for other IP types, so ignore it + return true; + } + + return false; // no match on port + } + } else throw std::invalid_argument("undersized IPv4 packet"); + break; + + case ZT_ETHERTYPE_IPV6: + if (len > 40) { + int nextHeader = ((const uint8_t *)data)[6]; + unsigned int pos = 40; + while ((pos < len)&&(nextHeader >= 0)&&(nextHeader != 59)) { // 59 == no next header + fprintf(stderr,"[rule] V6: start header parse, header %.2x pos %d\n",nextHeader,pos); + + switch(nextHeader) { + case 0: // hop-by-hop options + case 60: // destination options + case 43: // routing + case 135: // mobility (mobile IPv6 options) + if (_protocol((unsigned int)nextHeader)) + return true; // match if our goal was to match any of these + nextHeader = ((const uint8_t *)data)[pos]; + pos += 8 + (8 * ((const uint8_t *)data)[pos + 1]); + break; + case 44: // fragment + if (_protocol(44)) + return true; // match if our goal was to match fragments + nextHeader = ((const uint8_t *)data)[pos]; + pos += 8; + break; + case ZT_IPPROTO_AH: // AH + return _protocol(ZT_IPPROTO_AH); // true if AH is matched protocol, otherwise false since packet will be IPsec + case ZT_IPPROTO_ESP: // ESP + return _protocol(ZT_IPPROTO_ESP); // true if ESP is matched protocol, otherwise false since packet will be IPsec + case ZT_IPPROTO_ICMPV6: + // Only match ICMPv6 if we've selected it specifically + if (_protocol(ZT_IPPROTO_ICMPV6)) { + // Port is interpreted as ICMPv6 type + if ((!_port)||(_port(((const uint8_t *)data)[pos]))) + return true; + } + break; + case ZT_IPPROTO_TCP: + case ZT_IPPROTO_UDP: + case ZT_IPPROTO_SCTP: + case ZT_IPPROTO_UDPLITE: + // If we encounter any of these, match if protocol matches or is wildcard as + // we'll consider these the "real payload" if present. + if ((!_protocol)||(_protocol(nextHeader))) { + if ((!_port)||(_port(((const uint16_t *)data)[(pos / 2) + 1]))) + return true; // protocol matches or is ANY, port is ANY or matches + } + break; + default: { + char foo[128]; + Utils::snprintf(foo,sizeof(foo),"unrecognized IPv6 header type %d",(int)nextHeader); + throw std::invalid_argument(foo); + } + } + + fprintf(stderr,"[rule] V6: end header parse, next header %.2x, new pos %d\n",nextHeader,pos); + } + } else throw std::invalid_argument("undersized IPv6 packet"); + break; + + default: + // For other ethertypes, protocol and port are ignored. What would they mean? + return true; + } + } + + return false; +} + +std::string Filter::Rule::toString() const +{ + char buf[128]; + std::string s; + + switch(_etherType.magnitude()) { + case 0: + s.push_back('*'); + break; + case 1: + Utils::snprintf(buf,sizeof(buf),"%u",_etherType.start); + s.append(buf); + break; + default: + Utils::snprintf(buf,sizeof(buf),"%u-%u",_etherType.start,_etherType.end); + s.append(buf); + break; + } + s.push_back(';'); + switch(_protocol.magnitude()) { + case 0: + s.push_back('*'); + break; + case 1: + Utils::snprintf(buf,sizeof(buf),"%u",_protocol.start); + s.append(buf); + break; + default: + Utils::snprintf(buf,sizeof(buf),"%u-%u",_protocol.start,_protocol.end); + s.append(buf); + break; + } + s.push_back(';'); + switch(_port.magnitude()) { + case 0: + s.push_back('*'); + break; + case 1: + Utils::snprintf(buf,sizeof(buf),"%u",_port.start); + s.append(buf); + break; + default: + Utils::snprintf(buf,sizeof(buf),"%u-%u",_port.start,_port.end); + s.append(buf); + break; + } + + return s; +} + +Filter::Filter(const char *s) + throw(std::invalid_argument) +{ + char tmp[16384]; + if (!Utils::scopy(tmp,sizeof(tmp),s)) + throw std::invalid_argument("filter string too long"); + char *saveptr = (char *)0; + unsigned int fn = 0; + for(char *f=Utils::stok(tmp,",",&saveptr);(f);f=Utils::stok((char *)0,",",&saveptr)) { + try { + _rules.push_back(Rule(f)); + ++fn; + } catch (std::invalid_argument &exc) { + char tmp[256]; + Utils::snprintf(tmp,sizeof(tmp),"invalid rule at index %u: %s",fn,exc.what()); + throw std::invalid_argument(tmp); + } + } + std::sort(_rules.begin(),_rules.end()); +} + +std::string Filter::toString() const +{ + std::string s; + + for(std::vector::const_iterator r(_rules.begin());r!=_rules.end();++r) { + if (s.length() > 0) + s.push_back(','); + s.append(r->toString()); + } + + return s; +} + +void Filter::add(const Rule &r) +{ + for(std::vector::iterator rr(_rules.begin());rr!=_rules.end();++rr) { + if (r == *rr) + return; + } + _rules.push_back(r); + std::sort(_rules.begin(),_rules.end()); +} + +const char *Filter::etherTypeName(const unsigned int etherType) + throw() +{ + switch(etherType) { + case ZT_ETHERTYPE_IPV4: return "ETHERTYPE_IPV4"; + case ZT_ETHERTYPE_ARP: return "ETHERTYPE_ARP"; + case ZT_ETHERTYPE_RARP: return "ETHERTYPE_RARP"; + case ZT_ETHERTYPE_ATALK: return "ETHERTYPE_ATALK"; + case ZT_ETHERTYPE_AARP: return "ETHERTYPE_AARP"; + case ZT_ETHERTYPE_IPX_A: return "ETHERTYPE_IPX_A"; + case ZT_ETHERTYPE_IPX_B: return "ETHERTYPE_IPX_B"; + case ZT_ETHERTYPE_IPV6: return "ETHERTYPE_IPV6"; + } + return UNKNOWN_NAME; +} + +const char *Filter::ipProtocolName(const unsigned int ipp) + throw() +{ + switch(ipp) { + case ZT_IPPROTO_ICMP: return "IPPROTO_ICMP"; + case ZT_IPPROTO_IGMP: return "IPPROTO_IGMP"; + case ZT_IPPROTO_TCP: return "IPPROTO_TCP"; + case ZT_IPPROTO_UDP: return "IPPROTO_UDP"; + case ZT_IPPROTO_GRE: return "IPPROTO_GRE"; + case ZT_IPPROTO_ESP: return "IPPROTO_ESP"; + case ZT_IPPROTO_AH: return "IPPROTO_AH"; + case ZT_IPPROTO_ICMPV6: return "IPPROTO_ICMPV6"; + case ZT_IPPROTO_OSPF: return "IPPROTO_OSPF"; + case ZT_IPPROTO_IPIP: return "IPPROTO_IPIP"; + case ZT_IPPROTO_IPCOMP: return "IPPROTO_IPCOMP"; + case ZT_IPPROTO_L2TP: return "IPPROTO_L2TP"; + case ZT_IPPROTO_SCTP: return "IPPROTO_SCTP"; + case ZT_IPPROTO_FC: return "IPPROTO_FC"; + case ZT_IPPROTO_UDPLITE: return "IPPROTO_UDPLITE"; + case ZT_IPPROTO_HIP: return "IPPROTO_HIP"; + } + return UNKNOWN_NAME; +} + +const char *Filter::icmpTypeName(const unsigned int icmpType) + throw() +{ + switch(icmpType) { + case ZT_ICMP_ECHO_REPLY: return "ICMP_ECHO_REPLY"; + case ZT_ICMP_DESTINATION_UNREACHABLE: return "ICMP_DESTINATION_UNREACHABLE"; + case ZT_ICMP_SOURCE_QUENCH: return "ICMP_SOURCE_QUENCH"; + case ZT_ICMP_REDIRECT: return "ICMP_REDIRECT"; + case ZT_ICMP_ALTERNATE_HOST_ADDRESS: return "ICMP_ALTERNATE_HOST_ADDRESS"; + case ZT_ICMP_ECHO_REQUEST: return "ICMP_ECHO_REQUEST"; + case ZT_ICMP_ROUTER_ADVERTISEMENT: return "ICMP_ROUTER_ADVERTISEMENT"; + case ZT_ICMP_ROUTER_SOLICITATION: return "ICMP_ROUTER_SOLICITATION"; + case ZT_ICMP_TIME_EXCEEDED: return "ICMP_TIME_EXCEEDED"; + case ZT_ICMP_BAD_IP_HEADER: return "ICMP_BAD_IP_HEADER"; + case ZT_ICMP_TIMESTAMP: return "ICMP_TIMESTAMP"; + case ZT_ICMP_TIMESTAMP_REPLY: return "ICMP_TIMESTAMP_REPLY"; + case ZT_ICMP_INFORMATION_REQUEST: return "ICMP_INFORMATION_REQUEST"; + case ZT_ICMP_INFORMATION_REPLY: return "ICMP_INFORMATION_REPLY"; + case ZT_ICMP_ADDRESS_MASK_REQUEST: return "ICMP_ADDRESS_MASK_REQUEST"; + case ZT_ICMP_ADDRESS_MASK_REPLY: return "ICMP_ADDRESS_MASK_REPLY"; + case ZT_ICMP_TRACEROUTE: return "ICMP_TRACEROUTE"; + case ZT_ICMP_MOBILE_HOST_REDIRECT: return "ICMP_MOBILE_HOST_REDIRECT"; + case ZT_ICMP_MOBILE_REGISTRATION_REQUEST: return "ICMP_MOBILE_REGISTRATION_REQUEST"; + case ZT_ICMP_MOBILE_REGISTRATION_REPLY: return "ICMP_MOBILE_REGISTRATION_REPLY"; + } + return UNKNOWN_NAME; +} + +const char *Filter::icmp6TypeName(const unsigned int icmp6Type) + throw() +{ + switch(icmp6Type) { + case ZT_ICMP6_DESTINATION_UNREACHABLE: return "ICMP6_DESTINATION_UNREACHABLE"; + case ZT_ICMP6_PACKET_TOO_BIG: return "ICMP6_PACKET_TOO_BIG"; + case ZT_ICMP6_TIME_EXCEEDED: return "ICMP6_TIME_EXCEEDED"; + case ZT_ICMP6_PARAMETER_PROBLEM: return "ICMP6_PARAMETER_PROBLEM"; + case ZT_ICMP6_ECHO_REQUEST: return "ICMP6_ECHO_REQUEST"; + case ZT_ICMP6_ECHO_REPLY: return "ICMP6_ECHO_REPLY"; + case ZT_ICMP6_MULTICAST_LISTENER_QUERY: return "ICMP6_MULTICAST_LISTENER_QUERY"; + case ZT_ICMP6_MULTICAST_LISTENER_REPORT: return "ICMP6_MULTICAST_LISTENER_REPORT"; + case ZT_ICMP6_MULTICAST_LISTENER_DONE: return "ICMP6_MULTICAST_LISTENER_DONE"; + case ZT_ICMP6_ROUTER_SOLICITATION: return "ICMP6_ROUTER_SOLICITATION"; + case ZT_ICMP6_ROUTER_ADVERTISEMENT: return "ICMP6_ROUTER_ADVERTISEMENT"; + case ZT_ICMP6_NEIGHBOR_SOLICITATION: return "ICMP6_NEIGHBOR_SOLICITATION"; + case ZT_ICMP6_NEIGHBOR_ADVERTISEMENT: return "ICMP6_NEIGHBOR_ADVERTISEMENT"; + case ZT_ICMP6_REDIRECT_MESSAGE: return "ICMP6_REDIRECT_MESSAGE"; + case ZT_ICMP6_ROUTER_RENUMBERING: return "ICMP6_ROUTER_RENUMBERING"; + case ZT_ICMP6_NODE_INFORMATION_QUERY: return "ICMP6_NODE_INFORMATION_QUERY"; + case ZT_ICMP6_NODE_INFORMATION_RESPONSE: return "ICMP6_NODE_INFORMATION_RESPONSE"; + case ZT_ICMP6_INV_NEIGHBOR_SOLICITATION: return "ICMP6_INV_NEIGHBOR_SOLICITATION"; + case ZT_ICMP6_INV_NEIGHBOR_ADVERTISEMENT: return "ICMP6_INV_NEIGHBOR_ADVERTISEMENT"; + case ZT_ICMP6_MLDV2: return "ICMP6_MLDV2"; + case ZT_ICMP6_HOME_AGENT_ADDRESS_DISCOVERY_REQUEST: return "ICMP6_HOME_AGENT_ADDRESS_DISCOVERY_REQUEST"; + case ZT_ICMP6_HOME_AGENT_ADDRESS_DISCOVERY_REPLY: return "ICMP6_HOME_AGENT_ADDRESS_DISCOVERY_REPLY"; + case ZT_ICMP6_MOBILE_PREFIX_SOLICITATION: return "ICMP6_MOBILE_PREFIX_SOLICITATION"; + case ZT_ICMP6_MOBILE_PREFIX_ADVERTISEMENT: return "ICMP6_MOBILE_PREFIX_ADVERTISEMENT"; + case ZT_ICMP6_CERTIFICATION_PATH_SOLICITATION: return "ICMP6_CERTIFICATION_PATH_SOLICITATION"; + case ZT_ICMP6_CERTIFICATION_PATH_ADVERTISEMENT: return "ICMP6_CERTIFICATION_PATH_ADVERTISEMENT"; + case ZT_ICMP6_MULTICAST_ROUTER_ADVERTISEMENT: return "ICMP6_MULTICAST_ROUTER_ADVERTISEMENT"; + case ZT_ICMP6_MULTICAST_ROUTER_SOLICITATION: return "ICMP6_MULTICAST_ROUTER_SOLICITATION"; + case ZT_ICMP6_MULTICAST_ROUTER_TERMINATION: return "ICMP6_MULTICAST_ROUTER_TERMINATION"; + case ZT_ICMP6_RPL_CONTROL_MESSAGE: return "ICMP6_RPL_CONTROL_MESSAGE"; + } + return UNKNOWN_NAME; +} + +} // namespace ZeroTier diff --git a/attic/Filter.hpp b/attic/Filter.hpp new file mode 100644 index 000000000..4bea3715d --- /dev/null +++ b/attic/Filter.hpp @@ -0,0 +1,284 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#ifndef _ZT_FILTER_HPP +#define _ZT_FILTER_HPP + +#include +#include +#include + +#include +#include +#include +#include + +#include "Range.hpp" + +/* Ethernet frame types that might be relevant to us */ +#define ZT_ETHERTYPE_IPV4 0x0800 +#define ZT_ETHERTYPE_ARP 0x0806 +#define ZT_ETHERTYPE_RARP 0x8035 +#define ZT_ETHERTYPE_ATALK 0x809b +#define ZT_ETHERTYPE_AARP 0x80f3 +#define ZT_ETHERTYPE_IPX_A 0x8137 +#define ZT_ETHERTYPE_IPX_B 0x8138 +#define ZT_ETHERTYPE_IPV6 0x86dd + +/* IP protocols we might care about */ +#define ZT_IPPROTO_ICMP 0x01 +#define ZT_IPPROTO_IGMP 0x02 +#define ZT_IPPROTO_TCP 0x06 +#define ZT_IPPROTO_UDP 0x11 +#define ZT_IPPROTO_GRE 0x2f +#define ZT_IPPROTO_ESP 0x32 +#define ZT_IPPROTO_AH 0x33 +#define ZT_IPPROTO_ICMPV6 0x3a +#define ZT_IPPROTO_OSPF 0x59 +#define ZT_IPPROTO_IPIP 0x5e +#define ZT_IPPROTO_IPCOMP 0x6c +#define ZT_IPPROTO_L2TP 0x73 +#define ZT_IPPROTO_SCTP 0x84 +#define ZT_IPPROTO_FC 0x85 +#define ZT_IPPROTO_UDPLITE 0x88 +#define ZT_IPPROTO_HIP 0x8b + +/* IPv4 ICMP types */ +#define ZT_ICMP_ECHO_REPLY 0 +#define ZT_ICMP_DESTINATION_UNREACHABLE 3 +#define ZT_ICMP_SOURCE_QUENCH 4 +#define ZT_ICMP_REDIRECT 5 +#define ZT_ICMP_ALTERNATE_HOST_ADDRESS 6 +#define ZT_ICMP_ECHO_REQUEST 8 +#define ZT_ICMP_ROUTER_ADVERTISEMENT 9 +#define ZT_ICMP_ROUTER_SOLICITATION 10 +#define ZT_ICMP_TIME_EXCEEDED 11 +#define ZT_ICMP_BAD_IP_HEADER 12 +#define ZT_ICMP_TIMESTAMP 13 +#define ZT_ICMP_TIMESTAMP_REPLY 14 +#define ZT_ICMP_INFORMATION_REQUEST 15 +#define ZT_ICMP_INFORMATION_REPLY 16 +#define ZT_ICMP_ADDRESS_MASK_REQUEST 17 +#define ZT_ICMP_ADDRESS_MASK_REPLY 18 +#define ZT_ICMP_TRACEROUTE 30 +#define ZT_ICMP_MOBILE_HOST_REDIRECT 32 +#define ZT_ICMP_MOBILE_REGISTRATION_REQUEST 35 +#define ZT_ICMP_MOBILE_REGISTRATION_REPLY 36 + +/* IPv6 ICMP types */ +#define ZT_ICMP6_DESTINATION_UNREACHABLE 1 +#define ZT_ICMP6_PACKET_TOO_BIG 2 +#define ZT_ICMP6_TIME_EXCEEDED 3 +#define ZT_ICMP6_PARAMETER_PROBLEM 4 +#define ZT_ICMP6_ECHO_REQUEST 128 +#define ZT_ICMP6_ECHO_REPLY 129 +#define ZT_ICMP6_MULTICAST_LISTENER_QUERY 130 +#define ZT_ICMP6_MULTICAST_LISTENER_REPORT 131 +#define ZT_ICMP6_MULTICAST_LISTENER_DONE 132 +#define ZT_ICMP6_ROUTER_SOLICITATION 133 +#define ZT_ICMP6_ROUTER_ADVERTISEMENT 134 +#define ZT_ICMP6_NEIGHBOR_SOLICITATION 135 +#define ZT_ICMP6_NEIGHBOR_ADVERTISEMENT 136 +#define ZT_ICMP6_REDIRECT_MESSAGE 137 +#define ZT_ICMP6_ROUTER_RENUMBERING 138 +#define ZT_ICMP6_NODE_INFORMATION_QUERY 139 +#define ZT_ICMP6_NODE_INFORMATION_RESPONSE 140 +#define ZT_ICMP6_INV_NEIGHBOR_SOLICITATION 141 +#define ZT_ICMP6_INV_NEIGHBOR_ADVERTISEMENT 142 +#define ZT_ICMP6_MLDV2 143 +#define ZT_ICMP6_HOME_AGENT_ADDRESS_DISCOVERY_REQUEST 144 +#define ZT_ICMP6_HOME_AGENT_ADDRESS_DISCOVERY_REPLY 145 +#define ZT_ICMP6_MOBILE_PREFIX_SOLICITATION 146 +#define ZT_ICMP6_MOBILE_PREFIX_ADVERTISEMENT 147 +#define ZT_ICMP6_CERTIFICATION_PATH_SOLICITATION 148 +#define ZT_ICMP6_CERTIFICATION_PATH_ADVERTISEMENT 149 +#define ZT_ICMP6_MULTICAST_ROUTER_ADVERTISEMENT 151 +#define ZT_ICMP6_MULTICAST_ROUTER_SOLICITATION 152 +#define ZT_ICMP6_MULTICAST_ROUTER_TERMINATION 153 +#define ZT_ICMP6_RPL_CONTROL_MESSAGE 155 + +namespace ZeroTier { + +class RuntimeEnvironment; + +/** + * A simple Ethernet frame level filter + * + * This doesn't specify actions, since it's used as a deny filter. The rule + * in ZT1 is "that which is not explicitly prohibited is allowed." (Except for + * ethertypes, which are handled by a whitelist.) + */ +class Filter +{ +public: + /** + * Value returned by etherTypeName, etc. on unknown + * + * These static methods return precisely this, so a pointer equality + * check will work. + */ + static const char *const UNKNOWN_NAME; + + /** + * An empty range as a more idiomatic way of specifying a wildcard match + */ + static const Range ANY; + + /** + * A filter rule + */ + class Rule + { + public: + Rule() + throw() : + _etherType(), + _protocol(), + _port() + { + } + + /** + * Construct a rule from a string-serialized value + * + * @param s String formatted rule, such as returned by toString() + * @throws std::invalid_argument String formatted rule is not valid + */ + Rule(const char *s) + throw(std::invalid_argument); + + /** + * Construct a new rule + * + * @param etype Ethernet type or empty range for ANY + * @param prot Protocol or empty range for ANY (meaning depends on ethertype, e.g. IP protocol numbers) + * @param prt Port or empty range for ANY (only applies to some protocols) + */ + Rule(const Range &etype,const Range &prot,const Range &prt) + throw() : + _etherType(etype), + _protocol(prot), + _port(prt) + { + } + + inline const Range ðerType() const throw() { return _etherType; } + inline const Range &protocol() const throw() { return _protocol; } + inline const Range &port() const throw() { return _port; } + + /** + * Test this rule against a frame + * + * @param etype Type of ethernet frame + * @param data Ethernet frame data + * @param len Length of ethernet frame + * @return True if rule matches + * @throws std::invalid_argument Frame invalid or not parseable + */ + bool operator()(unsigned int etype,const void *data,unsigned int len) const + throw(std::invalid_argument); + + /** + * Serialize rule as string + * + * @return Human readable representation of rule + */ + std::string toString() const; + + inline bool operator==(const Rule &r) const throw() { return ((_etherType == r._etherType)&&(_protocol == r._protocol)&&(_port == r._port)); } + inline bool operator!=(const Rule &r) const throw() { return !(*this == r); } + inline bool operator<(const Rule &r) const + throw() + { + if (_etherType < r._etherType) + return true; + else if (_etherType == r._etherType) { + if (_protocol < r._protocol) + return true; + else if (_protocol == r._protocol) { + if (_port < r._port) + return true; + } + } + return false; + } + inline bool operator>(const Rule &r) const throw() { return (r < *this); } + inline bool operator<=(const Rule &r) const throw() { return !(r < *this); } + inline bool operator>=(const Rule &r) const throw() { return !(*this < r); } + + private: + Range _etherType; + Range _protocol; + Range _port; + }; + + Filter() {} + + /** + * @param s String-serialized filter representation + */ + Filter(const char *s) + throw(std::invalid_argument); + + /** + * @return Comma-delimited list of string-format rules + */ + std::string toString() const; + + /** + * Add a rule to this filter + * + * @param r Rule to add to filter + */ + void add(const Rule &r); + + inline bool operator()(unsigned int etype,const void *data,unsigned int len) const + throw(std::invalid_argument) + { + for(std::vector::const_iterator r(_rules.begin());r!=_rules.end();++r) { + if ((*r)(etype,data,len)) + return true; + } + return false; + } + + static const char *etherTypeName(const unsigned int etherType) + throw(); + static const char *ipProtocolName(const unsigned int ipp) + throw(); + static const char *icmpTypeName(const unsigned int icmpType) + throw(); + static const char *icmp6TypeName(const unsigned int icmp6Type) + throw(); + +private: + std::vector _rules; +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/README.md b/attic/README.md new file mode 100644 index 000000000..768bccd4a --- /dev/null +++ b/attic/README.md @@ -0,0 +1,4 @@ +Retired Code and Miscellaneous Junk +====== + +This directory is for old code that isn't used but we don't want to lose track of, and for anything else random like debug scripts. diff --git a/attic/decrypt b/attic/decrypt new file mode 100755 index 000000000..5af3acd44 --- /dev/null +++ b/attic/decrypt @@ -0,0 +1,32 @@ +#!/bin/bash + +export PATH=/bin:/usr/bin + +if [ ! -e /usr/bin/openssl ]; then + echo $0: requires /usr/bin/openssl, please install openssl tools + exit 1 +fi + +if [ "$#" -lt 1 ]; then + echo $0: Usage: $0 '' '[output]' + exit 1 +fi + +if [ ! -r "$1" ]; then + echo $0: $1 does not exist or is not readable. + exit 1 +fi + +outpath=`echo "$1" | sed 's/[.]aes$//'` +if [ "$#" -ge 2 ]; then + outpath="$2" +fi + +if [ -f "$outpath" ]; then + echo $0: $outpath already exists, delete or rename first. + exit 1 +fi + +openssl aes-256-cbc -d -salt -in "$1" -out "$outpath" + +echo $0: wrote "$outpath" diff --git a/attic/encrypt b/attic/encrypt new file mode 100755 index 000000000..243a46d79 --- /dev/null +++ b/attic/encrypt @@ -0,0 +1,32 @@ +#!/bin/bash + +export PATH=/bin:/usr/bin + +if [ ! -e /usr/bin/openssl ]; then + echo $0: requires /usr/bin/openssl, please install openssl tools + exit 1 +fi + +if [ "$#" -lt 1 ]; then + echo $0: Usage: $0 '' '[output]' + exit 1 +fi + +if [ ! -r "$1" ]; then + echo $0: $1 does not exist or is not readable. + exit 1 +fi + +outpath="$1.aes" +if [ "$#" -ge 2 ]; then + outpath="$2" +fi + +if [ -f "$outpath" ]; then + echo $0: $outpath already exists, delete or rename first. + exit 1 +fi + +openssl aes-256-cbc -salt -in "$1" -out "$outpath" + +echo $0: wrote "$outpath" diff --git a/attic/historic/anode/LICENSE.txt b/attic/historic/anode/LICENSE.txt deleted file mode 100644 index 94a9ed024..000000000 --- a/attic/historic/anode/LICENSE.txt +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/attic/historic/anode/config.mk.Darwin b/attic/historic/anode/config.mk.Darwin deleted file mode 100644 index a5cbeeecf..000000000 --- a/attic/historic/anode/config.mk.Darwin +++ /dev/null @@ -1,17 +0,0 @@ -CC=gcc -CXX=g++ - -#ARCH_FLAGS=-arch x86_64 -arch i386 -arch ppc - -DEFS=-DHAS_DEV_URANDOM -CXXDEFS=-DBOOST_DISABLE_ASSERTS -DBOOST_NO_TYPEID -DNDEBUG - -CFLAGS=-mmacosx-version-min=10.4 -std=c99 -O6 -ftree-vectorize -Wall $(DEFS) $(ARCH_FLAGS) -CXXFLAGS=-mmacosx-version-min=10.4 -Drestrict=__restrict__ -O6 -ftree-vectorize -Wall $(DEFS) $(CXXDEFS) $(ARCH_FLAGS) - -LDFLAGS=-mmacosx-version-min=10.4 $(ARCH_FLAGS) -DLLFLAGS=$(ARCH_FLAGS) -shared -DLLEXT=dylib - -LIBANODE_LIBS=-lcrypto -lpthread -lresolv -LIBSPARK_LIBS=-lz diff --git a/attic/historic/anode/config.mk.Linux b/attic/historic/anode/config.mk.Linux deleted file mode 100644 index 072fa4ceb..000000000 --- a/attic/historic/anode/config.mk.Linux +++ /dev/null @@ -1,17 +0,0 @@ -CC=gcc -CXX=g++ - -DEFS=-DHAS_DEV_URANDOM - -CFLAGS=-std=c99 -O6 -fPIC -Wall $(DEFS) -CXXFLAGS=-Drestrict=__restrict__ -O6 -Wall $(DEFS) -I.. - -#CFLAGS=-g -Wall $(DEFS) -#CXXFLAGS=-g -Wall $(DEFS) - -LDFLAGS= -DLLFLAGS=-shared -DLLEXT=so - -LIBANODE_LIBS=-lcrypto -lresolv -pthread -LIBSPARK_LIBS=-lz diff --git a/attic/historic/anode/docs/anode_protocol.txt b/attic/historic/anode/docs/anode_protocol.txt deleted file mode 100644 index 0adb92367..000000000 --- a/attic/historic/anode/docs/anode_protocol.txt +++ /dev/null @@ -1,764 +0,0 @@ -***************************************************************************** -Anode Protocol Specification Draft -Version 0.8 - -(c)2009-2010 Adam Ierymenko -***************************************************************************** - -Table of Contents - -***************************************************************************** - -1. Introduction - -Anode provides three components that work together to provide a global, -secure, and mobile addressing system for computer networks: - -1) An addressing system based on public key cryptography enabling network - devices or applications to assign themselves secure, unique, and globally - reachable network addresses in a flat address space. - -2) A system enabling network participants holding global addresses to locate - one another on local or global networks with "zero configuration." - -3) A communications protocol for communication between addressed network - participants that requires no special operating system support and no - changes to existing network infrastructure. - -Using Anode, both fixed and mobile applications and devices can communicate -directly as if they were all connected to the same VPN. Anode restores the -original vision of the Internet as a "flat" network where anything can talk -to anything, and adds the added benefits of address mobility and strong -protection against address spoofing and other protocol level attacks. - -1.1. Design Philosophy - -Anode's design philosophy is the classical "KISS" principle: "Keep It Simple -Stupid." Anode's design principles are: - -#1: Do not try to solve too many problems at once, and stay in scope. - -Anode does not attempt to solve too many problems at once. It attempts to -solve the problems of mobile addressing, address portability, and "flat" -addressing in the presence of NAT or other barriers. - -It does not attempt to duplicate the full functionality of SSL, X.509, SSH, -XMPP, an enterprise service bus, a pub/sub architecture, BitTorrent, etc. All -of those protocols and services can be used over Anode if their functionality -is desired. - -#2: Avoid state management. - -State multiplies the complexity and failure modes of network protocols. State -also tends to get in the way of the achievement of new features implicitly -(see principle #4). Avoid state whenever possible. - -#3: Avoid algorithm and dependency bloat. - -Anode uses only elliptic curve Diffie-Hellman (EC-DH) and AES-256. No other -cryptographic algorithms or hash functions are presently necessary. This -yields implementations compact enough for embedded devices. - -Anode also requires few or no dependencies, depending on whether the two -needed cryptographic algorithms are obtained through a library or included. -No other protocols or libraries are required in an implementation. - -#4: Achieve features implicitly. - -Use a simple stateless design that allows features to be achieved implicitly -rather than specified explicitly. For example, Anode can do multi-homing and -could be used to build a mesh network, but neither of these features is -explicitly specified. - -***************************************************************************** - -2. Core Concepts and Algorithms - -This section describes addresses, zones, common algorithms, and other core -concepts. - -2.1. Zones - -A zone is a 32-bit integer encoded into every Anode address. Zones serve to -assist in the location of peers by address on global IP networks. They are -not presently significant for local communications, though they could be -used to partition addresses into groups or link them with configuration -options. - -Each zone has a corresponding zone file which can be fetched in a number of -ways (see below). A zone file is a flat text format dictionary of the format -"key=value" separated by carriage returns. Line feeds are ignored, and any -character may be escaped with a backslash (\) character. Blank lines are -ignored. - -The following entries must appear in a zone file: - -n= -d= -c= -r= -ttl= - -Additional fields may appear as well, including fields specific to special -applications or protocols supported within the zone. Some of these are -defined in this document. - -Zone file fetching mechanisms are described below. Multiple mechanisms are -specified to enable fallback in the event that one mechanism is not available. - -2.1.1. Zone File Retrieval - -Zone files are retrieved via HTTP, with the HTTP address being formed in one -of two ways. - -The preferred DNS method: - -To fetch a zone file via DNS, use the zone ID to generate a host name and URI -of the form: - - http://a--XXXXXXXX.net/z - -The XXXXXXXX field is the zone ID in hexadecimal. - -The fallback IP method: - -For fallback in the absence of DNS, the zone ID can be used directly as an -IPv4 or IPv4-mapped-to-IPv6 IP address. A URI is generated of the form: - - http://ip_address/z - -Support for this method requires that a zone ID be chosen to correspond to a -permanent IPv4 (preferably mappable to IPv6 space as well) IP address. - -2.1.2. Zone ID Reservation - -By convention, a zone ID is considered reserved when a domain of the form -"a--XXXXXXXX.net" (where XXXXXXXX is the ID in hex) is registered. - -It is recommended that this be done even for zone IDs not used for global -address location in order to globally reserve them. - -2.2. Addresses - -Anode addresses are binary strings containing a 32-bit zone ID, a public key, -and possibly other fields. Only one address type is presently defined: - -|---------------------------------------------------------------------------| -| Name | Type ID | Elliptic Curve Parameters | Total Length | -|---------------------------------------------------------------------------| -| ANODE-256-40 | 1 | NIST-P-256 | 40 | -|---------------------------------------------------------------------------| - -|---------------------------------------------------------------------------| -| Name | Binary Layout | -|---------------------------------------------------------------------------| -| ANODE-256-40 | | -|---------------------------------------------------------------------------| - -The public key is a "compressed" form elliptic curve public key as described -in RFC5480. - -The unused section of the address must be zero. These bytes are reserved for -future use. - -2.2.1. ASCII Format For Addresses - -Addresses are encoded in ASCII using base-32, which provides a quotable and -printable encoding that is of manageable length and is case-insensitive. For -example, an ANODE-256-40 address is 64 characters long in base-32 encoding. - -2.3. Relaying - -An Anode peer may optionally relay packets to any other reachable peer. -Relaying is accomplished by sending a packet to a peer with the recipient set -to the final recipient. The receiving peer will, if relaying is allowed and if -it knows of or can reach the recipient, forward the packet. - -No error is returned if relaying fails, so relay paths are treated as possible -paths for communication until a return is received in the same way as direct -paths. - -Relaying can be used by peers to send messages indirectly, locate one -another, and determine network location information to facilitate the -establishment of direct communications. - -Peers may refuse to relay or may limit the transmission rate at which packets -can be relayed. - -2.3.1. Zone Relays - -If a zone's addresses are globally reachable on global IP networks, it must -have one or more zone relays. These must have globally reachable public -static IP addresses. - -Zone relays are specified in the zone file in the following format: - - zr.
=[,]::: - -The address checksum is the sum of the bytes in the Anode address modulus -the number of "zr" entries, in hexadecimal. For example, if a zone had four -global relays its zone file could contain the lines: - - zr.0=1.2.3.4:4343:4344:klj4j3... - zr.1=2.3.4.5:4343:4344:00194j... - zr.2=3.4.5.6:4343:4344:1j42zz... - zr.3=4.5.6.7:4343:4344:z94j1q... - -The relay would be chosen by taking the sum of the bytes in the address -modulo 4. For example, if the bytes of an address sum to 5081 then relay -zr.1 would be used to communicate with that address. - -If more than one IP address is listed for a given relay, the peer must choose -at random from among the addresses of the desired type (IPv4 or IPv6). - -Each relay must have one Anode address for every address type supported within -the zone. (At present there is only one address type defined.) - -Peers should prefer UDP and fall back to TCP only if UDP is not available. - -To make itself available, a peer must make itself known to its designated zone -relay. This is accomplished by sending a PING message. - -2.4. Key Agreement and Derivation - -Key agreement is performed using elliptic curve Diffie-Hellman. This yields -a raw key whose size depends on the elliptic curve parameters in use. - -The following algorithm is used to derive a key of any length from a raw -key generated through key agreement: - -1) Zero the derived key buffer. -2) Determine the largest of the original raw key or the derived key. -3) Loop from 0 to the largest length determined in step 2, XOR each byte of - the derived key buffer with the corresponding byte of the original key - buffer with each index being modulus the length of the respective buffer. - -2.5. Message Authentication - -For message authentication, CMAC-AES (with AES-256) is used. This is also -known in some literature as OMAC1-AES. The key is derived from key agreement -between the key pair of the sending peer and the address of the recipient. - -2.6. AES-DIGEST - -To maintain cryptographic algorithm frugality, a cryptographic hash function -is constructed from the AES-256 cipher. This hash function uses the common -Davis-Meyer construction with Merkle-Damgård length padding. - -It is described by the following pseudocode: - - byte previous_digest[16] - byte digest[16] = { 0,0,... } - byte block[32] = { 0,0,... } - integer block_counter = 0 - - ; digest message - for each byte b of message - block[block_counter] = b - block_counter = block_counter + 1 - if block_counter == 32 then - block_counter = 0 - save digest[] in previous_digest[] - encrypt digest[] with aes-256 using block[] as 256-bit aes-256 key - xor digest[] with previous_digest[] - end if - next - - ; append end marker, do final block - block[block_counter] = 0x80 - block_counter = block_counter + 1 - zero rest of block[] from block_counter to 15 - save digest[] in previous_digest[] - encrypt digest[] with aes-256 using block[] as 256-bit aes-256 key - xor digest[] with previous_digest[] - - ; Merkle-Damgård length padding - zero first 8 bytes of block[] - fill last 8 bytes of block[] w/64-bit length in big-endian order - save digest[] in previous_digest[] - encrypt digest[] with aes-256 using block[] as 256-bit aes-128 key - xor digest[] with previous_digest[] - - ; digest[] now contains 128-bit message digest - -2.7. Short Address Identifiers (Address IDs) - -A short 8-byte version of the Anode address is used in the protocol to reduce -transmission overhead when both sides are already aware of the other's full -address. - -The short address identifier is formed by computing the AES-DIGEST of the -full address and then XORing the first 8 bytes of the digest with the last -8 bytes to yield an 8-byte shortened digest. - -2.8. DNS Resolution of Anode Addresses - -Anode addresses can be saved in DNS TXT records in the following format: - -anode:
- -This permits Anode addresses to be resolved from normal DNS host name. - -2.9. Packet Transmission Mechanisms - -2.9.1. UDP Transmission - -The recommended method of sending Anode packets is UDP. Each packet is simply -sent as a UDP packet. - -2.9.2. TCP Transmission - -To send packets over TCP, each packet is prefixed by its size as a 16-bit -integer. - -2.9.3. HTTP Transmission - -Anode packets may be submitted in HTTP POST transactions for transport over -networks where HTTP is the only available protocol. - -Anode packets are simply prefixed with a 16-byte packet size and concatenated -together just as they are in a TCP stream. One or more packets may be sent -with each HTTP POST transaction for improved performance. - -Since this method is intended for use in "hostile" or highly restricted -circumstances, no additional details such as special headers or MIME types -are specified to allow maximum flexibility. Peers should ignore anything -other than the payload. - -2.10. Endpoints - -An endpoint indicates a place where Anode packets may be sent. The following -endpoint types are specified: - -|---------------------------------------------------------------------------| -| Endpoint Type | Description | Address Format | -|---------------------------------------------------------------------------| -| 0x00 | Unspecified | (none) | -| 0x01 | Ethernet | | -| 0x02 | UDP/IPv4 | | -| 0x03 | TCP/IPv4 | | -| 0x04 | UDP/IPv6 | | -| 0x05 | TCP/IPv6 | | -| 0x06 | HTTP | | -|---------------------------------------------------------------------------| - -Endpoints are encoded by beginning with a single byte indicating the endpoint -type followed by the address information required for the given type. - -Note that IP ports bear no relationship to Anode protocol ports. - -2.11. Notes - -All integers in the protocol are transmitted in network (big endian) byte -order. - -***************************************************************************** - -3. Common Packet Format - -A common header is used for all Anode packets: - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| Hop Count | 1 | 8-bit hop count (not included in MAC) | -| Flags | 1 | 8-bit flags | -| MAC | 8 | 8 byte shortened CMAC-AES of packet | -| Sender Address | ? | Full address or short ID of sender | -| Recipient Address | ? | Full address or short ID of recipient | -| Peer IDs | 1 | Two 4-bit peer IDs: sender, recipient | -| Message Type | 1 | 8-bit message type | -| Message | ? | Message payload | -|---------------------------------------------------------------------------| - -3.1. Hop Count - -The hop count begins at zero and must be incremented by each peer that relays -the packet to another peer. The hop count must not wrap to zero at 255. - -Because the hop count is modified in transit, it is not included in MAC -calculation or authentication. - -The hop count is used to prioritize endpoints that are direct over endpoints -that involve relaying, or to prioritize closer routes over more distant -ones. - -3.2. Flags and Flag Behavior - -|---------------------------------------------------------------------------| -| Flag | Description | -|---------------------------------------------------------------------------| -| 0x01 | Sender address fully specified | -| 0x02 | Recipient address fully specified | -| 0x04 | Authentication error response | -|---------------------------------------------------------------------------| - -If flag 0x01 is set, then the sender address will be the full address rather -than a short address identifier. The length of the address can be determined -from the first byte of the address, which always specifies the address type. -Flag 0x02 has the same meaning for the recipient address. - -A peer must send fully specified sender addresses until it receives a response -from the recipient. At this point the sender may assume that the recipient -knows its address and use short a short sender address instead. This -assumption should time out, with a recommended timeout of 60 seconds. - -There is presently no need to send fully specified recipient addresses, but -the flag is present in case it is needed and must be honored. - -Flag 0x04 indicates that this is an error response containing a failed -authentication error. Since authentication failed, this packet may not have -a valid MAC. Packets with this flag must never have any effect other than -to inform of an error. This error, since it is unauthenticated, must never -have any side effects such as terminating a connection. - -3.3. MAC - -The MAC is calculated as follows: - -1) Temporarily set the 64-bit/8-byte MAC field in the packet to the packet's - size as a 64-bit big-endian integer. -2) Calculate the MAC for the entire packet (excluding the first byte) using - the key agreed upon between the sender and the recipient, resulting in a - 16 byte full CMAC-AES MAC. -3) Derive the 8 byte packet MAC by XORing the first 8 bytes of the full 16 - byte CMAC-AES MAC with the last 8 bytes. Place this into the packet's MAC - field. - -3.4. Peer IDs - -Peer IDs provide a method for up to 15 different peers to share an address, -each with a unique ID allowing packets to be routed to them individually. - -A peer ID of zero indicates "any" or "unspecified." Real peers must have a -nonzero peer ID. In the normal single peer per address case, any peer ID may -be used. If multiple peers are to share an address, some implementation- -dependent method must be used to ensure that each peer has a unique peer ID. - -Relaying peers must follow these rules based on the recipient peer ID when -relaying messages: - - - IF the peer ID is zero or if the peer ID is not known, the message must - be forwarded to a random endpoint for the given recipient address. - - IF the peer ID is nonzero and matches one or more known endpoints for the - given recipient address and peer ID, the message must only be sent to - a matching endpoint. - -A receiving peer should process any message that it receives regardless of -whether its recipient peer ID is correct. The peer ID is primarily for relays. - -Peers should typically send messages with a nonzero recipient peer ID when -responding to or involved in a conversation with a specific peer (e.g. a -streaming connection), and send zero recipient peer IDs otherwise. - -3.5. Short Address Conflict Disambiguation - -In the unlikely event of two Anode addresses with the same short identifier, -the recipient should use MAC validation to disambiguate. The peer ID must not -be relied upon for this purpose. - -***************************************************************************** - -4. Basic Signaling and Transport Protocol - -4.1. Message Types - -|---------------------------------------------------------------------------| -| Type | ID | Description | -|---------------------------------------------------------------------------| -| ERROR | 0x00 | Error response | -| PING | 0x01 | Echo request | -| PONG | 0x02 | Echo response | -| EPC_REQ | 0x03 | Endpoint check request | -| EPC | 0x04 | Endpoint check response | -| EPI | 0x05 | Endpoint information | -| NAT_T | 0x06 | NAT traversal message | -| NETID_REQ | 0x07 | Request network address identification and/or test | -| NETID | 0x08 | Response to network address identification request | -| DGRAM | 0x09 | Simple UDP-like datagram | -|---------------------------------------------------------------------------| - -4.2. Message Details - -4.2.1. ERROR - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| Error Code | 2 | 16-bit error code | -| Error Arguments | ? | Error arguments, depending on error type | -|---------------------------------------------------------------------------| - -Error arguments are empty unless otherwise stated below. - -Error codes: - -|---------------------------------------------------------------------------| -| Error Code | Description | -|---------------------------------------------------------------------------| -| 0x01 | Message not valid | -| 0x02 | Message authentication or decryption failed | -| 0x03 | Relaying and related features not authorized | -| 0x04 | Relay recipient not reachable | -|---------------------------------------------------------------------------| - -Generation of errors is optional. A peer may choose to ignore invalid -messages or to throttle the sending of errors. - -4.2.2. PING - -(Payload unspecified.) - -Request echo of payload as PONG message. - -4.2.3. PONG - -(Payload unspecified.) - -Echoed payload of received PING message. - -4.2.4. EPC_REQ - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| Request ID | 4 | 32-bit request ID | -|---------------------------------------------------------------------------| - -Request echo of request ID in EPC message, used to check and learn endpoints. - -To learn a network endpoint for a peer, CHECK_REQ is sent. If CHECK is -returned with a valid request ID, the endpoint is considered valid. - -4.2.5. EPC - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| Request ID | 4 | 32-bit request ID echoed back | -|---------------------------------------------------------------------------| - -Response to EPC_REQ containing request ID. - -4.2.6. EPI - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| Flags | 1 | 8-bit flags | -| Endpoint | ? | Endpoint type and address | -| NAT-T mode | 1 | 8-bit NAT traversal mode | -| NAT-T options | ? | Options related to specified NAT-T mode | -|---------------------------------------------------------------------------| - -EPI stands for EndPoint Identification, and is sent to notify another peer of -a network endpoint where the sending peer is reachable. - -If the receiving peer is interested in communicating with the sending peer, -the receiving peer must send EPC_REQ to the sending peer at the specified -endpoint to check the validity of that endpoint. The endpoint is learned if a -valid EPC is returned. - -If the endpoint in EPI is unspecified, the actual source of the EPI message -is the endpoint. This allows EPI messages to be broadcast on a local LAN -segment to advertise the presence of an address on a local network. EPI -broadcasts on local IP networks must be made to UDP port 8737. - -Usually EPI is sent via relays (usually zone relays) to inform a peer of an -endpoint for direct communication. - -There are presently no flags, so flags must be zero. - -4.2.7. NAT_T - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| NAT-T mode | 1 | 8-bit NAT traversal mode | -| NAT-T options | ? | Options related to specified NAT-T mode | -|---------------------------------------------------------------------------| - -NAT_T is used to send messages specific to certain NAT traversal modes. - -4.2.8. NETID_REQ - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| Request ID | 4 | 32-bit request ID | -| Endpoint | ? | Endpoint type and address information | -|---------------------------------------------------------------------------| - -When a NETID_REQ message is received, the recipient attempts to echo it back -as a NETID message to the specified endpoint address. If the endpoint is -unspecified, the recipient must fill it in with the actual origin of the -NETID_REQ message. This allows a peer to cooperate with another peer (usually -a zone relay) to empirically determine its externally visible network -address information. - -A peer may ignore NETID_REQ or respond with an error if it does not allow -relaying. - -4.2.9. NETID - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| Request ID | 4 | 32-bit request ID echoed back | -| Endpoint Type | 1 | 8-bit endpoint type | -| Endpoint Address | ? | Endpoint Address (size depends on type) | -|---------------------------------------------------------------------------| - -NETID is sent in response to NETID_REQ to the specified endpoint address. It -always contains the endpoint address to which it was sent. - -4.2.10. DGRAM - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| Source Port | 2 | 16-bit source port | -| Destination Port | 2 | 16-bit destination port | -| Payload | ? | Datagram packet payload | -|---------------------------------------------------------------------------| - -A datagram is a UDP-like message without flow control or delivery assurance. - -***************************************************************************** - -5. Stream Protocol - -The stream protocol is very similar to TCP, though it omits some features -that are not required since they are taken care of by the encapsulating -protocol. SCTP was also an inspiration in the design. - -5.1. Message Types - -|---------------------------------------------------------------------------| -| Type | ID | Description | -|---------------------------------------------------------------------------| -| S_OPEN | 20 | Initiate a streaming connection (like TCP SYN) | -| S_CLOSE | 21 | Terminate a streaming connection (like TCP RST/FIN) | -| S_DATA | 22 | Data packet | -| S_ACK | 23 | Acknowedge receipt of one or more data packets | -| S_DACK | 24 | Combination of DATA and ACK | -|---------------------------------------------------------------------------| - -5.2. Message Details - -5.2.1. S_OPEN - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| Sender Link ID | 2 | 16-bit sender link ID | -| Destination Port | 2 | 16-bit destination port | -| Window Size | 2 | 16-bit window size in 1024-byte increments | -| Init. Seq. Number | 4 | 32-bit initial sequence number | -| Flags | 1 | 8-bit flags | -|---------------------------------------------------------------------------| - -The OPEN message corresponds to TCP SYN, and initiates a connection. It -specifies the initial window size for the sender and the sender's initial -sequence number, which should be randomly chosen to prevent replay attacks. - -If OPEN is successful, the recipient sends its own OPEN to establish the -connetion. If OPEN is unsuccessful, CLOSE is sent with its initial and current -sequence numbers equal and an appropriate reason such as "connection refused." - -The sender link ID must be unique for a given recipient. - -If flag 01 is set, the sender link ID is actually a source port where the -sender might be listening for connections as well. This exactly duplicates -the behavior of standard TCP. Otherwise, the sender link ID is simply an -arbitrary number that the sender uses to identify the connection with this -recipient and there is no port of origin. Ports of origin are optional for -Anode streaming connections to permit greater scalability. - -5.2.2. S_CLOSE - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| Sender Link ID | 2 | 16-bit sender link ID | -| Destination Port | 2 | 16-bit destination port | -| Flags | 1 | 8-bit flags | -| Reason | 1 | 8-bit close reason | -| Init. Seq. Number | 4 | 32-bit initial sequence number | -| Sequence Number | 4 | 32-bit current sequence number | -|---------------------------------------------------------------------------| - -The CLOSE message serves a function similar to TCP FIN. The initial sequence -number is the original starting sequence number sent with S_OPEN, while the -current sequence number is the sequence number corresponding to the close -and must be ACKed to complete the close operation. The use of the initial -sequence number helps to serve as a key to prevent replay attacks. - -CLOSE is also used to indicate a failed OPEN attempt. In this case the current -sequence number will be equal to the initial sequence number and no ACK will -be expected. - -There are currently no flags, so flags must be zero. - -The reason field describes the reason for the close: - -|---------------------------------------------------------------------------| -| Reason Code | Description | -|---------------------------------------------------------------------------| -| 00 | Application closed connection | -| 01 | Connection refused | -| 02 | Protocol error | -| 03 | Timed out | -|---------------------------------------------------------------------------| - -Established connections will usually be closed with reason 00, while reason -01 is usually provided if an OPEN is received but the port is not bound. - -5.2.3. S_DATA - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| Sender Link ID | 2 | 16-bit sender link ID | -| Destination Port | 2 | 16-bit destination port | -| Sequence Number | 4 | 32-bit sequence number | -| Payload | ? | Data payload | -|---------------------------------------------------------------------------| - -The DATA message carries a packet of data, with the sequence number -determining order. The sequence number is monotonically incremented with -each data packet, and wraps at the maximum value of an unsigned 32-bit -integer. - -5.2.4. S_ACK - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| Sender Link ID | 2 | 16-bit sender link ID | -| Destination Port | 2 | 16-bit destination port | -| Window Size | 2 | 16-bit window size in 1024-byte increments | -| Acknowledgements | ? | One or more acknowledgements (see below) | -|---------------------------------------------------------------------------| - -Each acknowledgement is a 32-bit integer followed by an 8-bit integer (5 bytes -total). The 32-bit integer is the first sequence number to acknowledge, and -the 8-bit integer is the number of sequential following sequence numbers to -acknowledge. For example "1, 4" would acknowledge sequence numbers 1, 2, 3, -and 4. - -5.2.5. S_DACK - -|---------------------------------------------------------------------------| -| Field | Length | Description | -|---------------------------------------------------------------------------| -| Sender Link ID | 2 | 16-bit sender link ID | -| Destination Port | 2 | 16-bit destination port | -| Window Size | 2 | 16-bit window size in 1024-byte increments | -| Num. Acks | 1 | 8-bit number of acknowledgements | -| Acknowledgements | ? | One or more acknowledgements | -| Payload | ? | Data payload | -|---------------------------------------------------------------------------| - -The DACK message combines ACK and DATA, allowing two peers that are both -transmitting data to efficiently ACK without a separate packet. diff --git a/attic/historic/anode/libanode/Makefile b/attic/historic/anode/libanode/Makefile deleted file mode 100644 index 088587bdd..000000000 --- a/attic/historic/anode/libanode/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -SYSNAME:=${shell uname} -SYSNAME!=uname -include ../config.mk.${SYSNAME} - -LIBANODE_OBJS= \ - impl/aes.o \ - impl/dictionary.o \ - impl/dns_txt.o \ - impl/ec.o \ - impl/environment.o \ - impl/misc.o \ - impl/thread.o \ - address.o \ - aes_digest.o \ - errors.o \ - identity.o \ - network_address.o \ - secure_random.o \ - system_transport.o \ - uri.o -# zone.o - -all: $(LIBANODE_OBJS) - ar rcs libanode.a $(LIBANODE_OBJS) - ranlib libanode.a - $(CC) $(CFLAGS) -o utils/anode-make-identity utils/anode-make-identity.c $(LIBANODE_OBJS) $(LIBANODE_LIBS) - -clean: force - rm -f $(LIBANODE_OBJS) - rm -f libanode.$(DLLEXT) libanode.a - rm -f utils/anode-make-identity - -force: ; diff --git a/attic/historic/anode/libanode/address.c b/attic/historic/anode/libanode/address.c deleted file mode 100644 index e7ab78378..000000000 --- a/attic/historic/anode/libanode/address.c +++ /dev/null @@ -1,98 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include "impl/aes.h" -#include "impl/ec.h" -#include "impl/misc.h" -#include "impl/types.h" -#include "anode.h" - -int AnodeAddress_calc_short_id( - const AnodeAddress *address, - AnodeAddressId *short_address_id) -{ - unsigned char digest[16]; - - switch(AnodeAddress_get_type(address)) { - case ANODE_ADDRESS_ANODE_256_40: - Anode_aes_digest(address->bits,ANODE_ADDRESS_LENGTH_ANODE_256_40,digest); - break; - default: - return ANODE_ERR_ADDRESS_INVALID; - } - - *((uint64_t *)short_address_id->bits) = ((uint64_t *)digest)[0] ^ ((uint64_t *)digest)[1]; - - return 0; -} - -int AnodeAddress_get_zone(const AnodeAddress *address,AnodeZone *zone) -{ - switch(AnodeAddress_get_type(address)) { - case ANODE_ADDRESS_ANODE_256_40: - *((uint32_t *)&(zone->bits[0])) = *((uint32_t *)&(address->bits[1])); - return 0; - } - return ANODE_ERR_ADDRESS_INVALID; -} - -int AnodeAddress_to_string(const AnodeAddress *address,char *buf,int len) -{ - const unsigned char *inptr; - char *outptr; - unsigned int i; - - switch(AnodeAddress_get_type(address)) { - case ANODE_ADDRESS_ANODE_256_40: - if (len < (((ANODE_ADDRESS_LENGTH_ANODE_256_40 / 5) * 8) + 1)) - return ANODE_ERR_BUFFER_TOO_SMALL; - inptr = (const unsigned char *)address->bits; - outptr = buf; - for(i=0;i<(ANODE_ADDRESS_LENGTH_ANODE_256_40 / 5);++i) { - Anode_base32_5_to_8(inptr,outptr); - inptr += 5; - outptr += 8; - } - *outptr = (char)0; - return ((ANODE_ADDRESS_LENGTH_ANODE_256_40 / 5) * 8); - } - return ANODE_ERR_ADDRESS_INVALID; -} - -int AnodeAddress_from_string(const char *str,AnodeAddress *address) -{ - const char *blk_start = str; - const char *ptr = str; - unsigned int address_len = 0; - - while (*ptr) { - if ((unsigned long)(ptr - blk_start) == 8) { - if ((address_len + 5) > sizeof(address->bits)) - return ANODE_ERR_ADDRESS_INVALID; - Anode_base32_8_to_5(blk_start,(unsigned char *)&(address->bits[address_len])); - address_len += 5; - blk_start = ptr; - } - ++ptr; - } - - if (ptr != blk_start) - return ANODE_ERR_ADDRESS_INVALID; - if (AnodeAddress_get_type(address) != ANODE_ADDRESS_ANODE_256_40) - return ANODE_ERR_ADDRESS_INVALID; - - return 0; -} diff --git a/attic/historic/anode/libanode/aes_digest.c b/attic/historic/anode/libanode/aes_digest.c deleted file mode 100644 index 07b0fc7ac..000000000 --- a/attic/historic/anode/libanode/aes_digest.c +++ /dev/null @@ -1,85 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include "anode.h" -#include "impl/aes.h" -#include "impl/misc.h" -#include "impl/types.h" - -void Anode_aes_digest(const void *const message,unsigned long message_len,void *const hash) -{ - unsigned char previous_digest[16]; - unsigned char digest[16]; - unsigned char block[32]; - const unsigned char *in = (const unsigned char *)message; - const unsigned char *end = in + message_len; - unsigned long block_counter; - AnodeAesExpandedKey expkey; - - ((uint64_t *)digest)[0] = 0ULL; - ((uint64_t *)digest)[1] = 0ULL; - ((uint64_t *)block)[0] = 0ULL; - ((uint64_t *)block)[1] = 0ULL; - ((uint64_t *)block)[2] = 0ULL; - ((uint64_t *)block)[3] = 0ULL; - - /* Davis-Meyer hash function built from block cipher */ - block_counter = 0; - while (in != end) { - block[block_counter++] = *(in++); - if (block_counter == 32) { - block_counter = 0; - ((uint64_t *)previous_digest)[0] = ((uint64_t *)digest)[0]; - ((uint64_t *)previous_digest)[1] = ((uint64_t *)digest)[1]; - Anode_aes256_expand_key(block,&expkey); - Anode_aes256_encrypt(&expkey,digest,digest); - ((uint64_t *)digest)[0] ^= ((uint64_t *)previous_digest)[0]; - ((uint64_t *)digest)[1] ^= ((uint64_t *)previous_digest)[1]; - } - } - - /* Davis-Meyer end marker */ - block[block_counter++] = 0x80; - while (block_counter != 32) block[block_counter++] = 0; - ((uint64_t *)previous_digest)[0] = ((uint64_t *)digest)[0]; - ((uint64_t *)previous_digest)[1] = ((uint64_t *)digest)[1]; - Anode_aes256_expand_key(block,&expkey); - Anode_aes256_encrypt(&expkey,digest,digest); - ((uint64_t *)digest)[0] ^= ((uint64_t *)previous_digest)[0]; - ((uint64_t *)digest)[1] ^= ((uint64_t *)previous_digest)[1]; - - /* Merkle-Damgård length padding */ - ((uint64_t *)block)[0] = 0ULL; - if (sizeof(message_len) >= 8) { /* 32/64 bit? this will get optimized out */ - block[8] = (uint8_t)((uint64_t)message_len >> 56); - block[9] = (uint8_t)((uint64_t)message_len >> 48); - block[10] = (uint8_t)((uint64_t)message_len >> 40); - block[11] = (uint8_t)((uint64_t)message_len >> 32); - } else ((uint32_t *)block)[2] = 0; - block[12] = (uint8_t)(message_len >> 24); - block[13] = (uint8_t)(message_len >> 16); - block[14] = (uint8_t)(message_len >> 8); - block[15] = (uint8_t)message_len; - ((uint64_t *)previous_digest)[0] = ((uint64_t *)digest)[0]; - ((uint64_t *)previous_digest)[1] = ((uint64_t *)digest)[1]; - Anode_aes256_expand_key(block,&expkey); - Anode_aes256_encrypt(&expkey,digest,digest); - ((uint64_t *)digest)[0] ^= ((uint64_t *)previous_digest)[0]; - ((uint64_t *)digest)[1] ^= ((uint64_t *)previous_digest)[1]; - - ((uint64_t *)hash)[0] = ((uint64_t *)digest)[0]; - ((uint64_t *)hash)[1] = ((uint64_t *)digest)[1]; -} diff --git a/attic/historic/anode/libanode/anode.h b/attic/historic/anode/libanode/anode.h deleted file mode 100644 index e0c51e2eb..000000000 --- a/attic/historic/anode/libanode/anode.h +++ /dev/null @@ -1,795 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#ifndef _ANODE_ANODE_H -#define _ANODE_ANODE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define ANODE_ADDRESS_LENGTH_ANODE_256_40 40 -#define ANODE_ADDRESS_MAX_LENGTH 40 -#define ANODE_ADDRESS_SECRET_LENGTH_ANODE_256_40 32 -#define ANODE_ADDRESS_MAX_SECRET_LENGTH 32 - -#define ANODE_ADDRESS_ID_LENGTH 8 -#define ANODE_ZONE_LENGTH 4 - -#define ANODE_ERR_NONE 0 -#define ANODE_ERR_INVALID_ARGUMENT (-10000) -#define ANODE_ERR_OUT_OF_MEMORY (-10001) -#define ANODE_ERR_INVALID_URI (-10002) -#define ANODE_ERR_BUFFER_TOO_SMALL (-10003) -#define ANODE_ERR_ADDRESS_INVALID (-10010) -#define ANODE_ERR_ADDRESS_TYPE_NOT_SUPPORTED (-10011) -#define ANODE_ERR_CONNECTION_CLOSED (-10012) -#define ANODE_ERR_CONNECTION_CLOSED_BY_REMOTE (-10013) -#define ANODE_ERR_CONNECT_FAILED (-10014) -#define ANODE_ERR_UNABLE_TO_BIND (-10015) -#define ANODE_ERR_TOO_MANY_OPEN_SOCKETS (-10016) -#define ANODE_ERR_DNS_NAME_NOT_FOUND_OR_TIMED_OUT (-10017) - -/** - * Get a human-readable error description for an error code - * - * The value of 'err' can be either negative or positive. - * - * @param err Error code - * @return Human-readable description - */ -extern const char *Anode_strerror(int err); - -/* ----------------------------------------------------------------------- */ -/* Secure random source */ -/* ----------------------------------------------------------------------- */ - -/** - * Opaque secure random instance - */ -typedef void AnodeSecureRandom; - -/** - * Initialize a secure random source - * - * No cleanup/destructor is necessary. - * - * @param srng Random structure to initialize - */ -extern AnodeSecureRandom *AnodeSecureRandom_new(); - -/** - * Generate random bytes - * - * @param srng Secure random source - * @param buf Buffer to fill - * @param count Number of bytes to generate - */ -extern void AnodeSecureRandom_gen_bytes(AnodeSecureRandom *srng,void *buf,long count); - -/** - * Destroy and free a secure random instance - * - * @param srng Secure random source - */ -extern void AnodeSecureRandom_delete(AnodeSecureRandom *srng); - -/* ----------------------------------------------------------------------- */ -/* AES-256 derived Davis-Meyer hash function */ -/* ----------------------------------------------------------------------- */ - -/** - * Digest a message using AES-DIGEST to yield a 16-byte hash code - * - * @param message Message to digest - * @param message_len Length of message in bytes - * @param hash Buffer to store 16 byte hash code - */ -extern void Anode_aes_digest( - const void *const message, - unsigned long message_len, - void *const hash); - -/* ----------------------------------------------------------------------- */ -/* Address Types and Components */ -/* ----------------------------------------------------------------------- */ - -/** - * Anode address - * - * The first byte always identifies the address type, which right now can - * only be type 1 (ANODE-256-40). - */ -typedef struct -{ - char bits[ANODE_ADDRESS_MAX_LENGTH]; -} AnodeAddress; - -/** - * 8-byte short Anode address ID - */ -typedef struct -{ - char bits[ANODE_ADDRESS_ID_LENGTH]; -} AnodeAddressId; - -/** - * 4-byte Anode zone ID - */ -typedef struct -{ - char bits[ANODE_ZONE_LENGTH]; -} AnodeZone; - -/** - * Anode address types - */ -enum AnodeAddressType -{ - ANODE_ADDRESS_ANODE_256_40 = 1 -}; - -/** - * Get the type of an Anode address - * - * This is a shortcut macro for just looking at the first byte and casting - * it to the AnodeAddressType enum. - * - * @param a Pointer to address - * @return Type as enum AnodeAddressType - */ -#define AnodeAddress_get_type(a) ((enum AnodeAddressType)((a)->bits[0])) - -/** - * Calculate the short 8 byte address ID from an address - * - * @param address Binary address - * @param short_address_id Buffer to store 8-byte short address ID - * @return 0 on success or error code on failure - */ -extern int AnodeAddress_calc_short_id( - const AnodeAddress *address, - AnodeAddressId *short_address_id); - -/** - * Extract the zone from an anode address - * - * @param address Binary address - * @param zone Zone value-result parameter to fill on success - * @return 0 on success or error code on failure - */ -extern int AnodeAddress_get_zone(const AnodeAddress *address,AnodeZone *zone); - -/** - * Convert an address to an ASCII string - * - * Anode addresses are 64 characters in ASCII form, so the buffer should - * have 65 bytes of space. - * - * @param address Address to convert - * @param buf Buffer to receive address in string form (should have 65 bytes of space) - * @param len Length of buffer - * @return Length of resulting string or a negative error code on error - */ -extern int AnodeAddress_to_string(const AnodeAddress *address,char *buf,int len); - -/** - * Convert a string into an address - * - * @param str Address in string form - * @param address Address buffer to receive result - * @return Zero on sucess or error code on error - */ -extern int AnodeAddress_from_string(const char *str,AnodeAddress *address); - -/** - * Supported network address types - */ -enum AnodeNetworkAddressType -{ - ANODE_NETWORK_ADDRESS_IPV4 = 0, - ANODE_NETWORK_ADDRESS_IPV6 = 1, - ANODE_NETWORK_ADDRESS_ETHERNET = 2, /* reserved but unused */ - ANODE_NETWORK_ADDRESS_USB = 3, /* reserved but unused */ - ANODE_NETWORK_ADDRESS_BLUETOOTH = 4, /* reserved but unused */ - ANODE_NETWORK_ADDRESS_IPC = 5, /* reserved but unused */ - ANODE_NETWORK_ADDRESS_80211S = 6, /* reserved but unused */ - ANODE_NETWORK_ADDRESS_SERIAL = 7, /* reserved but unused */ - ANODE_NETWORK_ADDRESS_ANODE_256_40 = 8 -}; - -/** - * Anode network address - * - * This can contain an address of any type: IPv4, IPv6, or Anode, and is used - * with the common transport API. - * - * The length of the address stored in bits[] is determined by the type. - */ -typedef struct -{ - enum AnodeNetworkAddressType type; - char bits[ANODE_ADDRESS_MAX_LENGTH]; -} AnodeNetworkAddress; - -/** - * An endpoint with an address and a port - */ -typedef struct -{ - AnodeNetworkAddress address; - int port; -} AnodeNetworkEndpoint; - -/* Constants for binding to any address (v4 or v6) */ -extern const AnodeNetworkAddress AnodeNetworkAddress_IP_ANY_V4; -extern const AnodeNetworkAddress AnodeNetworkAddress_IP_ANY_V6; - -/* Local host address in v4 and v6 */ -extern const AnodeNetworkAddress AnodeNetworkAddress_IP_LOCAL_V4; -extern const AnodeNetworkAddress AnodeNetworkAddress_IP_LOCAL_V6; - -/** - * Convert a network address to an ASCII string - * - * The buffer must have room for a 15 character string for IPv4, a 40 byte - * string for IPv6, and a 64 byte string for Anode addresses. This does not - * include the trailing null. - * - * @param address Address to convert - * @param buf Buffer to receive address in string form - * @param len Length of buffer - * @return Length of resulting string or a negative error code on error - */ -extern int AnodeNetworkAddress_to_string(const AnodeNetworkAddress *address,char *buf,int len); - -/** - * Convert a string into a network address of the correct type - * - * @param str Address in string form - * @param address Address buffer to receive result - * @return Zero on sucess or error code on error - */ -extern int AnodeNetworkAddress_from_string(const char *str,AnodeNetworkAddress *address); - -/** - * Fill a network endpoint from a C-API sockaddr structure - * - * The argument must be struct sockaddr_in for IPv4 or sockaddr_in6 for IPv6. - * The common sin_family field will be used to differentiate. - * - * @param sockaddr Pointer to proper sockaddr structure - * @param endpoint Endpoint structure to fill - * @return Zero on success or error on failure - */ -extern int AnodeNetworkEndpoint_from_sockaddr(const void *sockaddr,AnodeNetworkEndpoint *endpoint); - -/** - * Fill a sockaddr from a network endpoint - * - * To support either IPv4 or IPv6 addresses, there is a sockaddr_storage - * structure in most C APIs. If you supply anything other than an IP address - * such as an Anode address, this will return an error. - * - * @param endpoint Endpoint structure to convert - * @param sockaddr Sockaddr structure storage - * @param sockaddr_len Length of sockaddr structure storage in bytes - * @return Zero on success or error on failure - */ -extern int AnodeNetworkEndpoint_to_sockaddr(const AnodeNetworkEndpoint *endpoint,void *sockaddr,int sockaddr_len); - -/* ----------------------------------------------------------------------- */ -/* Identity Generation and Management */ -/* ----------------------------------------------------------------------- */ - -/** - * Anode identity structure containing address and secret key - * - * This structure is memcpy-safe, and its members are accessible. - */ -typedef struct -{ - /* The public Anode address */ - AnodeAddress address; - - /* Short address ID */ - AnodeAddressId address_id; - - /* The secret key corresponding with the public address */ - /* Secret length is determined by address type */ - char secret[ANODE_ADDRESS_MAX_SECRET_LENGTH]; -} AnodeIdentity; - -/** - * Generate a new identity - * - * This generates a public/private key pair and from that generates an - * identity containing an address and a secret key. - * - * @param identity Destination structure to store new identity - * @param zone Zone ID - * @param type Type of identity to generate - * @return Zero on success, error on failure - */ -extern int AnodeIdentity_generate( - AnodeIdentity *identity, - const AnodeZone *zone, - enum AnodeAddressType type); - -/** - * Convert an Anode identity to a string representation - * - * @param identity Identity to convert - * @param dest String buffer - * @param dest_len Length of string buffer - * @return Length of string created or negative error code on failure - */ -extern int AnodeIdentity_to_string( - const AnodeIdentity *identity, - char *dest, - int dest_len); - -/** - * Convert a string representation to an Anode identity structure - * - * @param identity Destination structure to fill - * @param str C-string containing string representation - * @return Zero on success or negative error code on failure - */ -extern int AnodeIdentity_from_string( - AnodeIdentity *identity, - const char *str); - -/* ----------------------------------------------------------------------- */ -/* Transport API */ -/* ----------------------------------------------------------------------- */ - -struct _AnodeTransport; -typedef struct _AnodeTransport AnodeTransport; -struct _AnodeEvent; -typedef struct _AnodeEvent AnodeEvent; - -/** - * Anode socket - */ -typedef struct -{ - /* Type of socket (read-only) */ - enum { - ANODE_SOCKET_DATAGRAM = 1, - ANODE_SOCKET_STREAM_LISTEN = 2, - ANODE_SOCKET_STREAM_CONNECTION = 3 - } type; - - /* Socket state */ - enum { - ANODE_SOCKET_CLOSED = 0, - ANODE_SOCKET_OPEN = 1, - ANODE_SOCKET_CONNECTING = 2, - } state; - - /* Local address or remote address for stream connections (read-only) */ - AnodeNetworkEndpoint endpoint; - - /* Name of owning class (read-only) */ - const char *class_name; - - /* Pointers for end user use (writable) */ - void *user_ptr[2]; - - /* Special handler to receive events or null for default (writable) */ - void (*event_handler)(const AnodeEvent *event); -} AnodeSocket; - -/** - * Anode transport I/O event - */ -struct _AnodeEvent -{ - enum { - ANODE_TRANSPORT_EVENT_DATAGRAM_RECEIVED = 1, - ANODE_TRANSPORT_EVENT_STREAM_INCOMING_CONNECT = 2, - ANODE_TRANSPORT_EVENT_STREAM_OUTGOING_CONNECT_ESTABLISHED = 3, - ANODE_TRANSPORT_EVENT_STREAM_OUTGOING_CONNECT_FAILED = 4, - ANODE_TRANSPORT_EVENT_STREAM_CLOSED = 5, - ANODE_TRANSPORT_EVENT_STREAM_DATA_RECEIVED = 6, - ANODE_TRANSPORT_EVENT_STREAM_AVAILABLE_FOR_WRITE = 7, - ANODE_TRANSPORT_EVENT_DNS_RESULT = 8 - } type; - - AnodeTransport *transport; - - /* Anode socket corresponding to this event */ - AnodeSocket *sock; - - /* Originating endpoint for incoming datagrams */ - AnodeNetworkEndpoint *datagram_from; - - /* DNS lookup results */ - const char *dns_name; - AnodeNetworkAddress *dns_addresses; - int dns_address_count; - - /* Error code or 0 for none */ - int error_code; - - /* Data for incoming datagrams and stream received events */ - int data_length; - char *data; -}; - -/** - * Enum used for dns_resolve method in transport to specify query rules - * - * This can be specified for ipv4, ipv6, and Anode address types to tell the - * DNS resolver when to bother querying for addresses of the given type. - * NEVER means to never query for this type, and ALWAYS means to always - * query. IF_NO_PREVIOUS means to query for this type if no addresses were - * found in previous queries. Addresses are queried in the order of ipv4, - * ipv6, then Anode, so if you specify IF_NO_PREVIOUS for all three you will - * get addresses in that order of priority. - */ -enum AnodeTransportDnsIncludeMode -{ - ANODE_TRANSPORT_DNS_QUERY_NEVER = 0, - ANODE_TRANSPORT_DNS_QUERY_ALWAYS = 1, - ANODE_TRANSPORT_DNS_QUERY_IF_NO_PREVIOUS = 2 -}; - -struct _AnodeTransport -{ - /** - * Set the default event handler - * - * @param transport Transport engine - * @param event_handler Default event handler - */ - void (*set_default_event_handler)(AnodeTransport *transport, - void (*event_handler)(const AnodeEvent *event)); - - /** - * Enqueue a function to be executed during a subsequent call to poll() - * - * This can be called from other threads, so it can be used to pass a - * message to the I/O thread in multithreaded applications. - * - * If it is called from the same thread, the function is still queued to be - * run later rather than being run instantly. - * - * The order in which invoked functions are called is undefined. - * - * @param transport Transport engine - * @param ptr Arbitrary pointer to pass to function to be called - * @param func Function to be called - */ - void (*invoke)(AnodeTransport *transport, - void *ptr, - void (*func)(void *)); - - /** - * Initiate a forward DNS query - * - * @param transport Transport instance - * @param name DNS name to query - * @param event_handler Event handler or null for default event path - * @param ipv4_include_mode Inclusion mode for IPv4 addresses - * @param ipv6_include_mode Inclusion mode for IPv6 addresses - * @param anode_include_mode Inclusion mode for Anode addresses - */ - void (*dns_resolve)(AnodeTransport *transport, - const char *name, - void (*event_handler)(const AnodeEvent *), - enum AnodeTransportDnsIncludeMode ipv4_include_mode, - enum AnodeTransportDnsIncludeMode ipv6_include_mode, - enum AnodeTransportDnsIncludeMode anode_include_mode); - - /** - * Open a datagram socket - * - * @param transport Transport instance - * @param local_address Local address to bind - * @param local_port Local port to bind - * @param error_code Value-result parameter to receive error code on error - * @return Listen socket or null if error (check error_code in error case) - */ - AnodeSocket *(*datagram_listen)(AnodeTransport *transport, - const AnodeNetworkAddress *local_address, - int local_port, - int *error_code); - - /** - * Open a socket to listen for incoming stream connections - * - * @param transport Transport instance - * @param local_address Local address to bind - * @param local_port Local port to bind - * @param error_code Value-result parameter to receive error code on error - * @return Listen socket or null if error (check error_code in error case) - */ - AnodeSocket *(*stream_listen)(AnodeTransport *transport, - const AnodeNetworkAddress *local_address, - int local_port, - int *error_code); - - /** - * Send a datagram to a network endpoint - * - * @param transport Transport instance - * @param socket Originating datagram socket - * @param data Data to send - * @param data_len Length of data to send - * @param to_endpoint Destination endpoint - * @return Zero on success or error code on error - */ - int (*datagram_send)(AnodeTransport *transport, - AnodeSocket *sock, - const void *data, - int data_len, - const AnodeNetworkEndpoint *to_endpoint); - - /** - * Initiate an outgoing stream connection attempt - * - * For IPv4 and IPv6 addresses, this will initiate a TCP connection. For - * Anode addresses, Anode's internal streaming protocol will be used. - * - * @param transport Transport instance - * @param to_endpoint Destination endpoint - * @param error_code Error code value-result parameter, filled on error - * @return Stream socket object or null on error (check error_code) - */ - AnodeSocket *(*stream_connect)(AnodeTransport *transport, - const AnodeNetworkEndpoint *to_endpoint, - int *error_code); - - /** - * Indicate that you are interested in writing to a stream - * - * This does nothing if the socket is not a stream connection or is not - * connected. - * - * @param transport Transport instance - * @param sock Stream connection - */ - void (*stream_start_writing)(AnodeTransport *transport, - AnodeSocket *sock); - - /** - * Indicate that you are no longer interested in writing to a stream - * - * This does nothing if the socket is not a stream connection or is not - * connected. - * - * @param transport Transport instance - * @param sock Stream connection - */ - void (*stream_stop_writing)(AnodeTransport *transport, - AnodeSocket *sock); - - /** - * Send data to a stream connection - * - * This must be called after a stream is indicated to be ready for writing. - * It returns the number of bytes actually written, or a negative error - * code on failure. - * - * A return value of zero can occur here, and simply indicates that nothing - * was sent. This may occur with certain network stacks on certain - * platforms. - * - * @param transport Transport engine - * @param sock Stream socket - * @param data Data to send - * @param data_len Maximum data to send in bytes - * @return Actual data sent or negative error code on error - */ - int (*stream_send)(AnodeTransport *transport, - AnodeSocket *sock, - const void *data, - int data_len); - - /** - * Close a socket - * - * If the socket is a stream connection in the connected state, this - * will generate a stream closed event with a zero error_code to indicate - * a normal close. - * - * @param transport Transport engine - * @param sock Socket object - */ - void (*close)(AnodeTransport *transport, - AnodeSocket *sock); - - /** - * Run main polling loop - * - * This should be called repeatedly from the I/O thread of your main - * process. It blocks until one or more events occur, and then returns - * the number of events. Error returns here are fatal and indicate - * serious problems such as build or platform issues or a lack of any - * network interface. - * - * Functions queued with invoke() are also called inside here. - * - * @param transport Transport engine - * @return Number of events handled or negative on (fatal) error - */ - int (*poll)(AnodeTransport *transport); - - /** - * Check whether transport supports an address type - * - * Inheriting classes should call their base if they do not natively - * speak the specified type. - * - * @param transport Transport engine - * @param at Address type - * @return Nonzero if true - */ - int (*supports_address_type)(const AnodeTransport *transport, - enum AnodeNetworkAddressType at); - - /** - * Get the instance of AnodeTransport under this one (if any) - * - * @param transport Transport engine - * @return Base instance or null if none - */ - AnodeTransport *(*base_instance)(const AnodeTransport *transport); - - /** - * @param transport Transport engine - * @return Class name of this instance - */ - const char *(*class_name)(AnodeTransport *transport); - - /** - * Delete this transport and its base transports - * - * The 'transport' pointer and any streams or sockets it owns are no longer - * valid after this call. - * - * @param transport Transport engine - */ - void (*delete)(AnodeTransport *transport); -}; - -/** - * Construct a new system transport - * - * This is the default base for AnodeTransport, and it is constructed - * automatically if 'base' is null in AnodeTransport_new(). However, it also - * exposed to the user so that specialized transports (such as those that use - * proxy servers) can be developed on top of it. These in turn can be supplied - * as 'base' to AnodeTransport_new() to talk Anode over these transports. - * - * The system transport supports IP protocols and possibly others. - * - * @param base Base class or null for none (usually null) - * @return Base transport engine instance - */ -extern AnodeTransport *AnodeSystemTransport_new(AnodeTransport *base); - -/** - * Construct a new Anode core transport - * - * This is the transport that talks Anode using the specified base transport. - * Requests for other address types are passed through to the base. If the - * base is null, an instance of AnodeSystemTransport is used. - * - * Since transport engines inherit their functionality, this transport - * will also do standard IP and everything else that the system transport - * supports. Most users will just want to construct this with a null base. - * - * @param base Base transport to use, or null to use SystemTransport - * @return Anode transport engine or null on error - */ -extern AnodeTransport *AnodeCoreTransport_new(AnodeTransport *base); - -/* ----------------------------------------------------------------------- */ -/* URI Parser */ -/* ----------------------------------------------------------------------- */ - -/** - * URI broken down by component - */ -typedef struct -{ - char scheme[8]; - char username[64]; - char password[64]; - char host[128]; - char path[256]; - char query[256]; - char fragment[64]; - int port; -} AnodeURI; - -/** - * URI parser - * - * A buffer too small error will occur if any field is too large for the - * AnodeURI structure. - * - * @param parsed_uri Structure to fill with parsed URI data - * @param uri_string URI in string format - * @return Zero on success or error on failure - */ -extern int AnodeURI_parse(AnodeURI *parsed_uri,const char *uri_string); - -/** - * Output a URI in string format - * - * @param uri URI to output as string - * @param buf Buffer to store URI string - * @param len Length of buffer - * @return Buffer or null on error - */ -extern char *AnodeURI_to_string(const AnodeURI *uri,char *buf,int len); - -/* ----------------------------------------------------------------------- */ -/* Zone File Lookup and Dictionary */ -/* ----------------------------------------------------------------------- */ - -/** - * Zone file dictionary - */ -typedef void AnodeZoneFile; - -/** - * Start asynchronous zone fetch - * - * When the zone is retrieved, the lookup handler is called. If zone lookup - * failed, the zone file argument to the handler will be null. - * - * @param transport Transport engine - * @param zone Zone ID - * @param user_ptr User pointer - * @param zone_lookup_handler Handler for Anode zone lookup - */ -extern void AnodeZoneFile_lookup( - AnodeTransport *transport, - const AnodeZone *zone, - void *ptr, - void (*zone_lookup_handler)(const AnodeZone *,AnodeZoneFile *,void *)); - -/** - * Look up a key in a zone file - * - * @param zone Zone file object - * @param key Key to get in zone file - */ -extern const char *AnodeZoneFile_get(const AnodeZoneFile *zone,const char *key); - -/** - * Free a zone file - * - * @param zone Zone to free - */ -extern void AnodeZoneFile_free(AnodeZoneFile *zone); - -/* ----------------------------------------------------------------------- */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/attic/historic/anode/libanode/errors.c b/attic/historic/anode/libanode/errors.c deleted file mode 100644 index 6836bdc44..000000000 --- a/attic/historic/anode/libanode/errors.c +++ /dev/null @@ -1,52 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include "anode.h" - -struct AnodeErrDesc -{ - int code; - const char *desc; -}; - -#define TOTAL_ERRORS 12 -static const struct AnodeErrDesc ANODE_ERRORS[TOTAL_ERRORS] = { - { ANODE_ERR_NONE, "No error (success)" }, - { ANODE_ERR_INVALID_ARGUMENT, "Invalid argument" }, - { ANODE_ERR_OUT_OF_MEMORY, "Out of memory" }, - { ANODE_ERR_INVALID_URI, "Invalid URI" }, - { ANODE_ERR_BUFFER_TOO_SMALL, "Supplied buffer too small" }, - { ANODE_ERR_ADDRESS_INVALID, "Address invalid" }, - { ANODE_ERR_ADDRESS_TYPE_NOT_SUPPORTED, "Address type not supported"}, - { ANODE_ERR_CONNECTION_CLOSED, "Connection closed"}, - { ANODE_ERR_CONNECT_FAILED, "Connect failed"}, - { ANODE_ERR_UNABLE_TO_BIND, "Unable to bind to address"}, - { ANODE_ERR_TOO_MANY_OPEN_SOCKETS, "Too many open sockets"}, - { ANODE_ERR_DNS_NAME_NOT_FOUND_OR_TIMED_OUT, "DNS name not found or timed out"} -}; - -extern const char *Anode_strerror(int err) -{ - int i; - int negerr = -err; - - for(i=0;i - * - * 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 . */ - -#include -#include -#include "impl/types.h" -#include "impl/ec.h" -#include "impl/misc.h" -#include "anode.h" - -int AnodeIdentity_generate(AnodeIdentity *identity,const AnodeZone *zone,enum AnodeAddressType type) -{ - struct AnodeECKeyPair kp; - - switch(type) { - case ANODE_ADDRESS_ANODE_256_40: - if (!AnodeECKeyPair_generate(&kp)) - return ANODE_ERR_OUT_OF_MEMORY; - - identity->address.bits[0] = (unsigned char)ANODE_ADDRESS_ANODE_256_40; - - identity->address.bits[1] = zone->bits[0]; - identity->address.bits[2] = zone->bits[1]; - identity->address.bits[3] = zone->bits[2]; - identity->address.bits[4] = zone->bits[3]; - - identity->address.bits[5] = 0; - identity->address.bits[6] = 0; - - Anode_memcpy((void *)&(identity->address.bits[7]),(const void *)kp.pub.key,ANODE_EC_PUBLIC_KEY_BYTES); - Anode_memcpy((void *)identity->secret,(const void *)kp.priv.key,kp.priv.bytes); - - AnodeAddress_calc_short_id(&identity->address,&identity->address_id); - - AnodeECKeyPair_destroy(&kp); - - return 0; - } - - return ANODE_ERR_INVALID_ARGUMENT; -} - -int AnodeIdentity_to_string(const AnodeIdentity *identity,char *dest,int dest_len) -{ - char hexbuf[128]; - char strbuf[128]; - int n; - - if ((n = AnodeAddress_to_string(&identity->address,strbuf,sizeof(strbuf))) <= 0) - return n; - - switch(AnodeAddress_get_type(&identity->address)) { - case ANODE_ADDRESS_ANODE_256_40: - Anode_to_hex((const unsigned char *)identity->secret,ANODE_ADDRESS_SECRET_LENGTH_ANODE_256_40,hexbuf,sizeof(hexbuf)); - n = snprintf(dest,dest_len,"ANODE-256-40:%s:%s",strbuf,hexbuf); - if (n >= dest_len) - return ANODE_ERR_BUFFER_TOO_SMALL; - return n; - } - - return ANODE_ERR_INVALID_ARGUMENT; -} - -int AnodeIdentity_from_string(AnodeIdentity *identity,const char *str) -{ - char buf[1024]; - char *id_name; - char *address; - char *secret; - int ec; - - Anode_str_copy(buf,str,sizeof(buf)); - - id_name = buf; - if (!id_name) return 0; - if (!*id_name) return 0; - address = (char *)Anode_strchr(id_name,':'); - if (!address) return 0; - if (!*address) return 0; - *(address++) = (char)0; - secret = (char *)Anode_strchr(address,':'); - if (!secret) return 0; - if (!*secret) return 0; - *(secret++) = (char)0; - - if (Anode_strcaseeq("ANODE-256-40",id_name)) { - if ((ec = AnodeAddress_from_string(address,&identity->address))) - return ec; - if (Anode_strlen(secret) != (ANODE_ADDRESS_SECRET_LENGTH_ANODE_256_40 * 2)) - return ANODE_ERR_INVALID_ARGUMENT; - Anode_from_hex(secret,(unsigned char *)identity->secret,sizeof(identity->secret)); - AnodeAddress_calc_short_id(&identity->address,&identity->address_id); - return 0; - } - - return ANODE_ERR_INVALID_ARGUMENT; -} diff --git a/attic/historic/anode/libanode/impl/aes.c b/attic/historic/anode/libanode/impl/aes.c deleted file mode 100644 index 90e5e23ba..000000000 --- a/attic/historic/anode/libanode/impl/aes.c +++ /dev/null @@ -1,72 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include "aes.h" - -void Anode_cmac_aes256( - const AnodeAesExpandedKey *expkey, - const unsigned char *restrict data, - unsigned long data_len, - unsigned char *restrict mac) -{ - unsigned char cbc[16]; - unsigned char pad[16]; - const unsigned char *restrict pos = data; - unsigned long i; - unsigned long remaining = data_len; - unsigned char c; - - ((uint64_t *)((void *)cbc))[0] = 0ULL; - ((uint64_t *)((void *)cbc))[1] = 0ULL; - - while (remaining >= 16) { - ((uint64_t *)((void *)cbc))[0] ^= ((uint64_t *)((void *)pos))[0]; - ((uint64_t *)((void *)cbc))[1] ^= ((uint64_t *)((void *)pos))[1]; - pos += 16; - if (remaining > 16) - Anode_aes256_encrypt(expkey,cbc,cbc); - remaining -= 16; - } - - ((uint64_t *)((void *)pad))[0] = 0ULL; - ((uint64_t *)((void *)pad))[1] = 0ULL; - Anode_aes256_encrypt(expkey,pad,pad); - - c = pad[0] & 0x80; - for(i=0;i<15;++i) - pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); - pad[15] <<= 1; - if (c) - pad[15] ^= 0x87; - - if (remaining||(!data_len)) { - for(i=0;i> 7); - pad[15] <<= 1; - if (c) - pad[15] ^= 0x87; - } - - ((uint64_t *)((void *)mac))[0] = ((uint64_t *)((void *)pad))[0] ^ ((uint64_t *)((void *)cbc))[0]; - ((uint64_t *)((void *)mac))[1] = ((uint64_t *)((void *)pad))[1] ^ ((uint64_t *)((void *)cbc))[1]; - - Anode_aes256_encrypt(expkey,mac,mac); -} diff --git a/attic/historic/anode/libanode/impl/aes.h b/attic/historic/anode/libanode/impl/aes.h deleted file mode 100644 index 25e33933d..000000000 --- a/attic/historic/anode/libanode/impl/aes.h +++ /dev/null @@ -1,64 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009 Adam Ierymenko - * - * 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 . */ - -#ifndef _ANODE_AES_H -#define _ANODE_AES_H - -#include -#include "types.h" - -/* This just glues us to OpenSSL's built-in AES-256 implementation */ - -#define ANODE_AES_BLOCK_SIZE 16 -#define ANODE_AES_KEY_SIZE 32 - -typedef AES_KEY AnodeAesExpandedKey; - -#define Anode_aes256_expand_key(k,ek) AES_set_encrypt_key((const unsigned char *)(k),256,(AES_KEY *)(ek)) - -/* Note: in and out can be the same thing */ -#define Anode_aes256_encrypt(ek,in,out) AES_encrypt((const unsigned char *)(in),(unsigned char *)(out),(const AES_KEY *)(ek)) - -/* Note: iv is modified */ -static inline void Anode_aes256_cfb_encrypt( - const AnodeAesExpandedKey *expkey, - const unsigned char *in, - unsigned char *out, - unsigned char *iv, - unsigned long len) -{ - int tmp = 0; - AES_cfb128_encrypt(in,out,len,(const AES_KEY *)expkey,iv,&tmp,AES_ENCRYPT); -} -static inline void Anode_aes256_cfb_decrypt( - const AnodeAesExpandedKey *expkey, - const unsigned char *in, - unsigned char *out, - unsigned char *iv, - unsigned long len) -{ - int tmp = 0; - AES_cfb128_encrypt(in,out,len,(const AES_KEY *)expkey,iv,&tmp,AES_DECRYPT); -} - -/* CMAC message authentication code */ -void Anode_cmac_aes256( - const AnodeAesExpandedKey *expkey, - const unsigned char *restrict data, - unsigned long data_len, - unsigned char *restrict mac); - -#endif diff --git a/attic/historic/anode/libanode/impl/dictionary.c b/attic/historic/anode/libanode/impl/dictionary.c deleted file mode 100644 index 060c38150..000000000 --- a/attic/historic/anode/libanode/impl/dictionary.c +++ /dev/null @@ -1,239 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include "dictionary.h" - -static const char *EMPTY_STR = ""; - -void AnodeDictionary_clear(struct AnodeDictionary *d) -{ - struct AnodeDictionaryEntry *e,*ne; - int oldcs; - unsigned int i; - - oldcs = d->case_sensitive; - - for(i=0;iht[i]; - while (e) { - ne = e->next; - if ((e->key)&&(e->key != EMPTY_STR)) free((void *)e->key); - if ((e->value)&&(e->value != EMPTY_STR)) free((void *)e->value); - free((void *)e); - e = ne; - } - } - - Anode_zero((void *)d,sizeof(struct AnodeDictionary)); - - d->case_sensitive = oldcs; -} - -void AnodeDictionary_put(struct AnodeDictionary *d,const char *key,const char *value) -{ - struct AnodeDictionaryEntry *e; - char *p1; - const char *p2; - unsigned int bucket = (d->case_sensitive) ? AnodeDictionary__get_bucket(key) : AnodeDictionary__get_bucket_ci(key); - unsigned int len,i; - - e = d->ht[bucket]; - while (e) { - if (((d->case_sensitive) ? Anode_streq(key,e->key) : Anode_strcaseeq(key,e->key))) { - if (!d->case_sensitive) { - p1 = e->key; - p2 = key; - while (*p2) *(p1++) = *(p2++); - } - - len = 0; - while (value[len]) ++len; - if (len) { - if ((e->value)&&(e->value != EMPTY_STR)) - e->value = (char *)realloc((void *)e->value,len + 1); - else e->value = (char *)malloc(len + 1); - for(i=0;ivalue[i] = value[i]; - e->value[i] = (char)0; - } else { - if ((e->value)&&(e->value != EMPTY_STR)) free((void *)e->value); - e->value = (char *)EMPTY_STR; - } - return; - } - e = e->next; - } - - e = (struct AnodeDictionaryEntry *)malloc(sizeof(struct AnodeDictionaryEntry)); - - len = 0; - while (key[len]) ++len; - if (len) { - e->key = (char *)malloc(len + 1); - for(i=0;ikey[i] = key[i]; - e->key[i] = (char)0; - } else e->key = (char *)EMPTY_STR; - - len = 0; - while (value[len]) ++len; - if (len) { - e->value = (char *)malloc(len + 1); - for(i=0;ivalue[i] = value[i]; - e->value[i] = (char)0; - } else e->value = (char *)EMPTY_STR; - - e->next = d->ht[bucket]; - d->ht[bucket] = e; - - ++d->size; -} - -void AnodeDictionary_read( - struct AnodeDictionary *d, - char *in, - const char *line_breaks, - const char *kv_breaks, - const char *comment_chars, - char escape_char, - int trim_whitespace_from_keys, - int trim_whitespace_from_values) -{ - char *line = in; - char *key; - char *value; - char *p1,*p2,*p3; - char last = ~escape_char; - int eof_state = 0; - - for(;;) { - if ((!*in)||((Anode_strchr(line_breaks,*in))&&((last != escape_char)||(!escape_char)))) { - if (!*in) - eof_state = 1; - else *in = (char)0; - - if ((*line)&&((comment_chars)&&(!Anode_strchr(comment_chars,*line)))) { - key = line; - - while (*line) { - if ((Anode_strchr(kv_breaks,*line))&&((last != escape_char)||(!escape_char))) { - *(line++) = (char)0; - break; - } else last = *(line++); - } - while ((*line)&&(Anode_strchr(kv_breaks,*line))&&((last != escape_char)||(!escape_char))) - last = *(line++); - value = line; - - if (escape_char) { - p1 = key; - while (*p1) { - if (*p1 == escape_char) { - p2 = p1; - p3 = p1 + 1; - while (*p3) - *(p2++) = *(p3++); - *p2 = (char)0; - } - ++p1; - } - p1 = value; - while (*p1) { - if (*p1 == escape_char) { - p2 = p1; - p3 = p1 + 1; - while (*p3) - *(p2++) = *(p3++); - *p2 = (char)0; - } - ++p1; - } - } - - if (trim_whitespace_from_keys) - Anode_trim(key); - if (trim_whitespace_from_values) - Anode_trim(value); - - AnodeDictionary_put(d,key,value); - } - - if (eof_state) - break; - else line = in + 1; - } - last = *(in++); - } -} - -long AnodeDictionary_write( - struct AnodeDictionary *d, - char *out, - long out_size, - const char *line_break, - const char *kv_break) -{ - struct AnodeDictionaryEntry *e; - const char *tmp; - long ptr = 0; - unsigned int bucket; - - if (out_size <= 0) - return -1; - - for(bucket=0;bucketht[bucket]; - while (e) { - tmp = e->key; - if (tmp) { - while (*tmp) { - out[ptr++] = *tmp++; - if (ptr >= (out_size - 1)) return -1; - } - } - - tmp = kv_break; - if (tmp) { - while (*tmp) { - out[ptr++] = *tmp++; - if (ptr >= (out_size - 1)) return -1; - } - } - - tmp = e->value; - if (tmp) { - while (*tmp) { - out[ptr++] = *tmp++; - if (ptr >= (out_size - 1)) return -1; - } - } - - tmp = line_break; - if (tmp) { - while (*tmp) { - out[ptr++] = *tmp++; - if (ptr >= (out_size - 1)) return -1; - } - } - - e = e->next; - } - } - - out[ptr] = (char)0; - - return ptr; -} diff --git a/attic/historic/anode/libanode/impl/dictionary.h b/attic/historic/anode/libanode/impl/dictionary.h deleted file mode 100644 index 48e1642a0..000000000 --- a/attic/historic/anode/libanode/impl/dictionary.h +++ /dev/null @@ -1,126 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 is a simple string hash table suitable for small tables such as zone - * files or HTTP header lists. */ - -#ifndef _ANODE_DICTIONARY_H -#define _ANODE_DICTIONARY_H - -#include "misc.h" - -/* This is a fixed hash table and is designed for relatively small numbers - * of keys for things like zone files. */ -#define ANODE_DICTIONARY_FIXED_HASH_TABLE_SIZE 16 -#define ANODE_DICTIONARY_FIXED_HASH_TABLE_MASK 15 - -/* Computes a hash code for a string and returns the hash bucket */ -static inline unsigned int AnodeDictionary__get_bucket(const char *s) -{ - unsigned int hc = 3; - while (*s) - hc = ((hc << 4) + hc) + (unsigned int)*(s++); - return ((hc ^ (hc >> 4)) & ANODE_DICTIONARY_FIXED_HASH_TABLE_MASK); -} -/* Case insensitive version of get_bucket */ -static inline unsigned int AnodeDictionary__get_bucket_ci(const char *s) -{ - unsigned int hc = 3; - while (*s) - hc = ((hc << 4) + hc) + (unsigned int)Anode_tolower(*(s++)); - return ((hc ^ (hc >> 4)) & ANODE_DICTIONARY_FIXED_HASH_TABLE_MASK); -} - -struct AnodeDictionaryEntry -{ - char *key; - char *value; - struct AnodeDictionaryEntry *next; -}; - -struct AnodeDictionary -{ - struct AnodeDictionaryEntry *ht[ANODE_DICTIONARY_FIXED_HASH_TABLE_SIZE]; - unsigned int size; - int case_sensitive; -}; - -static inline void AnodeDictionary_init(struct AnodeDictionary *d,int case_sensitive) -{ - Anode_zero((void *)d,sizeof(struct AnodeDictionary)); - d->case_sensitive = case_sensitive; -} - -void AnodeDictionary_clear(struct AnodeDictionary *d); - -static inline void AnodeDictionary_destroy(struct AnodeDictionary *d) -{ - AnodeDictionary_clear(d); -} - -void AnodeDictionary_put(struct AnodeDictionary *d,const char *key,const char *value); - -static inline const char *AnodeDictionary_get(struct AnodeDictionary *d,const char *key) -{ - struct AnodeDictionaryEntry *e; - unsigned int bucket = (d->case_sensitive) ? AnodeDictionary__get_bucket(key) : AnodeDictionary__get_bucket_ci(key); - - e = d->ht[bucket]; - while (e) { - if ((d->case_sensitive ? Anode_streq(key,e->key) : Anode_strcaseeq(key,e->key))) - return e->value; - e = e->next; - } - - return (const char *)0; -} - -static inline void AnodeDictionary_iterate( - struct AnodeDictionary *d, - void *arg, - int (*func)(void *,const char *,const char *)) -{ - struct AnodeDictionaryEntry *e; - unsigned int bucket; - - for(bucket=0;bucketht[bucket]; - while (e) { - if (!func(arg,e->key,e->value)) - return; - e = e->next; - } - } -} - -void AnodeDictionary_read( - struct AnodeDictionary *d, - char *in, - const char *line_breaks, - const char *kv_breaks, - const char *comment_chars, - char escape_char, - int trim_whitespace_from_keys, - int trim_whitespace_from_values); - -long AnodeDictionary_write( - struct AnodeDictionary *d, - char *out, - long out_size, - const char *line_break, - const char *kv_break); - -#endif diff --git a/attic/historic/anode/libanode/impl/dns_txt.c b/attic/historic/anode/libanode/impl/dns_txt.c deleted file mode 100644 index b5cf13184..000000000 --- a/attic/historic/anode/libanode/impl/dns_txt.c +++ /dev/null @@ -1,93 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dns_txt.h" - -#ifndef C_IN -#define C_IN ns_c_in -#endif -#ifndef T_TXT -#define T_TXT ns_t_txt -#endif - -static volatile int Anode_resolver_initialized = 0; - -int Anode_sync_resolve_txt(const char *host,char *txt,unsigned int txt_len) -{ - unsigned char answer[16384],*pptr,*end; - char name[16384]; - int len,explen,i; - - if (!Anode_resolver_initialized) { - Anode_resolver_initialized = 1; - res_init(); - } - - /* Do not taunt happy fun ball. */ - - len = res_search(host,C_IN,T_TXT,answer,sizeof(answer)); - if (len > 12) { - pptr = answer + 12; - end = answer + len; - - explen = dn_expand(answer,end,pptr,name,sizeof(name)); - if (explen > 0) { - pptr += explen; - - if ((pptr + 2) >= end) return 2; - if (ntohs(*((uint16_t *)pptr)) == T_TXT) { - pptr += 4; - if (pptr >= end) return 2; - - explen = dn_expand(answer,end,pptr,name,sizeof(name)); - if (explen > 0) { - pptr += explen; - - if ((pptr + 2) >= end) return 2; - if (ntohs(*((uint16_t *)pptr)) == T_TXT) { - pptr += 10; - if (pptr >= end) return 2; - - len = *(pptr++); - if (len <= 0) return 2; - if ((pptr + len) > end) return 2; - - if (txt_len < (len + 1)) - return 4; - else { - for(i=0;i - * - * 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 . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "types.h" -#include "misc.h" -#include "ec.h" - -static EC_GROUP *AnodeEC_group = (EC_GROUP *)0; - -static void *AnodeEC_KDF(const void *in,size_t inlen,void *out,size_t *outlen) -{ - unsigned long i,longest_length; - - if (!*outlen) - return out; - - for(i=0;i<(unsigned long)*outlen;++i) - ((unsigned char *)out)[i] = (unsigned char)0; - - longest_length = inlen; - if (longest_length < *outlen) - longest_length = *outlen; - for(i=0;i ANODE_EC_PRIME_BYTES)||(len < 0)) { - EC_KEY_free(key); - return 0; - } - BN_bn2bin(EC_KEY_get0_private_key(key),&(pair->priv.key[ANODE_EC_PRIME_BYTES - len])); - pair->priv.bytes = ANODE_EC_PRIME_BYTES; - - len = EC_POINT_point2oct(AnodeEC_group,EC_KEY_get0_public_key(key),POINT_CONVERSION_COMPRESSED,pair->pub.key,sizeof(pair->pub.key),0); - if (len != ANODE_EC_PUBLIC_KEY_BYTES) { - EC_KEY_free(key); - return 0; - } - pair->pub.bytes = ANODE_EC_PUBLIC_KEY_BYTES; - - /* Keep a copy of OpenSSL's structure around so we don't have to re-init - * it every time we use our key pair structure. */ - pair->internal_key = key; - - return 1; -} - -int AnodeECKeyPair_init(struct AnodeECKeyPair *pair,const struct AnodeECKey *pub,const struct AnodeECKey *priv) -{ - EC_KEY *key; - EC_POINT *kxy; - BIGNUM *pn; - - if (!AnodeEC_group) { - AnodeEC_group = EC_GROUP_new_by_curve_name(ANODE_EC_GROUP); - if (!AnodeEC_group) return 0; - } - - key = EC_KEY_new(); - if (!key) - return 0; - - if (!EC_KEY_set_group(key,AnodeEC_group)) { - EC_KEY_free(key); - return 0; - } - - /* Grab the private key */ - if (priv->bytes != ANODE_EC_PRIME_BYTES) { - EC_KEY_free(key); - return 0; - } - pn = BN_new(); - if (!pn) { - EC_KEY_free(key); - return 0; - } - if (!BN_bin2bn(priv->key,ANODE_EC_PRIME_BYTES,pn)) { - BN_free(pn); - EC_KEY_free(key); - return 0; - } - if (!EC_KEY_set_private_key(key,pn)) { - BN_free(pn); - EC_KEY_free(key); - return 0; - } - BN_free(pn); - - /* Set the public key */ - if (pub->bytes != ANODE_EC_PUBLIC_KEY_BYTES) { - EC_KEY_free(key); - return 0; - } - kxy = EC_POINT_new(AnodeEC_group); - if (!kxy) { - EC_KEY_free(key); - return 0; - } - EC_POINT_oct2point(AnodeEC_group,kxy,pub->key,ANODE_EC_PUBLIC_KEY_BYTES,0); - if (!EC_KEY_set_public_key(key,kxy)) { - EC_POINT_free(kxy); - EC_KEY_free(key); - return 0; - } - EC_POINT_free(kxy); - - Anode_zero(pair,sizeof(struct AnodeECKeyPair)); - Anode_memcpy((void *)&(pair->pub),(const void *)pub,sizeof(struct AnodeECKey)); - Anode_memcpy((void *)&(pair->priv),(const void *)priv,sizeof(struct AnodeECKey)); - pair->internal_key = key; - - return 1; -} - -void AnodeECKeyPair_destroy(struct AnodeECKeyPair *pair) -{ - if (pair) { - if (pair->internal_key) - EC_KEY_free((EC_KEY *)pair->internal_key); - } -} - -int AnodeECKeyPair_agree(const struct AnodeECKeyPair *my_key_pair,const struct AnodeECKey *their_pub_key,unsigned char *key_buf,unsigned int key_len) -{ - EC_POINT *pub; - int i; - - if (!AnodeEC_group) { - AnodeEC_group = EC_GROUP_new_by_curve_name(ANODE_EC_GROUP); - if (!AnodeEC_group) return 0; - } - - if (!my_key_pair->internal_key) - return 0; - - if (their_pub_key->bytes != ANODE_EC_PUBLIC_KEY_BYTES) - return 0; - pub = EC_POINT_new(AnodeEC_group); - if (!pub) - return 0; - EC_POINT_oct2point(AnodeEC_group,pub,their_pub_key->key,ANODE_EC_PUBLIC_KEY_BYTES,0); - - i = ECDH_compute_key(key_buf,key_len,pub,(EC_KEY *)my_key_pair->internal_key,&AnodeEC_KDF); - if (i != (int)key_len) { - EC_POINT_free(pub); - return 0; - } - - EC_POINT_free(pub); - - return 1; -} - -void AnodeEC_random(unsigned char *buf,unsigned int len) -{ - RAND_pseudo_bytes(buf,len); -} diff --git a/attic/historic/anode/libanode/impl/ec.h b/attic/historic/anode/libanode/impl/ec.h deleted file mode 100644 index f1262664d..000000000 --- a/attic/historic/anode/libanode/impl/ec.h +++ /dev/null @@ -1,61 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -/* Elliptic curve glue -- hides OpenSSL code behind this source module */ - -#ifndef _ANODE_EC_H -#define _ANODE_EC_H - -#include "misc.h" - -/* Right now, only one mode is supported: NIST-P-256. This is the only mode - * supported in the spec as well, and should be good for quite some time. - * If other modes are needed this code will need to be refactored. */ - -/* NIST-P-256 prime size in bytes */ -#define ANODE_EC_PRIME_BYTES 32 - -/* Sizes of key fields */ -#define ANODE_EC_GROUP NID_X9_62_prime256v1 -#define ANODE_EC_PUBLIC_KEY_BYTES (ANODE_EC_PRIME_BYTES + 1) -#define ANODE_EC_PRIVATE_KEY_BYTES ANODE_EC_PRIME_BYTES - -/* Larger of public or private key bytes, used for buffers */ -#define ANODE_EC_MAX_BYTES ANODE_EC_PUBLIC_KEY_BYTES - -struct AnodeECKey -{ - unsigned char key[ANODE_EC_MAX_BYTES]; - unsigned int bytes; -}; - -struct AnodeECKeyPair -{ - struct AnodeECKey pub; - struct AnodeECKey priv; - void *internal_key; -}; - -/* Key management functions */ -int AnodeECKeyPair_generate(struct AnodeECKeyPair *pair); -int AnodeECKeyPair_init(struct AnodeECKeyPair *pair,const struct AnodeECKey *pub,const struct AnodeECKey *priv); -void AnodeECKeyPair_destroy(struct AnodeECKeyPair *pair); -int AnodeECKeyPair_agree(const struct AnodeECKeyPair *my_key_pair,const struct AnodeECKey *their_pub_key,unsigned char *key_buf,unsigned int key_len); - -/* Provides access to the secure PRNG used to generate keys */ -void AnodeEC_random(unsigned char *buf,unsigned int len); - -#endif diff --git a/attic/historic/anode/libanode/impl/environment.c b/attic/historic/anode/libanode/impl/environment.c deleted file mode 100644 index 16e8ebe3d..000000000 --- a/attic/historic/anode/libanode/impl/environment.c +++ /dev/null @@ -1,118 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include "environment.h" - -#ifdef WINDOWS -#include -#else -#include -#include -#endif - -static char Anode_cache_base[1024] = { 0 }; - -const char *Anode_get_cache() -{ - if (Anode_cache_base[0]) - return Anode_cache_base; - -#ifdef WINDOWS -#else - char tmp[1024]; - char home[1024]; - unsigned int i; - struct stat st; - const char *_home = getenv("HOME"); - - if (!_home) - return (const char *)0; - for(i=0;i - * - * 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 . */ - -#ifndef _ANODE_ENVIRONMENT_H -#define _ANODE_ENVIRONMENT_H - -#ifdef WINDOWS -#define ANODE_PATH_SEPARATOR '\\' -#else -#define ANODE_PATH_SEPARATOR '/' -#endif - -const char *Anode_get_cache(); -char *Anode_get_cache_sub(const char *cache_subdir,char *buf,unsigned int len); - -#endif - diff --git a/attic/historic/anode/libanode/impl/http_client.c b/attic/historic/anode/libanode/impl/http_client.c deleted file mode 100644 index a398a5857..000000000 --- a/attic/historic/anode/libanode/impl/http_client.c +++ /dev/null @@ -1,558 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include -#include "http_client.h" -#include "misc.h" -#include "types.h" - -/* How much to increment read buffer at each capacity top? */ -#define ANODE_HTTP_CAPACITY_INCREMENT 4096 - -static void AnodeHttpClient_close_and_fail(struct AnodeHttpClient *client) -{ - if (client->impl.tcp_connection) { - client->impl.transport_engine->tcp_close(client->impl.transport_engine,client->impl.tcp_connection); - client->impl.tcp_connection = (AnodeTransportTcpConnection *)0; - } - - client->response.data_length = 0; - client->impl.phase = ANODE_HTTP_REQUEST_PHASE_CLOSED; - - if (client->handler) - client->handler(client); -} - -static void AnodeHttpClient_do_initiate_client(struct AnodeHttpClient *client) -{ - const char *method = ""; - long l,i; - - switch(client->method) { - case ANODE_HTTP_GET: method = "GET"; break; - case ANODE_HTTP_HEAD: method = "HEAD"; break; - case ANODE_HTTP_POST: method = "POST"; break; - } - client->impl.outbuf_len = snprintf((char *)client->impl.outbuf,sizeof(client->impl.outbuf), - "%s %s%s%s HTTP/1.1\r\nHost: %s:%d\r\n%s", - method, - client->uri.path, - ((client->uri.query[0]) ? "?" : ""), - client->uri.query, - client->uri.host, - ((client->uri.port > 0) ? client->uri.port : 80), - ((client->keepalive) ? "" : "Connection: close\r\n") - ); - if (client->impl.outbuf_len >= (sizeof(client->impl.outbuf) - 2)) { - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_HEADERS_TOO_LARGE; - AnodeHttpClient_close_and_fail(client); - return; - } - - if (client->method == ANODE_HTTP_POST) { - if ((client->data)&&(client->data_length)) { - client->impl.outbuf_len += snprintf((char *)client->impl.outbuf + client->impl.outbuf_len,sizeof(client->impl.outbuf) - client->impl.outbuf_len, - "Content-Type: %s\r\n", - (client->data_content_type ? client->data_content_type : "application/x-www-form-urlencoded") - ); - if (client->impl.outbuf_len >= (sizeof(client->impl.outbuf) - 2)) { - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_HEADERS_TOO_LARGE; - AnodeHttpClient_close_and_fail(client); - return; - } - client->impl.outbuf_len += snprintf((char *)client->impl.outbuf + client->impl.outbuf_len,sizeof(client->impl.outbuf) - client->impl.outbuf_len, - "Content-Length: %u\r\n", - client->data_length - ); - if (client->impl.outbuf_len >= (sizeof(client->impl.outbuf) - 2)) { - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_HEADERS_TOO_LARGE; - AnodeHttpClient_close_and_fail(client); - return; - } - } else { - client->impl.outbuf_len += snprintf((char *)client->impl.outbuf + client->impl.outbuf_len,sizeof(client->impl.outbuf) - client->impl.outbuf_len, - "Content-Length: 0\r\n" - ); - if (client->impl.outbuf_len >= (sizeof(client->impl.outbuf) - 2)) { - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_HEADERS_TOO_LARGE; - AnodeHttpClient_close_and_fail(client); - return; - } - } - } - - l = AnodeDictionary_write(&(client->headers),(char *)client->impl.outbuf + client->impl.outbuf_len,(long)(sizeof(client->impl.outbuf) - client->impl.outbuf_len - 2),"\r\n",": "); - if (l < 0) { - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_HEADERS_TOO_LARGE; - AnodeHttpClient_close_and_fail(client); - return; - } - - client->impl.outbuf_len += (unsigned int)l; - if (client->impl.outbuf_len >= (sizeof(client->impl.outbuf) - 2)) { /* sanity check */ - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_HEADERS_TOO_LARGE; - AnodeHttpClient_close_and_fail(client); - return; - } - - client->impl.outbuf[client->impl.outbuf_len++] = '\r'; - client->impl.outbuf[client->impl.outbuf_len++] = '\n'; - - if ((client->method == ANODE_HTTP_POST)&&(client->data)&&(client->data_length)) { - i = sizeof(client->impl.outbuf) - client->impl.outbuf_len; - if (i > client->data_length) - i = client->data_length; - Anode_memcpy((client->impl.outbuf + client->impl.outbuf_len),client->data,i); - client->impl.request_data_ptr += i; - client->impl.outbuf_len += i; - } - - client->impl.phase = ANODE_HTTP_REQUEST_PHASE_SEND; - client->impl.transport_engine->tcp_start_writing(client->impl.transport_engine,client->impl.tcp_connection); -} - -static void AnodeHttpClient_tcp_outgoing_connect_handler( - AnodeTransportEngine *transport, - AnodeTransportTcpConnection *connection, - int error_code) -{ - struct AnodeHttpClient *client; - - if (!(client = (struct AnodeHttpClient *)(connection->ptr))) - return; - - if ((client->impl.phase == ANODE_HTTP_REQUEST_PHASE_CONNECT)&&(!client->impl.freed)) { - if (error_code) { - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_CONNECT_FAILED; - AnodeHttpClient_close_and_fail(client); - } else { - client->impl.tcp_connection = connection; - AnodeHttpClient_do_initiate_client(client); - } - } else transport->tcp_close(transport,connection); -} - -static void AnodeHttpClient_tcp_connection_terminated_handler( - AnodeTransportEngine *transport, - AnodeTransportTcpConnection *connection, - int error_code) -{ - struct AnodeHttpClient *client; - - if (!(client = (struct AnodeHttpClient *)(connection->ptr))) - return; - if (client->impl.freed) - return; - - client->response.data_length = 0; - client->impl.tcp_connection = (AnodeTransportTcpConnection *)0; - if ((client->impl.phase != ANODE_HTTP_REQUEST_PHASE_KEEPALIVE)&&(client->impl.phase != ANODE_HTTP_REQUEST_PHASE_CLOSED)) { - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_SERVER_CLOSED_CONNECTION; - client->impl.phase = ANODE_HTTP_REQUEST_PHASE_CLOSED; - AnodeHttpClient_close_and_fail(client); - } else client->impl.phase = ANODE_HTTP_REQUEST_PHASE_CLOSED; -} - -static void AnodeHttpClient_tcp_receive_handler( - AnodeTransportEngine *transport, - AnodeTransportTcpConnection *connection, - void *data, - unsigned int data_length) -{ - struct AnodeHttpClient *client; - char *p1,*p2; - unsigned int i; - long l; - - if (!(client = (struct AnodeHttpClient *)(connection->ptr))) - return; - if (client->impl.freed) { - transport->tcp_close(transport,connection); - return; - } - - if (!client->response.data) - client->response.data = malloc(client->impl.response_data_capacity = ANODE_HTTP_CAPACITY_INCREMENT); - - i = 0; - while (i < data_length) { - switch(client->impl.read_mode) { - case ANODE_HTTP_READ_MODE_WAITING: - for(;iresponse.data)[client->response.data_length] = (char)0; - client->response.data_length = 0; - - p1 = (char *)Anode_strchr((char *)client->response.data,' '); - if (!p1) - p1 = (char *)Anode_strchr((char *)client->response.data,'\t'); - if (p1) { - while ((*p1 == ' ')||(*p1 == '\t')) ++p1; - if (!*p1) { - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_INVALID_RESPONSE; - AnodeHttpClient_close_and_fail(client); - return; - } - p2 = p1 + 1; - while (*p2) { - if ((*p2 == ' ')||(*p2 == '\t')||(*p2 == '\r')||(*p2 == '\n')) { - *p2 = (char)0; - break; - } else ++p2; - } - client->response.code = (int)strtol(p1,(char **)0,10); - client->impl.read_mode = ANODE_HTTP_READ_MODE_HEADERS; - ++i; break; /* Exit inner for() */ - } - } else { - ((char *)client->response.data)[client->response.data_length++] = ((const char *)data)[i]; - if (client->response.data_length >= client->impl.response_data_capacity) - client->response.data = realloc(client->response.data,client->impl.response_data_capacity += ANODE_HTTP_CAPACITY_INCREMENT); - } - } - break; - case ANODE_HTTP_READ_MODE_HEADERS: - case ANODE_HTTP_READ_MODE_CHUNKED_FOOTER: - for(;iimpl.header_line_buf[client->impl.header_line_buf_ptr] = (char)0; - client->impl.header_line_buf_ptr = 0; - - if ((!client->impl.header_line_buf[0])||((client->impl.header_line_buf[0] == '\r')&&(!client->impl.header_line_buf[1]))) { - /* If the line is empty (or is empty with \r\n as the - * line terminator), we're at the end. */ - if (client->impl.read_mode == ANODE_HTTP_READ_MODE_CHUNKED_FOOTER) { - /* If this is a chunked footer, we finally end the - * chunked response. */ - client->impl.read_mode = ANODE_HTTP_READ_MODE_WAITING; - if (client->keepalive) - client->impl.phase = ANODE_HTTP_REQUEST_PHASE_KEEPALIVE; - else { - client->impl.transport_engine->tcp_close(client->impl.transport_engine,client->impl.tcp_connection); - client->impl.tcp_connection = (AnodeTransportTcpConnection *)0; - client->impl.phase = ANODE_HTTP_REQUEST_PHASE_CLOSED; - } - if (client->handler) - client->handler(client); - if (client->impl.freed) - return; - } else { - /* Otherwise, this is a regular header block */ - if (client->response.code == 100) { - /* Ignore 100 Continue messages */ - client->impl.read_mode = ANODE_HTTP_READ_MODE_WAITING; - ++i; break; /* Exit inner for() */ - } else if ((client->response.code == 200)&&(client->method != ANODE_HTTP_HEAD)) { - /* Other messages get their headers parsed to determine - * how to read them. */ - p1 = (char *)AnodeDictionary_get(&(client->response.headers),"transfer-encoding"); - if ((p1)&&(Anode_strcaseeq(p1,"chunked"))) { - /* Chunked encoding enters chunked mode */ - client->impl.header_line_buf_ptr = 0; - client->impl.read_mode = ANODE_HTTP_READ_MODE_CHUNKED_CHUNK_SIZE; - ++i; break; /* Exit inner for() */ - } else { - /* Else we must have a Content-Length header */ - p1 = (char *)AnodeDictionary_get(&(client->response.headers),"content-length"); - if (!p1) { - /* No chunked or content length is not supported */ - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_INVALID_RESPONSE; - AnodeHttpClient_close_and_fail(client); - return; - } else { - /* Enter block read mode with content length */ - l = strtol(p1,(char **)0,10); - if (l <= 0) { - /* Zero length data is all done... */ - client->impl.expecting_response_length = 0; - client->impl.read_mode = ANODE_HTTP_READ_MODE_WAITING; - if (client->keepalive) - client->impl.phase = ANODE_HTTP_REQUEST_PHASE_KEEPALIVE; - else { - client->impl.transport_engine->tcp_close(client->impl.transport_engine,client->impl.tcp_connection); - client->impl.tcp_connection = (AnodeTransportTcpConnection *)0; - client->impl.phase = ANODE_HTTP_REQUEST_PHASE_CLOSED; - } - - if (client->handler) - client->handler(client); - if (client->impl.freed) - return; - - ++i; break; /* Exit inner for() */ - } else { - /* Else start reading... */ - client->impl.expecting_response_length = (unsigned int)l; - client->impl.read_mode = ANODE_HTTP_READ_MODE_BLOCK; - ++i; break; /* Exit inner for() */ - } - } - } - } else { - /* HEAD clients or non-200 codes get headers only */ - client->impl.expecting_response_length = 0; - client->impl.read_mode = ANODE_HTTP_READ_MODE_WAITING; - if (client->keepalive) - client->impl.phase = ANODE_HTTP_REQUEST_PHASE_KEEPALIVE; - else { - client->impl.transport_engine->tcp_close(client->impl.transport_engine,client->impl.tcp_connection); - client->impl.tcp_connection = (AnodeTransportTcpConnection *)0; - client->impl.phase = ANODE_HTTP_REQUEST_PHASE_CLOSED; - } - - if (client->handler) - client->handler(client); - if (client->impl.freed) - return; - - ++i; break; /* Exit inner for() */ - } - } - } else { - /* Otherwise this is another header, add to dictionary */ - AnodeDictionary_read( - &(client->response.headers), - client->impl.header_line_buf, - "\r\n", - ": \t", - "", - (char)0, - 1, - 1 - ); - } - } else { - client->impl.header_line_buf[client->impl.header_line_buf_ptr++] = ((const char *)data)[i]; - if (client->impl.header_line_buf_ptr >= sizeof(client->impl.header_line_buf)) { - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_INVALID_RESPONSE; - AnodeHttpClient_close_and_fail(client); - return; - } - } - } - break; - case ANODE_HTTP_READ_MODE_BLOCK: - if ((client->response.data_length + client->impl.expecting_response_length) > client->impl.response_data_capacity) - client->response.data = realloc(client->response.data,client->impl.response_data_capacity = (client->response.data_length + client->impl.expecting_response_length)); - - for(;((iimpl.expecting_response_length));++i) { - ((char *)client->response.data)[client->response.data_length++] = ((const char *)data)[i]; - --client->impl.expecting_response_length; - } - - if (!client->impl.expecting_response_length) { - client->impl.read_mode = ANODE_HTTP_READ_MODE_WAITING; - if (client->keepalive) - client->impl.phase = ANODE_HTTP_REQUEST_PHASE_KEEPALIVE; - else { - client->impl.transport_engine->tcp_close(client->impl.transport_engine,client->impl.tcp_connection); - client->impl.tcp_connection = (AnodeTransportTcpConnection *)0; - client->impl.phase = ANODE_HTTP_REQUEST_PHASE_CLOSED; - } - - if (client->handler) - client->handler(client); - if (client->impl.freed) - return; - } - break; - case ANODE_HTTP_READ_MODE_CHUNKED_CHUNK_SIZE: - for(;iimpl.header_line_buf[client->impl.header_line_buf_ptr] = (char)0; - client->impl.header_line_buf_ptr = 0; - - p1 = client->impl.header_line_buf; - while (*p1) { - if ((*p1 == ';')||(*p1 == ' ')||(*p1 == '\r')||(*p1 == '\n')||(*p1 == '\t')) { - *p1 = (char)0; - break; - } else ++p1; - } - - if (client->impl.header_line_buf[0]) { - l = strtol(client->impl.header_line_buf,(char **)0,16); - if (l <= 0) { - /* Zero length ends chunked and enters footer mode */ - client->impl.expecting_response_length = 0; - client->impl.read_mode = ANODE_HTTP_READ_MODE_CHUNKED_FOOTER; - } else { - /* Otherwise the next chunk is to be read */ - client->impl.expecting_response_length = (unsigned int)l; - client->impl.read_mode = ANODE_HTTP_READ_MODE_CHUNKED_DATA; - } - ++i; break; /* Exit inner for() */ - } - } else { - client->impl.header_line_buf[client->impl.header_line_buf_ptr++] = ((const char *)data)[i]; - if (client->impl.header_line_buf_ptr >= sizeof(client->impl.header_line_buf)) { - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_INVALID_RESPONSE; - AnodeHttpClient_close_and_fail(client); - return; - } - } - } - break; - case ANODE_HTTP_READ_MODE_CHUNKED_DATA: - if ((client->response.data_length + client->impl.expecting_response_length) > client->impl.response_data_capacity) - client->response.data = realloc(client->response.data,client->impl.response_data_capacity = (client->response.data_length + client->impl.expecting_response_length)); - - for(;((iimpl.expecting_response_length));++i) { - ((char *)client->response.data)[client->response.data_length++] = ((const char *)data)[i]; - --client->impl.expecting_response_length; - } - - if (!client->impl.expecting_response_length) - client->impl.read_mode = ANODE_HTTP_READ_MODE_CHUNKED_CHUNK_SIZE; - break; - } - } -} - -static void AnodeHttpClient_tcp_available_for_write_handler( - AnodeTransportEngine *transport, - AnodeTransportTcpConnection *connection) -{ - struct AnodeHttpClient *client; - unsigned int i,j; - int n; - - if (!(client = (struct AnodeHttpClient *)(connection->ptr))) - return; - if (client->impl.freed) { - transport->tcp_close(transport,connection); - return; - } - - if (client->impl.phase == ANODE_HTTP_REQUEST_PHASE_SEND) { - n = client->impl.transport_engine->tcp_send(client->impl.transport_engine,client->impl.tcp_connection,(const void *)client->impl.outbuf,(int)client->impl.outbuf_len); - if (n < 0) { - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_SERVER_CLOSED_CONNECTION; - AnodeHttpClient_close_and_fail(client); - } else if (n > 0) { - for(i=0,j=(client->impl.outbuf_len - (unsigned int)n);iimpl.outbuf[i] = client->impl.outbuf[i + (unsigned int)n]; - client->impl.outbuf_len -= (unsigned int)n; - - if ((client->method == ANODE_HTTP_POST)&&(client->data)&&(client->data_length)) { - i = sizeof(client->impl.outbuf) - client->impl.outbuf_len; - j = client->data_length - client->impl.request_data_ptr; - if (i > j) - i = j; - Anode_memcpy((client->impl.outbuf + client->impl.outbuf_len),client->data,i); - client->impl.request_data_ptr += i; - client->impl.outbuf_len += i; - } - - if (!client->impl.outbuf_len) { - client->impl.transport_engine->tcp_stop_writing(client->impl.transport_engine,client->impl.tcp_connection); - client->impl.phase = ANODE_HTTP_REQUEST_PHASE_RECEIVE; - } - } - } else client->impl.transport_engine->tcp_stop_writing(client->impl.transport_engine,client->impl.tcp_connection); -} - -static void AnodeHttpClient_dns_result_handler( - AnodeTransportEngine *transport, - void *ptr, - int error_code, - const char *name, - const AnodeTransportIpAddress *ip_addresses, - unsigned int ip_address_count, - const AnodeAddress *anode_address) -{ - struct AnodeHttpClient *client; - AnodeTransportIpEndpoint to_endpoint; - - if (!(client = (struct AnodeHttpClient *)ptr)) - return; - if (client->impl.freed) - return; - - if ((error_code)||(!ip_address_count)) { - if (client->impl.phase == ANODE_HTTP_REQUEST_PHASE_RESOLVE) { - client->response.code = ANODE_HTTP_SPECIAL_RESPONSE_DNS_RESOLVE_FAILED; - AnodeHttpClient_close_and_fail(client); - } - } else { - client->impl.phase = ANODE_HTTP_REQUEST_PHASE_CONNECT; - Anode_memcpy(&to_endpoint.address,ip_addresses,sizeof(AnodeTransportIpAddress)); - to_endpoint.port = (client->uri.port > 0) ? client->uri.port : 80; - client->impl.transport_engine->tcp_connect( - client->impl.transport_engine, - client, - &AnodeHttpClient_tcp_outgoing_connect_handler, - &AnodeHttpClient_tcp_connection_terminated_handler, - &AnodeHttpClient_tcp_receive_handler, - &AnodeHttpClient_tcp_available_for_write_handler, - &to_endpoint); - } -} - -struct AnodeHttpClient *AnodeHttpClient_new(AnodeTransportEngine *transport_engine) -{ - struct AnodeHttpClient *req = malloc(sizeof(struct AnodeHttpClient)); - Anode_zero(req,sizeof(struct AnodeHttpClient)); - - AnodeDictionary_init(&(req->headers),0); - AnodeDictionary_init(&(req->response.headers),0); - - req->impl.transport_engine = transport_engine; - - return req; -} - -void AnodeHttpClient_send(struct AnodeHttpClient *client) -{ - client->response.code = 0; - client->response.data_length = 0; - AnodeDictionary_clear(&(client->response.headers)); - - client->impl.request_data_ptr = 0; - client->impl.expecting_response_length = 0; - client->impl.read_mode = ANODE_HTTP_READ_MODE_WAITING; - client->impl.outbuf_len = 0; - - if (!client->impl.tcp_connection) { - client->impl.transport_engine->dns_resolve( - client->impl.transport_engine, - &AnodeHttpClient_dns_result_handler, - client, - client->uri.host, - ANODE_TRANSPORT_DNS_QUERY_ALWAYS, - ANODE_TRANSPORT_DNS_QUERY_IF_NO_PREVIOUS, - ANODE_TRANSPORT_DNS_QUERY_NEVER); - } else AnodeHttpClient_do_initiate_client(client); -} - -void AnodeHttpClient_free(struct AnodeHttpClient *client) -{ - AnodeDictionary_destroy(&(client->headers)); - AnodeDictionary_destroy(&(client->response.headers)); - - if (client->impl.tcp_connection) { - client->impl.transport_engine->tcp_close(client->impl.transport_engine,client->impl.tcp_connection); - client->impl.tcp_connection = (AnodeTransportTcpConnection *)0; - } - - if (client->response.data) - free(client->response.data); - - client->impl.freed = 1; - client->impl.transport_engine->run_later(client->impl.transport_engine,client,&free); -} diff --git a/attic/historic/anode/libanode/impl/http_client.h b/attic/historic/anode/libanode/impl/http_client.h deleted file mode 100644 index f16730976..000000000 --- a/attic/historic/anode/libanode/impl/http_client.h +++ /dev/null @@ -1,200 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#ifndef _ANODE_HTTP_CLIENT_H -#define _ANODE_HTTP_CLIENT_H - -#include -#include -#include "dictionary.h" -#include "../anode.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * HTTP request type - */ -enum AnodeHttpClientRequestMethod -{ - ANODE_HTTP_GET = 0, - ANODE_HTTP_HEAD = 1, - ANODE_HTTP_POST = 2 -}; - -/* - * Special response codes to indicate I/O errors - */ -#define ANODE_HTTP_SPECIAL_RESPONSE_DNS_RESOLVE_FAILED -1 -#define ANODE_HTTP_SPECIAL_RESPONSE_CONNECT_FAILED -2 -#define ANODE_HTTP_SPECIAL_RESPONSE_HEADERS_TOO_LARGE -3 -#define ANODE_HTTP_SPECIAL_RESPONSE_SERVER_CLOSED_CONNECTION -4 -#define ANODE_HTTP_SPECIAL_RESPONSE_INVALID_RESPONSE -5 - -/** - * Simple HTTP client - */ -struct AnodeHttpClient -{ - /** - * Request URI - */ - AnodeURI uri; - - /** - * Request method: GET, PUT, HEAD, or POST - */ - enum AnodeHttpClientRequestMethod method; - - /** - * Data for POST requests - * - * It is your responsibility to manage and/or free this pointer. The HTTP - * client only reads from it. - */ - const void *data; - unsigned int data_length; - - /** - * Content type for data, or null for application/x-www-form-urlencoded - */ - const char *data_content_type; - - /** - * Set to non-zero to use HTTP connection keepalive - * - * If keepalive is enabled, this request can be modified and re-used and - * its associated connection will stay open (being reopened if needed) - * until it is freed. - * - * Note that this client is too dumb to pool connections and pick them on - * the basis of host. Keepalive mode should only be set if the next request - * will be from the same host and port, otherwise you will get a '404'. - */ - int keepalive; - - /** - * Function pointer to be called when request is complete (or fails) - */ - void (*handler)(struct AnodeHttpClient *); - - /** - * Two arbitrary pointers that can be stored here for use by the handler. - * These are not accessed or modified by the client. - */ - void *ptr[2]; - - /** - * Request headers - */ - struct AnodeDictionary headers; - - struct { - /** - * Response code, set on completion or failure before handler is called - * - * Also check for the special response codes defined in http_client.h as - * these negative codes indicate network or other errors. - */ - int code; - - /** - * Response data, for GET and POST requests - */ - void *data; - - /** - * Length of response data - */ - unsigned int data_length; - - /** - * Response headers - */ - struct AnodeDictionary headers; - } response; - - /** - * Internal fields used by implementation - */ - struct { - /* Transport engine being used by request */ - AnodeTransportEngine *transport_engine; - - /* Connection to which request has been sent, or null if none */ - struct AnodeHttpConnection *connection; - - /* Buffer for reading chunked mode chunk lines (can't use data buf) */ - char header_line_buf[256]; - unsigned int header_line_buf_ptr; - - /* Where are we in sending request data? */ - unsigned int request_data_ptr; - - /* Capacity of response_data buffer */ - unsigned int response_data_capacity; - - /* How much response data are we currently expecting? */ - /* This is content-length in block mode or chunk length in chunked mode */ - unsigned int expecting_response_length; - - /* Read mode */ - enum { - ANODE_HTTP_READ_MODE_WAITING = 0, - ANODE_HTTP_READ_MODE_HEADERS = 1, - ANODE_HTTP_READ_MODE_BLOCK = 2, - ANODE_HTTP_READ_MODE_CHUNKED_CHUNK_SIZE = 3, - ANODE_HTTP_READ_MODE_CHUNKED_DATA = 4, - ANODE_HTTP_READ_MODE_CHUNKED_FOOTER = 5 - } read_mode; - - /* Connection from transport engine */ - AnodeTransportTcpConnection *tcp_connection; - - /* Write buffer */ - unsigned char outbuf[16384]; - unsigned int outbuf_len; - - /* Phase of request state machine */ - enum { - ANODE_HTTP_REQUEST_PHASE_RESOLVE = 0, - ANODE_HTTP_REQUEST_PHASE_CONNECT = 1, - ANODE_HTTP_REQUEST_PHASE_SEND = 2, - ANODE_HTTP_REQUEST_PHASE_RECEIVE = 3, - ANODE_HTTP_REQUEST_PHASE_KEEPALIVE = 4, - ANODE_HTTP_REQUEST_PHASE_CLOSED = 5 - } phase; - - /* Has request object been freed? */ - int freed; - - /** - * Pointer used internally for putting requests into linked lists - */ - struct AnodeHttpClient *next; - } impl; -}; - -struct AnodeHttpClient *AnodeHttpClient_new(AnodeTransportEngine *transport_engine); -void AnodeHttpClient_send(struct AnodeHttpClient *client); -void AnodeHttpClient_free(struct AnodeHttpClient *client); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/attic/historic/anode/libanode/impl/misc.c b/attic/historic/anode/libanode/impl/misc.c deleted file mode 100644 index edc73978c..000000000 --- a/attic/historic/anode/libanode/impl/misc.c +++ /dev/null @@ -1,190 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include -#include "misc.h" -#include "types.h" - -static const char Anode_hex_chars[16] = { - '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' -}; - -static const char Anode_base32_chars[32] = { - 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q', - 'r','s','t','u','v','w','x','y','z','2','3','4','5','6','7' -}; -static const unsigned char Anode_base32_bits[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,26,27,28,29,30,31,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5, - 6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0,0,1,2, - 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - -/* Table for converting ASCII chars to lower case */ -const unsigned char Anode_ascii_tolower_table[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; - -void Anode_trim(char *s) -{ - char *dest = s; - char *last; - while ((*s)&&((*s == ' ')||(*s == '\t')||(*s == '\r')||(*s == '\n'))) - ++s; - last = s; - while ((*dest = *s)) { - if ((*dest != ' ')&&(*dest != '\t')&&(*dest != '\r')&&(*dest != '\n')) - last = dest; - ++dest; - ++s; - } - if (*last) - *(++last) = (char)0; -} - -unsigned int Anode_rand() -{ - static volatile int need_seed = 1; - - if (need_seed) { - need_seed = 0; - srandom((unsigned long)Anode_time64()); - } - - return (unsigned int)random(); -} - -void Anode_to_hex(const unsigned char *b,unsigned int len,char *h,unsigned int hlen) -{ - unsigned int i; - - if ((len * 2) >= hlen) - len = (hlen - 1) / 2; - - for(i=0;i> 4]; - *(h++) = Anode_hex_chars[b[i] & 0xf]; - } - *h = (char)0; -} - -void Anode_from_hex(const char *h,unsigned char *b,unsigned int blen) -{ - unsigned char *end = b + blen; - unsigned char v = (unsigned char)0; - - while (b != end) { - switch(*(h++)) { - case '0': v = 0x00; break; - case '1': v = 0x10; break; - case '2': v = 0x20; break; - case '3': v = 0x30; break; - case '4': v = 0x40; break; - case '5': v = 0x50; break; - case '6': v = 0x60; break; - case '7': v = 0x70; break; - case '8': v = 0x80; break; - case '9': v = 0x90; break; - case 'a': v = 0xa0; break; - case 'b': v = 0xb0; break; - case 'c': v = 0xc0; break; - case 'd': v = 0xd0; break; - case 'e': v = 0xe0; break; - case 'f': v = 0xf0; break; - default: return; - } - - switch(*(h++)) { - case '0': v |= 0x00; break; - case '1': v |= 0x01; break; - case '2': v |= 0x02; break; - case '3': v |= 0x03; break; - case '4': v |= 0x04; break; - case '5': v |= 0x05; break; - case '6': v |= 0x06; break; - case '7': v |= 0x07; break; - case '8': v |= 0x08; break; - case '9': v |= 0x09; break; - case 'a': v |= 0x0a; break; - case 'b': v |= 0x0b; break; - case 'c': v |= 0x0c; break; - case 'd': v |= 0x0d; break; - case 'e': v |= 0x0e; break; - case 'f': v |= 0x0f; break; - default: return; - } - - *(b++) = v; - } -} - -void Anode_base32_5_to_8(const unsigned char *in,char *out) -{ - out[0] = Anode_base32_chars[(in[0]) >> 3]; - out[1] = Anode_base32_chars[(in[0] & 0x07) << 2 | (in[1] & 0xc0) >> 6]; - out[2] = Anode_base32_chars[(in[1] & 0x3e) >> 1]; - out[3] = Anode_base32_chars[(in[1] & 0x01) << 4 | (in[2] & 0xf0) >> 4]; - out[4] = Anode_base32_chars[(in[2] & 0x0f) << 1 | (in[3] & 0x80) >> 7]; - out[5] = Anode_base32_chars[(in[3] & 0x7c) >> 2]; - out[6] = Anode_base32_chars[(in[3] & 0x03) << 3 | (in[4] & 0xe0) >> 5]; - out[7] = Anode_base32_chars[(in[4] & 0x1f)]; -} - -void Anode_base32_8_to_5(const char *in,unsigned char *out) -{ - out[0] = ((Anode_base32_bits[(unsigned int)in[0]]) << 3) | (Anode_base32_bits[(unsigned int)in[1]] & 0x1C) >> 2; - out[1] = ((Anode_base32_bits[(unsigned int)in[1]] & 0x03) << 6) | (Anode_base32_bits[(unsigned int)in[2]]) << 1 | (Anode_base32_bits[(unsigned int)in[3]] & 0x10) >> 4; - out[2] = ((Anode_base32_bits[(unsigned int)in[3]] & 0x0F) << 4) | (Anode_base32_bits[(unsigned int)in[4]] & 0x1E) >> 1; - out[3] = ((Anode_base32_bits[(unsigned int)in[4]] & 0x01) << 7) | (Anode_base32_bits[(unsigned int)in[5]]) << 2 | (Anode_base32_bits[(unsigned int)in[6]] & 0x18) >> 3; - out[4] = ((Anode_base32_bits[(unsigned int)in[6]] & 0x07) << 5) | (Anode_base32_bits[(unsigned int)in[7]]); -} diff --git a/attic/historic/anode/libanode/impl/misc.h b/attic/historic/anode/libanode/impl/misc.h deleted file mode 100644 index 38ddea7c0..000000000 --- a/attic/historic/anode/libanode/impl/misc.h +++ /dev/null @@ -1,193 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 contains miscellaneous functions, including some re-implementations - * of some functions from string.h. This is to help us port to some platforms - * (cough Windows Mobile cough) that lack a lot of the basic C library. */ - -#ifndef _ANODE_MISC_H -#define _ANODE_MISC_H - -#include -#include -#include "types.h" - -#ifndef ANODE_NO_STRING_H -#include -#include -#endif - -/* Table mapping ASCII characters to themselves or their lower case */ -extern const unsigned char Anode_ascii_tolower_table[256]; - -/* Get the lower case version of an ASCII char */ -#define Anode_tolower(c) ((char)Anode_ascii_tolower_table[((unsigned long)((unsigned char)(c)))]) - -/* Test strings for equality, return nonzero if equal */ -static inline unsigned int Anode_streq(const char *restrict a,const char *restrict b) -{ - if ((!a)||(!b)) - return 0; - while (*a == *(b++)) { - if (!*(a++)) - return 1; - } - return 0; -} - -/* Equality test ignoring (ASCII) case */ -static inline unsigned int Anode_strcaseeq(const char *restrict a,const char *restrict b) -{ - if ((!a)||(!b)) - return 0; - while (Anode_tolower(*a) == Anode_tolower(*(b++))) { - if (!*(a++)) - return 1; - } - return 0; -} - -/* Safe c-string copy, ensuring that dest[] always ends with zero */ -static inline void Anode_str_copy(char *restrict dest,const char *restrict src,unsigned int dest_size) -{ - char *restrict dest_end = dest + (dest_size - 1); - while ((*src)&&(dest != dest_end)) - *(dest++) = *(src++); - *dest = (char)0; -} - -/* Simple memcpy() */ -#ifdef ANODE_NO_STRING_H -static inline void Anode_memcpy(void *restrict dest,const void *restrict src,unsigned int len) -{ - unsigned int i; - for(i=0;i 8 base32 characters and vice versa */ -void Anode_base32_5_to_8(const unsigned char *in,char *out); -void Anode_base32_8_to_5(const char *in,unsigned char *out); - -#endif diff --git a/attic/historic/anode/libanode/impl/mutex.h b/attic/historic/anode/libanode/impl/mutex.h deleted file mode 100644 index b20eb82bd..000000000 --- a/attic/historic/anode/libanode/impl/mutex.h +++ /dev/null @@ -1,34 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#ifndef _ANODE_MUTEX_H -#define _ANODE_MUTEX_H - -#ifdef WINDOWS - -#else /* WINDOWS */ - -#include - -#define AnodeMutex pthread_mutex_t -#define AnodeMutex_init(m) pthread_mutex_init((m),(const pthread_mutexattr_t *)0) -#define AnodeMutex_destroy(m) pthread_mutex_destroy((m)) -#define AnodeMutex_lock(m) pthread_mutex_lock((m)) -#define AnodeMutex_unlock(m) pthread_mutex_unlock((m)) - -#endif /* WINDOWS */ - -#endif diff --git a/attic/historic/anode/libanode/impl/thread.c b/attic/historic/anode/libanode/impl/thread.c deleted file mode 100644 index c20704622..000000000 --- a/attic/historic/anode/libanode/impl/thread.c +++ /dev/null @@ -1,58 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include "thread.h" -#include - -#ifdef WINDOWS - -#else /* not WINDOWS */ - -struct _AnodeThread -{ - void (*func)(void *); - void *arg; - int wait_for_join; - pthread_t thread; -}; - -static void *_AnodeThread_main(void *arg) -{ - ((struct _AnodeThread *)arg)->func(((struct _AnodeThread *)arg)->arg); - if (!((struct _AnodeThread *)arg)->wait_for_join) - free(arg); - return (void *)0; -} - -AnodeThread *AnodeThread_create(void (*func)(void *),void *arg,int wait_for_join) -{ - struct _AnodeThread *t = malloc(sizeof(struct _AnodeThread)); - t->func = func; - t->arg = arg; - t->wait_for_join = wait_for_join; - pthread_create(&t->thread,(const pthread_attr_t *)0,&_AnodeThread_main,(void *)t); - if (!wait_for_join) - pthread_detach(t->thread); - return (AnodeThread *)t; -} - -void AnodeThread_join(AnodeThread *thread) -{ - pthread_join(((struct _AnodeThread *)thread)->thread,(void **)0); - free((void *)thread); -} - -#endif /* WINDOWS / not WINDOWS */ diff --git a/attic/historic/anode/libanode/impl/thread.h b/attic/historic/anode/libanode/impl/thread.h deleted file mode 100644 index accf173ac..000000000 --- a/attic/historic/anode/libanode/impl/thread.h +++ /dev/null @@ -1,65 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#ifndef _ANODE_THREAD_H -#define _ANODE_THREAD_H - -#ifdef WINDOWS - -#include -#include -typedef DWORD AnodeThreadId; - -#else /* not WINDOWS */ - -#include -typedef pthread_t AnodeThreadId; - -#define AnodeThread_self() pthread_self() -#define AnodeThreadId_equal(a,b) pthread_equal((pthread_t)(a),(pthread_t)(b)) - -#endif - -typedef void AnodeThread; - -/** - * Create and launch a new thread - * - * If wait_for_join is true (nonzero), the thread can and must be joined. The - * thread object won't be freed until join is called and returns. If - * wait_for_join is false, the thread object frees itself automatically on - * termination. - * - * If wait_for_join is false (zero), there is really no need to keep track of - * the thread object. - * - * @param func Function to call as thread main - * @param arg Argument to pass to function - * @param wait_for_join If false, thread deletes itself when it terminates - */ -AnodeThread *AnodeThread_create(void (*func)(void *),void *arg,int wait_for_join); - -/** - * Wait for a thread to terminate and delete thread object - * - * This can only be used for threads created with wait_for_join set to true. - * The thread object is no longer valid after this call. - * - * @param thread Thread to wait for termination and delete - */ -void AnodeThread_join(AnodeThread *thread); - -#endif diff --git a/attic/historic/anode/libanode/impl/types.h b/attic/historic/anode/libanode/impl/types.h deleted file mode 100644 index 5f070e5a4..000000000 --- a/attic/historic/anode/libanode/impl/types.h +++ /dev/null @@ -1,25 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#ifndef _ANODE_TYPES_H -#define _ANODE_TYPES_H - -#ifdef WINDOWS -#else -#include -#endif - -#endif diff --git a/attic/historic/anode/libanode/network_address.c b/attic/historic/anode/libanode/network_address.c deleted file mode 100644 index 86ec054f1..000000000 --- a/attic/historic/anode/libanode/network_address.c +++ /dev/null @@ -1,136 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include "impl/misc.h" -#include "impl/types.h" -#include "anode.h" - -const AnodeNetworkAddress AnodeNetworkAddress_ANY4 = { - ANODE_NETWORK_ADDRESS_IPV4, - { 0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } -}; -const AnodeNetworkAddress AnodeNetworkAddress_ANY6 = { - ANODE_NETWORK_ADDRESS_IPV6, - { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } -}; -const AnodeNetworkAddress AnodeNetworkAddress_LOCAL4 = { - ANODE_NETWORK_ADDRESS_IPV4, - { 127,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } -}; -const AnodeNetworkAddress AnodeNetworkAddress_LOCAL6 = { - ANODE_NETWORK_ADDRESS_IPV6, - { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } -}; - -int AnodeNetworkAddress_to_string(const AnodeNetworkAddress *address,char *buf,int len) -{ - const char *s; - - switch(address->type) { - case ANODE_NETWORK_ADDRESS_IPV4: - s = inet_ntop(AF_INET,(const void *)address->bits,buf,len); - if (s) - return Anode_strlen(s); - else return ANODE_ERR_INVALID_ARGUMENT; - break; - case ANODE_NETWORK_ADDRESS_IPV6: - s = inet_ntop(AF_INET6,address->bits,buf,len); - if (s) - return Anode_strlen(s); - else return ANODE_ERR_INVALID_ARGUMENT; - /* - case ANODE_NETWORK_ADDRESS_ETHERNET: - break; - case ANODE_NETWORK_ADDRESS_USB: - break; - case ANODE_NETWORK_ADDRESS_BLUETOOTH: - break; - case ANODE_NETWORK_ADDRESS_IPC: - break; - case ANODE_NETWORK_ADDRESS_80211S: - break; - case ANODE_NETWORK_ADDRESS_SERIAL: - break; - */ - case ANODE_NETWORK_ADDRESS_ANODE_256_40: - return AnodeAddress_to_string((const AnodeAddress *)address->bits,buf,len); - default: - return ANODE_ERR_ADDRESS_TYPE_NOT_SUPPORTED; - } -} - -int AnodeNetworkAddress_from_string(const char *str,AnodeNetworkAddress *address) -{ - unsigned int dots = Anode_count_char(str,'.'); - unsigned int colons = Anode_count_char(str,':'); - - if ((dots == 3)&&(!colons)) { - address->type = ANODE_NETWORK_ADDRESS_IPV4; - if (inet_pton(AF_INET,str,address->bits) > 0) - return 0; - else return ANODE_ERR_INVALID_ARGUMENT; - } else if ((colons)&&(!dots)) { - address->type = ANODE_NETWORK_ADDRESS_IPV6; - if (inet_pton(AF_INET6,str,address->bits) > 0) - return 0; - else return ANODE_ERR_INVALID_ARGUMENT; - } else { - address->type = ANODE_NETWORK_ADDRESS_ANODE_256_40; - return AnodeAddress_from_string(str,(AnodeAddress *)address->bits); - } -} - -int AnodeNetworkEndpoint_from_sockaddr(const void *sockaddr,AnodeNetworkEndpoint *endpoint) -{ - switch(((struct sockaddr_storage *)sockaddr)->ss_family) { - case AF_INET: - *((uint32_t *)endpoint->address.bits) = (uint32_t)(((struct sockaddr_in *)sockaddr)->sin_addr.s_addr); - endpoint->port = (int)ntohs(((struct sockaddr_in *)sockaddr)->sin_port); - return 0; - case AF_INET6: - Anode_memcpy(endpoint->address.bits,((struct sockaddr_in6 *)sockaddr)->sin6_addr.s6_addr,16); - endpoint->port = (int)ntohs(((struct sockaddr_in6 *)sockaddr)->sin6_port); - return 0; - default: - return ANODE_ERR_INVALID_ARGUMENT; - } -} - -int AnodeNetworkEndpoint_to_sockaddr(const AnodeNetworkEndpoint *endpoint,void *sockaddr,int sockaddr_len) -{ - switch(endpoint->address.type) { - case ANODE_NETWORK_ADDRESS_IPV4: - if (sockaddr_len < (int)sizeof(struct sockaddr_in)) - return ANODE_ERR_BUFFER_TOO_SMALL; - Anode_zero(sockaddr,sizeof(struct sockaddr_in)); - ((struct sockaddr_in *)sockaddr)->sin_family = AF_INET; - ((struct sockaddr_in *)sockaddr)->sin_port = htons((uint16_t)endpoint->port); - ((struct sockaddr_in *)sockaddr)->sin_addr.s_addr = *((uint32_t *)endpoint->address.bits); - return 0; - case ANODE_NETWORK_ADDRESS_IPV6: - if (sockaddr_len < (int)sizeof(struct sockaddr_in6)) - return ANODE_ERR_BUFFER_TOO_SMALL; - Anode_zero(sockaddr,sizeof(struct sockaddr_in6)); - ((struct sockaddr_in6 *)sockaddr)->sin6_family = AF_INET6; - ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons((uint16_t)endpoint->port); - Anode_memcpy(((struct sockaddr_in6 *)sockaddr)->sin6_addr.s6_addr,endpoint->address.bits,16); - return 0; - default: - return ANODE_ERR_INVALID_ARGUMENT; - } -} diff --git a/attic/historic/anode/libanode/secure_random.c b/attic/historic/anode/libanode/secure_random.c deleted file mode 100644 index 4322d7de6..000000000 --- a/attic/historic/anode/libanode/secure_random.c +++ /dev/null @@ -1,88 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include "impl/aes.h" -#include "impl/misc.h" -#include "anode.h" - -#ifdef WINDOWS -#include -#include -#endif - -struct AnodeSecureRandomImpl -{ - AnodeAesExpandedKey key; - unsigned char state[ANODE_AES_BLOCK_SIZE]; - unsigned char block[ANODE_AES_BLOCK_SIZE]; - unsigned int ptr; -}; - -AnodeSecureRandom *AnodeSecureRandom_new() -{ - unsigned char keybuf[ANODE_AES_KEY_SIZE + ANODE_AES_BLOCK_SIZE + ANODE_AES_BLOCK_SIZE]; - unsigned int i; - struct AnodeSecureRandomImpl *srng; - -#ifdef WINDOWS - HCRYPTPROV hProv; - if (CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) { - CryptGenRandom(hProv,sizeof(keybuf),keybuf); - CryptReleaseContext(hProv,0); - } -#else - FILE *urandf = fopen("/dev/urandom","rb"); - if (urandf) { - fread((void *)keybuf,sizeof(keybuf),1,urandf); - fclose(urandf); - } -#endif - - for(i=0;i> 5); - - srng = malloc(sizeof(struct AnodeSecureRandomImpl)); - Anode_aes256_expand_key(keybuf,&srng->key); - for(i=0;istate[i] = keybuf[ANODE_AES_KEY_SIZE + i]; - for(i=0;iblock[i] = keybuf[ANODE_AES_KEY_SIZE + ANODE_AES_KEY_SIZE + i]; - srng->ptr = ANODE_AES_BLOCK_SIZE; - - return (AnodeSecureRandom *)srng; -} - -void AnodeSecureRandom_gen_bytes(AnodeSecureRandom *srng,void *buf,long count) -{ - long i,j; - - for(i=0;iptr == ANODE_AES_BLOCK_SIZE) { - Anode_aes256_encrypt(&((struct AnodeSecureRandomImpl *)srng)->key,((struct AnodeSecureRandomImpl *)srng)->state,((struct AnodeSecureRandomImpl *)srng)->state); - for(j=0;jblock[j] ^= ((struct AnodeSecureRandomImpl *)srng)->state[j]; - ((struct AnodeSecureRandomImpl *)srng)->ptr = 0; - } - ((unsigned char *)buf)[i] = ((struct AnodeSecureRandomImpl *)srng)->block[((struct AnodeSecureRandomImpl *)srng)->ptr++]; - } -} - -void AnodeSecureRandom_delete(AnodeSecureRandom *srng) -{ - free(srng); -} diff --git a/attic/historic/anode/libanode/system_transport.c b/attic/historic/anode/libanode/system_transport.c deleted file mode 100644 index 4bfb143ee..000000000 --- a/attic/historic/anode/libanode/system_transport.c +++ /dev/null @@ -1,948 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include -#include -#include -#include -#include -#include "anode.h" -#include "impl/mutex.h" -#include "impl/thread.h" -#include "impl/misc.h" -#include "impl/dns_txt.h" - -#ifdef WINDOWS -#include -#include -#define AnodeSystemTransport__close_socket(s) closesocket((s)) -#define ANODE_USE_SELECT 1 -#else -#include -#include -#define AnodeSystemTransport__close_socket(s) close((s)) -#endif - -static const char *AnodeSystemTransport_CLASS = "SystemTransport"; - -/* ======================================================================== */ - -struct AnodeSystemTransport; - -struct AnodeSystemTransport_AnodeSocket -{ - AnodeSocket base; /* must be first */ - unsigned int entry_idx; -}; - -#define ANODE_SYSTEM_TRANSPORT_DNS_MAX_RESULTS 16 -struct AnodeSystemTransport__dns_request -{ - struct AnodeSystemTransport__dns_request *next; - - AnodeThread *thread; - struct AnodeSystemTransport *owner; - - void (*event_handler)(const AnodeEvent *event); - - char name[256]; - enum AnodeTransportDnsIncludeMode ipv4_include_mode; - enum AnodeTransportDnsIncludeMode ipv6_include_mode; - enum AnodeTransportDnsIncludeMode anode_include_mode; - - AnodeNetworkAddress addresses[ANODE_SYSTEM_TRANSPORT_DNS_MAX_RESULTS]; - unsigned int address_count; - - int error_code; -}; - -#ifdef ANODE_USE_SELECT -typedef int AnodeSystemTransport__poll_fd; /* for select() */ -#else -typedef struct pollfd AnodeSystemTransport__poll_fd; /* for poll() */ -#endif - -struct AnodeSystemTransport -{ - AnodeTransport interface; /* must be first */ - - AnodeTransport *base; - -#ifdef ANODE_USE_SELECT - FD_SET readfds; - FD_SET writefds; -#endif - - void (*default_event_handler)(const AnodeEvent *event); - - AnodeSystemTransport__poll_fd *fds; - struct AnodeSystemTransport_AnodeSocket *sockets; - unsigned int fd_count; - unsigned int fd_capacity; - - struct AnodeSystemTransport__dns_request *pending_dns_requests; - - int invoke_pipe[2]; - AnodeMutex invoke_pipe_m; - void *invoke_pipe_buf[2]; - unsigned int invoke_pipe_buf_ptr; -}; - -/* ======================================================================== */ -/* Internal helper methods */ - -static unsigned int AnodeSystemTransport__add_entry(struct AnodeSystemTransport *transport) -{ - if ((transport->fd_count + 1) > transport->fd_capacity) { - transport->fd_capacity += 8; - transport->fds = realloc(transport->fds,sizeof(AnodeSystemTransport__poll_fd) * transport->fd_capacity); - transport->sockets = realloc(transport->sockets,sizeof(struct AnodeSystemTransport_AnodeSocket) * transport->fd_capacity); - } - return transport->fd_count++; -} - -static void AnodeSystemTransport__remove_entry(struct AnodeSystemTransport *transport,const unsigned int idx) -{ - unsigned int i; - - --transport->fd_count; - for(i=idx;ifd_count;++i) { - Anode_memcpy(&transport->fds[i],&transport->fds[i+1],sizeof(AnodeSystemTransport__poll_fd)); - Anode_memcpy(&transport->sockets[i],&transport->sockets[i+1],sizeof(struct AnodeSystemTransport_AnodeSocket)); - } - - if ((transport->fd_capacity - transport->fd_count) > 16) { - transport->fd_capacity -= 16; - transport->fds = realloc(transport->fds,sizeof(AnodeSystemTransport__poll_fd) * transport->fd_capacity); - transport->sockets = realloc(transport->sockets,sizeof(struct AnodeSystemTransport_AnodeSocket) * transport->fd_capacity); - } -} - -static void AnodeSystemTransport__dns_invoke_on_completion(void *_dreq) -{ - struct AnodeSystemTransport__dns_request *dreq = (struct AnodeSystemTransport__dns_request *)_dreq; - struct AnodeSystemTransport__dns_request *ptr,**lastnext; - - AnodeThread_join(dreq->thread); - - ptr = dreq->owner->pending_dns_requests; - lastnext = &dreq->owner->pending_dns_requests; - while (ptr) { - if (ptr == dreq) { - *lastnext = ptr->next; - break; - } else { - lastnext = &ptr->next; - ptr = ptr->next; - } - } - - free(dreq); -} - -static void AnodeSystemTransport__dns_thread_main(void *_dreq) -{ - struct AnodeSystemTransport__dns_request *dreq = (struct AnodeSystemTransport__dns_request *)_dreq; - - dreq->owner->interface.invoke((AnodeTransport *)dreq->owner,dreq,&AnodeSystemTransport__dns_invoke_on_completion); -} - -static void AnodeSystemTransport__do_close(struct AnodeSystemTransport *transport,struct AnodeSystemTransport_AnodeSocket *sock,const int error_code,const int generate_event) -{ - AnodeEvent evbuf; - int fd; - - if (sock->base.class_name == AnodeSystemTransport_CLASS) { -#ifdef ANODE_USE_SELECT - fd = (int)(transport->fds[((struct AnodeSystemTransport_AnodeSocket *)sock)->entry_idx]); -#else - fd = transport->fds[((struct AnodeSystemTransport_AnodeSocket *)sock)->entry_idx].fd; -#endif - - if ((sock->base.type == ANODE_SOCKET_STREAM_CONNECTION)&&(sock->base.state != ANODE_SOCKET_CLOSED)) { - sock->base.state = ANODE_SOCKET_CLOSED; - - if (generate_event) { - evbuf.type = ANODE_TRANSPORT_EVENT_STREAM_CLOSED; - evbuf.transport = (AnodeTransport *)transport; - evbuf.sock = (AnodeSocket *)sock; - evbuf.datagram_from = NULL; - evbuf.dns_name = NULL; - evbuf.dns_addresses = NULL; - evbuf.dns_address_count = 0; - evbuf.error_code = error_code; - evbuf.data_length = 0; - evbuf.data = NULL; - - if (sock->base.event_handler) - sock->base.event_handler(&evbuf); - else if (transport->default_event_handler) - transport->default_event_handler(&evbuf); - } - } - - AnodeSystemTransport__close_socket(fd); - AnodeSystemTransport__remove_entry(transport,((struct AnodeSystemTransport_AnodeSocket *)sock)->entry_idx); - -#ifdef ANODE_USE_SELECT - FD_CLR(sock,&THIS->readfds); - FD_CLR(sock,&THIS->writefds); -#endif - } else transport->base->close(transport->base,(AnodeSocket *)sock); -} - -static int AnodeSystemTransport__populate_network_endpoint(const struct sockaddr_storage *saddr,AnodeNetworkEndpoint *ep) -{ - switch(saddr->ss_family) { - case AF_INET: - ep->address.type = ANODE_NETWORK_ADDRESS_IPV4; - *((uint32_t *)ep->address.bits) = ((struct sockaddr_in *)saddr)->sin_addr.s_addr; - ep->port = ntohs(((struct sockaddr_in *)saddr)->sin_port); - return 1; - case AF_INET6: - ep->address.type = ANODE_NETWORK_ADDRESS_IPV6; - Anode_memcpy(ep->address.bits,((struct sockaddr_in6 *)saddr)->sin6_addr.s6_addr,16); - ep->port = ntohs(((struct sockaddr_in6 *)saddr)->sin6_port); - return 1; - } - return 0; -} - -/* ======================================================================== */ - -#ifdef THIS -#undef THIS -#endif -#define THIS ((struct AnodeSystemTransport *)transport) - -static void AnodeSystemTransport_invoke(AnodeTransport *transport, - void *ptr, - void (*func)(void *)) -{ - void *invoke_msg[2]; - - invoke_msg[0] = ptr; - invoke_msg[1] = (void *)func; - - AnodeMutex_lock(&THIS->invoke_pipe_m); - write(THIS->invoke_pipe[1],(void *)(&invoke_msg),sizeof(invoke_msg)); - AnodeMutex_unlock(&THIS->invoke_pipe_m); -} - -static void AnodeSystemTransport_dns_resolve(AnodeTransport *transport, - const char *name, - void (*event_handler)(const AnodeEvent *), - enum AnodeTransportDnsIncludeMode ipv4_include_mode, - enum AnodeTransportDnsIncludeMode ipv6_include_mode, - enum AnodeTransportDnsIncludeMode anode_include_mode) -{ - struct AnodeSystemTransport__dns_request *dreq = malloc(sizeof(struct AnodeSystemTransport__dns_request)); - - dreq->owner = THIS; - dreq->event_handler = event_handler; - Anode_str_copy(dreq->name,name,sizeof(dreq->name)); - dreq->ipv4_include_mode = ipv4_include_mode; - dreq->ipv6_include_mode = ipv6_include_mode; - dreq->anode_include_mode = anode_include_mode; - - dreq->address_count = 0; - dreq->error_code = 0; - - dreq->next = THIS->pending_dns_requests; - THIS->pending_dns_requests = dreq; - - dreq->thread = AnodeThread_create(&AnodeSystemTransport__dns_thread_main,dreq,0); -} - -static AnodeSocket *AnodeSystemTransport_datagram_listen(AnodeTransport *transport, - const AnodeNetworkAddress *local_address, - int local_port, - int *error_code) -{ - struct sockaddr_in sin4; - struct sockaddr_in6 sin6; - struct AnodeSystemTransport_AnodeSocket *sock; - unsigned int entry_idx; - int fd; - int tmp; - - switch(local_address->type) { - case ANODE_NETWORK_ADDRESS_IPV4: - fd = socket(AF_INET,SOCK_DGRAM,0); - if (fd <= 0) { - *error_code = ANODE_ERR_UNABLE_TO_BIND; - return (AnodeSocket *)0; - } - tmp = 1; - setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&tmp,sizeof(tmp)); - fcntl(fd,F_SETFL,O_NONBLOCK); - - Anode_zero(&sin4,sizeof(struct sockaddr_in)); - sin4.sin_family = AF_INET; - sin4.sin_port = htons(local_port); - sin4.sin_addr.s_addr = *((uint32_t *)local_address->bits); - - if (bind(fd,(const struct sockaddr *)&sin4,sizeof(sin4))) { - AnodeSystemTransport__close_socket(fd); - *error_code = ANODE_ERR_UNABLE_TO_BIND; - return (AnodeSocket *)0; - } - break; - case ANODE_NETWORK_ADDRESS_IPV6: - fd = socket(AF_INET6,SOCK_DGRAM,0); - if (fd <= 0) { - *error_code = ANODE_ERR_UNABLE_TO_BIND; - return (AnodeSocket *)0; - } - tmp = 1; setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&tmp,sizeof(tmp)); - fcntl(fd,F_SETFL,O_NONBLOCK); -#ifdef IPV6_V6ONLY - tmp = 1; setsockopt(fd,IPPROTO_IPV6,IPV6_V6ONLY,&tmp,sizeof(tmp)); -#endif - - Anode_zero(&sin6,sizeof(struct sockaddr_in6)); - sin6.sin6_family = AF_INET6; - sin6.sin6_port = htons(local_port); - Anode_memcpy(sin6.sin6_addr.s6_addr,local_address->bits,16); - - if (bind(fd,(const struct sockaddr *)&sin6,sizeof(sin6))) { - AnodeSystemTransport__close_socket(fd); - *error_code = ANODE_ERR_UNABLE_TO_BIND; - return (AnodeSocket *)0; - } - break; - default: - if (THIS->base) - return THIS->base->datagram_listen(THIS->base,local_address,local_port,error_code); - else { - *error_code = ANODE_ERR_ADDRESS_TYPE_NOT_SUPPORTED; - return (AnodeSocket *)0; - } - } - - entry_idx = AnodeSystemTransport__add_entry(THIS); - sock = &(THIS->sockets[entry_idx]); - - sock->base.type = ANODE_SOCKET_DATAGRAM; - sock->base.state = ANODE_SOCKET_OPEN; - Anode_memcpy(&sock->base.endpoint.address,local_address,sizeof(AnodeNetworkAddress)); - sock->base.endpoint.port = local_port; - sock->base.class_name = AnodeSystemTransport_CLASS; - sock->base.user_ptr[0] = NULL; - sock->base.user_ptr[1] = NULL; - sock->base.event_handler = NULL; - sock->entry_idx = entry_idx; - - THIS->fds[entry_idx].fd = fd; - THIS->fds[entry_idx].events = POLLIN; - THIS->fds[entry_idx].revents = 0; - - *error_code = 0; - return (AnodeSocket *)sock; -} - -static AnodeSocket *AnodeSystemTransport_stream_listen(AnodeTransport *transport, - const AnodeNetworkAddress *local_address, - int local_port, - int *error_code) -{ - struct sockaddr_in sin4; - struct sockaddr_in6 sin6; - struct AnodeSystemTransport_AnodeSocket *sock; - unsigned int entry_idx; - int fd; - int tmp; - - switch(local_address->type) { - case ANODE_NETWORK_ADDRESS_IPV4: - fd = socket(AF_INET,SOCK_STREAM,0); - if (fd < 0) { - *error_code = ANODE_ERR_UNABLE_TO_BIND; - return (AnodeSocket *)0; - } - fcntl(fd,F_SETFL,O_NONBLOCK); - - Anode_zero(&sin4,sizeof(struct sockaddr_in)); - sin4.sin_family = AF_INET; - sin4.sin_port = htons(local_port); - sin4.sin_addr.s_addr = *((uint32_t *)local_address->bits); - - if (bind(fd,(const struct sockaddr *)&sin4,sizeof(sin4))) { - AnodeSystemTransport__close_socket(fd); - *error_code = ANODE_ERR_UNABLE_TO_BIND; - return (AnodeSocket *)0; - } - if (listen(fd,8)) { - AnodeSystemTransport__close_socket(fd); - *error_code = ANODE_ERR_UNABLE_TO_BIND; - return (AnodeSocket *)0; - } - break; - case ANODE_NETWORK_ADDRESS_IPV6: - fd = socket(AF_INET6,SOCK_STREAM,0); - if (fd < 0) { - *error_code = ANODE_ERR_UNABLE_TO_BIND; - return (AnodeSocket *)0; - } - fcntl(fd,F_SETFL,O_NONBLOCK); -#ifdef IPV6_V6ONLY - tmp = 1; setsockopt(fd,IPPROTO_IPV6,IPV6_V6ONLY,&tmp,sizeof(tmp)); -#endif - - Anode_zero(&sin6,sizeof(struct sockaddr_in6)); - sin6.sin6_family = AF_INET6; - sin6.sin6_port = htons(local_port); - Anode_memcpy(sin6.sin6_addr.s6_addr,local_address->bits,16); - - if (bind(fd,(const struct sockaddr *)&sin6,sizeof(sin6))) { - AnodeSystemTransport__close_socket(fd); - *error_code = ANODE_ERR_UNABLE_TO_BIND; - return (AnodeSocket *)0; - } - if (listen(fd,8)) { - AnodeSystemTransport__close_socket(fd); - *error_code = ANODE_ERR_UNABLE_TO_BIND; - return (AnodeSocket *)0; - } - break; - default: - if (THIS->base) - return THIS->base->stream_listen(THIS->base,local_address,local_port,error_code); - else { - *error_code = ANODE_ERR_ADDRESS_TYPE_NOT_SUPPORTED; - return (AnodeSocket *)0; - } - } - - entry_idx = AnodeSystemTransport__add_entry(THIS); - sock = &(THIS->sockets[entry_idx]); - - sock->base.type = ANODE_SOCKET_STREAM_LISTEN; - sock->base.state = ANODE_SOCKET_OPEN; - Anode_memcpy(&sock->base.endpoint.address,local_address,sizeof(AnodeNetworkAddress)); - sock->base.endpoint.port = local_port; - sock->base.class_name = AnodeSystemTransport_CLASS; - sock->base.user_ptr[0] = NULL; - sock->base.user_ptr[1] = NULL; - sock->base.event_handler = NULL; - sock->entry_idx = entry_idx; - - THIS->fds[entry_idx].fd = fd; - THIS->fds[entry_idx].events = POLLIN; - THIS->fds[entry_idx].revents = 0; - - *error_code = 0; - return (AnodeSocket *)sock; -} - -static int AnodeSystemTransport_datagram_send(AnodeTransport *transport, - AnodeSocket *sock, - const void *data, - int data_len, - const AnodeNetworkEndpoint *to_endpoint) -{ - struct sockaddr_in sin4; - struct sockaddr_in6 sin6; - -#ifdef ANODE_USE_SELECT - const int fd = (int)(THIS->fds[((struct AnodeSystemTransport_AnodeSocket *)sock)->entry_idx]); -#else - const int fd = THIS->fds[((struct AnodeSystemTransport_AnodeSocket *)sock)->entry_idx].fd; -#endif - - switch(to_endpoint->address.type) { - case ANODE_NETWORK_ADDRESS_IPV4: - Anode_zero(&sin4,sizeof(struct sockaddr_in)); - sin4.sin_family = AF_INET; - sin4.sin_port = htons((uint16_t)to_endpoint->port); - sin4.sin_addr.s_addr = *((uint32_t *)to_endpoint->address.bits); - sendto(fd,data,data_len,0,(struct sockaddr *)&sin4,sizeof(sin4)); - return 0; - case ANODE_NETWORK_ADDRESS_IPV6: - Anode_zero(&sin6,sizeof(struct sockaddr_in6)); - sin6.sin6_family = AF_INET6; - sin6.sin6_port = htons((uint16_t)to_endpoint->port); - Anode_memcpy(sin6.sin6_addr.s6_addr,to_endpoint->address.bits,16); - sendto(fd,data,data_len,0,(struct sockaddr *)&sin6,sizeof(sin6)); - return 0; - default: - if (THIS->base) - return THIS->base->datagram_send(THIS->base,sock,data,data_len,to_endpoint); - else return ANODE_ERR_ADDRESS_TYPE_NOT_SUPPORTED; - } -} - -static AnodeSocket *AnodeSystemTransport_stream_connect(AnodeTransport *transport, - const AnodeNetworkEndpoint *to_endpoint, - int *error_code) -{ - struct sockaddr_in sin4; - struct sockaddr_in6 sin6; - struct AnodeSystemTransport_AnodeSocket *sock; - unsigned int entry_idx; - int fd; - - switch(to_endpoint->address.type) { - case ANODE_NETWORK_ADDRESS_IPV4: - Anode_zero(&sin4,sizeof(struct sockaddr_in)); - sin4.sin_family = AF_INET; - sin4.sin_port = htons(to_endpoint->port); - sin4.sin_addr.s_addr = *((uint32_t *)to_endpoint->address.bits); - - fd = socket(AF_INET,SOCK_STREAM,0); - if (fd < 0) { - *error_code = ANODE_ERR_ADDRESS_TYPE_NOT_SUPPORTED; - return (AnodeSocket *)0; - } - fcntl(fd,F_SETFL,O_NONBLOCK); - - if (connect(fd,(struct sockaddr *)&sin4,sizeof(sin4))) { - if (errno != EINPROGRESS) { - *error_code = ANODE_ERR_CONNECT_FAILED; - AnodeSystemTransport__close_socket(fd); - return (AnodeSocket *)0; - } - } - break; - case ANODE_NETWORK_ADDRESS_IPV6: - Anode_zero(&sin6,sizeof(struct sockaddr_in6)); - sin6.sin6_family = AF_INET6; - sin6.sin6_port = htons(to_endpoint->port); - Anode_memcpy(sin6.sin6_addr.s6_addr,to_endpoint->address.bits,16); - - fd = socket(AF_INET6,SOCK_STREAM,0); - if (fd < 0) { - *error_code = ANODE_ERR_ADDRESS_TYPE_NOT_SUPPORTED; - return (AnodeSocket *)0; - } - fcntl(fd,F_SETFL,O_NONBLOCK); - - if (connect(fd,(struct sockaddr *)&sin6,sizeof(sin6))) { - if (errno == EINPROGRESS) { - *error_code = ANODE_ERR_CONNECT_FAILED; - AnodeSystemTransport__close_socket(fd); - return (AnodeSocket *)0; - } - } - break; - default: - if (THIS->base) - return THIS->base->stream_connect(THIS->base,to_endpoint,error_code); - else { - *error_code = ANODE_ERR_ADDRESS_TYPE_NOT_SUPPORTED; - return (AnodeSocket *)0; - } - } - - entry_idx = AnodeSystemTransport__add_entry(THIS); - sock = &(THIS->sockets[entry_idx]); - - sock->base.type = ANODE_SOCKET_STREAM_CONNECTION; - sock->base.state = ANODE_SOCKET_CONNECTING; - Anode_memcpy(&sock->base.endpoint,to_endpoint,sizeof(AnodeNetworkEndpoint)); - sock->base.class_name = AnodeSystemTransport_CLASS; - sock->base.user_ptr[0] = NULL; - sock->base.user_ptr[1] = NULL; - sock->base.event_handler = NULL; - sock->entry_idx = entry_idx; - - THIS->fds[entry_idx].fd = fd; - THIS->fds[entry_idx].events = POLLIN|POLLOUT; - THIS->fds[entry_idx].revents = 0; - - return (AnodeSocket *)sock; -} - -static void AnodeSystemTransport_stream_start_writing(AnodeTransport *transport, - AnodeSocket *sock) -{ - if ((sock->type == ANODE_SOCKET_STREAM_CONNECTION)&&(((struct AnodeSystemTransport_AnodeSocket *)sock)->base.state == ANODE_SOCKET_OPEN)) { - if (sock->class_name == AnodeSystemTransport_CLASS) { -#ifdef ANODE_USE_SELECT - FD_SET((int)(THIS->fds[((struct AnodeSystemTransport_AnodeSocket *)sock)->entry_idx]),&THIS->writefds); -#else - THIS->fds[((struct AnodeSystemTransport_AnodeSocket *)sock)->entry_idx].events = (POLLIN|POLLOUT); -#endif - } else THIS->base->stream_start_writing(THIS->base,sock); - } -} - -static void AnodeSystemTransport_stream_stop_writing(AnodeTransport *transport, - AnodeSocket *sock) -{ - if ((sock->type == ANODE_SOCKET_STREAM_CONNECTION)&&(((struct AnodeSystemTransport_AnodeSocket *)sock)->base.state == ANODE_SOCKET_OPEN)) { - if (sock->class_name == AnodeSystemTransport_CLASS) { -#ifdef ANODE_USE_SELECT - FD_CLR((int)(THIS->fds[((struct AnodeSystemTransport_AnodeSocket *)sock)->entry_idx]),&THIS->writefds); -#else - THIS->fds[((struct AnodeSystemTransport_AnodeSocket *)sock)->entry_idx].events = POLLIN; -#endif - } else THIS->base->stream_stop_writing(THIS->base,sock); - } -} - -static int AnodeSystemTransport_stream_send(AnodeTransport *transport, - AnodeSocket *sock, - const void *data, - int data_len) -{ - int result; - - if (sock->type == ANODE_SOCKET_STREAM_CONNECTION) { - if (sock->class_name == AnodeSystemTransport_CLASS) { - if (((struct AnodeSystemTransport_AnodeSocket *)sock)->base.state != ANODE_SOCKET_OPEN) - return ANODE_ERR_CONNECTION_CLOSED; - -#ifdef ANODE_USE_SELECT - result = send((int)(THIS->fds[((struct AnodeSystemTransport_AnodeSocket *)sock)->entry_idx]),data,data_len,0); -#else - result = send(THIS->fds[((struct AnodeSystemTransport_AnodeSocket *)sock)->entry_idx].fd,data,data_len,0); -#endif - - if (result >= 0) - return result; - else { - AnodeSystemTransport__do_close(THIS,(struct AnodeSystemTransport_AnodeSocket *)sock,ANODE_ERR_CONNECTION_CLOSED_BY_REMOTE,1); - return ANODE_ERR_CONNECTION_CLOSED; - } - } else return THIS->base->stream_send(THIS->base,sock,data,data_len); - } else return ANODE_ERR_INVALID_ARGUMENT; -} - -static void AnodeSystemTransport_close(AnodeTransport *transport, - AnodeSocket *sock) -{ - AnodeSystemTransport__do_close(THIS,(struct AnodeSystemTransport_AnodeSocket *)sock,0,1); -} - -static void AnodeSystemTransport__poll_do_read_datagram(struct AnodeSystemTransport *transport,int fd,struct AnodeSystemTransport_AnodeSocket *sock) -{ - char buf[16384]; - struct sockaddr_storage fromaddr; - AnodeNetworkEndpoint tmp_ep; - AnodeEvent evbuf; - socklen_t addrlen; - int n; - - addrlen = sizeof(struct sockaddr_storage); - n = recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr *)&fromaddr,&addrlen); - if ((n >= 0)&&(AnodeSystemTransport__populate_network_endpoint(&fromaddr,&tmp_ep))) { - evbuf.type = ANODE_TRANSPORT_EVENT_DATAGRAM_RECEIVED; - evbuf.transport = (AnodeTransport *)transport; - evbuf.sock = (AnodeSocket *)sock; - evbuf.datagram_from = &tmp_ep; - evbuf.dns_name = NULL; - evbuf.dns_addresses = NULL; - evbuf.dns_address_count = 0; - evbuf.error_code = 0; - evbuf.data_length = n; - evbuf.data = buf; - - if (sock->base.event_handler) - sock->base.event_handler(&evbuf); - else if (transport->default_event_handler) - transport->default_event_handler(&evbuf); - } -} - -static void AnodeSystemTransport__poll_do_accept_incoming_connection(struct AnodeSystemTransport *transport,int fd,struct AnodeSystemTransport_AnodeSocket *sock) -{ - struct sockaddr_storage fromaddr; - AnodeNetworkEndpoint tmp_ep; - AnodeEvent evbuf; - struct AnodeSystemTransport_AnodeSocket *newsock; - socklen_t addrlen; - int n; - unsigned int entry_idx; - - addrlen = sizeof(struct sockaddr_storage); - n = accept(fd,(struct sockaddr *)&fromaddr,&addrlen); - if ((n >= 0)&&(AnodeSystemTransport__populate_network_endpoint(&fromaddr,&tmp_ep))) { - entry_idx = AnodeSystemTransport__add_entry(transport); - newsock = &(transport->sockets[entry_idx]); - - newsock->base.type = ANODE_SOCKET_STREAM_CONNECTION; - newsock->base.state = ANODE_SOCKET_OPEN; - Anode_memcpy(&newsock->base.endpoint,&tmp_ep,sizeof(AnodeNetworkEndpoint)); - newsock->base.class_name = AnodeSystemTransport_CLASS; - newsock->base.user_ptr[0] = NULL; - newsock->base.user_ptr[1] = NULL; - newsock->base.event_handler = NULL; - newsock->entry_idx = entry_idx; - - THIS->fds[entry_idx].fd = n; - THIS->fds[entry_idx].events = POLLIN; - THIS->fds[entry_idx].revents = 0; - - evbuf.type = ANODE_TRANSPORT_EVENT_STREAM_INCOMING_CONNECT; - evbuf.transport = (AnodeTransport *)transport; - evbuf.sock = (AnodeSocket *)newsock; - evbuf.datagram_from = NULL; - evbuf.dns_name = NULL; - evbuf.dns_addresses = NULL; - evbuf.dns_address_count = 0; - evbuf.error_code = 0; - evbuf.data_length = 0; - evbuf.data = NULL; - - if (sock->base.event_handler) - sock->base.event_handler(&evbuf); - else if (transport->default_event_handler) - transport->default_event_handler(&evbuf); - } -} - -static void AnodeSystemTransport__poll_do_read_stream(struct AnodeSystemTransport *transport,int fd,struct AnodeSystemTransport_AnodeSocket *sock) -{ - char buf[65536]; - AnodeEvent evbuf; - int n; - - n = recv(fd,buf,sizeof(buf),0); - if (n > 0) { - evbuf.type = ANODE_TRANSPORT_EVENT_STREAM_DATA_RECEIVED; - evbuf.transport = (AnodeTransport *)transport; - evbuf.sock = (AnodeSocket *)sock; - evbuf.datagram_from = NULL; - evbuf.dns_name = NULL; - evbuf.dns_addresses = NULL; - evbuf.dns_address_count = 0; - evbuf.error_code = 0; - evbuf.data_length = n; - evbuf.data = buf; - - if (sock->base.event_handler) - sock->base.event_handler(&evbuf); - else if (transport->default_event_handler) - transport->default_event_handler(&evbuf); - } else AnodeSystemTransport__do_close(transport,sock,ANODE_ERR_CONNECTION_CLOSED_BY_REMOTE,1); -} - -static void AnodeSystemTransport__poll_do_stream_available_for_write(struct AnodeSystemTransport *transport,int fd,struct AnodeSystemTransport_AnodeSocket *sock) -{ - AnodeEvent evbuf; - - evbuf.type = ANODE_TRANSPORT_EVENT_STREAM_DATA_RECEIVED; - evbuf.transport = (AnodeTransport *)transport; - evbuf.sock = (AnodeSocket *)sock; - evbuf.datagram_from = NULL; - evbuf.dns_name = NULL; - evbuf.dns_addresses = NULL; - evbuf.dns_address_count = 0; - evbuf.error_code = 0; - evbuf.data_length = 0; - evbuf.data = NULL; - - if (sock->base.event_handler) - sock->base.event_handler(&evbuf); - else if (transport->default_event_handler) - transport->default_event_handler(&evbuf); -} - -static void AnodeSystemTransport__poll_do_outgoing_connect(struct AnodeSystemTransport *transport,int fd,struct AnodeSystemTransport_AnodeSocket *sock) -{ - AnodeEvent evbuf; - int err_code; - socklen_t optlen; - - optlen = sizeof(err_code); - if (getsockopt(fd,SOL_SOCKET,SO_ERROR,(void *)&err_code,&optlen)) { - /* Error getting result, so we assume a failure */ - evbuf.type = ANODE_TRANSPORT_EVENT_STREAM_OUTGOING_CONNECT_FAILED; - evbuf.transport = (AnodeTransport *)transport; - evbuf.sock = (AnodeSocket *)sock; - evbuf.datagram_from = NULL; - evbuf.dns_name = NULL; - evbuf.dns_addresses = NULL; - evbuf.dns_address_count = 0; - evbuf.error_code = ANODE_ERR_CONNECT_FAILED; - evbuf.data_length = 0; - evbuf.data = NULL; - - AnodeSystemTransport__do_close(transport,sock,0,0); - } else if (err_code) { - /* Error code is nonzero, so connect failed */ - evbuf.type = ANODE_TRANSPORT_EVENT_STREAM_OUTGOING_CONNECT_FAILED; - evbuf.transport = (AnodeTransport *)transport; - evbuf.sock = (AnodeSocket *)sock; - evbuf.datagram_from = NULL; - evbuf.dns_name = NULL; - evbuf.dns_addresses = NULL; - evbuf.dns_address_count = 0; - evbuf.error_code = ANODE_ERR_CONNECT_FAILED; - evbuf.data_length = 0; - evbuf.data = NULL; - - AnodeSystemTransport__do_close(transport,sock,0,0); - } else { - /* Connect succeeded */ - evbuf.type = ANODE_TRANSPORT_EVENT_STREAM_OUTGOING_CONNECT_ESTABLISHED; - evbuf.transport = (AnodeTransport *)transport; - evbuf.sock = (AnodeSocket *)sock; - evbuf.datagram_from = NULL; - evbuf.dns_name = NULL; - evbuf.dns_addresses = NULL; - evbuf.dns_address_count = 0; - evbuf.error_code = 0; - evbuf.data_length = 0; - evbuf.data = NULL; - } - - if (sock->base.event_handler) - sock->base.event_handler(&evbuf); - else if (transport->default_event_handler) - transport->default_event_handler(&evbuf); -} - -static int AnodeSystemTransport_poll(AnodeTransport *transport) -{ - int timeout = -1; - unsigned int fd_idx; - int event_count = 0; - int n; - - if (poll((struct pollfd *)THIS->fds,THIS->fd_count,timeout) > 0) { - for(fd_idx=0;fd_idxfd_count;++fd_idx) { - if ((THIS->fds[fd_idx].revents & (POLLERR|POLLHUP|POLLNVAL))) { - if (THIS->sockets[fd_idx].base.type == ANODE_SOCKET_STREAM_CONNECTION) { - if (THIS->sockets[fd_idx].base.state == ANODE_SOCKET_CONNECTING) - AnodeSystemTransport__poll_do_outgoing_connect(THIS,THIS->fds[fd_idx].fd,&THIS->sockets[fd_idx]); - else AnodeSystemTransport__do_close(THIS,&THIS->sockets[fd_idx],ANODE_ERR_CONNECTION_CLOSED_BY_REMOTE,1); - ++event_count; - } - } else { - if ((THIS->fds[fd_idx].revents & POLLIN)) { - if (THIS->fds[fd_idx].fd == THIS->invoke_pipe[0]) { - n = read(THIS->invoke_pipe[0],&(((unsigned char *)(&(THIS->invoke_pipe_buf)))[THIS->invoke_pipe_buf_ptr]),sizeof(THIS->invoke_pipe_buf) - THIS->invoke_pipe_buf_ptr); - if (n > 0) { - THIS->invoke_pipe_buf_ptr += (unsigned int)n; - if (THIS->invoke_pipe_buf_ptr >= sizeof(THIS->invoke_pipe_buf)) { - THIS->invoke_pipe_buf_ptr -= sizeof(THIS->invoke_pipe_buf); - ((void (*)(void *))(THIS->invoke_pipe_buf[1]))(THIS->invoke_pipe_buf[0]); - } - } - } else { - switch(THIS->sockets[fd_idx].base.type) { - case ANODE_SOCKET_DATAGRAM: - AnodeSystemTransport__poll_do_read_datagram(THIS,THIS->fds[fd_idx].fd,&THIS->sockets[fd_idx]); - break; - case ANODE_SOCKET_STREAM_LISTEN: - AnodeSystemTransport__poll_do_accept_incoming_connection(THIS,THIS->fds[fd_idx].fd,&THIS->sockets[fd_idx]); - break; - case ANODE_SOCKET_STREAM_CONNECTION: - if (THIS->sockets[fd_idx].base.state == ANODE_SOCKET_CONNECTING) - AnodeSystemTransport__poll_do_outgoing_connect(THIS,THIS->fds[fd_idx].fd,&THIS->sockets[fd_idx]); - else AnodeSystemTransport__poll_do_read_stream(THIS,THIS->fds[fd_idx].fd,&THIS->sockets[fd_idx]); - break; - } - ++event_count; - } - } - - if ((THIS->fds[fd_idx].revents & POLLOUT)) { - if (THIS->sockets[fd_idx].base.state == ANODE_SOCKET_CONNECTING) - AnodeSystemTransport__poll_do_outgoing_connect(THIS,THIS->fds[fd_idx].fd,&THIS->sockets[fd_idx]); - else AnodeSystemTransport__poll_do_stream_available_for_write(THIS,THIS->fds[fd_idx].fd,&THIS->sockets[fd_idx]); - ++event_count; - } - } - } - } - - return event_count; -} - -static int AnodeSystemTransport_supports_address_type(const AnodeTransport *transport, - enum AnodeNetworkAddressType at) -{ - switch(at) { - case ANODE_NETWORK_ADDRESS_IPV4: - return 1; - case ANODE_NETWORK_ADDRESS_IPV6: - return 1; - default: - if (THIS->base) - return THIS->base->supports_address_type(THIS->base,at); - return 0; - } -} - -static AnodeTransport *AnodeSystemTransport_base_instance(const AnodeTransport *transport) -{ - return THIS->base; -} - -static const char *AnodeSystemTransport_class_name(AnodeTransport *transport) -{ - return AnodeSystemTransport_CLASS; -} - -static void AnodeSystemTransport_delete(AnodeTransport *transport) -{ - close(THIS->invoke_pipe[0]); - close(THIS->invoke_pipe[1]); - - AnodeMutex_destroy(&THIS->invoke_pipe_m); - - if (THIS->fds) free(THIS->fds); - if (THIS->sockets) free(THIS->sockets); - - if (THIS->base) THIS->base->delete(THIS->base); - - free(transport); -} - -/* ======================================================================== */ - -AnodeTransport *AnodeSystemTransport_new(AnodeTransport *base) -{ - struct AnodeSystemTransport *t; - unsigned int entry_idx; - - t = malloc(sizeof(struct AnodeSystemTransport)); - if (!t) return (AnodeTransport *)0; - Anode_zero(t,sizeof(struct AnodeSystemTransport)); - - t->interface.invoke = &AnodeSystemTransport_invoke; - t->interface.dns_resolve = &AnodeSystemTransport_dns_resolve; - t->interface.datagram_listen = &AnodeSystemTransport_datagram_listen; - t->interface.stream_listen = &AnodeSystemTransport_stream_listen; - t->interface.datagram_send = &AnodeSystemTransport_datagram_send; - t->interface.stream_connect = &AnodeSystemTransport_stream_connect; - t->interface.stream_start_writing = &AnodeSystemTransport_stream_start_writing; - t->interface.stream_stop_writing = &AnodeSystemTransport_stream_stop_writing; - t->interface.stream_send = &AnodeSystemTransport_stream_send; - t->interface.close = &AnodeSystemTransport_close; - t->interface.poll = &AnodeSystemTransport_poll; - t->interface.supports_address_type = &AnodeSystemTransport_supports_address_type; - t->interface.base_instance = &AnodeSystemTransport_base_instance; - t->interface.class_name = &AnodeSystemTransport_class_name; - t->interface.delete = &AnodeSystemTransport_delete; - - t->base = base; - - pipe(t->invoke_pipe); - fcntl(t->invoke_pipe[0],F_SETFL,O_NONBLOCK); - entry_idx = AnodeSystemTransport__add_entry(t); - t->fds[entry_idx].fd = t->invoke_pipe[0]; - t->fds[entry_idx].events = POLLIN; - t->fds[entry_idx].revents = 0; - AnodeMutex_init(&t->invoke_pipe_m); - - return (AnodeTransport *)t; -} diff --git a/attic/historic/anode/libanode/tests/Makefile b/attic/historic/anode/libanode/tests/Makefile deleted file mode 100644 index a479092c2..000000000 --- a/attic/historic/anode/libanode/tests/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -all: force clean anode-utils-test anode-zone-test aes-test ec-test - -aes-test: - gcc -Wall -O6 -ftree-vectorize -std=c99 -o aes-test aes-test.c ../aes_digest.c -lcrypto - -http_client-test: - gcc -O0 -g -std=c99 -o http_client-test http_client-test.c ../anode-utils.c ../misc.c ../http_client.c ../dictionary.c ../iptransport.c ../anode-transport.c -lcrypto - -anode-utils-test: - gcc -O0 -g -std=c99 -o anode-utils-test anode-utils-test.c ../anode-utils.c ../misc.c - -ec-test: - gcc -O0 -g -std=c99 -o ec-test ec-test.c ../impl/ec.c ../impl/misc.c -lcrypto - -anode-zone-test: - gcc -O0 -g -std=c99 -o anode-zone-test anode-zone-test.c ../anode-zone.c ../http_client.c ../dictionary.c ../misc.c ../anode-transport.c ../iptransport.c ../environment.c - -system_transport-test: - gcc -O0 -g -std=c99 -o system_transport-test system_transport-test.c ../system_transport.c ../network_address.c ../address.c ../aes_digest.c ../impl/misc.c ../impl/thread.c ../impl/dns_txt.c ../impl/aes.c -lresolv -lcrypto - -clean: force - rm -rf *.dSYM - rm -f http_client-test anode-utils-test anode-zone-test ec-test aes-test system_transport-test - -force: ; diff --git a/attic/historic/anode/libanode/tests/aes-test.c b/attic/historic/anode/libanode/tests/aes-test.c deleted file mode 100644 index bca63b892..000000000 --- a/attic/historic/anode/libanode/tests/aes-test.c +++ /dev/null @@ -1,191 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include -#include -#include -#include "../impl/aes.h" -#include "../anode.h" - -static const unsigned char AES_TEST_KEY[32] = { - 0x08,0x09,0x0A,0x0B,0x0D,0x0E,0x0F,0x10,0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1A, - 0x1C,0x1D,0x1E,0x1F,0x21,0x22,0x23,0x24,0x26,0x27,0x28,0x29,0x2B,0x2C,0x2D,0x2E -}; -static const unsigned char AES_TEST_IN[16] = { - 0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21 -}; -static const unsigned char AES_TEST_OUT[16] = { - 0x08,0x0e,0x95,0x17,0xeb,0x16,0x77,0x71,0x9a,0xcf,0x72,0x80,0x86,0x04,0x0a,0xe3 -}; - -static const unsigned char CMAC_TEST_KEY[32] = { - 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, - 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 -}; - -static const unsigned char CMAC_TEST1_OUT[16] = { - 0x02,0x89,0x62,0xf6,0x1b,0x7b,0xf8,0x9e,0xfc,0x6b,0x55,0x1f,0x46,0x67,0xd9,0x83 -}; - -static const unsigned char CMAC_TEST2_IN[16] = { - 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a -}; -static const unsigned char CMAC_TEST2_OUT[16] = { - 0x28,0xa7,0x02,0x3f,0x45,0x2e,0x8f,0x82,0xbd,0x4b,0xf2,0x8d,0x8c,0x37,0xc3,0x5c -}; - -static const unsigned char CMAC_TEST3_IN[40] = { - 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, - 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, - 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11 -}; -static const unsigned char CMAC_TEST3_OUT[16] = { - 0xaa,0xf3,0xd8,0xf1,0xde,0x56,0x40,0xc2,0x32,0xf5,0xb1,0x69,0xb9,0xc9,0x11,0xe6 -}; - -static const unsigned char CMAC_TEST4_IN[64] = { - 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, - 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, - 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11,0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef, - 0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17,0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10 -}; -static const unsigned char CMAC_TEST4_OUT[16] = { - 0xe1,0x99,0x21,0x90,0x54,0x9f,0x6e,0xd5,0x69,0x6a,0x2c,0x05,0x6c,0x31,0x54,0x10 -}; - -static void test_cmac(const AnodeAesExpandedKey *expkey,const unsigned char *in,unsigned int inlen,const unsigned char *expected) -{ - unsigned int i; - unsigned char out[16]; - - printf("Testing CMAC with %u byte input:\n",inlen); - printf(" IN: "); - for(i=0;i - * - * 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 . */ - -#include -#include -#include "../anode.h" -#include "../misc.h" - -int main(int argc,char **argv) -{ - unsigned char test[10005]; - unsigned int i; - AnodeSecureRandom srng; - - AnodeSecureRandom_init(&srng); - - AnodeSecureRandom_gen_bytes(&srng,test,sizeof(test)); - - for(i=0;i - * - * 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 . */ - -#include -#include -#include "../anode.h" -#include "../misc.h" - -static const char *testuris[22] = { - "http://www.test.com", - "http://www.test.com/", - "http://www.test.com/path/to/something", - "http://user@www.test.com", - "http://user@www.test.com/path/to/something", - "http://user:password@www.test.com/path/to/something", - "http://www.test.com/path/to/something?query=foo&bar=baz", - "http://www.test.com/path/to/something#fragment", - "http://www.test.com/path/to/something?query=foo&bar=baz#fragment", - "http://user:password@www.test.com/path/to/something#fragment", - "http://user:password@www.test.com/path/to/something?query=foo&bar=baz#fragment", - "http://@www.test.com/", - "http://:@www.test.com/", - "http://www.test.com:8080/path/to/something", - "http://user:password@www.test.com:8080/path/to/something?query=foo#fragment", - "http://", - "http://www.test.com/path/to/something?#", - "http://www.test.com/path/to/something?#fragment", - "http:", - "http", - "mailto:this_is_a_urn@somedomain.com", - "" -}; - -int main(int argc,char **argv) -{ - int i,r; - char reconstbuf[2048]; - char *reconst; - AnodeURI uri; - - for(i=0;i<22;++i) { - printf("\"%s\":\n",testuris[i]); - r = AnodeURI_parse(&uri,testuris[i]); - if (r) { - printf(" error: %d\n",r); - } else { - printf(" scheme: %s\n",uri.scheme); - printf(" username: %s\n",uri.username); - printf(" password: %s\n",uri.password); - printf(" host: %s\n",uri.host); - printf(" port: %d\n",uri.port); - printf(" path: %s\n",uri.path); - printf(" query: %s\n",uri.query); - printf(" fragment: %s\n",uri.fragment); - } - reconst = AnodeURI_to_string(&uri,reconstbuf,sizeof(reconstbuf)); - printf("Reconstituted URI: %s\n",reconst ? reconst : "(null)"); - printf("\n"); - } - - return 0; -} diff --git a/attic/historic/anode/libanode/tests/anode-zone-test.c b/attic/historic/anode/libanode/tests/anode-zone-test.c deleted file mode 100644 index 08396716c..000000000 --- a/attic/historic/anode/libanode/tests/anode-zone-test.c +++ /dev/null @@ -1,47 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include -#include "../anode.h" -#include "../dictionary.h" - -static int got_it = 0; - -static void zone_lookup_handler(void *ptr,long zone_id,AnodeZone *zone) -{ - if (zone) - printf("got %.8lx: %d entries\n",(unsigned long)zone_id & 0xffffffff,((struct AnodeDictionary *)zone)->size); - else printf("failed.\n"); - got_it = 1; -} - -int main(int argc,char **argv) -{ - AnodeTransportEngine transport; - - Anode_init_ip_transport_engine(&transport); - - AnodeZone_lookup(&transport,0,0,&zone_lookup_handler); - - while (!got_it) - transport.poll(&transport); - - transport.destroy(&transport); - - return 0; -} diff --git a/attic/historic/anode/libanode/tests/dictionary-test.c b/attic/historic/anode/libanode/tests/dictionary-test.c deleted file mode 100644 index 12a5fb2fd..000000000 --- a/attic/historic/anode/libanode/tests/dictionary-test.c +++ /dev/null @@ -1,149 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include -#include -#include -#include "../dictionary.h" - -static const char *HASH_TESTS[16] = { - "test", - "testt", - "", - "foo", - "fooo", - "1", - "2", - "3", - "4", - "11", - "22", - "33", - "44", - "adklfjklejrer", - "erngnetbekjrq", - "erklerqqqqre" -}; - -int diterate(void *arg,const char *key,const char *value) -{ - printf(" %s: %s\n",key ? key : "(null)",value ? value : "(null)"); - return 1; -} - -int main(int argc,char **argv) -{ - char tmp[1024]; - char fuzzparam1[16],fuzzparam2[16],fuzzparam3[16]; - struct AnodeDictionary d; - unsigned int i,j,k,cs; - - srandom(time(0)); - - printf("Trying out hash function a little...\n"); - for(i=0;i<16;++i) - printf(" %s: %u\n",HASH_TESTS[i],(unsigned int)AnodeDictionary__get_bucket(HASH_TESTS[i])); - - for(cs=0;cs<2;++cs) { - printf("\nTesting with case sensitivity = %d\n",cs); - AnodeDictionary_init(&d,cs); - - printf("\nTesting dictionary by adding and retrieving some keys...\n"); - AnodeDictionary_put(&d,"test1","This is the first test"); - AnodeDictionary_put(&d,"test2","This is the second test"); - AnodeDictionary_put(&d,"test3","This is the third test (lower case)"); - AnodeDictionary_put(&d,"TEST3","This is the third test (UPPER CASE)"); - AnodeDictionary_iterate(&d,(void *)0,&diterate); - if (d.size != (cs ? 4 : 3)) { - printf("Failed (size).\n"); - return 1; - } - - AnodeDictionary_clear(&d); - if (d.size||(AnodeDictionary_get(&d,"test1"))) { - printf("Failed (clear).\n"); - return 1; - } - - printf("\nTesting read, trial 1: simple key=value with unterminated line\n"); - strcpy(tmp,"foo=bar\nbar=baz\ntest1=Happy happy joyjoy!\ntest2=foobarbaz\nlinewithnocr=thisworked"); - AnodeDictionary_read(&d,tmp,"\r\n","=","",'\\',0,0); - printf("Results:\n"); - AnodeDictionary_iterate(&d,(void *)0,&diterate); - AnodeDictionary_clear(&d); - - printf("\nTesting read, trial 2: key=value with escape chars, escaped CRs\n"); - strcpy(tmp,"foo=bar\r\nbar==baz\nte\\=st1=\\=Happy happy joyjoy!\ntest2=foobarbaz\\\nfoobarbaz on next line\r\n"); - AnodeDictionary_read(&d,tmp,"\r\n","=","",'\\',0,0); - printf("Results:\n"); - AnodeDictionary_iterate(&d,(void *)0,&diterate); - AnodeDictionary_clear(&d); - - printf("\nTesting read, trial 3: HTTP header-like dictionary\n"); - strcpy(tmp,"Host: some.host.net\r\nX-Some-Header: foo bar\r\nX-Some-Other-Header: y0y0y0y0y0\r\n"); - AnodeDictionary_read(&d,tmp,"\r\n",": ","",0,0,0); - printf("Results:\n"); - AnodeDictionary_iterate(&d,(void *)0,&diterate); - AnodeDictionary_clear(&d); - - printf("\nTesting read, trial 4: single line key/value\n"); - strcpy(tmp,"Header: one line only"); - AnodeDictionary_read(&d,tmp,"\r\n",": ","",0,0,0); - printf("Results:\n"); - AnodeDictionary_iterate(&d,(void *)0,&diterate); - AnodeDictionary_clear(&d); - - printf("\nFuzzing dictionary reader...\n"); fflush(stdout); - for(i=0;i<200000;++i) { - j = random() % (sizeof(tmp) - 1); - for(k=0;k> 3); - if (!tmp[k]) tmp[k] = 1; - } - tmp[j] = (char)0; - - j = random() % (sizeof(fuzzparam1) - 1); - for(k=0;k> 3); - if (!fuzzparam1[k]) fuzzparam1[k] = 1; - } - fuzzparam1[j] = (char)0; - - j = random() % (sizeof(fuzzparam2) - 1); - for(k=0;k> 3); - if (!fuzzparam2[k]) fuzzparam2[k] = 1; - } - fuzzparam2[j] = (char)0; - - j = random() % (sizeof(fuzzparam3) - 1); - for(k=0;k> 3); - if (!fuzzparam3[k]) fuzzparam3[k] = 1; - } - fuzzparam3[j] = (char)0; - - AnodeDictionary_read(&d,tmp,fuzzparam1,fuzzparam2,fuzzparam3,random() & 3,random() & 1,random() & 1); - AnodeDictionary_clear(&d); - } - - AnodeDictionary_destroy(&d); - } - - return 0; -} diff --git a/attic/historic/anode/libanode/tests/ec-test.c b/attic/historic/anode/libanode/tests/ec-test.c deleted file mode 100644 index 49f04265b..000000000 --- a/attic/historic/anode/libanode/tests/ec-test.c +++ /dev/null @@ -1,97 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include -#include "../impl/ec.h" -#include "../impl/misc.h" - -#define TEST_KEY_LEN 128 -#define AnodeEC_key_to_hex(k,b,l) Anode_to_hex((k)->key,(k)->bytes,(b),l) - -int main(int argc,char **argv) -{ - struct AnodeECKeyPair pair1; - struct AnodeECKeyPair pair2; - struct AnodeECKeyPair pair3; - unsigned char key[TEST_KEY_LEN]; - char str[16384]; - - printf("Creating key pair #1...\n"); - if (!AnodeECKeyPair_generate(&pair1)) { - printf("Could not create key pair.\n"); - return 1; - } - AnodeEC_key_to_hex(&pair1.pub,str,sizeof(str)); - printf("Public: %s\n",str); - AnodeEC_key_to_hex(&pair1.priv,str,sizeof(str)); - printf("Private: %s\n\n",str); - - printf("Creating key pair #2...\n"); - if (!AnodeECKeyPair_generate(&pair2)) { - printf("Could not create key pair.\n"); - return 1; - } - AnodeEC_key_to_hex(&pair2.pub,str,sizeof(str)); - printf("Public: %s\n",str); - AnodeEC_key_to_hex(&pair2.priv,str,sizeof(str)); - printf("Private: %s\n\n",str); - - printf("Key agreement between public #2 and private #1...\n"); - if (!AnodeECKeyPair_agree(&pair1,&pair2.pub,key,TEST_KEY_LEN)) { - printf("Agreement failed.\n"); - return 1; - } - Anode_to_hex(key,TEST_KEY_LEN,str,sizeof(str)); - printf("Agreed secret: %s\n\n",str); - - printf("Key agreement between public #1 and private #2...\n"); - if (!AnodeECKeyPair_agree(&pair2,&pair1.pub,key,TEST_KEY_LEN)) { - printf("Agreement failed.\n"); - return 1; - } - Anode_to_hex(key,TEST_KEY_LEN,str,sizeof(str)); - printf("Agreed secret: %s\n\n",str); - - printf("Testing key pair init function (init #3 from #2's parts)...\n"); - if (!AnodeECKeyPair_init(&pair3,&(pair2.pub),&(pair2.priv))) { - printf("Init failed.\n"); - return 1; - } - - printf("Key agreement between public #1 and private #3...\n"); - if (!AnodeECKeyPair_agree(&pair3,&pair1.pub,key,TEST_KEY_LEN)) { - printf("Agreement failed.\n"); - return 1; - } - Anode_to_hex(key,TEST_KEY_LEN,str,sizeof(str)); - printf("Agreed secret: %s\n\n",str); - - printf("Key agreement between public #1 and private #1...\n"); - if (!AnodeECKeyPair_agree(&pair1,&pair1.pub,key,TEST_KEY_LEN)) { - printf("Agreement failed.\n"); - return 1; - } - Anode_to_hex(key,TEST_KEY_LEN,str,sizeof(str)); - printf("Agreed secret (should not match): %s\n\n",str); - - AnodeECKeyPair_destroy(&pair1); - AnodeECKeyPair_destroy(&pair2); - AnodeECKeyPair_destroy(&pair3); - - return 0; -} diff --git a/attic/historic/anode/libanode/tests/environment-test.c b/attic/historic/anode/libanode/tests/environment-test.c deleted file mode 100644 index c481a1296..000000000 --- a/attic/historic/anode/libanode/tests/environment-test.c +++ /dev/null @@ -1,28 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include "../environment.h" - -int main(int argc,char **argv) -{ - const char *cache = Anode_get_cache(); - - printf("Cache folder: %s\n",cache ? cache : "(null)"); - - return 0; -} diff --git a/attic/historic/anode/libanode/tests/http_client-test.c b/attic/historic/anode/libanode/tests/http_client-test.c deleted file mode 100644 index e1f93967f..000000000 --- a/attic/historic/anode/libanode/tests/http_client-test.c +++ /dev/null @@ -1,233 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include -#include -#include "../anode.h" -#include "../misc.h" -#include "../http_client.h" -#include "../dictionary.h" - -struct TestCase -{ - int method; - AnodeURI uri; - const void *client_data; - unsigned int client_data_len; - const char *expected_sha1; - char actual_sha1[64]; - int got_it; - int keepalive; - struct TestCase *next; -}; - -#define NUM_TEST_CASES 7 -static struct TestCase test_cases[NUM_TEST_CASES]; - -static void init_test_cases(int keepalive) -{ - AnodeURI_parse(&(test_cases[0].uri),"http://zerotier.com/for_unit_tests/test1.txt"); - test_cases[0].method = ANODE_HTTP_GET; - test_cases[0].client_data_len = 0; - test_cases[0].expected_sha1 = "0828324174b10cc867b7255a84a8155cf89e1b8b"; - test_cases[0].actual_sha1[0] = (char)0; - test_cases[0].got_it = 0; - test_cases[0].keepalive = keepalive; - test_cases[0].next = &(test_cases[1]); - - AnodeURI_parse(&(test_cases[1].uri),"http://zerotier.com/for_unit_tests/test2.bin"); - test_cases[1].method = ANODE_HTTP_GET; - test_cases[1].client_data_len = 0; - test_cases[1].expected_sha1 = "6b67c635786ab52666211d02412c0d0f0372980d"; - test_cases[1].actual_sha1[0] = (char)0; - test_cases[1].got_it = 0; - test_cases[1].keepalive = keepalive; - test_cases[1].next = &(test_cases[2]); - - AnodeURI_parse(&(test_cases[2].uri),"http://zerotier.com/for_unit_tests/test3.bin"); - test_cases[2].method = ANODE_HTTP_GET; - test_cases[2].client_data_len = 0; - test_cases[2].expected_sha1 = "efa7722029fdbb6abd0e3ed32a0b44bfb982cff0"; - test_cases[2].actual_sha1[0] = (char)0; - test_cases[2].got_it = 0; - test_cases[2].keepalive = keepalive; - test_cases[2].next = &(test_cases[3]); - - AnodeURI_parse(&(test_cases[3].uri),"http://zerotier.com/for_unit_tests/test4.bin"); - test_cases[3].method = ANODE_HTTP_GET; - test_cases[3].client_data_len = 0; - test_cases[3].expected_sha1 = "da39a3ee5e6b4b0d3255bfef95601890afd80709"; - test_cases[3].actual_sha1[0] = (char)0; - test_cases[3].got_it = 0; - test_cases[3].keepalive = keepalive; - test_cases[3].next = &(test_cases[4]); - - AnodeURI_parse(&(test_cases[4].uri),"http://zerotier.com/for_unit_tests/echo.php?echo=foobar"); - test_cases[4].method = ANODE_HTTP_GET; - test_cases[4].client_data_len = 0; - test_cases[4].expected_sha1 = "8843d7f92416211de9ebb963ff4ce28125932878"; - test_cases[4].actual_sha1[0] = (char)0; - test_cases[4].got_it = 0; - test_cases[4].keepalive = keepalive; - test_cases[4].next = &(test_cases[5]); - - AnodeURI_parse(&(test_cases[5].uri),"http://zerotier.com/for_unit_tests/echo.php"); - test_cases[5].method = ANODE_HTTP_POST; - test_cases[5].client_data = "echo=foobar"; - test_cases[5].client_data_len = strlen((char *)test_cases[5].client_data); - test_cases[5].expected_sha1 = "8843d7f92416211de9ebb963ff4ce28125932878"; - test_cases[5].actual_sha1[0] = (char)0; - test_cases[5].got_it = 0; - test_cases[5].keepalive = keepalive; - test_cases[5].next = &(test_cases[6]); - - AnodeURI_parse(&(test_cases[6].uri),"http://zerotier.com/for_unit_tests/test3.bin"); - test_cases[6].method = ANODE_HTTP_HEAD; - test_cases[6].client_data_len = 0; - test_cases[6].expected_sha1 = "da39a3ee5e6b4b0d3255bfef95601890afd80709"; - test_cases[6].actual_sha1[0] = (char)0; - test_cases[6].got_it = 0; - test_cases[6].keepalive = keepalive; - test_cases[6].next = 0; -} - -static int http_handler_dump_headers(void *arg,const char *key,const char *value) -{ - printf(" H %s: %s\n",key,value); - return 1; -} - -static void http_handler(struct AnodeHttpClient *client) -{ - const char *method = "???"; - char buf[1024]; - unsigned char sha[20]; - struct TestCase *test = (struct TestCase *)client->ptr[0]; - - switch(client->method) { - case ANODE_HTTP_GET: - method = "GET"; - break; - case ANODE_HTTP_HEAD: - method = "HEAD"; - break; - case ANODE_HTTP_POST: - method = "POST"; - break; - } - - if (client->response.code == 200) { - SHA1((unsigned char *)client->response.data,client->response.data_length,sha); - Anode_to_hex(sha,20,test->actual_sha1,sizeof(test->actual_sha1)); - printf("%s %s\n * SHA1: %s exp: %s\n",method,AnodeURI_to_string(&(test->uri),buf,sizeof(buf)),test->actual_sha1,test->expected_sha1); - if (strcmp(test->actual_sha1,test->expected_sha1)) - printf(" ! SHA1 MISMATCH!\n"); - AnodeDictionary_iterate(&(client->response.headers),0,&http_handler_dump_headers); - } else printf("%s %s: ERROR: %d\n",method,AnodeURI_to_string(&(test->uri),buf,sizeof(buf)),client->response.code); - - test->got_it = 1; - - if (!test->keepalive) - AnodeHttpClient_free(client); - else { - test = test->next; - if (test) { - memcpy((void *)&(client->uri),(const void *)&(test->uri),sizeof(AnodeURI)); - - client->data = test->client_data; - client->data_length = test->client_data_len; - client->ptr[0] = test; - client->keepalive = test->keepalive; - client->method = test->method; - client->handler = &http_handler; - - AnodeHttpClient_send(client); - } else { - AnodeHttpClient_free(client); - } - } -} - -int main(int argc,char **argv) -{ - struct AnodeHttpClient *client; - AnodeTransportEngine transport_engine; - int i; - - if (Anode_init_ip_transport_engine(&transport_engine)) { - printf("Failed (transport engine init)\n"); - return 1; - } - - printf("Testing without keepalive...\n\n"); - init_test_cases(0); - for(i=0;iuri),(const void *)&(test_cases[i].uri),sizeof(AnodeURI)); - client->data = test_cases[i].client_data; - client->data_length = test_cases[i].client_data_len; - client->ptr[0] = &test_cases[i]; - client->keepalive = test_cases[i].keepalive; - client->method = test_cases[i].method; - client->handler = &http_handler; - - AnodeHttpClient_send(client); - } - - for(;;) { - for(i=0;iuri),(const void *)&(test_cases[i].uri),sizeof(AnodeURI)); - client->data = test_cases[i].client_data; - client->data_length = test_cases[i].client_data_len; - client->ptr[0] = &test_cases[i]; - client->keepalive = test_cases[i].keepalive; - client->method = test_cases[i].method; - client->handler = &http_handler; - - AnodeHttpClient_send(client); - - for(;;) { - for(i=0;i - * - * 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 . */ - -#include -#include -#include -#include -#include -#include "../misc.h" - -int main(int argc,char **argv) -{ - const char *base32TestStr = "asdf"; - char *fields[16]; - char buf[1024]; - char buf2[1024]; - char buf3[4096]; - unsigned int i; - unsigned long tmpl,tmpl2; - unsigned long long tmp64; - - srand(time(0)); - - Anode_base32_5_to_8((const unsigned char *)base32TestStr,buf); - printf("Base32 from test string: %s\n",buf); - Anode_base32_8_to_5("MFZWIZQA",(unsigned char *)buf2); - printf("Test string from Base32 (upper case): %s\n",buf2); - Anode_base32_8_to_5("mfzwizqa",(unsigned char *)buf2); - printf("Test string from Base32 (lower case): %s\n",buf2); - printf("Testing variable length encoding/decoded with pad5 functions...\n"); - for(i=0;i<1024;++i) { - tmpl = rand() % (sizeof(buf) - 8); - if (!tmpl) - tmpl = 1; - for(tmpl2=0;tmpl2> 3)); - if (!Anode_base32_encode_pad5(buf2,tmpl,buf3,sizeof(buf3))) { - printf("Failed (encode failed).\n"); - return 1; - } - memset(buf2,0,sizeof(buf2)); - if (!Anode_base32_decode_pad5(buf3,buf2,sizeof(buf2))) { - printf("Failed (decode failed).\n"); - return 1; - } - if (memcmp(buf,buf2,tmpl)) { - printf("Failed (compare failed).\n"); - return 1; - } - } - - printf("Anode_htonll(0x0102030405060708) == 0x%.16llx\n",tmp64 = Anode_htonll(0x0102030405060708ULL)); - printf("Anode_ntohll(0x%.16llx) == 0x%.16llx\n",tmp64,Anode_ntohll(tmp64)); - if (Anode_ntohll(tmp64) != 0x0102030405060708ULL) { - printf("Failed.\n"); - return 1; - } - - strcpy(buf,"foo bar baz"); - Anode_trim(buf); - printf("Testing string trim: 'foo bar baz' -> '%s'\n",buf); - strcpy(buf,"foo bar baz "); - Anode_trim(buf); - printf("Testing string trim: 'foo bar baz ' -> '%s'\n",buf); - strcpy(buf," foo bar baz"); - Anode_trim(buf); - printf("Testing string trim: ' foo bar baz' -> '%s'\n",buf); - strcpy(buf," foo bar baz "); - Anode_trim(buf); - printf("Testing string trim: ' foo bar baz ' -> '%s'\n",buf); - strcpy(buf,""); - Anode_trim(buf); - printf("Testing string trim: '' -> '%s'\n",buf); - strcpy(buf," "); - Anode_trim(buf); - printf("Testing string trim: ' ' -> '%s'\n",buf); - - printf("Testing string split.\n"); - strcpy(buf,"66.246.138.121,5323,0"); - i = Anode_split(buf,';',fields,16); - if (i != 1) { - printf("Failed.\n"); - return 1; - } else printf("Fields: %s\n",fields[0]); - strcpy(buf,"a;b;c"); - i = Anode_split(buf,';',fields,16); - if (i != 3) { - printf("Failed.\n"); - return 1; - } else printf("Fields: %s %s %s\n",fields[0],fields[1],fields[2]); - strcpy(buf,";;"); - i = Anode_split(buf,';',fields,16); - if (i != 3) { - printf("Failed.\n"); - return 1; - } else printf("Fields: %s %s %s\n",fields[0],fields[1],fields[2]); - strcpy(buf,"a;b;"); - i = Anode_split(buf,';',fields,16); - if (i != 3) { - printf("Failed.\n"); - return 1; - } else printf("Fields: %s %s %s\n",fields[0],fields[1],fields[2]); - strcpy(buf,"a;;c"); - i = Anode_split(buf,';',fields,16); - if (i != 3) { - printf("Failed.\n"); - return 1; - } else printf("Fields: %s %s %s\n",fields[0],fields[1],fields[2]); - strcpy(buf,";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"); - i = Anode_split(buf,';',fields,16); - if (i != 16) { - printf("Failed.\n"); - return 1; - } - strcpy(buf,""); - i = Anode_split(buf,';',fields,16); - if (i != 0) { - printf("Failed.\n"); - return 1; - } - printf("Passed.\n"); - - return 0; -} diff --git a/attic/historic/anode/libanode/tests/system_transport-test.c b/attic/historic/anode/libanode/tests/system_transport-test.c deleted file mode 100644 index bda575ed8..000000000 --- a/attic/historic/anode/libanode/tests/system_transport-test.c +++ /dev/null @@ -1,70 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include -#include -#include "../anode.h" -#include "../impl/thread.h" - -static int do_client() -{ - AnodeTransport *st; - AnodeSocket *udp_sock; - int run = 1; - - st = AnodeSystemTransport_new(NULL); - if (!st) { - printf("FAILED: unable to construct AnodeSystemTransport.\n"); - return -1; - } - printf("Created AnodeSystemTransport.\n"); - - while (run) - st->poll(st); -} - -static int do_server() -{ - AnodeTransport *st; - AnodeSocket *udp_sock; - AnodeSocket *tcp_sock; - int run = 1; - - st = AnodeSystemTransport_new(NULL); - if (!st) { - printf("FAILED: unable to construct AnodeSystemTransport.\n"); - return -1; - } - printf("Created AnodeSystemTransport.\n"); - - while (run) - st->poll(st); -} - -int main(int argc,char **argv) -{ - if (argc == 2) { - if (!strcmp(argv[1],"client")) - return do_client(); - else if (!strcmp(argv[1],"server")) - return do_server(); - } - - printf("Usage: system_transport-test \n"); - return -1; -} diff --git a/attic/historic/anode/libanode/uri.c b/attic/historic/anode/libanode/uri.c deleted file mode 100644 index ca644b6aa..000000000 --- a/attic/historic/anode/libanode/uri.c +++ /dev/null @@ -1,185 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include "impl/misc.h" -#include "anode.h" - -int AnodeURI_parse(AnodeURI *parsed_uri,const char *uri_string) -{ - char buf[sizeof(AnodeURI)]; - unsigned long ptr = 0; - char c; - char *p1,*p2; - - Anode_zero((void *)parsed_uri,sizeof(AnodeURI)); - - /* Get the scheme */ - for(;;) { - c = *(uri_string++); - if (!c) { - parsed_uri->scheme[ptr] = (char)0; - return ANODE_ERR_INVALID_URI; - } else if (c == ':') { - parsed_uri->scheme[ptr] = (char)0; - break; - } else { - parsed_uri->scheme[ptr++] = c; - if (ptr == sizeof(parsed_uri->scheme)) - return ANODE_ERR_BUFFER_TOO_SMALL; - } - } - - if (*uri_string == '/') { - /* If it starts with /, it's a URL */ - - /* Skip double slash */ - if (!(*(++uri_string))) - return 0; /* Scheme with no path */ - if (*uri_string == '/') { - if (!(*(++uri_string))) - return 0; /* Scheme with no path */ - } - - /* Get the host section and put it in buf[] */ - ptr = 0; - while ((*uri_string)&&(*uri_string != '/')) { - buf[ptr++] = *(uri_string++); - if (ptr == sizeof(buf)) - return ANODE_ERR_BUFFER_TOO_SMALL; - } - buf[ptr] = (char)0; - - /* Parse host section for host, username, password, and port */ - if (buf[0]) { - p1 = (char *)Anode_strchr(buf,'@'); - if (p1) { - *(p1++) = (char)0; - if (*p1) { - p2 = (char *)Anode_strchr(buf,':'); - if (p2) { - *(p2++) = (char)0; - Anode_str_copy(parsed_uri->password,p2,sizeof(parsed_uri->password)); - } - Anode_str_copy(parsed_uri->username,buf,sizeof(parsed_uri->username)); - } else return ANODE_ERR_INVALID_URI; - } else p1 = buf; - - p2 = (char *)Anode_strchr(p1,':'); - if (p2) { - *(p2++) = (char)0; - if (*p2) - parsed_uri->port = (int)strtoul(p2,(char **)0,10); - } - Anode_str_copy(parsed_uri->host,p1,sizeof(parsed_uri->host)); - } - - /* Get the path, query, and fragment section and put it in buf[] */ - ptr = 0; - while ((buf[ptr++] = *(uri_string++))) { - if (ptr == sizeof(buf)) - return ANODE_ERR_BUFFER_TOO_SMALL; - } - - /* Parse path section for path, query, and fragment */ - if (buf[0]) { - p1 = (char *)Anode_strchr(buf,'?'); - if (p1) { - *(p1++) = (char)0; - p2 = (char *)Anode_strchr(p1,'#'); - if (p2) { - *(p2++) = (char)0; - Anode_str_copy(parsed_uri->fragment,p2,sizeof(parsed_uri->fragment)); - } - Anode_str_copy(parsed_uri->query,p1,sizeof(parsed_uri->query)); - } else { - p2 = (char *)Anode_strchr(buf,'#'); - if (p2) { - *(p2++) = (char)0; - Anode_str_copy(parsed_uri->fragment,p2,sizeof(parsed_uri->fragment)); - } - } - Anode_str_copy(parsed_uri->path,buf,sizeof(parsed_uri->path)); - } - } else { - /* Otherwise, it's a URN and what remains is all path */ - ptr = 0; - while ((parsed_uri->path[ptr++] = *(uri_string++))) { - if (ptr == sizeof(parsed_uri->path)) - return ANODE_ERR_BUFFER_TOO_SMALL; - } - } - - return 0; -} - -char *AnodeURI_to_string(const AnodeURI *uri,char *buf,int len) -{ - int i = 0; - char portbuf[16]; - const char *p; - - p = uri->scheme; - while (*p) { buf[i++] = *(p++); if (i >= len) return (char *)0; } - - buf[i++] = ':'; if (i >= len) return (char *)0; - - if (uri->host[0]) { - buf[i++] = '/'; if (i >= len) return (char *)0; - buf[i++] = '/'; if (i >= len) return (char *)0; - - if (uri->username[0]) { - p = uri->username; - while (*p) { buf[i++] = *(p++); if (i >= len) return (char *)0; } - if (uri->password[0]) { - buf[i++] = ':'; if (i >= len) return (char *)0; - p = uri->password; - while (*p) { buf[i++] = *(p++); if (i >= len) return (char *)0; } - } - buf[i++] = '@'; if (i >= len) return (char *)0; - } - - p = uri->host; - while (*p) { buf[i++] = *(p++); if (i >= len) return (char *)0; } - - if ((uri->port > 0)&&(uri->port <= 0xffff)) { - buf[i++] = ':'; if (i >= len) return (char *)0; - snprintf(portbuf,sizeof(portbuf),"%d",uri->port); - p = portbuf; - while (*p) { buf[i++] = *(p++); if (i >= len) return (char *)0; } - } - } - - p = uri->path; - while (*p) { buf[i++] = *(p++); if (i >= len) return (char *)0; } - - if (uri->query[0]) { - buf[i++] = '?'; if (i >= len) return (char *)0; - p = uri->query; - while (*p) { buf[i++] = *(p++); if (i >= len) return (char *)0; } - } - - if (uri->fragment[0]) { - buf[i++] = '#'; if (i >= len) return (char *)0; - p = uri->fragment; - while (*p) { buf[i++] = *(p++); if (i >= len) return (char *)0; } - } - - buf[i] = (char)0; - - return buf; -} diff --git a/attic/historic/anode/libanode/utils/anode-make-identity.c b/attic/historic/anode/libanode/utils/anode-make-identity.c deleted file mode 100644 index 99a3897a4..000000000 --- a/attic/historic/anode/libanode/utils/anode-make-identity.c +++ /dev/null @@ -1,50 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include -#include -#include "../anode.h" -#include "../impl/misc.h" -#include "../impl/types.h" - -int main(int argc,char **argv) -{ - char str[1024]; - AnodeZone zone; - AnodeIdentity identity; - - if (argc < 2) { - printf("Usage: anode-make-identity <32-bit zone ID hex>\n"); - return 0; - } - - *((uint32_t *)zone.bits) = htonl((uint32_t)strtoul(argv[1],(char **)0,16)); - - if (AnodeIdentity_generate(&identity,&zone,ANODE_ADDRESS_ANODE_256_40)) { - fprintf(stderr,"Error: identity key pair generation failed (check build settings).\n"); - return 1; - } - if (AnodeIdentity_to_string(&identity,str,sizeof(str)) <= 0) { - fprintf(stderr,"Error: internal error converting identity to string.\n"); - return -1; - } - - printf("%s\n",str); - - return 0; -} diff --git a/attic/historic/anode/libanode/zone.c b/attic/historic/anode/libanode/zone.c deleted file mode 100644 index a6e397ae8..000000000 --- a/attic/historic/anode/libanode/zone.c +++ /dev/null @@ -1,184 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009-2010 Adam Ierymenko - * - * 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 . */ - -#include -#include -#include -#include -#include -#include -#include "impl/types.h" -#include "impl/misc.h" -#include "impl/dictionary.h" -#include "impl/environment.h" -#include "impl/http_client.h" -#include "anode.h" - -static const char *_MONTHS[12] = { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" }; -static const char *_DAYS_OF_WEEK[7] = { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" }; -static inline unsigned long get_file_time_for_http(const char *path,char *buf,unsigned int len) -{ - struct stat st; - struct tm *gmt; - - if (!stat(path,(struct stat *)&st)) { - gmt = gmtime(&st.st_mtime); - if (gmt) { - snprintf(buf,len,"%s, %d %s %d %d:%d:%d GMT", - _DAYS_OF_WEEK[gmt->tm_wday], - gmt->tm_mday, - _MONTHS[gmt->tm_mon], - (1900 + gmt->tm_year), - gmt->tm_hour, - gmt->tm_min, - gmt->tm_sec); - buf[len - 1] = (char)0; - return (unsigned long)st.st_size; - } - } - - return 0; -} - -struct AnodeZoneLookupJob -{ - char cached_zone_file[2048]; - struct AnodeDictionary *zone_dict; - AnodeZone zone; - void *ptr; - void (*zone_lookup_handler)(void *,const AnodeZone *,AnodeZoneFile *); - int had_cached_zone; -}; - -static void AnodeZone_lookup_http_handler(struct AnodeHttpClient *client) -{ - char *data_tmp; - struct AnodeZoneLookupJob *job = (struct AnodeZoneLookupJob *)client->ptr[0]; - FILE *zf; - - if ((client->response.code == 200)&&(client->response.data_length > 0)) { - zf = fopen(job->cached_zone_file,"w"); - if (zf) { - fwrite(client->response.data,1,client->response.data_length,zf); - fclose(zf); - } - - data_tmp = (char *)malloc(client->response.data_length + 1); - Anode_memcpy((void *)data_tmp,client->response.data,client->response.data_length); - data_tmp[client->response.data_length] = (char)0; - - AnodeDictionary_clear(job->zone_dict); - AnodeDictionary_read( - job->zone_dict, - data_tmp, - "\r\n", - "=", - ";", - '\\', - 1,1); - - free((void *)data_tmp); - - job->zone_lookup_handler(job->ptr,&job->zone,(AnodeZoneFile *)job->zone_dict); - } else if (job->had_cached_zone) - job->zone_lookup_handler(job->ptr,&job->zone,(AnodeZoneFile *)job->zone_dict); - else { - AnodeDictionary_destroy(job->zone_dict); - free((void *)job->zone_dict); - job->zone_lookup_handler(job->ptr,&job->zone,(AnodeZoneFile *)0); - } - - free((void *)job); - AnodeHttpClient_free(client); -} - -void AnodeZone_lookup( - AnodeTransportEngine *transport, - const AnodeZone *zone, - void *ptr, - void (*zone_lookup_handler)(void *,const AnodeZone *,AnodeZone *)) -{ - char cached_zones_folder[2048]; - char cached_zone_file[2048]; - char if_modified_since[256]; - unsigned long file_size; - struct AnodeZoneLookupJob *job; - struct AnodeHttpClient *client; - char *file_data; - FILE *zf; - - if (Anode_get_cache_sub("zones",cached_zones_folder,sizeof(cached_zones_folder))) { - snprintf(cached_zone_file,sizeof(cached_zone_file),"%s%c%.2x%.2x%.2x%.2x.z",cached_zones_folder,ANODE_PATH_SEPARATOR,(unsigned int)zone->bits[0],(unsigned int)zone->bits[1],(unsigned int)zone->bits[2],(unsigned int)zone->bits[3]); - cached_zone_file[sizeof(cached_zone_file)-1] = (char)0; - - job = (struct AnodeZoneLookupJob *)malloc(sizeof(struct AnodeZoneLookupJob)); - Anode_str_copy(job->cached_zone_file,cached_zone_file,sizeof(job->cached_zone_file)); - job->zone_dict = (struct AnodeDictionary *)malloc(sizeof(struct AnodeDictionary)); - AnodeDictionary_init(job->zone_dict,0); - job->zone.bits[0] = zone->bits[0]; - job->zone.bits[1] = zone->bits[1]; - job->zone.bits[2] = zone->bits[2]; - job->zone.bits[3] = zone->bits[3]; - job->ptr = ptr; - job->zone_lookup_handler = zone_lookup_handler; - job->had_cached_zone = 0; - - client = AnodeHttpClient_new(transport); - - Anode_str_copy(client->uri.scheme,"http",sizeof(client->uri.scheme)); - snprintf(client->uri.host,sizeof(client->uri.host),"a--%.2x%.2x%.2x%.2x.net",(unsigned int)zone->bits[0],(unsigned int)zone->bits[1],(unsigned int)zone->bits[2],(unsigned int)zone->bits[3]); - client->uri.host[sizeof(client->uri.host)-1] = (char)0; - Anode_str_copy(client->uri.path,"/z",sizeof(client->uri.path)); - - client->handler = &AnodeZone_lookup_http_handler; - client->ptr[0] = job; - - if ((file_size = get_file_time_for_http(cached_zone_file,if_modified_since,sizeof(if_modified_since)))) { - zf = fopen(cached_zone_file,"r"); - if (zf) { - AnodeDictionary_put(&client->headers,"If-Modified-Since",if_modified_since); - file_data = (char *)malloc(file_size + 1); - if (fread((void *)file_data,1,file_size,zf)) { - file_data[file_size] = (char)0; - AnodeDictionary_read( - job->zone_dict, - file_data, - "\r\n", - "=", - ";", - '\\', - 1,1); - job->had_cached_zone = 1; - } - free((void *)file_data); - fclose(zf); - } - } - - AnodeHttpClient_send(client); - } else zone_lookup_handler(ptr,zone,(AnodeZone *)0); -} - -const char *AnodeZoneFile_get(AnodeZoneFile *zone,const char *key) -{ - return AnodeDictionary_get((struct AnodeDictionary *)zone,key); -} - -void AnodeZoneFile_free(AnodeZoneFile *zone) -{ - AnodeDictionary_destroy((struct AnodeDictionary *)zone); - free((void *)zone); -} diff --git a/attic/historic/anode/libspark/Makefile b/attic/historic/anode/libspark/Makefile deleted file mode 100644 index 0d3fedd87..000000000 --- a/attic/historic/anode/libspark/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -SYSNAME:=${shell uname} -SYSNAME!=uname -include ../config.mk.${SYSNAME} - -LIBSPARK_OBJS= - -all: libspark - -libspark: $(LIBSPARK_OBJS) - ar rcs libspark.a $(LIBSPARK_OBJS) - ranlib libspark.a - -clean: force - rm -f *.a *.so *.dylib *.dll *.lib *.exe *.o - -force: ; diff --git a/attic/historic/anode/libspark/experiments/FindGoodSegmentDelimiters.cpp b/attic/historic/anode/libspark/experiments/FindGoodSegmentDelimiters.cpp deleted file mode 100644 index 9b1ecaa15..000000000 --- a/attic/historic/anode/libspark/experiments/FindGoodSegmentDelimiters.cpp +++ /dev/null @@ -1,161 +0,0 @@ -// Searches for good delimiters to cut streams into relatively well sized -// segments. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Desired size range -#define MIN_DESIRED_SIZE 4096 -#define MAX_DESIRED_SIZE 131072 - -#define DELIMITER_SET_SIZE 1 -typedef boost::array DelimArray; - -struct BestEntry -{ - DelimArray best; - double bestScore; - std::vector data; -}; - -boost::mutex bestLock; -boost::mutex outLock; -std::map best; - -static void runThread(const std::string &fileName) -{ - char tmp[4096]; - - boost::mt19937 prng; - { - boost::uint32_t seed; - FILE *ur = fopen("/dev/urandom","r"); - fread((void *)&seed,1,sizeof(seed),ur); - fclose(ur); - prng.seed(seed); - } - - BestEntry *myEntry; - { - boost::mutex::scoped_lock l(bestLock); - myEntry = &(best[fileName]); - myEntry->bestScore = 99999999.0; - } - - { - boost::mutex::scoped_lock l(outLock); - - std::cout << "*** Reading test data from: " << fileName << std::endl; - FILE *f = fopen(fileName.c_str(),"r"); - if (f) { - int n; - while ((n = fread((void *)tmp,1,sizeof(tmp),f)) > 0) { - for(int i=0;idata.push_back((unsigned char)tmp[i]); - } - fclose(f); - } - - if (myEntry->data.size() <= 0) { - std::cout << "Error: no data read." << std::endl; - exit(1); - } else std::cout << "*** Read " << myEntry->data.size() << " bytes of test data." << std::endl; - - std::cout.flush(); - } - - DelimArray current; - for(unsigned int i=0;i::iterator i=myEntry->data.begin();i!=myEntry->data.end();++i) { - shiftRegister <<= 1; - shiftRegister |= (((boost::uint32_t)*i) & 1); - - ++segSize; - - boost::uint16_t transformedShiftRegister = (boost::uint16_t)(shiftRegister); - - for(DelimArray::iterator d=current.begin();d!=current.end();++d) { - if (transformedShiftRegister == *d) { - if (segSize < MIN_DESIRED_SIZE) - ++numTooShort; - else if (segSize > MAX_DESIRED_SIZE) - ++numTooLong; - else ++numGood; - segSize = 0; - break; - } - } - } - if (segSize) { - if (segSize < MIN_DESIRED_SIZE) - ++numTooShort; - else if (segSize > MAX_DESIRED_SIZE) - ++numTooLong; - else ++numGood; - } - - if (numGood) { - double score = ((double)(numTooShort + numTooLong)) / ((double)numGood); - - if (score < myEntry->bestScore) { - myEntry->best = current; - myEntry->bestScore = score; - - boost::mutex::scoped_lock l(outLock); - - std::cout << fileName << ": "; - - for(DelimArray::iterator d=current.begin();d!=current.end();++d) { - sprintf(tmp,"0x%.4x",(unsigned int)*d); - if (d != current.begin()) - std::cout << ','; - std::cout << tmp; - } - - std::cout << ": " << numTooShort << " / " << numGood << " / " << numTooLong << " (" << score << ")" << std::endl; - std::cout.flush(); - - if ((numTooShort == 0)&&(numTooLong == 0)) - break; - } - } - - for(DelimArray::iterator i=current.begin();i!=current.end();++i) - *i = (boost::uint16_t)prng(); - } -} - -int main(int argc,char **argv) -{ - std::vector< boost::shared_ptr > threads; - - for(int i=1;i t(new boost::thread(boost::bind(&runThread,std::string(argv[i])))); - threads.push_back(t); - } - - for(std::vector< boost::shared_ptr >::iterator i=threads.begin();i!=threads.end();++i) - (*i)->join(); - - return 0; -} diff --git a/attic/historic/anode/libspark/experiments/Makefile b/attic/historic/anode/libspark/experiments/Makefile deleted file mode 100644 index 83aa4f67b..000000000 --- a/attic/historic/anode/libspark/experiments/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -all: - g++ -O6 -ftree-vectorize -o FindGoodSegmentDelimiters FindGoodSegmentDelimiters.cpp -lboost_thread -lpthread - -clean: - rm FindGoodSegmentDelimiters diff --git a/attic/historic/anode/libspark/streamencoder.h b/attic/historic/anode/libspark/streamencoder.h deleted file mode 100644 index b487ca402..000000000 --- a/attic/historic/anode/libspark/streamencoder.h +++ /dev/null @@ -1,108 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009 Adam Ierymenko - * - * 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 . */ - -#ifndef _SPARK_STREAMENCODER_H -#define _SPARK_STREAMENCODER_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct -{ - unsigned char *input_buf; - unsigned long input_buf_capacity; - unsigned long input_length; - - unsigned char *stream_out_buf; - unsigned long stream_out_buf_capacity; - unsigned long stream_out_length; - - void (*data_segment_add_func)(const void *data,unsigned long len,const void *global_hash,unsigned long global_hash_len); -} SparkStreamEncoder; - -/** - * Initialize a spark stream encoder - * - * @param enc Encoder structure to initialize - * @param data_segment_add_func Function to call to store or cache data - */ -void SparkStreamEncoder_init( - SparkStreamEncoder *enc, - void (*data_segment_add_func)( - const void *data, - unsigned long len, - const void *global_hash, - unsigned long global_hash_len)); - -/** - * Clean up a spark stream encoder structure - * - * @param enc Structure to clear - */ -void SparkStreamEncoder_destroy(SparkStreamEncoder *enc); - -/** - * Add data to encode - * - * @param enc Encoder structure - * @param data Data to encode - * @param len Length of data in bytes - * @return Number of bytes of result stream now available - */ -unsigned long SparkStreamEncoder_put( - SparkStreamEncoder *enc, - const void *data, - unsigned long len); - -/** - * Flush all data currently in input buffer - * - * @param enc Encoder structure to flush - */ -void SparkStreamEncoder_flush(SparkStreamEncoder *enc); - -/** - * @return Number of bytes of output stream available - */ -static inline unsigned long SparkStreamEncoder_available(SparkStreamEncoder *enc) -{ - return enc->stream_out_length; -} - -/** - * @return Pointer to result stream bytes (may return null if none available) - */ -static inline const void *SparkStreamEncoder_get(SparkStreamEncoder *enc) -{ - return (const void *)(enc->stream_out_buf); -} - -/** - * @return "Consume" result stream bytes after they're read or sent - */ -static inline void SparkStreamEncoder_consume(SparkStreamEncoder *enc,unsigned long len) -{ - unsigned long i; - for(i=len;istream_out_length;++i) - enc->stream_out_buf[i - len] = enc->stream_out_buf[i]; -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/attic/historic/anode/libspark/wrapper.h b/attic/historic/anode/libspark/wrapper.h deleted file mode 100644 index eb8c593da..000000000 --- a/attic/historic/anode/libspark/wrapper.h +++ /dev/null @@ -1,66 +0,0 @@ -/* libanode: the Anode C reference implementation - * Copyright (C) 2009 Adam Ierymenko - * - * 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 . */ - -#ifndef _SPARK_WRAPPER_H -#define _SPARK_WRAPPER_H - -#include -#include "../libanode/aes128.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Spark uses SHA-256 with hash length 32 */ -#define SPARK_HASH_LENGTH 32 - -// Wrap a segment for forward propagation -static inline void Spark_wrap(void *data,unsigned long len,void *plaintext_hash_buf,void *global_hash_buf) -{ - unsigned char expkey[ANODE_AES128_EXP_KEY_SIZE]; - - SHA256((const unsigned char *)data,len,(unsigned char *)plaintext_hash_buf); - - Anode_aes128_expand_key(expkey,(const unsigned char *)plaintext_hash_buf); - Anode_aes128_cfb_encrypt(expkey,((const unsigned char *)plaintext_hash_buf) + 16,(unsigned char *)data,len); - - SHA256((const unsigned char *)data,len,(unsigned char *)global_hash_buf); -} - -// Unwrap a segment and check its integrity -static inline int Spark_unwrap(void *data,unsigned long len,const void *plaintext_hash) -{ - unsigned char expkey[ANODE_AES128_EXP_KEY_SIZE]; - unsigned char check_hash[32]; - unsigned long i; - - Anode_aes128_expand_key(expkey,(const unsigned char *)plaintext_hash); - Anode_aes128_cfb_decrypt(expkey,((const unsigned char *)plaintext_hash) + 16,(unsigned char *)data,len); - - SHA256((const unsigned char *)data,len,check_hash); - - for(i=0;i<32;++i) { - if (check_hash[i] != ((const unsigned char *)plaintext_hash)[i]) - return 0; - } - return 1; -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/attic/rtbl/BSDRoutingTable.cpp b/attic/rtbl/BSDRoutingTable.cpp new file mode 100644 index 000000000..6d44c3ecd --- /dev/null +++ b/attic/rtbl/BSDRoutingTable.cpp @@ -0,0 +1,331 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../node/Constants.hpp" +#include "BSDRoutingTable.hpp" + +// All I wanted was the bloody rounting table. I didn't expect the Spanish inquisition. + +#define ZT_BSD_ROUTE_CMD "/sbin/route" + +namespace ZeroTier { + +BSDRoutingTable::BSDRoutingTable() +{ +} + +BSDRoutingTable::~BSDRoutingTable() +{ +} + +std::vector BSDRoutingTable::get(bool includeLinkLocal,bool includeLoopback) const +{ + std::vector entries; + int mib[6]; + size_t needed; + + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = 0; + mib[4] = NET_RT_DUMP; + mib[5] = 0; + if (!sysctl(mib,6,NULL,&needed,NULL,0)) { + if (needed <= 0) + return entries; + + char *buf = (char *)::malloc(needed); + if (buf) { + if (!sysctl(mib,6,buf,&needed,NULL,0)) { + struct rt_msghdr *rtm; + for(char *next=buf,*end=buf+needed;nextrtm_msglen; + + if (((rtm->rtm_flags & RTF_LLINFO) == 0)&&((rtm->rtm_flags & RTF_HOST) == 0)&&((rtm->rtm_flags & RTF_UP) != 0)&&((rtm->rtm_flags & RTF_MULTICAST) == 0)) { + RoutingTable::Entry e; + e.deviceIndex = -9999; // unset + + int which = 0; + while (saptr < saend) { + struct sockaddr *sa = (struct sockaddr *)saptr; + unsigned int salen = sa->sa_len; + if (!salen) + break; + + // Skip missing fields in rtm_addrs bit field + while ((rtm->rtm_addrs & 1) == 0) { + rtm->rtm_addrs >>= 1; + ++which; + if (which > 6) + break; + } + if (which > 6) + break; + + rtm->rtm_addrs >>= 1; + switch(which++) { + case 0: + //printf("RTA_DST\n"); + if (sa->sa_family == AF_INET6) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; + // Nobody expects the Spanish inquisition! + if ((sin6->sin6_addr.s6_addr[0] == 0xfe)&&((sin6->sin6_addr.s6_addr[1] & 0xc0) == 0x80)) { + // Our chief weapon is... in-band signaling! + // Seriously who in the living fuck thought this was a good idea and + // then had the sadistic idea to not document it anywhere? Of course it's + // not like there is any documentation on BSD sysctls anyway. + unsigned int interfaceIndex = ((((unsigned int)sin6->sin6_addr.s6_addr[2]) << 8) & 0xff) | (((unsigned int)sin6->sin6_addr.s6_addr[3]) & 0xff); + sin6->sin6_addr.s6_addr[2] = 0; + sin6->sin6_addr.s6_addr[3] = 0; + if (!sin6->sin6_scope_id) + sin6->sin6_scope_id = interfaceIndex; + } + } + e.destination.set(sa); + break; + case 1: + //printf("RTA_GATEWAY\n"); + switch(sa->sa_family) { + case AF_LINK: + e.deviceIndex = (int)((const struct sockaddr_dl *)sa)->sdl_index; + break; + case AF_INET: + case AF_INET6: + e.gateway.set(sa); + break; + } + break; + case 2: { + if (e.destination.isV6()) { + salen = sizeof(struct sockaddr_in6); // Confess! + unsigned int bits = 0; + for(int i=0;i<16;++i) { + unsigned char c = (unsigned char)((const struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[i]; + if (c == 0xff) + bits += 8; + else break; + /* must they be multiples of 8? Most of the BSD source I can find says yes..? + else { + while ((c & 0x80) == 0x80) { + ++bits; + c <<= 1; + } + break; + } + */ + } + e.destination.setPort(bits); + } else { + salen = sizeof(struct sockaddr_in); // Confess! + e.destination.setPort((unsigned int)Utils::countBits((uint32_t)((const struct sockaddr_in *)sa)->sin_addr.s_addr)); + } + //printf("RTA_NETMASK\n"); + } break; + /* + case 3: + //printf("RTA_GENMASK\n"); + break; + case 4: + //printf("RTA_IFP\n"); + break; + case 5: + //printf("RTA_IFA\n"); + break; + case 6: + //printf("RTA_AUTHOR\n"); + break; + */ + } + + saptr += salen; + } + + e.metric = (int)rtm->rtm_rmx.rmx_hopcount; + if (e.metric < 0) + e.metric = 0; + + if (((includeLinkLocal)||(!e.destination.isLinkLocal()))&&((includeLoopback)||((!e.destination.isLoopback())&&(!e.gateway.isLoopback())))) + entries.push_back(e); + } + + next = saend; + } + } + + ::free(buf); + } + } + + for(std::vector::iterator e1(entries.begin());e1!=entries.end();++e1) { + if ((!e1->device[0])&&(e1->deviceIndex >= 0)) + if_indextoname(e1->deviceIndex,e1->device); + } + for(std::vector::iterator e1(entries.begin());e1!=entries.end();++e1) { + if ((!e1->device[0])&&(e1->gateway)) { + int bestMetric = 9999999; + for(std::vector::iterator e2(entries.begin());e2!=entries.end();++e2) { + if ((e1->gateway.within(e2->destination))&&(e2->metric <= bestMetric)) { + bestMetric = e2->metric; + Utils::scopy(e1->device,sizeof(e1->device),e2->device); + } + } + } + } + + std::sort(entries.begin(),entries.end()); + + return entries; +} + +RoutingTable::Entry BSDRoutingTable::set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric) +{ + if ((!gateway)&&((!device)||(!device[0]))) + return RoutingTable::Entry(); + + std::vector rtab(get(true,true)); + + for(std::vector::iterator e(rtab.begin());e!=rtab.end();++e) { + if (e->destination == destination) { + if (((!device)||(!device[0]))||(!strcmp(device,e->device))) { + long p = (long)fork(); + if (p > 0) { + int exitcode = -1; + ::waitpid(p,&exitcode,0); + } else if (p == 0) { + ::close(STDOUT_FILENO); + ::close(STDERR_FILENO); + ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,"delete",(destination.isV6() ? "-inet6" : "-inet"),destination.toString().c_str(),(const char *)0); + ::_exit(-1); + } + } + } + } + + if (metric < 0) + return RoutingTable::Entry(); + + { + char hcstr[64]; + Utils::snprintf(hcstr,sizeof(hcstr),"%d",metric); + long p = (long)fork(); + if (p > 0) { + int exitcode = -1; + ::waitpid(p,&exitcode,0); + } else if (p == 0) { + ::close(STDOUT_FILENO); + ::close(STDERR_FILENO); + if (gateway) { + ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,"add",(destination.isV6() ? "-inet6" : "-inet"),destination.toString().c_str(),gateway.toIpString().c_str(),"-hopcount",hcstr,(const char *)0); + } else if ((device)&&(device[0])) { + ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,"add",(destination.isV6() ? "-inet6" : "-inet"),destination.toString().c_str(),"-interface",device,"-hopcount",hcstr,(const char *)0); + } + ::_exit(-1); + } + } + + rtab = get(true,true); + std::vector::iterator bestEntry(rtab.end()); + for(std::vector::iterator e(rtab.begin());e!=rtab.end();++e) { + if ((e->destination == destination)&&(e->gateway.ipsEqual(gateway))) { + if ((device)&&(device[0])) { + if (!strcmp(device,e->device)) { + if (metric == e->metric) + bestEntry = e; + } + } + if (bestEntry == rtab.end()) + bestEntry = e; + } + } + if (bestEntry != rtab.end()) + return *bestEntry; + + return RoutingTable::Entry(); +} + +} // namespace ZeroTier + +// Enable and build to test routing table interface +#if 0 +using namespace ZeroTier; +int main(int argc,char **argv) +{ + BSDRoutingTable rt; + + printf(" \n"); + std::vector ents(rt.get()); + for(std::vector::iterator e(ents.begin());e!=ents.end();++e) + printf("%s\n",e->toString().c_str()); + printf("\n"); + + printf("adding 1.1.1.0 and 2.2.2.0...\n"); + rt.set(InetAddress("1.1.1.0",24),InetAddress("1.2.3.4",0),(const char *)0,1); + rt.set(InetAddress("2.2.2.0",24),InetAddress(),"en0",1); + printf("\n"); + + printf(" \n"); + ents = rt.get(); + for(std::vector::iterator e(ents.begin());e!=ents.end();++e) + printf("%s\n",e->toString().c_str()); + printf("\n"); + + printf("deleting 1.1.1.0 and 2.2.2.0...\n"); + rt.set(InetAddress("1.1.1.0",24),InetAddress("1.2.3.4",0),(const char *)0,-1); + rt.set(InetAddress("2.2.2.0",24),InetAddress(),"en0",-1); + printf("\n"); + + printf(" \n"); + ents = rt.get(); + for(std::vector::iterator e(ents.begin());e!=ents.end();++e) + printf("%s\n",e->toString().c_str()); + printf("\n"); + + return 0; +} +#endif diff --git a/attic/rtbl/BSDRoutingTable.hpp b/attic/rtbl/BSDRoutingTable.hpp new file mode 100644 index 000000000..97969666a --- /dev/null +++ b/attic/rtbl/BSDRoutingTable.hpp @@ -0,0 +1,51 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#ifndef ZT_BSDROUTINGTABLE_HPP +#define ZT_BSDROUTINGTABLE_HPP + +#include "../node/RoutingTable.hpp" + +namespace ZeroTier { + +/** + * Routing table interface for BSD with sysctl() and BSD /sbin/route + * + * Has currently only been tested on OSX/Darwin. + */ +class BSDRoutingTable : public RoutingTable +{ +public: + BSDRoutingTable(); + virtual ~BSDRoutingTable(); + virtual std::vector get(bool includeLinkLocal = false,bool includeLoopback = false) const; + virtual RoutingTable::Entry set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric); +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/rtbl/LinuxRoutingTable.cpp b/attic/rtbl/LinuxRoutingTable.cpp new file mode 100644 index 000000000..581054e26 --- /dev/null +++ b/attic/rtbl/LinuxRoutingTable.cpp @@ -0,0 +1,235 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../node/Constants.hpp" +#include "../node/Utils.hpp" +#include "LinuxRoutingTable.hpp" + +#define ZT_LINUX_IP_COMMAND "/sbin/ip" + +namespace ZeroTier { + +LinuxRoutingTable::LinuxRoutingTable() +{ +} + +LinuxRoutingTable::~LinuxRoutingTable() +{ +} + +std::vector LinuxRoutingTable::get(bool includeLinkLocal,bool includeLoopback) const +{ + char buf[131072]; + char *stmp,*stmp2; + std::vector entries; + + { + int fd = ::open("/proc/net/route",O_RDONLY); + if (fd <= 0) + buf[0] = (char)0; + else { + int n = (int)::read(fd,buf,sizeof(buf) - 1); + ::close(fd); + if (n < 0) n = 0; + buf[n] = (char)0; + } + } + + int lineno = 0; + for(char *line=Utils::stok(buf,"\r\n",&stmp);(line);line=Utils::stok((char *)0,"\r\n",&stmp)) { + if (lineno == 0) { + ++lineno; + continue; // skip header + } + + char *iface = (char *)0; + uint32_t destination = 0; + uint32_t gateway = 0; + int metric = 0; + uint32_t mask = 0; + + int fno = 0; + for(char *f=Utils::stok(line,"\t \r\n",&stmp2);(f);f=Utils::stok((char *)0,"\t \r\n",&stmp2)) { + switch(fno) { + case 0: iface = f; break; + case 1: destination = (uint32_t)Utils::hexStrToULong(f); break; + case 2: gateway = (uint32_t)Utils::hexStrToULong(f); break; + case 6: metric = (int)Utils::strToInt(f); break; + case 7: mask = (uint32_t)Utils::hexStrToULong(f); break; + } + ++fno; + } + + if ((iface)&&(destination)) { + RoutingTable::Entry e; + if (destination) + e.destination.set(&destination,4,Utils::countBits(mask)); + e.gateway.set(&gateway,4,0); + e.deviceIndex = 0; // not used on Linux + e.metric = metric; + Utils::scopy(e.device,sizeof(e.device),iface); + if ((e.destination)&&((includeLinkLocal)||(!e.destination.isLinkLocal()))&&((includeLoopback)||((!e.destination.isLoopback())&&(!e.gateway.isLoopback())&&(strcmp(iface,"lo"))))) + entries.push_back(e); + } + + ++lineno; + } + + { + int fd = ::open("/proc/net/ipv6_route",O_RDONLY); + if (fd <= 0) + buf[0] = (char)0; + else { + int n = (int)::read(fd,buf,sizeof(buf) - 1); + ::close(fd); + if (n < 0) n = 0; + buf[n] = (char)0; + } + } + + for(char *line=Utils::stok(buf,"\r\n",&stmp);(line);line=Utils::stok((char *)0,"\r\n",&stmp)) { + char *destination = (char *)0; + unsigned int destPrefixLen = 0; + char *gateway = (char *)0; // next hop in ipv6 terminology + int metric = 0; + char *device = (char *)0; + + int fno = 0; + for(char *f=Utils::stok(line,"\t \r\n",&stmp2);(f);f=Utils::stok((char *)0,"\t \r\n",&stmp2)) { + switch(fno) { + case 0: destination = f; break; + case 1: destPrefixLen = (unsigned int)Utils::hexStrToULong(f); break; + case 4: gateway = f; break; + case 5: metric = (int)Utils::hexStrToLong(f); break; + case 9: device = f; break; + } + ++fno; + } + + if ((device)&&(destination)) { + unsigned char tmp[16]; + RoutingTable::Entry e; + Utils::unhex(destination,tmp,16); + if ((!Utils::isZero(tmp,16))&&(tmp[0] != 0xff)) + e.destination.set(tmp,16,destPrefixLen); + Utils::unhex(gateway,tmp,16); + e.gateway.set(tmp,16,0); + e.deviceIndex = 0; // not used on Linux + e.metric = metric; + Utils::scopy(e.device,sizeof(e.device),device); + if ((e.destination)&&((includeLinkLocal)||(!e.destination.isLinkLocal()))&&((includeLoopback)||((!e.destination.isLoopback())&&(!e.gateway.isLoopback())&&(strcmp(device,"lo"))))) + entries.push_back(e); + } + } + + std::sort(entries.begin(),entries.end()); + return entries; +} + +RoutingTable::Entry LinuxRoutingTable::set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric) +{ + char metstr[128]; + + if ((!gateway)&&((!device)||(!device[0]))) + return RoutingTable::Entry(); + + Utils::snprintf(metstr,sizeof(metstr),"%d",metric); + + if (metric < 0) { + long pid = (long)vfork(); + if (pid == 0) { + if (gateway) { + if ((device)&&(device[0])) { + ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","del",destination.toString().c_str(),"via",gateway.toIpString().c_str(),"dev",device,(const char *)0); + } else { + ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","del",destination.toString().c_str(),"via",gateway.toIpString().c_str(),(const char *)0); + } + } else { + ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","del",destination.toString().c_str(),"dev",device,(const char *)0); + } + ::_exit(-1); + } else if (pid > 0) { + int exitcode = -1; + ::waitpid(pid,&exitcode,0); + } + } else { + long pid = (long)vfork(); + if (pid == 0) { + if (gateway) { + if ((device)&&(device[0])) { + ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","replace",destination.toString().c_str(),"metric",metstr,"via",gateway.toIpString().c_str(),"dev",device,(const char *)0); + } else { + ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","replace",destination.toString().c_str(),"metric",metstr,"via",gateway.toIpString().c_str(),(const char *)0); + } + } else { + ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","replace",destination.toString().c_str(),"metric",metstr,"dev",device,(const char *)0); + } + ::_exit(-1); + } else if (pid > 0) { + int exitcode = -1; + ::waitpid(pid,&exitcode,0); + } + } + + std::vector rtab(get(true,true)); + std::vector::iterator bestEntry(rtab.end()); + for(std::vector::iterator e(rtab.begin());e!=rtab.end();++e) { + if ((e->destination == destination)&&(e->gateway.ipsEqual(gateway))) { + if ((device)&&(device[0])) { + if (!strcmp(device,e->device)) { + if (metric == e->metric) + bestEntry = e; + } + } + if (bestEntry == rtab.end()) + bestEntry = e; + } + } + if (bestEntry != rtab.end()) + return *bestEntry; + + return RoutingTable::Entry(); +} + +} // namespace ZeroTier diff --git a/attic/rtbl/LinuxRoutingTable.hpp b/attic/rtbl/LinuxRoutingTable.hpp new file mode 100644 index 000000000..808ec7eab --- /dev/null +++ b/attic/rtbl/LinuxRoutingTable.hpp @@ -0,0 +1,49 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#ifndef ZT_LINUXROUTINGTABLE_HPP +#define ZT_LINUXROUTINGTABLE_HPP + +#include "../node/RoutingTable.hpp" + +namespace ZeroTier { + +/** + * Routing table interface via /proc/net/route, /proc/net/ipv6_route, and /sbin/route command + */ +class LinuxRoutingTable : public RoutingTable +{ +public: + LinuxRoutingTable(); + virtual ~LinuxRoutingTable(); + virtual std::vector get(bool includeLinkLocal = false,bool includeLoopback = false) const; + virtual RoutingTable::Entry set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric); +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/rtbl/RoutingTable.cpp b/attic/rtbl/RoutingTable.cpp new file mode 100644 index 000000000..bae4bea90 --- /dev/null +++ b/attic/rtbl/RoutingTable.cpp @@ -0,0 +1,77 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#include +#include +#include +#include + +#include "Constants.hpp" +#include "RoutingTable.hpp" +#include "Utils.hpp" + +namespace ZeroTier { + +std::string RoutingTable::Entry::toString() const +{ + char tmp[1024]; + Utils::snprintf(tmp,sizeof(tmp),"%s %s %s %d",destination.toString().c_str(),((gateway) ? gateway.toIpString().c_str() : ""),device,metric); + return std::string(tmp); +} + +bool RoutingTable::Entry::operator==(const Entry &re) const +{ + return ((destination == re.destination)&&(gateway == re.gateway)&&(strcmp(device,re.device) == 0)&&(metric == re.metric)); +} + +bool RoutingTable::Entry::operator<(const Entry &re) const +{ + if (destination < re.destination) + return true; + else if (destination == re.destination) { + if (gateway < re.gateway) + return true; + else if (gateway == re.gateway) { + int tmp = (int)::strcmp(device,re.device); + if (tmp < 0) + return true; + else if (tmp == 0) + return (metric < re.metric); + } + } + return false; +} + +RoutingTable::RoutingTable() +{ +} + +RoutingTable::~RoutingTable() +{ +} + +} // namespace ZeroTier diff --git a/attic/rtbl/RoutingTable.hpp b/attic/rtbl/RoutingTable.hpp new file mode 100644 index 000000000..e1c98984b --- /dev/null +++ b/attic/rtbl/RoutingTable.hpp @@ -0,0 +1,122 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#ifndef ZT_ROUTINGTABLE_HPP +#define ZT_ROUTINGTABLE_HPP + +#include +#include + +#include "InetAddress.hpp" +#include "NonCopyable.hpp" + +namespace ZeroTier { + +/** + * Base class for OS routing table interfaces + */ +class RoutingTable : NonCopyable +{ +public: + class Entry + { + public: + Entry() throw() { device[0] = (char)0; } + + /** + * Destination IP and netmask bits (CIDR format) + */ + InetAddress destination; + + /** + * Gateway or null address if direct link-level route, netmask/port part of InetAddress not used + */ + InetAddress gateway; + + /** + * System device index or ID (not included in comparison operators, may not be set on all platforms) + */ + int deviceIndex; + + /** + * Metric or hop count -- higher = lower routing priority + */ + int metric; + + /** + * System device name + */ + char device[128]; + + /** + * @return Human-readable representation of this route + */ + std::string toString() const; + + /** + * @return True if at least one required field is present (object is not null) + */ + inline operator bool() const { return ((destination)||(gateway)||(device[0])); } + + bool operator==(const Entry &re) const; + inline bool operator!=(const Entry &re) const { return (!(*this == re)); } + bool operator<(const Entry &re) const; + inline bool operator>(const Entry &re) const { return (re < *this); } + inline bool operator<=(const Entry &re) const { return (!(re < *this)); } + inline bool operator>=(const Entry &re) const { return (!(*this < re)); } + }; + + RoutingTable(); + virtual ~RoutingTable(); + + /** + * Get routing table + * + * @param includeLinkLocal If true, include link-local address routes (default: false) + * @param includeLoopback Include loopback (default: false) + * @return Sorted routing table entries + */ + virtual std::vector get(bool includeLinkLocal = false,bool includeLoopback = false) const = 0; + + /** + * Add or update a routing table entry + * + * If there is no change, the existing entry is returned. Use a value of -1 + * for metric to delete a route. + * + * @param destination Destination IP/netmask + * @param gateway Gateway IP (netmask/port part unused) or NULL/zero for device-level route + * @param device Device name (can be null for gateway routes) + * @param metric Route metric or hop count (higher = lower priority) or negative to delete + * @return Entry or null entry on failure (or delete) + */ + virtual RoutingTable::Entry set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric) = 0; +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/rtbl/TestRoutingTable.cpp b/attic/rtbl/TestRoutingTable.cpp new file mode 100644 index 000000000..fd61b3140 --- /dev/null +++ b/attic/rtbl/TestRoutingTable.cpp @@ -0,0 +1,50 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#include "TestRoutingTable.hpp" + +namespace ZeroTier { + +TestRoutingTable::TestRoutingTable() +{ +} + +TestRoutingTable::~TestRoutingTable() +{ +} + +std::vector TestRoutingTable::get(bool includeLinkLocal,bool includeLoopback) const +{ + return std::vector(); +} + +RoutingTable::Entry TestRoutingTable::set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric) +{ + return RoutingTable::Entry(); +} + +} // namespace ZeroTier diff --git a/attic/rtbl/TestRoutingTable.hpp b/attic/rtbl/TestRoutingTable.hpp new file mode 100644 index 000000000..69bd3d9fb --- /dev/null +++ b/attic/rtbl/TestRoutingTable.hpp @@ -0,0 +1,50 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#ifndef ZT_TESTROUTINGTABLE_HPP +#define ZT_TESTROUTINGTABLE_HPP + +#include "../node/RoutingTable.hpp" + +namespace ZeroTier { + +/** + * Dummy routing table -- right now this just does nothing + */ +class TestRoutingTable : public RoutingTable +{ +public: + TestRoutingTable(); + virtual ~TestRoutingTable(); + + virtual std::vector get(bool includeLinkLocal = false,bool includeLoopback = false) const; + virtual RoutingTable::Entry set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric); +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/rtbl/WindowsRoutingTable.cpp b/attic/rtbl/WindowsRoutingTable.cpp new file mode 100644 index 000000000..00674620f --- /dev/null +++ b/attic/rtbl/WindowsRoutingTable.cpp @@ -0,0 +1,178 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../node/Constants.hpp" +#include "WindowsRoutingTable.hpp" + +namespace ZeroTier { + +static void _copyInetAddressToSockaddrInet(const InetAddress &a,SOCKADDR_INET &sinet) +{ + memset(&sinet,0,sizeof(sinet)); + if (a.isV4()) { + sinet.Ipv4.sin_addr.S_un.S_addr = *((const uint32_t *)a.rawIpData()); + sinet.Ipv4.sin_family = AF_INET; + sinet.Ipv4.sin_port = htons(a.port()); + } else if (a.isV6()) { + memcpy(sinet.Ipv6.sin6_addr.u.Byte,a.rawIpData(),16); + sinet.Ipv6.sin6_family = AF_INET6; + sinet.Ipv6.sin6_port = htons(a.port()); + } +} + +WindowsRoutingTable::WindowsRoutingTable() +{ +} + +WindowsRoutingTable::~WindowsRoutingTable() +{ +} + +std::vector WindowsRoutingTable::get(bool includeLinkLocal,bool includeLoopback) const +{ + std::vector entries; + PMIB_IPFORWARD_TABLE2 rtbl = NULL; + + if (GetIpForwardTable2(AF_UNSPEC,&rtbl) != NO_ERROR) + return entries; + if (!rtbl) + return entries; + + for(ULONG r=0;rNumEntries;++r) { + RoutingTable::Entry e; + switch(rtbl->Table[r].DestinationPrefix.Prefix.si_family) { + case AF_INET: + e.destination.set(&(rtbl->Table[r].DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr),4,rtbl->Table[r].DestinationPrefix.PrefixLength); + break; + case AF_INET6: + e.destination.set(rtbl->Table[r].DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Byte,16,rtbl->Table[r].DestinationPrefix.PrefixLength); + break; + } + switch(rtbl->Table[r].NextHop.si_family) { + case AF_INET: + e.gateway.set(&(rtbl->Table[r].NextHop.Ipv4.sin_addr.S_un.S_addr),4,0); + break; + case AF_INET6: + e.gateway.set(rtbl->Table[r].NextHop.Ipv6.sin6_addr.u.Byte,16,0); + break; + } + e.deviceIndex = (int)rtbl->Table[r].InterfaceIndex; + e.metric = (int)rtbl->Table[r].Metric; + ConvertInterfaceLuidToNameA(&(rtbl->Table[r].InterfaceLuid),e.device,sizeof(e.device)); + if ((e.destination)&&((includeLinkLocal)||(!e.destination.isLinkLocal()))&&((includeLoopback)||((!e.destination.isLoopback())&&(!e.gateway.isLoopback())))) + entries.push_back(e); + } + + FreeMibTable(rtbl); + std::sort(entries.begin(),entries.end()); + return entries; +} + +RoutingTable::Entry WindowsRoutingTable::set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric) +{ + NET_LUID luid; + luid.Value = 0; + if (ConvertInterfaceNameToLuidA(device,&luid) != NO_ERROR) + return RoutingTable::Entry(); + + bool needCreate = true; + PMIB_IPFORWARD_TABLE2 rtbl = NULL; + if (GetIpForwardTable2(AF_UNSPEC,&rtbl) != NO_ERROR) + return RoutingTable::Entry(); + if (!rtbl) + return RoutingTable::Entry(); + for(ULONG r=0;rNumEntries;++r) { + if (rtbl->Table[r].InterfaceLuid.Value == luid.Value) { + InetAddress rdest; + switch(rtbl->Table[r].DestinationPrefix.Prefix.si_family) { + case AF_INET: + rdest.set(&(rtbl->Table[r].DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr),4,rtbl->Table[r].DestinationPrefix.PrefixLength); + break; + case AF_INET6: + rdest.set(rtbl->Table[r].DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Byte,16,rtbl->Table[r].DestinationPrefix.PrefixLength); + break; + } + if (rdest == destination) { + if (metric >= 0) { + _copyInetAddressToSockaddrInet(gateway,rtbl->Table[r].NextHop); + rtbl->Table[r].Metric = metric; + SetIpForwardEntry2(&(rtbl->Table[r])); + needCreate = false; + } else { + DeleteIpForwardEntry2(&(rtbl->Table[r])); + FreeMibTable(rtbl); + return RoutingTable::Entry(); + } + } + } + } + FreeMibTable(rtbl); + + if ((metric >= 0)&&(needCreate)) { + MIB_IPFORWARD_ROW2 nr; + InitializeIpForwardEntry(&nr); + nr.InterfaceLuid.Value = luid.Value; + _copyInetAddressToSockaddrInet(destination,nr.DestinationPrefix.Prefix); + nr.DestinationPrefix.PrefixLength = destination.netmaskBits(); + _copyInetAddressToSockaddrInet(gateway,nr.NextHop); + nr.Metric = metric; + nr.Protocol = MIB_IPPROTO_NETMGMT; + DWORD result = CreateIpForwardEntry2(&nr); + if (result != NO_ERROR) + return RoutingTable::Entry(); + } + + std::vector rtab(get(true,true)); + std::vector::iterator bestEntry(rtab.end()); + for(std::vector::iterator e(rtab.begin());e!=rtab.end();++e) { + if ((e->destination == destination)&&(e->gateway.ipsEqual(gateway))) { + if ((device)&&(device[0])) { + if (!strcmp(device,e->device)) { + if (metric == e->metric) + bestEntry = e; + } + } + if (bestEntry == rtab.end()) + bestEntry = e; + } + } + if (bestEntry != rtab.end()) + return *bestEntry; + return RoutingTable::Entry(); +} + +} // namespace ZeroTier diff --git a/attic/rtbl/WindowsRoutingTable.hpp b/attic/rtbl/WindowsRoutingTable.hpp new file mode 100644 index 000000000..491c3424d --- /dev/null +++ b/attic/rtbl/WindowsRoutingTable.hpp @@ -0,0 +1,49 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#ifndef ZT_WINDOWSROUTINGTABLE_HPP +#define ZT_WINDOWSROUTINGTABLE_HPP + +#include "../node/RoutingTable.hpp" + +namespace ZeroTier { + +/** + * Interface to Microsoft Windows (Vista or newer) routing table + */ +class WindowsRoutingTable : public RoutingTable +{ +public: + WindowsRoutingTable(); + virtual ~WindowsRoutingTable(); + virtual std::vector get(bool includeLinkLocal = false,bool includeLoopback = false) const; + virtual RoutingTable::Entry set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric); +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/world/README.md b/attic/world/README.md deleted file mode 100644 index dda4920ae..000000000 --- a/attic/world/README.md +++ /dev/null @@ -1,7 +0,0 @@ -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 deleted file mode 100755 index f3bcfabc9..000000000 --- a/attic/world/build.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/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 deleted file mode 100644 index ed2c499a0..000000000 --- a/attic/world/mkworld.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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))) { - ECC::Pair np(ECC::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; - } - ECC::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); - ECC::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 deleted file mode 100644 index 88049ccdc..000000000 Binary files a/attic/world/world.bin and /dev/null differ diff --git a/attic/world/world.c b/attic/world/world.c deleted file mode 100644 index ecf30e6f0..000000000 --- a/attic/world/world.c +++ /dev/null @@ -1,3 +0,0 @@ - -#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/ci/Dockerfile-build.deb b/ci/Dockerfile-build.deb deleted file mode 100644 index 09ed717f8..000000000 --- a/ci/Dockerfile-build.deb +++ /dev/null @@ -1,13 +0,0 @@ -ARG ZT_NAME -FROM 084037375216.dkr.ecr.us-east-2.amazonaws.com/${ZT_NAME}-builder as builder -WORKDIR /work/build -COPY . . -RUN pwd -RUN ls -la . -RUN make clean -RUN make debian -RUN ls -ls /work - -FROM scratch AS export -ARG ZT_NAME -COPY --from=builder /work/*.deb ./${ZT_NAME}/ diff --git a/ci/Dockerfile-build.el6 b/ci/Dockerfile-build.el6 deleted file mode 100644 index c5848c984..000000000 --- a/ci/Dockerfile-build.el6 +++ /dev/null @@ -1,36 +0,0 @@ -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-build.rpm b/ci/Dockerfile-build.rpm deleted file mode 100644 index cab00a06d..000000000 --- a/ci/Dockerfile-build.rpm +++ /dev/null @@ -1,9 +0,0 @@ -ARG ZT_NAME -FROM 084037375216.dkr.ecr.us-east-2.amazonaws.com/${ZT_NAME}-builder as builder -WORKDIR /root/rpmbuild/BUILD -COPY . . -RUN make redhat - -FROM scratch AS export -ARG ZT_NAME -COPY --from=builder /root/rpmbuild/RPMS/*/*.rpm ./${ZT_NAME}/ diff --git a/ci/Dockerfile-test.deb b/ci/Dockerfile-test.deb deleted file mode 100644 index 7c709a863..000000000 --- a/ci/Dockerfile-test.deb +++ /dev/null @@ -1,13 +0,0 @@ -ARG ZT_NAME -FROM 084037375216.dkr.ecr.us-east-2.amazonaws.com/${ZT_NAME}-tester -ARG BASEURL -ARG VERSION -ARG DEB_ARCH -ARG ZT_NAME -ARG DISTRO -RUN curl -s http://${BASEURL}/key.gpg -o /etc/apt/trusted.gpg.d/zerotier.gpg -RUN echo "deb [arch=${DEB_ARCH} signed-by=/etc/apt/trusted.gpg.d/zerotier.gpg] http://${BASEURL}/${DISTRO} ${ZT_NAME} main" > /etc/apt/sources.list.d/zerotier.list -RUN apt-get -qq update -RUN apt-get -qq install zerotier-one=${VERSION} - -RUN ldd $(which zerotier-cli) diff --git a/ci/Dockerfile-test.el6 b/ci/Dockerfile-test.el6 deleted file mode 100644 index 499667313..000000000 --- a/ci/Dockerfile-test.el6 +++ /dev/null @@ -1,4 +0,0 @@ -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/Dockerfile-test.rpm b/ci/Dockerfile-test.rpm deleted file mode 100644 index 6a98607b9..000000000 --- a/ci/Dockerfile-test.rpm +++ /dev/null @@ -1,17 +0,0 @@ -ARG ZT_NAME -FROM 084037375216.dkr.ecr.us-east-2.amazonaws.com/${ZT_NAME}-tester -ARG BASEURL -ARG VERSION -ARG DEB_ARCH -ARG ZT_NAME -ARG DISTRO -ARG DNF_ARCH -RUN curl -s http://${BASEURL}/key.asc -o /etc/pki/rpm-gpg/RPM-GPG-KEY-zerotier -RUN rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-zerotier -RUN rpm -q gpg-pubkey --qf '%{NAME}-%{VERSION}-%{RELEASE}\t%{SUMMARY}\n' -RUN printf "[zerotier]\nname=zerotier\nbaseurl=http://${BASEURL}/${DISTRO}/${ZT_NAME}/$basearch/\nenabled=1\ngpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-zerotier\n" > /etc/yum.repos.d/zerotier.repo - -# RUN yum -v repolist -RUN setarch ${DNF_ARCH} yum -y install zerotier-one-${VERSION} -RUN file $(which zerotier-cli) -RUN ldd $(which zerotier-cli) diff --git a/ci/scripts/build.sh b/ci/scripts/build.sh deleted file mode 100755 index a4b8ca94b..000000000 --- a/ci/scripts/build.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/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 deleted file mode 100755 index 43c35762b..000000000 --- a/ci/scripts/lib.sh +++ /dev/null @@ -1,63 +0,0 @@ - -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 deleted file mode 100755 index d37cb0638..000000000 --- a/ci/scripts/munge_debian_changelog.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/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 deleted file mode 100755 index 289df1ed4..000000000 --- a/ci/scripts/munge_rpm_spec.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/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 deleted file mode 100755 index fa1e2468a..000000000 --- a/ci/scripts/publish.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/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 deleted file mode 100755 index 931e9bb91..000000000 --- a/ci/scripts/test.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/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/CV1.cpp b/controller/CV1.cpp deleted file mode 100644 index 51f78a6be..000000000 --- a/controller/CV1.cpp +++ /dev/null @@ -1,2110 +0,0 @@ -/* - * 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 "CV1.hpp" - -#ifdef ZT_CONTROLLER_USE_LIBPQ - -#include "../node/Constants.hpp" -#include "../node/SHA512.hpp" -#include "../version.h" -#include "CtlUtil.hpp" -#include "EmbeddedNetworkController.hpp" -#include "Redis.hpp" -#include "opentelemetry/trace/provider.h" - -#include -#include -#include -#include -#include -#include - -// #define REDIS_TRACE 1 - -using json = nlohmann::json; - -namespace { - -static const int DB_MINIMUM_VERSION = 38; - -} // anonymous namespace - -using namespace ZeroTier; - -using Attrs = std::vector >; -using Item = std::pair; -using ItemStream = std::vector; - -CV1::CV1(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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::CV1"); - auto scope = tracer->WithActiveSpan(span); - - 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) { - auto innerspan = tracer->StartSpan("cv1::CV1::configureRedis"); - auto innerscope = tracer->WithActiveSpan(innerspan); - - 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) { - innerspan->SetAttribute("cluster_mode", "true"); - fprintf(stderr, "Using Redis in Cluster Mode\n"); - _cluster = std::make_shared(opts, poolOpts); - } - else { - innerspan->SetAttribute("cluster_mode", "false"); - 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(&CV1::heartbeat, this); - _membersDbWatcher = std::thread(&CV1::membersDbWatcher, this); - _networksDbWatcher = std::thread(&CV1::networksDbWatcher, this); - for (int i = 0; i < ZT_CENTRAL_CONTROLLER_COMMIT_THREADS; ++i) { - _commitThread[i] = std::thread(&CV1::commitThread, this); - } - _onlineNotificationThread = std::thread(&CV1::onlineNotificationThread, this); - - configureSmee(); -} - -CV1::~CV1() -{ - 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 CV1::configureSmee() -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::configureSmee"); - auto scope = tracer->WithActiveSpan(span); - - 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 CV1::waitForReady() -{ - while (_ready < 2) { - _readyLock.lock(); - _readyLock.unlock(); - } - return true; -} - -bool CV1::isReady() -{ - return ((_ready == 2) && (_connected)); -} - -bool CV1::save(nlohmann::json& record, bool notifyListeners) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::save"); - auto scope = tracer->WithActiveSpan(span); - - 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 CV1::eraseNetwork(const uint64_t networkId) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::eraseNetwork"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - - 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 CV1::eraseMember(const uint64_t networkId, const uint64_t memberId) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::eraseMember"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - char memberIdStr[11]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - span->SetAttribute("member_id", Utils::hex10(memberId, memberIdStr)); - - 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 CV1::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::nodeIsOnline"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - char memberIdStr[11]; - char ipStr[INET6_ADDRSTRLEN]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - span->SetAttribute("member_id", Utils::hex10(memberId, memberIdStr)); - span->SetAttribute("physical_address", physicalAddress.toString(ipStr)); - span->SetAttribute("os_arch", osArch); - - std::lock_guard l(_lastOnline_l); - NodeOnlineRecord& i = _lastOnline[std::pair(networkId, memberId)]; - i.lastSeen = OSUtils::now(); - if (physicalAddress) { - i.physicalAddress = physicalAddress; - } - i.osArch = std::string(osArch); -} - -void CV1::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress) -{ - this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown"); -} - -AuthInfo CV1::getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::getSSOAuthInfo"); - auto scope = tracer->WithActiveSpan(span); - - 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) { - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - fprintf(stderr, "ERROR: Error updating member on load for network %s: %s\n", networkId.c_str(), e.what()); - } - - return info; // std::string(authenticationURL); -} - -void CV1::initializeNetworks() -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::initializeNetworks"); - auto scope = tracer->WithActiveSpan(span); - - 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) { - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - 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) { - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - fprintf(stderr, "ERROR: Error initializing networks: %s\n", e.what()); - std::this_thread::sleep_for(std::chrono::milliseconds(5000)); - exit(-1); - } -} - -void CV1::initializeMembers() -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::initializeMembers"); - auto scope = tracer->WithActiveSpan(span); - - 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) { - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - fprintf(stderr, "ERROR: Error initializing members (redis): %s\n", e.what()); - exit(-1); - } - catch (std::exception& e) { - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - fprintf(stderr, "ERROR: Error initializing member: %s-%s %s\n", networkId.c_str(), memberId.c_str(), e.what()); - exit(-1); - } -} - -void CV1::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) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::heartbeat"); - auto scope = tracer->WithActiveSpan(span); - - // 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()); - span->End(); - 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()); - } - - span->End(); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - } - fprintf(stderr, "Exited heartbeat thread\n"); -} - -void CV1::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 CV1::_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 CV1::_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) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::_membersWatcher_Redis"); - auto scope = tracer->WithActiveSpan(span); - - 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) { - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - fprintf(stderr, "Error in Redis members watcher: %s\n", e.what()); - } - } - fprintf(stderr, "membersWatcher ended\n"); -} - -void CV1::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 CV1::_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) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::_networksWatcher_Postgres"); - auto scope = tracer->WithActiveSpan(span); - - c->c->await_notification(5, 0); - } -} - -void CV1::_networksWatcher_Redis() -{ - char buf[11] = { 0 }; - std::string key = "network-stream:{" + std::string(_myAddress.toString(buf)) + "}"; - std::string lastID = "0"; - while (_run == 1) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::_networksWatcher_Redis"); - auto scope = tracer->WithActiveSpan(span); - - 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) { - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - fprintf(stderr, "Error in Redis networks watcher: %s\n", e.what()); - } - } - fprintf(stderr, "networksWatcher ended\n"); -} - -void CV1::commitThread() -{ - fprintf(stderr, "%s: commitThread start\n", _myAddressStr.c_str()); - std::pair qitem; - while (_commitQueue.get(qitem) && (_run == 1)) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::commitThread"); - auto scope = tracer->WithActiveSpan(span); - - // 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") { - auto mspan = tracer->StartSpan("cv1::commitThread::member"); - auto mscope = tracer->WithActiveSpan(mspan); - - // 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()); - mspan->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - } - } - else if (objtype == "network") { - auto nspan = tracer->StartSpan("cv1::commitThread::network"); - auto nscope = tracer->WithActiveSpan(nspan); - - 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) { - nspan->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - 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) { - nspan->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - fprintf(stderr, "ERROR: Error adding network to Redis: %s\n", e.what()); - } - } - } - else if (objtype == "_delete_network") { - auto dspan = tracer->StartSpan("cv1::commitThread::_delete_network"); - auto dscope = tracer->WithActiveSpan(dspan); - - // 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) { - dspan->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - 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) { - dspan->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - fprintf(stderr, "ERROR: Error adding network to Redis: %s\n", e.what()); - } - } - } - else if (objtype == "_delete_member") { - auto mspan = tracer->StartSpan("cv1::commitThread::_delete_member"); - auto mscope = tracer->WithActiveSpan(mspan); - - // 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) { - mspan->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - 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) { - mspan->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - 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) { - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - 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 CV1::notifyNewMember(const std::string& networkID, const std::string& memberID) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::notifyNewMember"); - auto scope = tracer->WithActiveSpan(span); - - smeeclient::smee_client_notify_network_joined(_smee, networkID.c_str(), memberID.c_str()); -} - -void CV1::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 CV1::onlineNotification_Postgres() -{ - _connected = 1; - - nlohmann::json jtmp1, jtmp2; - while (_run == 1) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::onlineNotification_Postgres"); - auto scope = tracer->WithActiveSpan(span); - - auto c = _pool->borrow(); - auto c2 = _pool->borrow(); - try { - fprintf(stderr, "%s onlineNotification_Postgres\n", _myAddressStr.c_str()); - std::unordered_map, NodeOnlineRecord, _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.lastSeen; - std::string ipAddr = i->second.physicalAddress.toIpString(ipTmp); - std::string timestamp = std::to_string(ts); - std::string osArch = i->second.osArch; - std::vector osArchSplit = split(osArch, '/'); - std::string os = "unknown"; - std::string arch = "unknown"; - if (osArchSplit.size() == 2) { - os = osArchSplit[0]; - arch = osArchSplit[1]; - } - - std::stringstream memberUpdate; - memberUpdate << "INSERT INTO ztc_member_status (network_id, member_id, address, last_updated, os, arch) VALUES " - << "('" << networkId << "', '" << memberId << "', "; - if (ipAddr.empty()) { - memberUpdate << "NULL, "; - } - else { - memberUpdate << "'" << ipAddr << "', "; - } - memberUpdate << "TO_TIMESTAMP(" << timestamp << "::double precision/1000), " - << "'" << os << "', " - << "'" << arch << "'" - << ") " - << " ON CONFLICT (network_id, member_id) DO UPDATE SET address = EXCLUDED.address, last_updated = EXCLUDED.last_updated, " - << "os = EXCLUDED.os, arch = EXCLUDED.arch"; - - 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)); - - span->End(); - - 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 CV1::onlineNotification_Redis() -{ - _connected = 1; - - char buf[11] = { 0 }; - std::string controllerId = std::string(_myAddress.toString(buf)); - - while (_run == 1) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::onlineNotification_Redis"); - auto scope = tracer->WithActiveSpan(span); - - fprintf(stderr, "onlineNotification tick\n"); - auto start = std::chrono::high_resolution_clock::now(); - uint64_t count = 0; - - std::unordered_map, NodeOnlineRecord, _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); - span->End(); - - std::this_thread::sleep_for(std::chrono::seconds(5)); - } -} - -uint64_t CV1::_doRedisUpdate(sw::redis::Transaction& tx, std::string& controllerId, std::unordered_map, NodeOnlineRecord, _PairHasher>& lastOnline) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv1"); - auto span = tracer->StartSpan("cv1::_doRedisUpdate"); - auto scope = tracer->WithActiveSpan(span); - - 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.lastSeen; - std::string ipAddr = i->second.physicalAddress.toIpString(ipTmp); - std::string timestamp = std::to_string(ts); - std::string osArch = i->second.osArch; - std::vector osArchSplit = split(osArch, '/'); - std::string os = "unknown"; - std::string arch = "unknown"; - if (osArchSplit.size() == 2) { - os = osArchSplit[0]; - arch = osArchSplit[1]; - } - - std::unordered_map record = { { "id", memberId }, { "address", ipAddr }, { "last_updated", std::to_string(ts) }, { "os", os }, { "arch", arch } }; - 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/CV1.hpp b/controller/CV1.hpp deleted file mode 100644 index b1a362798..000000000 --- a/controller/CV1.hpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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_CV1_HPP -#define ZT_CONTROLLER_CV1_HPP - -#define ZT_CENTRAL_CONTROLLER_COMMIT_THREADS 4 - -#include "../node/Metrics.hpp" -#include "ConnectionPool.hpp" -#include "PostgreSQL.hpp" - -#include -#include -#include - -namespace smeeclient { -struct SmeeClient; -} - -namespace ZeroTier { - -struct RedisConfig; - -/** - * 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 CV1 : public DB { - friend class MemberNotificationReceiver; - friend class NetworkNotificationReceiver; - - public: - CV1(const Identity& myId, const char* path, int listenPort, RedisConfig* rc); - virtual ~CV1(); - - 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 void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch); - virtual AuthInfo getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL); - - virtual bool ready() - { - return _ready == 2; - } - - 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, NodeOnlineRecord, _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 > _commitQueue; - - std::thread _heartbeatThread; - std::thread _membersDbWatcher; - std::thread _networksDbWatcher; - std::thread _commitThread[ZT_CENTRAL_CONTROLLER_COMMIT_THREADS]; - std::thread _onlineNotificationThread; - - std::unordered_map, NodeOnlineRecord, _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_CV1_HPP - -#endif // ZT_CONTROLLER_USE_LIBPQ diff --git a/controller/CV2.cpp b/controller/CV2.cpp deleted file mode 100644 index db9effb3c..000000000 --- a/controller/CV2.cpp +++ /dev/null @@ -1,1244 +0,0 @@ -/* - * Copyright (c)2025 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 "CV2.hpp" - -#ifdef ZT_CONTROLLER_USE_LIBPQ - -#include "../node/Constants.hpp" -#include "../node/SHA512.hpp" -#include "../version.h" -#include "CtlUtil.hpp" -#include "EmbeddedNetworkController.hpp" -#include "opentelemetry/trace/provider.h" - -#include -#include -#include -#include -#include - -using json = nlohmann::json; - -namespace { - -} - -using namespace ZeroTier; - -CV2::CV2(const Identity& myId, const char* path, int listenPort) : DB(), _pool(), _myId(myId), _myAddress(myId.address()), _ready(0), _connected(1), _run(1), _waitNoticePrinted(false), _listenPort(listenPort) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv2"); - auto span = tracer->StartSpan("cv2::CV2"); - auto scope = tracer->WithActiveSpan(span); - - fprintf(stderr, "CV2::CV2\n"); - 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)); - } - - _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(&CV2::heartbeat, this); - _membersDbWatcher = std::thread(&CV2::membersDbWatcher, this); - _networksDbWatcher = std::thread(&CV2::networksDbWatcher, this); - for (int i = 0; i < ZT_CENTRAL_CONTROLLER_COMMIT_THREADS; ++i) { - _commitThread[i] = std::thread(&CV2::commitThread, this); - } - _onlineNotificationThread = std::thread(&CV2::onlineNotificationThread, this); -} - -CV2::~CV2() -{ - _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(); -} - -bool CV2::waitForReady() -{ - while (_ready < 2) { - _readyLock.lock(); - _readyLock.unlock(); - } - return true; -} - -bool CV2::isReady() -{ - return (_ready == 2) && _connected; -} - -void CV2::_memberChanged(nlohmann::json& old, nlohmann::json& memberConfig, bool notifyListeners) -{ - DB::_memberChanged(old, memberConfig, notifyListeners); -} - -void CV2::_networkChanged(nlohmann::json& old, nlohmann::json& networkConfig, bool notifyListeners) -{ - DB::_networkChanged(old, networkConfig, notifyListeners); -} - -bool CV2::save(nlohmann::json& record, bool notifyListeners) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv2"); - auto span = tracer->StartSpan("cv2::save"); - auto scope = tracer->WithActiveSpan(span); - - 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") { - auto nspan = tracer->StartSpan("cv2::save::network"); - auto nscope = tracer->WithActiveSpan(nspan); - - // 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") { - auto mspan = tracer->StartSpan("cv2::save::member"); - auto mscope = tracer->WithActiveSpan(mspan); - - 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 CV2::eraseNetwork(const uint64_t networkId) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv2"); - auto span = tracer->StartSpan("cv2::eraseNetwork"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - std::string nwid = Utils::hex(networkId, networkIdStr); - span->SetAttribute("network_id", nwid); - - fprintf(stderr, "CV2::eraseNetwork\n"); - waitForReady(); - std::pair tmp; - tmp.first["id"] = nwid; - tmp.first["objtype"] = "_delete_network"; - tmp.second = true; - _commitQueue.post(tmp); - // nlohmann::json nullJson; - //_networkChanged(tmp.first, nullJson, isReady()); -} - -void CV2::eraseMember(const uint64_t networkId, const uint64_t memberId) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv2"); - auto span = tracer->StartSpan("cv2::eraseMember"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - char memberIdStr[11]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - span->SetAttribute("member_id", Utils::hex10(memberId, memberIdStr)); - - 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, isReady()); -} - -void CV2::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv2"); - auto span = tracer->StartSpan("cv2::nodeIsOnline"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - char memberIdStr[11]; - char ipAddressStr[INET6_ADDRSTRLEN]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - span->SetAttribute("member_id", Utils::hex10(memberId, memberIdStr)); - span->SetAttribute("physical_address", ipAddressStr); - span->SetAttribute("os_arch", osArch); - - std::lock_guard l(_lastOnline_l); - NodeOnlineRecord& i = _lastOnline[std::pair(networkId, memberId)]; - i.lastSeen = OSUtils::now(); - if (physicalAddress) { - i.physicalAddress = physicalAddress; - } - i.osArch = std::string(osArch); -} - -void CV2::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress) -{ - this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown"); -} - -AuthInfo CV2::getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL) -{ - // TODO: Redo this for CV2 - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv2"); - auto span = tracer->StartSpan("cv2::getSSOAuthInfo"); - auto scope = tracer->WithActiveSpan(span); - - 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()); - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - } - - return info; // std::string(authenticationURL); -} - -void CV2::initializeNetworks() -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv2"); - auto span = tracer->StartSpan("cv2::initializeNetworks"); - auto scope = tracer->WithActiveSpan(span); - - fprintf(stderr, "Initializing networks...\n"); - - try { - char qbuf[2048]; - sprintf( - qbuf, - "SELECT id, name, configuration , (EXTRACT(EPOCH FROM creation_time AT TIME ZONE 'UTC')*1000)::bigint, " - "(EXTRACT(EPOCH FROM last_modified AT TIME ZONE 'UTC')*1000)::bigint, revision " - "FROM networks_ctl WHERE controller_id = '%s'", - _myAddressStr.c_str()); - - auto c = _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 // name - , - std::string // configuration - , - std::optional // creation_time - , - std::optional // last_modified - , - std::optional // revision - > - row; - uint64_t count = 0; - 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::string name = std::get<1>(row).value_or(""); - json cfgtmp = json::parse(std::get<2>(row)); - std::optional created_at = std::get<3>(row); - std::optional last_modified = std::get<4>(row); - std::optional revision = std::get<5>(row); - - config["id"] = nwid; - config["name"] = name; - config["creationTime"] = created_at.value_or(0); - config["lastModified"] = last_modified.value_or(0); - config["revision"] = revision.value_or(0); - config["capabilities"] = cfgtmp["capabilities"].is_array() ? cfgtmp["capabilities"] : json::array(); - config["enableBroadcast"] = cfgtmp["enableBroadcast"].is_boolean() ? cfgtmp["enableBroadcast"].get() : false; - config["mtu"] = cfgtmp["mtu"].is_number() ? cfgtmp["mtu"].get() : 2800; - config["multicastLimit"] = cfgtmp["multicastLimit"].is_number() ? cfgtmp["multicastLimit"].get() : 64; - config["private"] = cfgtmp["private"].is_boolean() ? cfgtmp["private"].get() : true; - config["remoteTraceLevel"] = cfgtmp["remoteTraceLevel"].is_number() ? cfgtmp["remoteTraceLevel"].get() : 0; - config["remoteTraceTarget"] = cfgtmp["remoteTraceTarget"].is_string() ? cfgtmp["remoteTraceTarget"].get() : ""; - config["revision"] = revision.value_or(0); - config["rules"] = cfgtmp["rules"].is_array() ? cfgtmp["rules"] : json::array(); - config["tags"] = cfgtmp["tags"].is_array() ? cfgtmp["tags"] : json::array(); - if (cfgtmp["v4AssignMode"].is_object()) { - config["v4AssignMode"] = cfgtmp["v4AssignMode"]; - } - else { - config["v4AssignMode"] = json::object(); - config["v4AssignMode"]["zt"] = true; - } - if (cfgtmp["v6AssignMode"].is_object()) { - config["v6AssignMode"] = cfgtmp["v6AssignMode"]; - } - else { - config["v6AssignMode"] = json::object(); - config["v6AssignMode"]["zt"] = true; - config["v6AssignMode"]["6plane"] = true; - config["v6AssignMode"]["rfc4193"] = false; - } - config["ssoEnabled"] = cfgtmp["ssoEnabled"].is_boolean() ? cfgtmp["ssoEnabled"].get() : false; - config["objtype"] = "network"; - config["routes"] = cfgtmp["routes"].is_array() ? cfgtmp["routes"] : json::array(); - config["clientId"] = cfgtmp["clientId"].is_string() ? cfgtmp["clientId"].get() : ""; - config["authorizationEndpoint"] = cfgtmp["authorizationEndpoint"].is_string() ? cfgtmp["authorizationEndpoint"].get() : nullptr; - config["provider"] = cfgtmp["ssoProvider"].is_string() ? cfgtmp["ssoProvider"].get() : ""; - if (! cfgtmp["dns"].is_object()) { - cfgtmp["dns"] = json::object(); - cfgtmp["dns"]["domain"] = ""; - cfgtmp["dns"]["servers"] = json::array(); - } - else { - config["dns"] = cfgtmp["dns"]; - } - config["ipAssignmentPools"] = cfgtmp["ipAssignmentPools"].is_array() ? cfgtmp["ipAssignmentPools"] : json::array(); - - 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 %lu us per network\n", (total / count)); - } - } - - w.commit(); - _pool->unborrow(c); - 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 (std::exception& e) { - fprintf(stderr, "ERROR: Error initializing networks: %s\n", e.what()); - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - std::this_thread::sleep_for(std::chrono::milliseconds(5000)); - exit(-1); - } -} - -void CV2::initializeMembers() -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv2"); - auto span = tracer->StartSpan("cv2::initializeMembers"); - auto scope = tracer->WithActiveSpan(span); - - std::string memberId; - std::string networkId; - try { - char qbuf[2048]; - sprintf( - qbuf, - "SELECT nm.device_id, nm.network_id, nm.authorized, nm.active_bridge, nm.ip_assignments, nm.no_auto_assign_ips, " - "nm.sso_exempt, (EXTRACT(EPOCH FROM nm.authentication_expiry_time AT TIME ZONE 'UTC')*1000)::bigint, " - "(EXTRACT(EPOCH FROM nm.creation_time AT TIME ZONE 'UTC')*1000)::bigint, nm.identity, " - "(EXTRACT(EPOCH FROM nm.last_authorized_time AT TIME ZONE 'UTC')*1000)::bigint, " - "(EXTRACT(EPOCH FROM nm.last_deauthorized_time AT TIME ZONE 'UTC')*1000)::bigint, " - "nm.remote_trace_level, nm.remote_trace_target, nm.revision, nm.capabilities, nm.tags " - "FROM network_memberships_ctl nm " - "INNER JOIN networks_ctl n " - " ON nm.network_id = n.id " - "WHERE n.controller_id = '%s'", - _myAddressStr.c_str()); - - auto c = _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 // device ID - , - std::string // network ID - , - bool // authorized - , - std::optional // active_bridge - , - std::optional // ip_assignments - , - std::optional // no_auto_assign_ips - , - std::optional // sso_exempt - , - std::optional // authentication_expiry_time - , - std::optional // creation_time - , - std::optional // identity - , - std::optional // last_authorized_time - , - std::optional // last_deauthorized_time - , - std::optional // remote_trace_level - , - std::optional // remote_trace_target - , - std::optional // revision - , - std::optional // capabilities - , - std::optional // tags - > - row; - - uint64_t count = 0; - 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); - bool authorized = std::get<2>(row); - std::optional active_bridge = std::get<3>(row); - std::string ip_assignments = std::get<4>(row).value_or(""); - std::optional no_auto_assign_ips = std::get<5>(row); - std::optional sso_exempt = std::get<6>(row); - std::optional authentication_expiry_time = std::get<7>(row); - std::optional creation_time = std::get<8>(row); - std::optional identity = std::get<9>(row); - std::optional last_authorized_time = std::get<10>(row); - std::optional last_deauthorized_time = std::get<11>(row); - std::optional remote_trace_level = std::get<12>(row); - std::optional remote_trace_target = std::get<13>(row); - std::optional revision = std::get<14>(row); - std::optional capabilities = std::get<15>(row); - std::optional tags = std::get<16>(row); - - config["objtype"] = "member"; - config["id"] = memberId; - config["address"] = identity.value_or(""); - config["nwid"] = networkId; - config["authorized"] = authorized; - config["activeBridge"] = active_bridge.value_or(false); - config["ipAssignments"] = json::array(); - if (ip_assignments != "{}") { - std::string tmp = ip_assignments.substr(1, ip_assignments.length() - 2); - std::vector addrs = split(tmp, ','); - for (auto it = addrs.begin(); it != addrs.end(); ++it) { - config["ipAssignments"].push_back(*it); - } - } - config["capabilities"] = json::parse(capabilities.value_or("[]")); - config["creationTime"] = creation_time.value_or(0); - config["lastAuthorizedTime"] = last_authorized_time.value_or(0); - config["lastDeauthorizedTime"] = last_deauthorized_time.value_or(0); - config["noAutoAssignIPs"] = no_auto_assign_ips.value_or(false); - config["remoteTraceLevel"] = remote_trace_level.value_or(0); - config["remoteTraceTarget"] = remote_trace_target.value_or(nullptr); - config["revision"] = revision.value_or(0); - config["ssoExempt"] = sso_exempt.value_or(false); - config["authenticationExpiryTime"] = authentication_expiry_time.value_or(0); - config["tags"] = json::parse(tags.value_or("[]")); - - 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 %lu us per member\n", (total / count)); - } - } - if (count > 0) { - fprintf(stderr, "Took %lu us per member to load\n", (total / count)); - } - - stream.complete(); - w.commit(); - _pool->unborrow(c); - 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, "member init done\n"); - } - catch (std::exception& e) { - fprintf(stderr, "ERROR: Error initializing member: %s-%s %s\n", networkId.c_str(), memberId.c_str(), e.what()); - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - exit(-1); - } -} - -void CV2::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) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv2"); - auto span = tracer->StartSpan("cv2::heartbeat"); - auto scope = tracer->WithActiveSpan(span); - - 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 version = major + "." + minor + "." + rev; - std::string versionStr = "v" + version; - - try { - pqxx::work w { *c->c }; - w.exec_params0( - "INSERT INTO controllers_ctl (id, hostname, last_heartbeat, public_identity, version) VALUES " - "($1, $2, TO_TIMESTAMP($3::double precision/1000), $4, $5) " - "ON CONFLICT (id) DO UPDATE SET hostname = EXCLUDED.hostname, last_heartbeat = EXCLUDED.last_heartbeat, " - "public_identity = EXCLUDED.public_identity, version = EXCLUDED.version", - controllerId, - hostname, - ts, - publicIdentity, - versionStr); - w.commit(); - } - catch (std::exception& e) { - fprintf(stderr, "ERROR: Error in heartbeat: %s\n", e.what()); - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - continue; - } - catch (...) { - fprintf(stderr, "ERROR: Unknown error in heartbeat\n"); - span->SetStatus(opentelemetry::trace::StatusCode::kError, "Unknown error in heartbeat"); - continue; - } - } - - _pool->unborrow(c); - span->End(); - - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - fprintf(stderr, "Exited heartbeat thread\n"); -} - -void CV2::membersDbWatcher() -{ - 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); - - fprintf(stderr, "Exited membersDbWatcher\n"); -} - -void CV2::networksDbWatcher() -{ - 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); - } - - _pool->unborrow(c); - fprintf(stderr, "Exited networksDbWatcher\n"); -} - -void CV2::commitThread() -{ - fprintf(stderr, "%s: commitThread start\n", _myAddressStr.c_str()); - std::pair qitem; - while (_commitQueue.get(qitem) && (_run == 1)) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv2"); - auto span = tracer->StartSpan("cv2::commitThread"); - auto scope = tracer->WithActiveSpan(span); - - // 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") { - auto mspan = tracer->StartSpan("cv2::commitThread::member"); - auto mscope = tracer->WithActiveSpan(span); - - // 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 networks 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; - } - - // only needed for hooks, and no hooks for now - // pqxx::row mrow = w.exec_params1("SELECT COUNT(id) FROM device_networks WHERE device_id = $1 AND network_id = $2", memberId, networkId); - // int membercount = mrow[0].as(); - // bool isNewMember = (membercount == 0); - - pqxx::result res = w.exec_params0( - "INSERT INTO network_memberships_ctl (device_id, network_id, authorized, active_bridge, ip_assignments, " - "no_auto_assign_ips, sso_exempt, authentication_expiry_time, capabilities, creation_time, " - "identity, last_authorized_time, last_deauthorized_time, " - "remote_trace_level, remote_trace_target, revision, tags, version_major, version_minor, " - "version_revision, version_protocol) " - "VALUES ($1, $2, $3, $4, $5, $6, $7, TO_TIMESTAMP($8::double precision/1000), $9, " - "TO_TIMESTAMP($10::double precision/1000), $11, TO_TIMESTAMP($12::double precision/1000), " - "TO_TIMESTAMP($13::double precision/1000), $14, $15, $16, $17, $18, $19, $20, $21) " - "ON CONFLICT (device_id, network_id) DO UPDATE SET " - "authorized = EXCLUDED.authorized, active_bridge = EXCLUDED.active_bridge, " - "ip_assignments = EXCLUDED.ip_assignments, no_auto_assign_ips = EXCLUDED.no_auto_assign_ips, " - "sso_exempt = EXCLUDED.sso_exempt, authentication_expiry_time = EXCLUDED.authentication_expiry_time, " - "capabilities = EXCLUDED.capabilities, creation_time = EXCLUDED.creation_time, " - "identity = EXCLUDED.identity, last_authorized_time = EXCLUDED.last_authorized_time, " - "last_deauthorized_time = EXCLUDED.last_deauthorized_time, " - "remote_trace_level = EXCLUDED.remote_trace_level, remote_trace_target = EXCLUDED.remote_trace_target, " - "revision = EXCLUDED.revision, tags = EXCLUDED.tags, version_major = EXCLUDED.version_major, " - "version_minor = EXCLUDED.version_minor, version_revision = EXCLUDED.version_revision, " - "version_protocol = EXCLUDED.version_protocol", - memberId, - networkId, - (bool)config["authorized"], - (bool)config["activeBridge"], - config["ipAssignments"].get >(), - (bool)config["noAutoAssignIps"], - (bool)config["ssoExempt"], - (uint64_t)config["authenticationExpiryTime"], - OSUtils::jsonDump(config["capabilities"], -1), - (uint64_t)config["creationTime"], - OSUtils::jsonString(config["identity"], ""), - (uint64_t)config["lastAuthorizedTime"], - (uint64_t)config["lastDeauthorizedTime"], - (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"]); - - w.commit(); - - // No hooks for now - // 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 (pqxx::data_exception& e) { - std::string cfgDump = OSUtils::jsonDump(config, 2); - fprintf(stderr, "Member save %s-%s: %s\n", networkId.c_str(), memberId.c_str(), cfgDump.c_str()); - - const pqxx::sql_error* s = dynamic_cast(&e); - fprintf(stderr, "%s ERROR: Error updating member: %s\n", _myAddressStr.c_str(), e.what()); - if (s) { - fprintf(stderr, "%s ERROR: SQL error: %s\n", _myAddressStr.c_str(), s->query().c_str()); - } - mspan->SetStatus(opentelemetry::trace::StatusCode::kError, "pqxx::data_exception"); - mspan->SetAttribute("error", e.what()); - mspan->SetAttribute("config", cfgDump); - } - catch (std::exception& e) { - std::string cfgDump = OSUtils::jsonDump(config, 2); - fprintf(stderr, "%s ERROR: Error updating member %s-%s: %s\njsonDump: %s\n", _myAddressStr.c_str(), networkId.c_str(), memberId.c_str(), e.what(), cfgDump.c_str()); - mspan->SetStatus(opentelemetry::trace::StatusCode::kError, "std::exception"); - mspan->SetAttribute("error", e.what()); - mspan->SetAttribute("config", cfgDump); - } - } - else if (objtype == "network") { - auto nspan = tracer->StartSpan("cv2::commitThread::network"); - auto nscope = tracer->WithActiveSpan(span); - - try { - // fprintf(stderr, "%s: commitThread: network\n", _myAddressStr.c_str()); - pqxx::work w(*c->c); - - std::string id = config["id"]; - - // network must already exist - pqxx::result res = w.exec_params0( - "INSERT INTO networks_ctl (id, name, configuration, controller_id, revision) " - "VALUES ($1, $2, $3, $4, $5) " - "ON CONFLICT (id) DO UPDATE SET " - "name = EXCLUDED.name, configuration = EXCLUDED.configuration, revision = EXCLUDED.revision+1", - id, - OSUtils::jsonString(config["name"], ""), - OSUtils::jsonDump(config, -1), - _myAddressStr, - ((uint64_t)config["revision"])); - - 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 (pqxx::data_exception& e) { - const pqxx::sql_error* s = dynamic_cast(&e); - fprintf(stderr, "%s ERROR: Error updating network: %s\n", _myAddressStr.c_str(), e.what()); - if (s) { - fprintf(stderr, "%s ERROR: SQL error: %s\n", _myAddressStr.c_str(), s->query().c_str()); - } - nspan->SetStatus(opentelemetry::trace::StatusCode::kError, "pqxx::data_exception"); - nspan->SetAttribute("error", e.what()); - nspan->SetAttribute("config", OSUtils::jsonDump(config, 2)); - } - catch (std::exception& e) { - fprintf(stderr, "%s ERROR: Error updating network: %s\n", _myAddressStr.c_str(), e.what()); - nspan->SetStatus(opentelemetry::trace::StatusCode::kError, "std::exception"); - nspan->SetAttribute("error", e.what()); - nspan->SetAttribute("config", OSUtils::jsonDump(config, 2)); - } - } - else if (objtype == "_delete_network") { - auto dspan = tracer->StartSpan("cv2::commitThread::delete_network"); - auto dscope = tracer->WithActiveSpan(span); - - // fprintf(stderr, "%s: commitThread: delete network\n", _myAddressStr.c_str()); - try { - pqxx::work w(*c->c); - std::string networkId = config["id"]; - fprintf(stderr, "Deleting network %s\n", networkId.c_str()); - w.exec_params0("DELETE FROM network_memberships_ctl WHERE network_id = $1", networkId); - w.exec_params0("DELETE FROM networks_ctl WHERE id = $1", networkId); - - w.commit(); - - uint64_t nwidInt = OSUtils::jsonIntHex(config["nwid"], 0ULL); - json oldConfig; - get(nwidInt, oldConfig); - json empty; - _networkChanged(oldConfig, empty, qitem.second); - } - catch (std::exception& e) { - fprintf(stderr, "%s ERROR: Error deleting network: %s\n", _myAddressStr.c_str(), e.what()); - dspan->SetStatus(opentelemetry::trace::StatusCode::kError, "std::exception"); - dspan->SetAttribute("error", e.what()); - dspan->SetAttribute("config", OSUtils::jsonDump(config, 2)); - } - } - else if (objtype == "_delete_member") { - auto dspan = tracer->StartSpan("cv2::commitThread::delete_member"); - auto dscope = tracer->WithActiveSpan(span); - - // 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("DELETE FROM network_memberships_ctl WHERE device_id = $1 AND network_id = $2", memberId, networkId); - - w.commit(); - - uint64_t nwidInt = OSUtils::jsonIntHex(config["nwid"], 0ULL); - uint64_t memberidInt = OSUtils::jsonIntHex(config["id"], 0ULL); - - nlohmann::json networkConfig; - nlohmann::json oldConfig; - - get(nwidInt, networkConfig, memberidInt, oldConfig); - json empty; - _memberChanged(oldConfig, empty, qitem.second); - } - catch (std::exception& e) { - fprintf(stderr, "%s ERROR: Error deleting member: %s\n", _myAddressStr.c_str(), e.what()); - dspan->SetStatus(opentelemetry::trace::StatusCode::kError, "std::exception"); - dspan->SetAttribute("error", e.what()); - dspan->SetAttribute("config", OSUtils::jsonDump(config, 2)); - } - } - 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()); - span->SetStatus(opentelemetry::trace::StatusCode::kError, "std::exception"); - span->SetAttribute("error", e.what()); - } - _pool->unborrow(c); - c.reset(); - } - - fprintf(stderr, "%s commitThread finished\n", _myAddressStr.c_str()); -} - -void CV2::onlineNotificationThread() -{ - waitForReady(); - - _connected = 1; - - nlohmann::json jtmp1, jtmp2; - while (_run == 1) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("cv2"); - auto span = tracer->StartSpan("cv2::onlineNotificationThread"); - auto scope = tracer->WithActiveSpan(span); - - auto c = _pool->borrow(); - auto c2 = _pool->borrow(); - - try { - fprintf(stderr, "%s onlineNotificationThread\n", _myAddressStr.c_str()); - - std::unordered_map, NodeOnlineRecord, _PairHasher> lastOnline; - { - std::lock_guard l(_lastOnline_l); - lastOnline.swap(_lastOnline); - } - - pqxx::work w(*c->c); - pqxx::work w2(*c2->c); - - bool firstRun = true; - bool memberAdded = false; - uint64_t updateCount = 0; - - pqxx::pipeline pipe(w); - - for (auto i = lastOnline.begin(); i != lastOnline.end(); ++i) { - updateCount++; - - 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 device_id, network_id FROM network_memberships_ctl WHERE network_id = $1 AND device_id = $2", networkId, memberId); - } - catch (pqxx::unexpected_rows& e) { - continue; - } - - int64_t ts = i->second.lastSeen; - std::string ipAddr = i->second.physicalAddress.toIpString(ipTmp); - std::string timestamp = std::to_string(ts); - std::string osArch = i->second.osArch; - std::vector osArchSplit = split(osArch, '/'); - std::string os = osArchSplit[0]; - std::string arch = osArchSplit[1]; - - if (ipAddr.empty()) { - ipAddr = "relayed"; - } - - json record = { - { ipAddr, ts }, - }; - - std::string device_network_insert = "INSERT INTO network_memberships_ctl (device_id, network_id, last_seen, os, arch) " - "VALUES ('" - + w2.esc(memberId) + "', '" + w2.esc(networkId) + "', '" + w2.esc(record.dump()) - + "'::JSONB, " - "'" - + w2.esc(os) + "', '" + w2.esc(arch) - + "') " - "ON CONFLICT (device_id, network_id) DO UPDATE SET os = EXCLUDED.os, arch = EXCLUDED.arch, " - "last_seen = network_memberships_ctl.last_seen || EXCLUDED.last_seen"; - pipe.insert(device_network_insert); - - Metrics::pgsql_node_checkin++; - } - - pipe.complete(); - ; - w2.commit(); - w.commit(); - fprintf(stderr, "%s: Updated online status of %lu members\n", _myAddressStr.c_str(), updateCount); - } - catch (std::exception& e) { - fprintf(stderr, "%s ERROR: Error in onlineNotificationThread: %s\n", _myAddressStr.c_str(), e.what()); - span->SetStatus(opentelemetry::trace::StatusCode::kError, "std::exception"); - span->SetAttribute("error", e.what()); - } - catch (...) { - fprintf(stderr, "%s ERROR: Unknown error in onlineNotificationThread\n", _myAddressStr.c_str()); - span->SetStatus(opentelemetry::trace::StatusCode::kError, "unknown"); - } - _pool->unborrow(c2); - _pool->unborrow(c); - span->End(); - - 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); - } -} -#endif // ZT_CONTROLLER_USE_LIBPQ \ No newline at end of file diff --git a/controller/CV2.hpp b/controller/CV2.hpp deleted file mode 100644 index 09501e021..000000000 --- a/controller/CV2.hpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c)2025 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_CV2_HPP -#define ZT_CONTROLLER_CV2_HPP - -#define ZT_CENTRAL_CONTROLLER_COMMIT_THREADS 4 - -#include "../node/Metrics.hpp" -#include "ConnectionPool.hpp" -#include "PostgreSQL.hpp" - -#include -#include -#include - -namespace ZeroTier { - -class CV2 : public DB { - friend class MemberNotificationReceiver; - friend class NetworkNotificationReceiver; - - public: - CV2(const Identity& myId, const char* path, int listenPort); - virtual ~CV2(); - - 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 void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch); - virtual AuthInfo getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL); - - virtual bool ready() - { - return _ready == 2; - } - - 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); - - virtual void _networkChanged(nlohmann::json& old, nlohmann::json& networkConfig, bool notifyListeners); - - private: - void initializeNetworks(); - void initializeMembers(); - void heartbeat(); - void membersDbWatcher(); - void networksDbWatcher(); - - void commitThread(); - void onlineNotificationThread(); - - // 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 > _commitQueue; - - std::thread _heartbeatThread; - std::thread _membersDbWatcher; - std::thread _networksDbWatcher; - std::thread _commitThread[ZT_CENTRAL_CONTROLLER_COMMIT_THREADS]; - std::thread _onlineNotificationThread; - - std::unordered_map, NodeOnlineRecord, _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]; -}; - -} // namespace ZeroTier - -#endif // ZT_CONTROLLER_CV2_HPP -#endif // ZT_CONTROLLER_USE_LIBPQ \ No newline at end of file diff --git a/controller/ConnectionPool.hpp b/controller/ConnectionPool.hpp deleted file mode 100644 index 75690fab4..000000000 --- a/controller/ConnectionPool.hpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - * 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 "opentelemetry/trace/provider.h" - -#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() - { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("connection_pool"); - auto span = tracer->StartSpan("connection_pool::borrow"); - auto scope = tracer->WithActiveSpan(span); - - 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) { - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - 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) { - span->SetStatus(opentelemetry::trace::StatusCode::kError, e.what()); - // Error creating a replacement connection - Metrics::pool_errors++; - throw ConnectionUnavailable(); - } - } - } - - span->SetStatus(opentelemetry::trace::StatusCode::kError, "No available connections in pool"); - // 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) - { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("connection_pool"); - auto span = tracer->StartSpan("connection_pool::unborrow"); - auto scope = tracer->WithActiveSpan(span); - - // 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; -}; - -} // namespace ZeroTier - -#endif diff --git a/controller/CtlUtil.cpp b/controller/CtlUtil.cpp deleted file mode 100644 index e1e82f7a3..000000000 --- a/controller/CtlUtil.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "CtlUtil.hpp" - -#ifdef ZT_CONTROLLER_USE_LIBPQ - -#include -#include - -namespace ZeroTier { - -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::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(); -} - -} // namespace ZeroTier - -#endif \ No newline at end of file diff --git a/controller/CtlUtil.hpp b/controller/CtlUtil.hpp deleted file mode 100644 index 0ba665af3..000000000 --- a/controller/CtlUtil.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef ZT_CTLUTIL_HPP -#define ZT_CTLUTIL_HPP - -#include -#include - -namespace ZeroTier { - -const char* _timestr(); - -std::vector split(std::string str, char delim); - -std::string url_encode(const std::string& value); -} // namespace ZeroTier - -#endif // namespace ZeroTier \ No newline at end of file diff --git a/controller/DB.cpp b/controller/DB.cpp deleted file mode 100644 index 4cce312ed..000000000 --- a/controller/DB.cpp +++ /dev/null @@ -1,548 +0,0 @@ -/* - * 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 "../node/Metrics.hpp" -#include "EmbeddedNetworkController.hpp" -#include "opentelemetry/trace/provider.h" - -#include -#include -#include - -using json = nlohmann::json; - -namespace ZeroTier { - -void DB::initNetwork(nlohmann::json& network) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db"); - auto span = tracer->StartSpan("db::initNetwork"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db"); - auto span = tracer->StartSpan("db::initMember"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db"); - auto span = tracer->StartSpan("db::cleanNetwork"); - auto scope = tracer->WithActiveSpan(span); - - network.erase("clock"); - network.erase("authorizedMemberCount"); - network.erase("activeMemberCount"); - network.erase("totalMemberCount"); - network.erase("lastModified"); -} - -void DB::cleanMember(nlohmann::json& member) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db"); - auto span = tracer->StartSpan("db::cleanMember"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db"); - auto span = tracer->StartSpan("db::getNetwork"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db"); - auto span = tracer->StartSpan("db::getNetworkAndMember"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - char memberIdStr[11]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - span->SetAttribute("member_id", Utils::hex(networkId, memberIdStr)); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db"); - auto span = tracer->StartSpan("db::getNetworkAndMemberAndSummary"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - char memberIdStr[11]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - span->SetAttribute("member_id", Utils::hex(memberId, memberIdStr)); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db"); - auto span = tracer->StartSpan("db::getNetworkAndMembers"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db"); - auto span = tracer->StartSpan("db::networks"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db"); - auto span = tracer->StartSpan("db::_memberChanged"); - auto scope = tracer->WithActiveSpan(span); - - 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; i < ips.size(); ++i) { - json& ipj = ips[i]; - if (ipj.is_string()) { - const std::string ips = ipj; - InetAddress ipa(ips.c_str()); - ipa.setPort(0); - nw->allocatedIps.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; i < ips.size(); ++i) { - json& ipj = ips[i]; - if (ipj.is_string()) { - const std::string ips = ipj; - InetAddress ipa(ips.c_str()); - ipa.setPort(0); - nw->allocatedIps.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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db"); - auto span = tracer->StartSpan("db::_networkChanged"); - span->SetAttribute("old_network_config", old.dump()); - span->SetAttribute("network_config", networkConfig.dump()); - span->SetAttribute("notify_listeners", notifyListeners); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db"); - auto span = tracer->StartSpan("db::_fillSummaryInfo"); - auto scope = tracer->WithActiveSpan(span); - - 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 deleted file mode 100644 index 01b6f1266..000000000 --- a/controller/DB.hpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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/BlockingQueue.hpp" -#include "../osdep/OSUtils.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 void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch) = 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 > _networks; - std::unordered_multimap _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 deleted file mode 100644 index f8c6f0366..000000000 --- a/controller/DBMirrorSet.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/* - * 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" - -#include "opentelemetry/trace/provider.h" - -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)); - } - - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db::syncChecker"); - auto scope = tracer->WithActiveSpan(span); - - std::vector > 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 -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::hasNetwork"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::getNetwork"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::getNetworkAndMember"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - char memberIdStr[11]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - span->SetAttribute("member_id", Utils::hex10(memberId, memberIdStr)); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::getNetworkAndMemberWithSummary"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - char memberIdStr[11]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - span->SetAttribute("member_id", Utils::hex10(memberId, memberIdStr)); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::getNetworkAndMembers"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::getSSOAuthInfo"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::networks"); - auto scope = tracer->WithActiveSpan(span); - - std::shared_lock l(_dbs_l); - for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { - (*d)->networks(networks); - } -} - -bool DBMirrorSet::waitForReady() -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::waitForReady"); - auto scope = tracer->WithActiveSpan(span); - - 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() -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::isReady"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::save"); - auto scope = tracer->WithActiveSpan(span); - - std::vector > 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::eraseNetwork"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::eraseMember"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - char memberIdStr[11]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - span->SetAttribute("member_id", Utils::hex10(memberId, memberIdStr)); - - 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, const char* osArch) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::nodeIsOnline"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - char memberIdStr[11]; - char phyAddressStr[INET6_ADDRSTRLEN]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - span->SetAttribute("member_id", Utils::hex10(memberId, memberIdStr)); - span->SetAttribute("physical_address", physicalAddress.toString(phyAddressStr)); - span->SetAttribute("os_arch", osArch); - - std::shared_lock l(_dbs_l); - for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { - (*d)->nodeIsOnline(networkId, memberId, physicalAddress, osArch); - } -} - -void DBMirrorSet::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress) -{ - this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown"); -} - -void DBMirrorSet::onNetworkUpdate(const void* db, uint64_t networkId, const nlohmann::json& network) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::onNetworkUpdate"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::onNetworkMemberUpdate"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - char memberIdStr[11]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - span->SetAttribute("member_id", Utils::hex10(memberId, memberIdStr)); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_mirror_set"); - auto span = tracer->StartSpan("db_mirror_set::onNetworkMemberDeauthorize"); - auto scope = tracer->WithActiveSpan(span); - char networkIdStr[17]; - char memberIdStr[11]; - span->SetAttribute("network_id", Utils::hex(networkId, networkIdStr)); - span->SetAttribute("member_id", Utils::hex10(memberId, memberIdStr)); - - _listener->onNetworkMemberDeauthorize(this, networkId, memberId); -} - -} // namespace ZeroTier diff --git a/controller/DBMirrorSet.hpp b/controller/DBMirrorSet.hpp deleted file mode 100644 index 50230c545..000000000 --- a/controller/DBMirrorSet.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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); - virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress); - virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch); - - // 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 > _dbs; - mutable std::shared_mutex _dbs_l; -}; - -} // namespace ZeroTier - -#endif diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp deleted file mode 100644 index b7ba04299..000000000 --- a/controller/EmbeddedNetworkController.cpp +++ /dev/null @@ -1,2396 +0,0 @@ -/* - * 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/ZeroTierOne.h" -#include "../version.h" -#include "EmbeddedNetworkController.hpp" -#include "FileDB.hpp" -#include "LFDB.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef ZT_CONTROLLER_USE_LIBPQ -#include "CV1.hpp" -#include "CV2.hpp" -#endif - -#include "../node/CertificateOfMembership.hpp" -#include "../node/Dictionary.hpp" -#include "../node/MAC.hpp" -#include "../node/NetworkConfig.hpp" -#include "../node/Node.hpp" -#include "opentelemetry/trace/provider.h" - -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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::renderRule"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::parseRule"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::init"); - auto scope = tracer->WithActiveSpan(span); - - 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:")) { - fprintf(stderr, "CV1\n"); - _db.addDB(std::shared_ptr(new CV1(_signingId, _path.substr(9).c_str(), _listenPort, _rc))); - } - else if ((_path.length() > 4) && (_path.substr(0, 4) == "cv2:")) { - fprintf(stderr, "CV2\n"); - _db.addDB(std::shared_ptr(new CV2(_signingId, _path.substr(4).c_str(), _listenPort))); - } - else { - fprintf(stderr, "FileDB\n"); -#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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::request"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::networkUpdateFromPostData"); - auto scope = tracer->WithActiveSpan(span); - - 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 < rts.size(); ++i) { - json& rt = rts[i]; - if (rt.is_object()) { - json& target = rt["target"]; - json& via = rt["via"]; - if (target.is_string()) { - 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)) && (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 < ipp.size(); ++i) { - json& ip = ipp[i]; - if ((ip.is_object()) && (ip.count("ipRangeStart")) && (ip.count("ipRangeEnd"))) { - InetAddress f(OSUtils::jsonString(ip["ipRangeStart"], "").c_str()); - InetAddress t(OSUtils::jsonString(ip["ipRangeEnd"], "").c_str()); - if (((f.ss_family == AF_INET) || (f.ss_family == AF_INET6)) && (f.ss_family == t.ss_family)) { - json tmp = json::object(); - char tmp2[64]; - tmp["ipRangeStart"] = f.toIpString(tmp2); - tmp["ipRangeEnd"] = t.toIpString(tmp2); - nipp.push_back(tmp); - if (nipp.size() >= 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 < rules.size(); ++i) { - json& rule = rules[i]; - if (rule.is_object()) { - ZT_VirtualNetworkRule ztr; - if (_parseRule(rule, ztr)) { - nrules.push_back(_renderRule(ztr)); - if (nrules.size() >= 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 ncaps; - for (unsigned long i = 0; i < capabilities.size(); ++i) { - json& cap = capabilities[i]; - if (cap.is_object()) { - json ncap = json::object(); - const uint64_t capId = OSUtils::jsonInt(cap["id"], 0ULL); - ncap["id"] = capId; - ncap["default"] = OSUtils::jsonBool(cap["default"], false); - - json& rules = cap["rules"]; - json nrules = json::array(); - if (rules.is_array()) { - for (unsigned long i = 0; i < rules.size(); ++i) { - json& rule = rules[i]; - if (rule.is_object()) { - ZT_VirtualNetworkRule ztr; - if (_parseRule(rule, ztr)) { - nrules.push_back(_renderRule(ztr)); - if (nrules.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE) - break; - } - } - } - } - ncap["rules"] = nrules; - - ncaps[capId] = ncap; - } - } - - json ncapsa = json::array(); - for (std::map::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 ntags; - for (unsigned long i = 0; i < tags.size(); ++i) { - json& tag = tags[i]; - if (tag.is_object()) { - json ntag = json::object(); - const uint64_t tagId = OSUtils::jsonInt(tag["id"], 0ULL); - ntag["id"] = tagId; - json& dfl = tag["default"]; - if (dfl.is_null()) - ntag["default"] = dfl; - else - ntag["default"] = OSUtils::jsonInt(dfl, 0ULL); - ntags[tagId] = ntag; - } - } - - json ntagsa = json::array(); - for (std::map::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 < srv.size(); ++i) { - ns.push_back(srv[i]); - } - nd["servers"] = ns; - } - - network["dns"] = nd; - } - } - - network["id"] = nwids; - network["nwid"] = nwids; - - DB::cleanNetwork(network); - _db.save(network, true); - - return network.dump(); -} - -void EmbeddedNetworkController::configureHTTPControlPlane(httplib::Server& s, httplib::Server& sv6, const std::function 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) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::controllerGet"); - auto scope = tracer->WithActiveSpan(span); - - 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) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::networkListGet"); - auto scope = tracer->WithActiveSpan(span); - - 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) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::networkListGet2"); - auto scope = tracer->WithActiveSpan(span); - - 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 provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::networkGet"); - auto scope = tracer->WithActiveSpan(span); - - 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) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::createNewNetwork"); - auto scope = tracer->WithActiveSpan(span); - - // 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 provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::createNewNetworkOldAndBusted"); - auto scope = tracer->WithActiveSpan(span); - - 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 provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::networkPost"); - auto scope = tracer->WithActiveSpan(span); - - 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 provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::networkDelete"); - auto scope = tracer->WithActiveSpan(span); - - 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 provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::memberListGet"); - auto scope = tracer->WithActiveSpan(span); - - 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 provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::memberListGet2"); - auto scope = tracer->WithActiveSpan(span); - - 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 provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::memberGet"); - auto scope = tracer->WithActiveSpan(span); - - 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 provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::memberPost"); - auto scope = tracer->WithActiveSpan(span); - - 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 < ipa.size(); ++i) { - std::string ips = ipa[i]; - InetAddress ip(ips.c_str()); - if ((ip.ss_family == AF_INET) || (ip.ss_family == AF_INET6)) { - char tmpip[64]; - mipa.push_back(ip.toIpString(tmpip)); - if (mipa.size() >= 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 < tags.size(); ++i) { - json& tag = tags[i]; - if ((tag.is_array()) && (tag.size() == 2)) - mtags[OSUtils::jsonInt(tag[0], 0ULL) & 0xffffffffULL] = OSUtils::jsonInt(tag[1], 0ULL) & 0xffffffffULL; - } - json mtagsa = json::array(); - for (std::map::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 < capabilities.size(); ++i) { - mcaps.push_back(OSUtils::jsonInt(capabilities[i], 0ULL)); - if (mcaps.size() >= 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 provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::memberDelete"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::handleRemoteTrace"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::onNetworkUpdate"); - auto scope = tracer->WithActiveSpan(span); - - // 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::onNetworkMemberUpdate"); - auto scope = tracer->WithActiveSpan(span); - - // 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::onNetworkMemberDeauthorize"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_controller"); - auto span = tracer->StartSpan("embedded_controller::_request"); - auto scope = tracer->WithActiveSpan(span); - - 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 - char osArch[256]; - metaData.get(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_OS_ARCH, osArch, sizeof(osArch)); - // fprintf(stderr, "Network Config Request: nwid=%.16llx, nodeid=%.10llx, osArch=%s\n", - // nwid, identity.address().toInt(), osArch); - _db.nodeIsOnline(nwid, identity.address().toInt(), fromAddr, osArch); -#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()); - authInfo.add(ZT_AUTHINFO_DICT_KEY_SSO_PROVIDER, info.ssoProvider.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; i < rules.size(); ++i) { - if (nc->ruleCount >= ZT_MAX_NETWORK_RULES) - break; - if (_parseRule(rules[i], nc->rules[nc->ruleCount])) - ++nc->ruleCount; - } - } - - std::map capsById; - if (! memberCapabilities.is_array()) - memberCapabilities = json::array(); - if (capabilities.is_array()) { - for (unsigned long i = 0; i < capabilities.size(); ++i) { - json& cap = capabilities[i]; - if (cap.is_object()) { - const uint64_t id = OSUtils::jsonInt(cap["id"], 0ULL) & 0xffffffffULL; - capsById[id] = ∩ - if ((newMember) && (OSUtils::jsonBool(cap["default"], false))) { - bool have = false; - for (unsigned long i = 0; i < memberCapabilities.size(); ++i) { - if (id == (OSUtils::jsonInt(memberCapabilities[i], 0ULL) & 0xffffffffULL)) { - have = true; - break; - } - } - if (! have) - memberCapabilities.push_back(id); - } - } - } - } - for (unsigned long i = 0; i < memberCapabilities.size(); ++i) { - const uint64_t capId = OSUtils::jsonInt(memberCapabilities[i], 0ULL) & 0xffffffffULL; - std::map::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 < caprj.size(); ++j) { - if (caprc >= 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 memberTagsById; - if (memberTags.is_array()) { - for (unsigned long i = 0; i < memberTags.size(); ++i) { - json& t = memberTags[i]; - if ((t.is_array()) && (t.size() == 2)) - memberTagsById[(uint32_t)(OSUtils::jsonInt(t[0], 0ULL) & 0xffffffffULL)] = (uint32_t)(OSUtils::jsonInt(t[1], 0ULL) & 0xffffffffULL); - } - } - if (tags.is_array()) { // check network tags array for defaults that are not present in member tags - for (unsigned long i = 0; i < tags.size(); ++i) { - json& t = tags[i]; - if (t.is_object()) { - const uint32_t id = (uint32_t)(OSUtils::jsonInt(t["id"], 0) & 0xffffffffULL); - json& dfl = t["default"]; - if ((dfl.is_number()) && (memberTagsById.find(id) == memberTagsById.end())) { - memberTagsById[id] = (uint32_t)(OSUtils::jsonInt(dfl, 0) & 0xffffffffULL); - json mt = json::array(); - mt.push_back(id); - mt.push_back(dfl); - memberTags.push_back(mt); // add default to member tags if not present - } - } - } - } - for (std::map::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; i < routes.size(); ++i) { - if (nc->routeCount >= 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; i < ipAssignments.size(); ++i) { - if (ipAssignments[i].is_string()) { - const std::string ips = ipAssignments[i]; - InetAddress ip(ips.c_str()); - - int routedNetmaskBits = -1; - for (unsigned int rk = 0; rk < nc->routeCount; ++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 < ipAssignmentPools.size()) && (! haveManagedIpv6AutoAssignment)); ++p) { - json& pool = ipAssignmentPools[p]; - if (pool.is_object()) { - InetAddress ipRangeStart(OSUtils::jsonString(pool["ipRangeStart"], "").c_str()); - InetAddress ipRangeEnd(OSUtils::jsonString(pool["ipRangeEnd"], "").c_str()); - if ((ipRangeStart.ss_family == AF_INET6) && (ipRangeEnd.ss_family == AF_INET6)) { - uint64_t s[2], e[2], x[2], xx[2]; - memcpy(s, ipRangeStart.rawIpData(), 16); - memcpy(e, ipRangeEnd.rawIpData(), 16); - s[0] = Utils::ntoh(s[0]); - s[1] = Utils::ntoh(s[1]); - e[0] = Utils::ntoh(e[0]); - e[1] = Utils::ntoh(e[1]); - x[0] = s[0]; - x[1] = s[1]; - - for (unsigned int trialCount = 0; trialCount < 1000; ++trialCount) { - if ((trialCount == 0) && (e[1] > 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; rk < nc->routeCount; ++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 < ipAssignmentPools.size()) && (! haveManagedIpv4AutoAssignment)); ++p) { - json& pool = ipAssignmentPools[p]; - if (pool.is_object()) { - InetAddress ipRangeStartIA(OSUtils::jsonString(pool["ipRangeStart"], "").c_str()); - InetAddress ipRangeEndIA(OSUtils::jsonString(pool["ipRangeEnd"], "").c_str()); - if ((ipRangeStartIA.ss_family == AF_INET) && (ipRangeEndIA.ss_family == AF_INET)) { - uint32_t ipRangeStart = Utils::ntoh((uint32_t)(reinterpret_cast(&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; rk < nc->routeCount; ++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; i < nc->staticIpCount; ++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() -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_network_controller"); - auto span = tracer->StartSpan("embedded_network_controller::_startThreads"); - auto scope = tracer->WithActiveSpan(span); - - 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 < hwc; ++t) { - _threads.emplace_back([this]() { - Metrics::network_config_request_threads++; - for (;;) { - _RQEntry* qe = (_RQEntry*)0; - Metrics::network_config_request_queue_size = _queue.size(); - auto timedWaitResult = _queue.get(qe, 1000); - if (timedWaitResult == BlockingQueue<_RQEntry*>::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) { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("embedded_network_controller"); - auto span = tracer->StartSpan("embedded_network_controller::_ssoExpiryThread"); - auto scope = tracer->WithActiveSpan(span); - - 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); - } - span->End(); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } -} - -} // namespace ZeroTier diff --git a/controller/EmbeddedNetworkController.hpp b/controller/EmbeddedNetworkController.hpp deleted file mode 100644 index 111417bfb..000000000 --- a/controller/EmbeddedNetworkController.hpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 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 "../node/Address.hpp" -#include "../node/Constants.hpp" -#include "../node/InetAddress.hpp" -#include "../node/NetworkController.hpp" -#include "../node/Utils.hpp" -#include "../osdep/BlockingQueue.hpp" -#include "../osdep/OSUtils.hpp" -#include "../osdep/Thread.hpp" -#include "DB.hpp" -#include "DBMirrorSet.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 > _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 deleted file mode 100644 index 6472022e2..000000000 --- a/controller/FileDB.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - * 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" -#include "opentelemetry/trace/provider.h" - -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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("filedb"); - auto span = tracer->StartSpan("filedb::FileDB"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("filedb"); - auto span = tracer->StartSpan("filedb::save"); - auto scope = tracer->WithActiveSpan(span); - - char p1[4096], p2[4096], pb[4096]; - bool modified = false; - try { - const std::string objtype = record["objtype"]; - if (objtype == "network") { - auto span = tracer->StartSpan("filedb::save::network"); - auto scope = tracer->WithActiveSpan(span); - - 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") { - auto span = tracer->StartSpan("filedb::save::member"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("filedb"); - auto span = tracer->StartSpan("filedb::eraseNetwork"); - auto scope = tracer->WithActiveSpan(span); - - 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) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("filedb"); - auto span = tracer->StartSpan("filedb::eraseMember"); - auto scope = tracer->WithActiveSpan(span); - - 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, const char* osArch) -{ - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("filedb"); - auto span = tracer->StartSpan("filedb::nodeIsOnline"); - auto scope = tracer->WithActiveSpan(span); - - 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; -} - -void FileDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress) -{ - this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown"); -} - -} // namespace ZeroTier diff --git a/controller/FileDB.hpp b/controller/FileDB.hpp deleted file mode 100644 index e10753223..000000000 --- a/controller/FileDB.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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); - virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch); - - protected: - std::string _path; - std::string _networksPath; - std::string _tracePath; - std::thread _onlineUpdateThread; - std::map > > _online; - std::mutex _online_l; - bool _running; -}; - -} // namespace ZeroTier - -#endif diff --git a/controller/LFDB.cpp b/controller/LFDB.cpp deleted file mode 100644 index 77fa8ffe1..000000000 --- a/controller/LFDB.cpp +++ /dev/null @@ -1,443 +0,0 @@ -/* - * 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 "../ext/cpp-httplib/httplib.h" -#include "../osdep/OSUtils.hpp" - -#include -#include -#include -#include - -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 < results.size(); ++ri) { - nlohmann::json& rset = results[ri]; - if ((rset.is_array()) && (! rset.empty())) { - nlohmann::json& result = rset[0]; - if (result.is_object()) { - nlohmann::json& record = result["Record"]; - if (record.is_object()) { - const std::string recordValue = result["Value"]; - // printf("GET network %s\n",recordValue.c_str()); - nlohmann::json network(OSUtils::jsonParse(recordValue)); - if (network.is_object()) { - const std::string idstr = network["id"]; - const uint64_t id = Utils::hexStrToU64(idstr.c_str()); - if ((id >> 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 < results.size(); ++ri) { - nlohmann::json& rset = results[ri]; - if ((rset.is_array()) && (! rset.empty())) { - nlohmann::json& result = rset[0]; - if (result.is_object()) { - nlohmann::json& record = result["Record"]; - if (record.is_object()) { - const std::string recordValue = result["Value"]; - // printf("GET member %s\n",recordValue.c_str()); - nlohmann::json member(OSUtils::jsonParse(recordValue)); - if (member.is_object()) { - const std::string nwidstr = member["nwid"]; - const std::string idstr = member["id"]; - const uint64_t nwid = Utils::hexStrToU64(nwidstr.c_str()); - const uint64_t id = Utils::hexStrToU64(idstr.c_str()); - if ((id) && ((nwid >> 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, const char* osArch) -{ - 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; - } - } -} - -void LFDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress) -{ - this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown"); -} - -} // namespace ZeroTier diff --git a/controller/LFDB.hpp b/controller/LFDB.hpp deleted file mode 100644 index 3632e483f..000000000 --- a/controller/LFDB.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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); - virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch); - - 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 deleted file mode 100644 index 3bc864601..000000000 --- a/controller/PostgreSQL.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#ifdef ZT_CONTROLLER_USE_LIBPQ - -#include "PostgreSQL.hpp" - -#include - -using namespace nlohmann; - -using namespace ZeroTier; - -#endif \ No newline at end of file diff --git a/controller/PostgreSQL.hpp b/controller/PostgreSQL.hpp deleted file mode 100644 index 41f36e3c5..000000000 --- a/controller/PostgreSQL.hpp +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c)2025 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. - */ -/****/ - -#ifdef ZT_CONTROLLER_USE_LIBPQ - -#ifndef ZT_CONTROLLER_POSTGRESQL_HPP -#define ZT_CONTROLLER_POSTGRESQL_HPP - -#include "ConnectionPool.hpp" -#include "DB.hpp" -#include "opentelemetry/trace/provider.h" - -#include -#include -#include - -namespace ZeroTier { - -extern "C" { -typedef struct pg_conn PGconn; -} - -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; -}; - -template class MemberNotificationReceiver : public pqxx::notification_receiver { - public: - MemberNotificationReceiver(T* p, pqxx::connection& c, const std::string& channel) : pqxx::notification_receiver(c, channel), _psql(p) - { - fprintf(stderr, "initialize MemberNotificationReceiver\n"); - } - - virtual ~MemberNotificationReceiver() - { - fprintf(stderr, "MemberNotificationReceiver destroyed\n"); - } - - virtual void operator()(const std::string& payload, int backendPid) - { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_member_notification"); - auto span = tracer->StartSpan("db_member_notification::operator()"); - auto scope = tracer->WithActiveSpan(span); - span->SetAttribute("payload", payload); - span->SetAttribute("psqlReady", _psql->isReady()); - - fprintf(stderr, "Member Notification received: %s\n", payload.c_str()); - Metrics::pgsql_mem_notification++; - nlohmann::json tmp(nlohmann::json::parse(payload)); - nlohmann::json& ov = tmp["old_val"]; - nlohmann::json& nv = tmp["new_val"]; - nlohmann::json oldConfig, newConfig; - if (ov.is_object()) - oldConfig = ov; - if (nv.is_object()) - newConfig = nv; - - if (oldConfig.is_object() && newConfig.is_object()) { - _psql->save(newConfig, _psql->isReady()); - fprintf(stderr, "payload sent\n"); - } - else if (newConfig.is_object() && ! oldConfig.is_object()) { - // new member - Metrics::member_count++; - _psql->save(newConfig, _psql->isReady()); - fprintf(stderr, "new member payload sent\n"); - } - else if (! newConfig.is_object() && oldConfig.is_object()) { - // member delete - uint64_t networkId = OSUtils::jsonIntHex(oldConfig["nwid"], 0ULL); - uint64_t memberId = OSUtils::jsonIntHex(oldConfig["id"], 0ULL); - if (memberId && networkId) { - _psql->eraseMember(networkId, memberId); - fprintf(stderr, "member delete payload sent\n"); - } - } - } - - private: - T* _psql; -}; - -template class NetworkNotificationReceiver : public pqxx::notification_receiver { - public: - NetworkNotificationReceiver(T* p, pqxx::connection& c, const std::string& channel) : pqxx::notification_receiver(c, channel), _psql(p) - { - fprintf(stderr, "initialize NetworkrNotificationReceiver\n"); - } - - virtual ~NetworkNotificationReceiver() - { - fprintf(stderr, "NetworkNotificationReceiver destroyed\n"); - }; - - virtual void operator()(const std::string& payload, int packend_pid) - { - auto provider = opentelemetry::trace::Provider::GetTracerProvider(); - auto tracer = provider->GetTracer("db_network_notification"); - auto span = tracer->StartSpan("db_network_notification::operator()"); - auto scope = tracer->WithActiveSpan(span); - span->SetAttribute("payload", payload); - span->SetAttribute("psqlReady", _psql->isReady()); - - fprintf(stderr, "Network Notification received: %s\n", payload.c_str()); - Metrics::pgsql_net_notification++; - nlohmann::json tmp(nlohmann::json::parse(payload)); - - nlohmann::json& ov = tmp["old_val"]; - nlohmann::json& nv = tmp["new_val"]; - nlohmann::json oldConfig, newConfig; - - if (ov.is_object()) - oldConfig = ov; - if (nv.is_object()) - newConfig = nv; - - if (oldConfig.is_object() && newConfig.is_object()) { - std::string nwid = oldConfig["id"]; - span->SetAttribute("action", "network_change"); - span->SetAttribute("network_id", nwid); - _psql->save(newConfig, _psql->isReady()); - fprintf(stderr, "payload sent\n"); - } - else if (newConfig.is_object() && ! oldConfig.is_object()) { - std::string nwid = newConfig["id"]; - span->SetAttribute("network_id", nwid); - span->SetAttribute("action", "new_network"); - // new network - _psql->save(newConfig, _psql->isReady()); - fprintf(stderr, "new network payload sent\n"); - } - else if (! newConfig.is_object() && oldConfig.is_object()) { - // network delete - span->SetAttribute("action", "delete_network"); - std::string nwid = oldConfig["id"]; - span->SetAttribute("network_id", nwid); - uint64_t networkId = Utils::hexStrToU64(nwid.c_str()); - span->SetAttribute("network_id_int", networkId); - if (networkId) { - _psql->eraseNetwork(networkId); - fprintf(stderr, "network delete payload sent\n"); - } - } - } - - private: - T* _psql; -}; - -struct NodeOnlineRecord { - uint64_t lastSeen; - InetAddress physicalAddress; - std::string osArch; -}; - -} // namespace ZeroTier - -#endif // ZT_CONTROLLER_POSTGRESQL_HPP - -#endif // ZT_CONTROLLER_USE_LIBPQ \ No newline at end of file diff --git a/controller/README.md b/controller/README.md index 41cfd3ff3..612dba7b8 100644 --- a/controller/README.md +++ b/controller/README.md @@ -1,55 +1,32 @@ -Network Controller Microservice +Network Controller Implementation ====== -Every ZeroTier virtual network has a *network controller* responsible for admitting members to the network, issuing certificates, and issuing default configuration information. +This folder contains code implementing the node/NetworkController.hpp interface to allow ZeroTier nodes to create and manage virtual networks. -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. +### Building -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. +By default this code is not built or included in the client. To build on Linux, BSD, or Mac add ZT\_ENABLE\_NETCONF\_MASTER=1 to the make command line. You'll need the development headers for Sqlite3 installed. They ship as part of OSX and Xcode. On Linux or BSD you'll probably need to install a package. -See the API section below for information about controlling the controller. +### Running -### Scalability and Reliability +When started, a controller-enabled build of ZeroTier One will automatically create and initialize a *controller.db* in its home folder. This is where all the controller's data and persistent state lives. -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 Sqlite3 supports multiple processes attached to the same database, it is safe to back up a running database with the command line *sqlite3* utility: -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. + sqlite3 /path/to/controller.db .dump -### Dockerizing Controllers +In production ZeroTier runs this frequently and keeps many timestamped copies going back about a week. These are also backed up (encrypted) to Amazon S3 along with the rest of our data. -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. +### Administrating -### Upgrading from Older (1.1.14 or earlier) Versions +See service/README.md for documentation on the JSON API presented by this network controller implementation. Also see *nodejs-zt1-client* for a NodeJS JavaScript interface. -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. +### Reliability -The migration tool is written in nodeJS and can be used like this: +Network controllers can go offline without affecting already-configured members of running networks. You just won't be able to change anything and new members will not be able to join. - cd migrate-sqlite - npm install - node migrate.js +High-availability can be implemented through fail-over. A simple method involves making a frequent backup of the SQLite database (use the SQLite command line client to do this safely) and the network configuration master's working directory. Then, if the master goes down, another instance of it can rapidly be provisioned elsewhere. Since ZeroTier addresses are mobile, the new instance will quickly (usually no more than 30s) take over for the old one and service requests. -### Network Controller API +### Limits -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| +A single network configuration master can administrate up to 2^24 (~16m) networks as per the ZeroTier protocol limit. There is no hard limit on the number of clients, though millions or more would impose significant CPU demands on a server. Optimizations could be implemented such as memoization/caching to reduce this. diff --git a/controller/Redis.hpp b/controller/Redis.hpp deleted file mode 100644 index c6845d517..000000000 --- a/controller/Redis.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#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; -}; -} // namespace ZeroTier - -#endif \ No newline at end of file diff --git a/controller/SqliteNetworkController.cpp b/controller/SqliteNetworkController.cpp new file mode 100644 index 000000000..c95d3b74b --- /dev/null +++ b/controller/SqliteNetworkController.cpp @@ -0,0 +1,1729 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../include/ZeroTierOne.h" +#include "../node/Constants.hpp" + +#include "../ext/json-parser/json.h" + +#include "SqliteNetworkController.hpp" +#include "../node/Utils.hpp" +#include "../node/CertificateOfMembership.hpp" +#include "../node/NetworkConfig.hpp" +#include "../node/InetAddress.hpp" +#include "../node/MAC.hpp" +#include "../node/Address.hpp" +#include "../osdep/OSUtils.hpp" + +// Include ZT_NETCONF_SCHEMA_SQL constant to init database +#include "schema.sql.c" + +// Stored in database as schemaVersion key in Config. +// If not present, database is assumed to be empty and at the current schema version +// and this key/value is added automatically. +#define ZT_NETCONF_SQLITE_SCHEMA_VERSION 1 +#define ZT_NETCONF_SQLITE_SCHEMA_VERSION_STR "1" + +// API version reported via JSON control plane +#define ZT_NETCONF_CONTROLLER_API_VERSION 1 + +// Drop requests for a given peer and network ID that occur more frequently +// than this (ms). +#define ZT_NETCONF_MIN_REQUEST_PERIOD 1000 + +namespace ZeroTier { + +namespace { + +static std::string _jsonEscape(const char *s) +{ + if (!s) + return std::string(); + std::string buf; + for(const char *p=s;(*p);++p) { + switch(*p) { + case '\t': buf.append("\\t"); break; + case '\b': buf.append("\\b"); break; + case '\r': buf.append("\\r"); break; + case '\n': buf.append("\\n"); break; + case '\f': buf.append("\\f"); break; + case '"': buf.append("\\\""); break; + case '\\': buf.append("\\\\"); break; + case '/': buf.append("\\/"); break; + default: buf.push_back(*p); break; + } + } + return buf; +} +static std::string _jsonEscape(const std::string &s) { return _jsonEscape(s.c_str()); } + +struct MemberRecord { + int64_t rowid; + char nodeId[16]; + bool authorized; + bool activeBridge; +}; + +struct NetworkRecord { + char id[24]; + const char *name; + const char *v4AssignMode; + const char *v6AssignMode; + bool isPrivate; + bool enableBroadcast; + bool allowPassiveBridging; + int multicastLimit; + uint64_t creationTime; + uint64_t revision; + uint64_t memberRevisionCounter; +}; + +} // anonymous namespace + +SqliteNetworkController::SqliteNetworkController(const char *dbPath) : + _dbPath(dbPath), + _db((sqlite3 *)0) +{ + if (sqlite3_open_v2(dbPath,&_db,SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE,(const char *)0) != SQLITE_OK) + throw std::runtime_error("SqliteNetworkController cannot open database file"); + sqlite3_busy_timeout(_db,10000); + + sqlite3_stmt *s = (sqlite3_stmt *)0; + if ((sqlite3_prepare_v2(_db,"SELECT v FROM Config WHERE k = 'schemaVersion';",-1,&s,(const char **)0) == SQLITE_OK)&&(s)) { + int schemaVersion = -1234; + if (sqlite3_step(s) == SQLITE_ROW) { + schemaVersion = sqlite3_column_int(s,0); + } + + sqlite3_finalize(s); + + if (schemaVersion == -1234) { + sqlite3_close(_db); + throw std::runtime_error("SqliteNetworkController schemaVersion not found in Config table (init failure?)"); + } else if (schemaVersion != ZT_NETCONF_SQLITE_SCHEMA_VERSION) { + // Note -- this will eventually run auto-upgrades so this isn't how it'll work going forward + sqlite3_close(_db); + throw std::runtime_error("SqliteNetworkController database schema version mismatch"); + } + } else { + // Prepare statement will fail if Config table doesn't exist, which means our DB + // needs to be initialized. + if (sqlite3_exec(_db,ZT_NETCONF_SCHEMA_SQL"INSERT INTO Config (k,v) VALUES ('schemaVersion',"ZT_NETCONF_SQLITE_SCHEMA_VERSION_STR");",0,0,0) != SQLITE_OK) { + char err[1024]; + Utils::snprintf(err,sizeof(err),"SqliteNetworkController cannot initialize database and/or insert schemaVersion into Config table: %s",sqlite3_errmsg(_db)); + sqlite3_close(_db); + throw std::runtime_error(err); + } + } + + if ( + + /* Network */ + (sqlite3_prepare_v2(_db,"SELECT name,private,enableBroadcast,allowPassiveBridging,v4AssignMode,v6AssignMode,multicastLimit,creationTime,revision,memberRevisionCounter FROM Network WHERE id = ?",-1,&_sGetNetworkById,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT revision FROM Network WHERE id = ?",-1,&_sGetNetworkRevision,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"UPDATE Network SET revision = ? WHERE id = ?",-1,&_sSetNetworkRevision,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"INSERT INTO Network (id,name,creationTime,revision) VALUES (?,?,?,1)",-1,&_sCreateNetwork,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"DELETE FROM Network WHERE id = ?",-1,&_sDeleteNetwork,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT id FROM Network ORDER BY id ASC",-1,&_sListNetworks,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"UPDATE Network SET memberRevisionCounter = (memberRevisionCounter + 1) WHERE id = ?",-1,&_sIncrementMemberRevisionCounter,(const char **)0) != SQLITE_OK) + + /* Node */ + ||(sqlite3_prepare_v2(_db,"SELECT identity FROM Node WHERE id = ?",-1,&_sGetNodeIdentity,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"INSERT INTO Node (id,identity) VALUES (?,?)",-1,&_sCreateNode,(const char **)0) != SQLITE_OK) + + /* Rule */ + ||(sqlite3_prepare_v2(_db,"SELECT etherType FROM Rule WHERE networkId = ? AND \"action\" = 'accept'",-1,&_sGetEtherTypesFromRuleTable,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"INSERT INTO Rule (networkId,ruleNo,nodeId,sourcePort,destPort,vlanId,vlanPcP,etherType,macSource,macDest,ipSource,ipDest,ipTos,ipProtocol,ipSourcePort,ipDestPort,flags,invFlags,\"action\") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",-1,&_sCreateRule,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT ruleNo,nodeId,sourcePort,destPort,vlanId,vlanPcp,etherType,macSource,macDest,ipSource,ipDest,ipTos,ipProtocol,ipSourcePort,ipDestPort,\"flags\",invFlags,\"action\" FROM Rule WHERE networkId = ? ORDER BY ruleNo ASC",-1,&_sListRules,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"DELETE FROM Rule WHERE networkId = ?",-1,&_sDeleteRulesForNetwork,(const char **)0) != SQLITE_OK) + + /* IpAssignmentPool */ + ||(sqlite3_prepare_v2(_db,"SELECT ipRangeStart,ipRangeEnd FROM IpAssignmentPool WHERE networkId = ? AND ipVersion = ?",-1,&_sGetIpAssignmentPools,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT ipRangeStart,ipRangeEnd,ipVersion FROM IpAssignmentPool WHERE networkId = ? ORDER BY ipRangeStart ASC",-1,&_sGetIpAssignmentPools2,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"INSERT INTO IpAssignmentPool (networkId,ipRangeStart,ipRangeEnd,ipVersion) VALUES (?,?,?,?)",-1,&_sCreateIpAssignmentPool,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"DELETE FROM IpAssignmentPool WHERE networkId = ?",-1,&_sDeleteIpAssignmentPoolsForNetwork,(const char **)0) != SQLITE_OK) + + /* IpAssignment */ + ||(sqlite3_prepare_v2(_db,"SELECT \"type\",ip,ipNetmaskBits FROM IpAssignment WHERE networkId = ? AND (nodeId = ? OR nodeId IS NULL) AND ipVersion = ?",-1,&_sGetIpAssignmentsForNode,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT ip,ipNetmaskBits,ipVersion FROM IpAssignment WHERE networkId = ? AND nodeId = ? AND \"type\" = ? ORDER BY ip ASC",-1,&_sGetIpAssignmentsForNode2,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT ip,ipNetmaskBits,ipVersion FROM IpAssignment WHERE networkId = ? AND nodeId IS NULL AND \"type\" = ?",-1,&_sGetLocalRoutes,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT 1 FROM IpAssignment WHERE networkId = ? AND ip = ? AND ipVersion = ? AND \"type\" = ?",-1,&_sCheckIfIpIsAllocated,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"INSERT INTO IpAssignment (networkId,nodeId,\"type\",ip,ipNetmaskBits,ipVersion) VALUES (?,?,?,?,?,?)",-1,&_sAllocateIp,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"DELETE FROM IpAssignment WHERE networkId = ? AND nodeId = ? AND \"type\" = ?",-1,&_sDeleteIpAllocations,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"DELETE FROM IpAssignment WHERE networkId = ? AND nodeId IS NULL AND \"type\" = ?",-1,&_sDeleteLocalRoutes,(const char **)0) != SQLITE_OK) + + /* Relay */ + ||(sqlite3_prepare_v2(_db,"SELECT \"address\",\"phyAddress\" FROM Relay WHERE \"networkId\" = ? ORDER BY \"address\" ASC",-1,&_sGetRelays,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"DELETE FROM Relay WHERE networkId = ?",-1,&_sDeleteRelaysForNetwork,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"INSERT INTO Relay (\"networkId\",\"address\",\"phyAddress\") VALUES (?,?,?)",-1,&_sCreateRelay,(const char **)0) != SQLITE_OK) + + /* Member */ + ||(sqlite3_prepare_v2(_db,"SELECT rowid,authorized,activeBridge FROM Member WHERE networkId = ? AND nodeId = ?",-1,&_sGetMember,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT m.authorized,m.activeBridge,m.memberRevision,n.identity FROM Member AS m JOIN Node AS n ON n.id = m.nodeId WHERE m.networkId = ? AND m.nodeId = ?",-1,&_sGetMember2,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"INSERT INTO Member (networkId,nodeId,authorized,activeBridge,memberRevision) VALUES (?,?,?,0,(SELECT memberRevisionCounter FROM Network WHERE id = ?))",-1,&_sCreateMember,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT nodeId FROM Member WHERE networkId = ? AND activeBridge > 0 AND authorized > 0",-1,&_sGetActiveBridges,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT m.nodeId,m.memberRevision FROM Member AS m WHERE m.networkId = ? ORDER BY m.nodeId ASC",-1,&_sListNetworkMembers,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"UPDATE Member SET authorized = ?,memberRevision = (SELECT memberRevisionCounter FROM Network WHERE id = ?) WHERE rowid = ?",-1,&_sUpdateMemberAuthorized,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"UPDATE Member SET activeBridge = ?,memberRevision = (SELECT memberRevisionCounter FROM Network WHERE id = ?) WHERE rowid = ?",-1,&_sUpdateMemberActiveBridge,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"DELETE FROM Member WHERE networkId = ? AND nodeId = ?",-1,&_sDeleteMember,(const char **)0) != SQLITE_OK) + + /* Gateway */ + ||(sqlite3_prepare_v2(_db,"SELECT \"ip\",ipVersion,metric FROM Gateway WHERE networkId = ? ORDER BY metric ASC",-1,&_sGetGateways,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"DELETE FROM Gateway WHERE networkId = ?",-1,&_sDeleteGateways,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"INSERT INTO Gateway (networkId,\"ip\",ipVersion,metric) VALUES (?,?,?,?)",-1,&_sCreateGateway,(const char **)0) != SQLITE_OK) + + /* Log */ + ||(sqlite3_prepare_v2(_db,"INSERT INTO \"Log\" (networkId,nodeId,\"ts\",\"authorized\",\"version\",fromAddr) VALUES (?,?,?,?,?,?)",-1,&_sPutLog,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT \"ts\",\"authorized\",\"version\",fromAddr FROM \"Log\" WHERE networkId = ? AND nodeId = ? AND \"ts\" >= ? ORDER BY \"ts\" ASC",-1,&_sGetMemberLog,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT \"ts\",\"authorized\",\"version\",fromAddr FROM \"Log\" WHERE networkId = ? AND nodeId = ? ORDER BY \"ts\" DESC LIMIT 10",-1,&_sGetRecentMemberLog,(const char **)0) != SQLITE_OK) + + /* Config */ + ||(sqlite3_prepare_v2(_db,"SELECT \"v\" FROM \"Config\" WHERE \"k\" = ?",-1,&_sGetConfig,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"INSERT OR REPLACE INTO \"Config\" (\"k\",\"v\") VALUES (?,?)",-1,&_sSetConfig,(const char **)0) != SQLITE_OK) + + ) { + //printf("%s\n",sqlite3_errmsg(_db)); + sqlite3_close(_db); + throw std::runtime_error("SqliteNetworkController unable to initialize one or more prepared statements"); + } + + /* Generate a 128-bit / 32-character "instance ID" if one isn't already + * defined. Clients can use this to determine if this is the same controller + * database they know and love. */ + sqlite3_reset(_sGetConfig); + sqlite3_bind_text(_sGetConfig,1,"instanceId",10,SQLITE_STATIC); + if (sqlite3_step(_sGetConfig) != SQLITE_ROW) { + unsigned char sr[32]; + Utils::getSecureRandom(sr,32); + for(unsigned int i=0;i<32;++i) + _instanceId.push_back("0123456789abcdef"[(unsigned int)sr[i] & 0xf]); + + sqlite3_reset(_sSetConfig); + sqlite3_bind_text(_sSetConfig,1,"instanceId",10,SQLITE_STATIC); + sqlite3_bind_text(_sSetConfig,2,_instanceId.c_str(),-1,SQLITE_STATIC); + if (sqlite3_step(_sSetConfig) != SQLITE_DONE) + throw std::runtime_error("SqliteNetworkController unable to read or initialize instanceId"); + } else { + const char *iid = reinterpret_cast(sqlite3_column_text(_sGetConfig,0)); + if (!iid) + throw std::runtime_error("SqliteNetworkController unable to read instanceId (it's NULL)"); + _instanceId = iid; + } +} + +SqliteNetworkController::~SqliteNetworkController() +{ + Mutex::Lock _l(_lock); + if (_db) { + sqlite3_finalize(_sGetNetworkById); + sqlite3_finalize(_sGetMember); + sqlite3_finalize(_sCreateMember); + sqlite3_finalize(_sGetNodeIdentity); + sqlite3_finalize(_sCreateNode); + sqlite3_finalize(_sUpdateNode); + sqlite3_finalize(_sUpdateNode2); + sqlite3_finalize(_sGetEtherTypesFromRuleTable); + sqlite3_finalize(_sGetActiveBridges); + sqlite3_finalize(_sGetIpAssignmentsForNode); + sqlite3_finalize(_sGetIpAssignmentPools); + sqlite3_finalize(_sGetLocalRoutes); + sqlite3_finalize(_sCheckIfIpIsAllocated); + sqlite3_finalize(_sAllocateIp); + sqlite3_finalize(_sDeleteIpAllocations); + sqlite3_finalize(_sDeleteLocalRoutes); + sqlite3_finalize(_sGetRelays); + sqlite3_finalize(_sListNetworks); + sqlite3_finalize(_sListNetworkMembers); + sqlite3_finalize(_sGetMember2); + sqlite3_finalize(_sGetIpAssignmentPools2); + sqlite3_finalize(_sListRules); + sqlite3_finalize(_sCreateRule); + sqlite3_finalize(_sCreateNetwork); + sqlite3_finalize(_sGetNetworkRevision); + sqlite3_finalize(_sSetNetworkRevision); + sqlite3_finalize(_sGetIpAssignmentsForNode2); + sqlite3_finalize(_sDeleteRelaysForNetwork); + sqlite3_finalize(_sCreateRelay); + sqlite3_finalize(_sDeleteIpAssignmentPoolsForNetwork); + sqlite3_finalize(_sDeleteRulesForNetwork); + sqlite3_finalize(_sCreateIpAssignmentPool); + sqlite3_finalize(_sUpdateMemberAuthorized); + sqlite3_finalize(_sUpdateMemberActiveBridge); + sqlite3_finalize(_sDeleteMember); + sqlite3_finalize(_sDeleteNetwork); + sqlite3_finalize(_sGetGateways); + sqlite3_finalize(_sDeleteGateways); + sqlite3_finalize(_sCreateGateway); + sqlite3_finalize(_sIncrementMemberRevisionCounter); + sqlite3_finalize(_sGetConfig); + sqlite3_finalize(_sSetConfig); + sqlite3_finalize(_sPutLog); + sqlite3_finalize(_sGetMemberLog); + sqlite3_finalize(_sGetRecentMemberLog); + sqlite3_close(_db); + } +} + +NetworkController::ResultCode SqliteNetworkController::doNetworkConfigRequest(const InetAddress &fromAddr,const Identity &signingId,const Identity &identity,uint64_t nwid,const Dictionary &metaData,uint64_t haveRevision,Dictionary &netconf) +{ + // Decode some stuff from metaData + const unsigned int clientMajorVersion = (unsigned int)metaData.getHexUInt(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,0); + const unsigned int clientMinorVersion = (unsigned int)metaData.getHexUInt(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,0); + const unsigned int clientRevision = (unsigned int)metaData.getHexUInt(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,0); + const bool clientIs104 = (Utils::compareVersion(clientMajorVersion,clientMinorVersion,clientRevision,1,0,4) >= 0); + + Mutex::Lock _l(_lock); + + // Note: we can't reuse prepared statements that return const char * pointers without + // making our own copy in e.g. a std::string first. + + if ((!signingId)||(!signingId.hasPrivate())) { + netconf["error"] = "signing identity invalid or lacks private key"; + return NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR; + } + if (signingId.address().toInt() != (nwid >> 24)) { + netconf["error"] = "signing identity address does not match most significant 40 bits of network ID"; + return NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR; + } + + // Check rate limit + + { + uint64_t &lrt = _lastRequestTime[std::pair(identity.address(),nwid)]; + uint64_t lrt2 = lrt; + if (((lrt = OSUtils::now()) - lrt2) <= ZT_NETCONF_MIN_REQUEST_PERIOD) + return NetworkController::NETCONF_QUERY_IGNORE; + } + + NetworkRecord network; + memset(&network,0,sizeof(network)); + Utils::snprintf(network.id,sizeof(network.id),"%.16llx",(unsigned long long)nwid); + + MemberRecord member; + memset(&member,0,sizeof(member)); + Utils::snprintf(member.nodeId,sizeof(member.nodeId),"%.10llx",(unsigned long long)identity.address().toInt()); + + // Create Node record or do full identity check if we already have one + + sqlite3_reset(_sGetNodeIdentity); + sqlite3_bind_text(_sGetNodeIdentity,1,member.nodeId,10,SQLITE_STATIC); + if (sqlite3_step(_sGetNodeIdentity) == SQLITE_ROW) { + try { + Identity alreadyKnownIdentity((const char *)sqlite3_column_text(_sGetNodeIdentity,0)); + if (alreadyKnownIdentity != identity) + return NetworkController::NETCONF_QUERY_ACCESS_DENIED; + } catch ( ... ) { // identity stored in database is not valid or is NULL + return NetworkController::NETCONF_QUERY_ACCESS_DENIED; + } + } else { + std::string idstr(identity.toString(false)); + sqlite3_reset(_sCreateNode); + sqlite3_bind_text(_sCreateNode,1,member.nodeId,10,SQLITE_STATIC); + sqlite3_bind_text(_sCreateNode,2,idstr.c_str(),-1,SQLITE_STATIC); + if (sqlite3_step(_sCreateNode) != SQLITE_DONE) { + netconf["error"] = "unable to create new Node record"; + return NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR; + } + } + + // Fetch Network record + + sqlite3_reset(_sGetNetworkById); + sqlite3_bind_text(_sGetNetworkById,1,network.id,16,SQLITE_STATIC); + if (sqlite3_step(_sGetNetworkById) == SQLITE_ROW) { + network.name = (const char *)sqlite3_column_text(_sGetNetworkById,0); + network.isPrivate = (sqlite3_column_int(_sGetNetworkById,1) > 0); + network.enableBroadcast = (sqlite3_column_int(_sGetNetworkById,2) > 0); + network.allowPassiveBridging = (sqlite3_column_int(_sGetNetworkById,3) > 0); + network.v4AssignMode = (const char *)sqlite3_column_text(_sGetNetworkById,4); + network.v6AssignMode = (const char *)sqlite3_column_text(_sGetNetworkById,5); + network.multicastLimit = sqlite3_column_int(_sGetNetworkById,6); + network.creationTime = (uint64_t)sqlite3_column_int64(_sGetNetworkById,7); + network.revision = (uint64_t)sqlite3_column_int64(_sGetNetworkById,8); + network.memberRevisionCounter = (uint64_t)sqlite3_column_int64(_sGetNetworkById,9); + } else { + return NetworkController::NETCONF_QUERY_OBJECT_NOT_FOUND; + } + + // Fetch Member record + + bool foundMember = false; + sqlite3_reset(_sGetMember); + sqlite3_bind_text(_sGetMember,1,network.id,16,SQLITE_STATIC); + sqlite3_bind_text(_sGetMember,2,member.nodeId,10,SQLITE_STATIC); + if (sqlite3_step(_sGetMember) == SQLITE_ROW) { + foundMember = true; + member.rowid = (int64_t)sqlite3_column_int64(_sGetMember,0); + member.authorized = (sqlite3_column_int(_sGetMember,1) > 0); + member.activeBridge = (sqlite3_column_int(_sGetMember,2) > 0); + } + + // Create Member record for unknown nodes, auto-authorizing if network is public + + if (!foundMember) { + member.authorized = (network.isPrivate ? false : true); + member.activeBridge = false; + sqlite3_reset(_sCreateMember); + sqlite3_bind_text(_sCreateMember,1,network.id,16,SQLITE_STATIC); + sqlite3_bind_text(_sCreateMember,2,member.nodeId,10,SQLITE_STATIC); + sqlite3_bind_int(_sCreateMember,3,(member.authorized ? 1 : 0)); + sqlite3_bind_text(_sCreateMember,4,network.id,16,SQLITE_STATIC); + if (sqlite3_step(_sCreateMember) != SQLITE_DONE) { + netconf["error"] = "unable to create new member record"; + return NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR; + } + member.rowid = (int64_t)sqlite3_last_insert_rowid(_db); + + sqlite3_reset(_sIncrementMemberRevisionCounter); + sqlite3_bind_text(_sIncrementMemberRevisionCounter,1,network.id,16,SQLITE_STATIC); + sqlite3_step(_sIncrementMemberRevisionCounter); + } + + // Add log entry + { + char ver[16]; + std::string fa; + if (fromAddr) { + fa = fromAddr.toString(); + if (fa.length() > 64) + fa = fa.substr(0,64); + } + sqlite3_reset(_sPutLog); + sqlite3_bind_text(_sPutLog,1,network.id,16,SQLITE_STATIC); + sqlite3_bind_text(_sPutLog,2,member.nodeId,10,SQLITE_STATIC); + sqlite3_bind_int64(_sPutLog,3,(long long)OSUtils::now()); + sqlite3_bind_int(_sPutLog,4,member.authorized ? 1 : 0); + if ((clientMajorVersion > 0)||(clientMinorVersion > 0)||(clientRevision > 0)) { + Utils::snprintf(ver,sizeof(ver),"%u.%u.%u",clientMajorVersion,clientMinorVersion,clientRevision); + sqlite3_bind_text(_sPutLog,5,ver,-1,SQLITE_STATIC); + } else sqlite3_bind_null(_sPutLog,5); + if (fa.length() > 0) + sqlite3_bind_text(_sPutLog,6,fa.c_str(),-1,SQLITE_STATIC); + else sqlite3_bind_null(_sPutLog,6); + sqlite3_step(_sPutLog); + } + + // Check member authorization + + if (!member.authorized) + return NetworkController::NETCONF_QUERY_ACCESS_DENIED; + + // Create and sign netconf + + netconf.clear(); + { + char tss[24],rs[24]; + Utils::snprintf(tss,sizeof(tss),"%.16llx",(unsigned long long)OSUtils::now()); + Utils::snprintf(rs,sizeof(rs),"%.16llx",(unsigned long long)network.revision); + netconf[ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP] = tss; + netconf[ZT_NETWORKCONFIG_DICT_KEY_REVISION] = rs; + netconf[ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID] = network.id; + netconf[ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO] = member.nodeId; + netconf[ZT_NETWORKCONFIG_DICT_KEY_PRIVATE] = network.isPrivate ? "1" : "0"; + netconf[ZT_NETWORKCONFIG_DICT_KEY_NAME] = (network.name) ? network.name : ""; + netconf[ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST] = network.enableBroadcast ? "1" : "0"; + netconf[ZT_NETWORKCONFIG_DICT_KEY_ALLOW_PASSIVE_BRIDGING] = network.allowPassiveBridging ? "1" : "0"; + + { // TODO: right now only etherTypes are supported in rules + std::vector allowedEtherTypes; + sqlite3_reset(_sGetEtherTypesFromRuleTable); + sqlite3_bind_text(_sGetEtherTypesFromRuleTable,1,network.id,16,SQLITE_STATIC); + while (sqlite3_step(_sGetEtherTypesFromRuleTable) == SQLITE_ROW) { + if (sqlite3_column_type(_sGetEtherTypesFromRuleTable,0) == SQLITE_NULL) { + allowedEtherTypes.clear(); + allowedEtherTypes.push_back(0); // NULL 'allow' matches ANY + break; + } else { + int et = sqlite3_column_int(_sGetEtherTypesFromRuleTable,0); + if ((et >= 0)&&(et <= 0xffff)) + allowedEtherTypes.push_back(et); + } + } + std::sort(allowedEtherTypes.begin(),allowedEtherTypes.end()); + allowedEtherTypes.erase(std::unique(allowedEtherTypes.begin(),allowedEtherTypes.end()),allowedEtherTypes.end()); + std::string allowedEtherTypesCsv; + for(std::vector::const_iterator i(allowedEtherTypes.begin());i!=allowedEtherTypes.end();++i) { + if (allowedEtherTypesCsv.length()) + allowedEtherTypesCsv.push_back(','); + char tmp[16]; + Utils::snprintf(tmp,sizeof(tmp),"%.4x",(unsigned int)*i); + allowedEtherTypesCsv.append(tmp); + } + netconf[ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES] = allowedEtherTypesCsv; + } + + if (network.multicastLimit > 0) { + char ml[16]; + Utils::snprintf(ml,sizeof(ml),"%lx",(unsigned long)network.multicastLimit); + netconf[ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT] = ml; + } + + { + std::string activeBridges; + sqlite3_reset(_sGetActiveBridges); + sqlite3_bind_text(_sGetActiveBridges,1,network.id,16,SQLITE_STATIC); + while (sqlite3_step(_sGetActiveBridges) == SQLITE_ROW) { + const char *ab = (const char *)sqlite3_column_text(_sGetActiveBridges,0); + if ((ab)&&(strlen(ab) == 10)) { + if (activeBridges.length()) + activeBridges.push_back(','); + activeBridges.append(ab); + } + if (activeBridges.length() > 1024) // sanity check -- you can't have too many active bridges at the moment + break; + } + if (activeBridges.length()) + netconf[ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES] = activeBridges; + } + + { + std::string relays; + sqlite3_reset(_sGetRelays); + sqlite3_bind_text(_sGetRelays,1,network.id,16,SQLITE_STATIC); + while (sqlite3_step(_sGetRelays) == SQLITE_ROW) { + const char *n = (const char *)sqlite3_column_text(_sGetRelays,0); + const char *a = (const char *)sqlite3_column_text(_sGetRelays,1); + if ((n)&&(a)) { + Address node(n); + InetAddress addr(a); + if ((node)&&(addr)) { + if (relays.length()) + relays.push_back(','); + relays.append(node.toString()); + relays.push_back(';'); + relays.append(addr.toString()); + } + } + } + if (relays.length()) + netconf[ZT_NETWORKCONFIG_DICT_KEY_RELAYS] = relays; + } + + { + char tmp[128]; + std::string gateways; + sqlite3_reset(_sGetGateways); + sqlite3_bind_text(_sGetGateways,1,network.id,16,SQLITE_STATIC); + while (sqlite3_step(_sGetGateways) == SQLITE_ROW) { + const unsigned char *ip = (const unsigned char *)sqlite3_column_blob(_sGetGateways,0); + switch(sqlite3_column_int(_sGetGateways,1)) { // ipVersion + case 4: + Utils::snprintf(tmp,sizeof(tmp),"%s%d.%d.%d.%d/%d", + (gateways.length() > 0) ? "," : "", + (int)ip[12], + (int)ip[13], + (int)ip[14], + (int)ip[15], + (int)sqlite3_column_int(_sGetGateways,2)); // metric + gateways.append(tmp); + break; + case 6: + Utils::snprintf(tmp,sizeof(tmp),"%s%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x/%d", + (gateways.length() > 0) ? "," : "", + (int)ip[0], + (int)ip[1], + (int)ip[2], + (int)ip[3], + (int)ip[4], + (int)ip[5], + (int)ip[6], + (int)ip[7], + (int)ip[8], + (int)ip[9], + (int)ip[10], + (int)ip[11], + (int)ip[12], + (int)ip[13], + (int)ip[14], + (int)ip[15], + (int)sqlite3_column_int(_sGetGateways,2)); // metric + gateways.append(tmp); + break; + } + } + if (gateways.length()) + netconf[ZT_NETWORKCONFIG_DICT_KEY_GATEWAYS] = gateways; + } + + if ((network.v4AssignMode)&&(!strcmp(network.v4AssignMode,"zt"))) { + std::string v4s; + + // Get existing IPv4 IP assignments and network routes -- keep routes in a + // vector for use in auto-assign if we need them. + std::vector< std::pair > routedNetworks; + bool haveStaticIpAssignment = false; + sqlite3_reset(_sGetIpAssignmentsForNode); + sqlite3_bind_text(_sGetIpAssignmentsForNode,1,network.id,16,SQLITE_STATIC); + sqlite3_bind_text(_sGetIpAssignmentsForNode,2,member.nodeId,10,SQLITE_STATIC); + sqlite3_bind_int(_sGetIpAssignmentsForNode,3,4); // 4 == IPv4 + while (sqlite3_step(_sGetIpAssignmentsForNode) == SQLITE_ROW) { + const unsigned char *ip = (const unsigned char *)sqlite3_column_blob(_sGetIpAssignmentsForNode,1); + if ((!ip)||(sqlite3_column_bytes(_sGetIpAssignmentsForNode,1) != 16)) + continue; + int ipNetmaskBits = sqlite3_column_int(_sGetIpAssignmentsForNode,2); + if ((ipNetmaskBits <= 0)||(ipNetmaskBits > 32)) + continue; + + const IpAssignmentType ipt = (IpAssignmentType)sqlite3_column_int(_sGetIpAssignmentsForNode,0); + switch(ipt) { + case ZT_IP_ASSIGNMENT_TYPE_ADDRESS: + haveStaticIpAssignment = true; + break; + case ZT_IP_ASSIGNMENT_TYPE_NETWORK: + routedNetworks.push_back(std::pair(Utils::ntoh(*(reinterpret_cast(ip + 12))),ipNetmaskBits)); + break; + default: + continue; + } + + // 1.0.4 or newer clients support network routes in addition to IPs. + // Older clients only support IP address / netmask entries. + if ((clientIs104)||(ipt == ZT_IP_ASSIGNMENT_TYPE_ADDRESS)) { + char tmp[32]; + Utils::snprintf(tmp,sizeof(tmp),"%d.%d.%d.%d/%d",(int)ip[12],(int)ip[13],(int)ip[14],(int)ip[15],ipNetmaskBits); + if (v4s.length()) + v4s.push_back(','); + v4s.append(tmp); + } + } + + if (!haveStaticIpAssignment) { + // Attempt to auto-assign an IPv4 address from an available routed pool + sqlite3_reset(_sGetIpAssignmentPools); + sqlite3_bind_text(_sGetIpAssignmentPools,1,network.id,16,SQLITE_STATIC); + sqlite3_bind_int(_sGetIpAssignmentPools,2,4); // 4 == IPv4 + + while (sqlite3_step(_sGetIpAssignmentPools) == SQLITE_ROW) { + const unsigned char *ipRangeStartB = reinterpret_cast(sqlite3_column_blob(_sGetIpAssignmentPools,0)); + const unsigned char *ipRangeEndB = reinterpret_cast(sqlite3_column_blob(_sGetIpAssignmentPools,1)); + if ((!ipRangeStartB)||(!ipRangeEndB)||(sqlite3_column_bytes(_sGetIpAssignmentPools,0) != 16)||(sqlite3_column_bytes(_sGetIpAssignmentPools,1) != 16)) + continue; + + uint32_t ipRangeStart = Utils::ntoh(*(reinterpret_cast(ipRangeStartB + 12))); + uint32_t ipRangeEnd = Utils::ntoh(*(reinterpret_cast(ipRangeEndB + 12))); + if (ipRangeEnd < ipRangeStart) + 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,l=0;(k<=ipRangeEnd)&&(l < 1000000);++k,++l) { + uint32_t ip = (ipRangeLen > 0) ? (ipRangeStart + (ipTrialCounter % ipRangeLen)) : ipRangeStart; + ++ipTrialCounter; + + for(std::vector< std::pair >::const_iterator r(routedNetworks.begin());r!=routedNetworks.end();++r) { + if ((ip & (0xffffffff << (32 - r->second))) == r->first) { + // IP is included in a routed network, so check if it's allocated + + uint32_t ipBlob[4]; + ipBlob[0] = 0; ipBlob[1] = 0; ipBlob[2] = 0; ipBlob[3] = Utils::hton(ip); + + sqlite3_reset(_sCheckIfIpIsAllocated); + sqlite3_bind_text(_sCheckIfIpIsAllocated,1,network.id,16,SQLITE_STATIC); + sqlite3_bind_blob(_sCheckIfIpIsAllocated,2,(const void *)ipBlob,16,SQLITE_STATIC); + sqlite3_bind_int(_sCheckIfIpIsAllocated,3,4); // 4 == IPv4 + sqlite3_bind_int(_sCheckIfIpIsAllocated,4,(int)ZT_IP_ASSIGNMENT_TYPE_ADDRESS); + if (sqlite3_step(_sCheckIfIpIsAllocated) != SQLITE_ROW) { + // No rows returned, so the IP is available + sqlite3_reset(_sAllocateIp); + sqlite3_bind_text(_sAllocateIp,1,network.id,16,SQLITE_STATIC); + sqlite3_bind_text(_sAllocateIp,2,member.nodeId,10,SQLITE_STATIC); + sqlite3_bind_int(_sAllocateIp,3,(int)ZT_IP_ASSIGNMENT_TYPE_ADDRESS); + sqlite3_bind_blob(_sAllocateIp,4,(const void *)ipBlob,16,SQLITE_STATIC); + sqlite3_bind_int(_sAllocateIp,5,r->second); // IP netmask bits from matching route + sqlite3_bind_int(_sAllocateIp,6,4); // 4 == IPv4 + if (sqlite3_step(_sAllocateIp) == SQLITE_DONE) { + char tmp[32]; + Utils::snprintf(tmp,sizeof(tmp),"%d.%d.%d.%d/%d",(int)((ip >> 24) & 0xff),(int)((ip >> 16) & 0xff),(int)((ip >> 8) & 0xff),(int)(ip & 0xff),r->second); + if (v4s.length()) + v4s.push_back(','); + v4s.append(tmp); + haveStaticIpAssignment = true; // break outer loop + } + } + + break; // stop checking routed networks + } + } + + if (haveStaticIpAssignment) + break; + } + } + } + + if (v4s.length()) + netconf[ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC] = v4s; + } + + // TODO: IPv6 auto-assign once it's supported in UI + + if (network.isPrivate) { + CertificateOfMembership com(OSUtils::now(),ZT_NETWORK_AUTOCONF_DELAY + (ZT_NETWORK_AUTOCONF_DELAY / 2),nwid,identity.address()); + if (com.sign(signingId)) // basically can't fail unless our identity is invalid + netconf[ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP] = com.toString(); + else { + netconf["error"] = "unable to sign COM"; + return NETCONF_QUERY_INTERNAL_SERVER_ERROR; + } + } + + if (!netconf.sign(signingId,OSUtils::now())) { + netconf["error"] = "unable to sign netconf dictionary"; + return NETCONF_QUERY_INTERNAL_SERVER_ERROR; + } + } + + return NetworkController::NETCONF_QUERY_OK; +} + +unsigned int SqliteNetworkController::handleControlPlaneHttpGET( + const std::vector &path, + const std::map &urlArgs, + const std::map &headers, + const std::string &body, + std::string &responseBody, + std::string &responseContentType) +{ + Mutex::Lock _l(_lock); + return _doCPGet(path,urlArgs,headers,body,responseBody,responseContentType); +} + +unsigned int SqliteNetworkController::handleControlPlaneHttpPOST( + const std::vector &path, + const std::map &urlArgs, + const std::map &headers, + const std::string &body, + std::string &responseBody, + std::string &responseContentType) +{ + if (path.empty()) + return 404; + Mutex::Lock _l(_lock); + + if (path[0] == "network") { + + if ((path.size() >= 2)&&(path[1].length() == 16)) { + uint64_t nwid = Utils::hexStrToU64(path[1].c_str()); + char nwids[24]; + Utils::snprintf(nwids,sizeof(nwids),"%.16llx",(unsigned long long)nwid); + + int64_t revision = 0; + sqlite3_reset(_sGetNetworkRevision); + sqlite3_bind_text(_sGetNetworkRevision,1,nwids,16,SQLITE_STATIC); + bool networkExists = false; + if (sqlite3_step(_sGetNetworkRevision) == SQLITE_ROW) { + networkExists = true; + revision = sqlite3_column_int64(_sGetNetworkRevision,0); + } + + if (path.size() >= 3) { + + if (!networkExists) + return 404; + + if ((path.size() == 4)&&(path[2] == "member")&&(path[3].length() == 10)) { + uint64_t address = Utils::hexStrToU64(path[3].c_str()); + char addrs[24]; + Utils::snprintf(addrs,sizeof(addrs),"%.10llx",address); + + int64_t addToNetworkRevision = 0; + + int64_t memberRowId = 0; + sqlite3_reset(_sGetMember); + sqlite3_bind_text(_sGetMember,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_text(_sGetMember,2,addrs,10,SQLITE_STATIC); + bool memberExists = false; + if (sqlite3_step(_sGetMember) == SQLITE_ROW) { + memberExists = true; + memberRowId = sqlite3_column_int64(_sGetMember,0); + } + + if (!memberExists) { + sqlite3_reset(_sCreateMember); + sqlite3_bind_text(_sCreateMember,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_text(_sCreateMember,2,addrs,10,SQLITE_STATIC); + sqlite3_bind_int(_sCreateMember,3,0); + sqlite3_bind_text(_sCreateMember,4,nwids,16,SQLITE_STATIC); + if (sqlite3_step(_sCreateMember) != SQLITE_DONE) + return 500; + memberRowId = (int64_t)sqlite3_last_insert_rowid(_db); + + sqlite3_reset(_sIncrementMemberRevisionCounter); + sqlite3_bind_text(_sIncrementMemberRevisionCounter,1,nwids,16,SQLITE_STATIC); + sqlite3_step(_sIncrementMemberRevisionCounter); + addToNetworkRevision = 1; + } + + json_value *j = json_parse(body.c_str(),body.length()); + if (j) { + if (j->type == json_object) { + for(unsigned int k=0;ku.object.length;++k) { + + if (!strcmp(j->u.object.values[k].name,"authorized")) { + if (j->u.object.values[k].value->type == json_boolean) { + sqlite3_reset(_sUpdateMemberAuthorized); + sqlite3_bind_int(_sUpdateMemberAuthorized,1,(j->u.object.values[k].value->u.boolean == 0) ? 0 : 1); + sqlite3_bind_text(_sUpdateMemberAuthorized,2,nwids,16,SQLITE_STATIC); + sqlite3_bind_int64(_sUpdateMemberAuthorized,3,memberRowId); + if (sqlite3_step(_sUpdateMemberAuthorized) != SQLITE_DONE) + return 500; + + sqlite3_reset(_sIncrementMemberRevisionCounter); + sqlite3_bind_text(_sIncrementMemberRevisionCounter,1,nwids,16,SQLITE_STATIC); + sqlite3_step(_sIncrementMemberRevisionCounter); + addToNetworkRevision = 1; + } + } else if (!strcmp(j->u.object.values[k].name,"activeBridge")) { + if (j->u.object.values[k].value->type == json_boolean) { + sqlite3_reset(_sUpdateMemberActiveBridge); + sqlite3_bind_int(_sUpdateMemberActiveBridge,1,(j->u.object.values[k].value->u.boolean == 0) ? 0 : 1); + sqlite3_bind_text(_sUpdateMemberActiveBridge,2,nwids,16,SQLITE_STATIC); + sqlite3_bind_int64(_sUpdateMemberActiveBridge,3,memberRowId); + if (sqlite3_step(_sUpdateMemberActiveBridge) != SQLITE_DONE) + return 500; + + sqlite3_reset(_sIncrementMemberRevisionCounter); + sqlite3_bind_text(_sIncrementMemberRevisionCounter,1,nwids,16,SQLITE_STATIC); + sqlite3_step(_sIncrementMemberRevisionCounter); + addToNetworkRevision = 1; + } + } else if (!strcmp(j->u.object.values[k].name,"ipAssignments")) { + if (j->u.object.values[k].value->type == json_array) { + sqlite3_reset(_sDeleteIpAllocations); + sqlite3_bind_text(_sDeleteIpAllocations,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_text(_sDeleteIpAllocations,2,addrs,10,SQLITE_STATIC); + sqlite3_bind_int(_sDeleteIpAllocations,3,(int)ZT_IP_ASSIGNMENT_TYPE_ADDRESS); + if (sqlite3_step(_sDeleteIpAllocations) != SQLITE_DONE) + return 500; + for(unsigned int kk=0;kku.object.values[k].value->u.array.length;++kk) { + json_value *ipalloc = j->u.object.values[k].value->u.array.values[kk]; + if (ipalloc->type == json_string) { + InetAddress a(ipalloc->u.string.ptr); + char ipBlob[16]; + int ipVersion = 0; + switch(a.ss_family) { + case AF_INET: + if ((a.netmaskBits() > 0)&&(a.netmaskBits() <= 32)) { + memset(ipBlob,0,12); + memcpy(ipBlob + 12,a.rawIpData(),4); + ipVersion = 4; + } + break; + case AF_INET6: + if ((a.netmaskBits() > 0)&&(a.netmaskBits() <= 128)) { + memcpy(ipBlob,a.rawIpData(),16); + ipVersion = 6; + } + break; + } + if (ipVersion > 0) { + sqlite3_reset(_sAllocateIp); + sqlite3_bind_text(_sAllocateIp,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_text(_sAllocateIp,2,addrs,10,SQLITE_STATIC); + sqlite3_bind_int(_sAllocateIp,3,(int)ZT_IP_ASSIGNMENT_TYPE_ADDRESS); + sqlite3_bind_blob(_sAllocateIp,4,(const void *)ipBlob,16,SQLITE_STATIC); + sqlite3_bind_int(_sAllocateIp,5,(int)a.netmaskBits()); + sqlite3_bind_int(_sAllocateIp,6,ipVersion); + if (sqlite3_step(_sAllocateIp) != SQLITE_DONE) + return 500; + } + } + } + addToNetworkRevision = 1; + } + } + + } + } + json_value_free(j); + } + + if ((addToNetworkRevision > 0)&&(revision > 0)) { + sqlite3_reset(_sSetNetworkRevision); + sqlite3_bind_int64(_sSetNetworkRevision,1,revision + addToNetworkRevision); + sqlite3_bind_text(_sSetNetworkRevision,2,nwids,16,SQLITE_STATIC); + sqlite3_step(_sSetNetworkRevision); + } + + return _doCPGet(path,urlArgs,headers,body,responseBody,responseContentType); + } // else 404 + + } else { + std::vector path_copy(path); + + if (!networkExists) { + if (path[1].substr(10) == "______") { + // A special POST /network/##########______ feature lets users create a network + // with an arbitrary unused network number at this controller. + nwid = 0; + + uint64_t nwidPrefix = (Utils::hexStrToU64(path[1].substr(0,10).c_str()) << 24) & 0xffffffffff000000ULL; + uint64_t nwidPostfix = 0; + Utils::getSecureRandom(&nwidPostfix,sizeof(nwidPostfix)); + uint64_t nwidOriginalPostfix = nwidPostfix; + do { + uint64_t tryNwid = nwidPrefix | (nwidPostfix & 0xffffffULL); + if (!nwidPostfix) + tryNwid |= 1; + Utils::snprintf(nwids,sizeof(nwids),"%.16llx",(unsigned long long)tryNwid); + + sqlite3_reset(_sGetNetworkRevision); + sqlite3_bind_text(_sGetNetworkRevision,1,nwids,16,SQLITE_STATIC); + if (sqlite3_step(_sGetNetworkRevision) != SQLITE_ROW) { + nwid = tryNwid; + break; + } + + ++nwidPostfix; + } while (nwidPostfix != nwidOriginalPostfix); + + // 503 means we have no more free IDs for this prefix. You shouldn't host anywhere + // near 16 million networks on the same controller, so shouldn't happen. + if (!nwid) + return 503; + } + + sqlite3_reset(_sCreateNetwork); + sqlite3_bind_text(_sCreateNetwork,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_text(_sCreateNetwork,2,"",0,SQLITE_STATIC); + sqlite3_bind_int64(_sCreateNetwork,3,(long long)OSUtils::now()); + if (sqlite3_step(_sCreateNetwork) != SQLITE_DONE) + return 500; + path_copy[1].assign(nwids); + } + + json_value *j = json_parse(body.c_str(),body.length()); + if (j) { + if (j->type == json_object) { + for(unsigned int k=0;ku.object.length;++k) { + sqlite3_stmt *stmt = (sqlite3_stmt *)0; + + if (!strcmp(j->u.object.values[k].name,"name")) { + if ((j->u.object.values[k].value->type == json_string)&&(j->u.object.values[k].value->u.string.ptr[0])) { + if (sqlite3_prepare_v2(_db,"UPDATE Network SET \"name\" = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK) + sqlite3_bind_text(stmt,1,j->u.object.values[k].value->u.string.ptr,-1,SQLITE_STATIC); + } + } else if (!strcmp(j->u.object.values[k].name,"private")) { + if (j->u.object.values[k].value->type == json_boolean) { + if (sqlite3_prepare_v2(_db,"UPDATE Network SET \"private\" = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK) + sqlite3_bind_int(stmt,1,(j->u.object.values[k].value->u.boolean == 0) ? 0 : 1); + } + } else if (!strcmp(j->u.object.values[k].name,"enableBroadcast")) { + if (j->u.object.values[k].value->type == json_boolean) { + if (sqlite3_prepare_v2(_db,"UPDATE Network SET enableBroadcast = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK) + sqlite3_bind_int(stmt,1,(j->u.object.values[k].value->u.boolean == 0) ? 0 : 1); + } + } else if (!strcmp(j->u.object.values[k].name,"allowPassiveBridging")) { + if (j->u.object.values[k].value->type == json_boolean) { + if (sqlite3_prepare_v2(_db,"UPDATE Network SET allowPassiveBridging = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK) + sqlite3_bind_int(stmt,1,(j->u.object.values[k].value->u.boolean == 0) ? 0 : 1); + } + } else if (!strcmp(j->u.object.values[k].name,"v4AssignMode")) { + if (j->u.object.values[k].value->type == json_string) { + if (sqlite3_prepare_v2(_db,"UPDATE Network SET v4AssignMode = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK) + sqlite3_bind_text(stmt,1,j->u.object.values[k].value->u.string.ptr,-1,SQLITE_STATIC); + } + } else if (!strcmp(j->u.object.values[k].name,"v6AssignMode")) { + if (j->u.object.values[k].value->type == json_string) { + if (sqlite3_prepare_v2(_db,"UPDATE Network SET v6AssignMode = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK) + sqlite3_bind_text(stmt,1,j->u.object.values[k].value->u.string.ptr,-1,SQLITE_STATIC); + } + } else if (!strcmp(j->u.object.values[k].name,"multicastLimit")) { + if (j->u.object.values[k].value->type == json_integer) { + if (sqlite3_prepare_v2(_db,"UPDATE Network SET multicastLimit = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK) + sqlite3_bind_int(stmt,1,(int)j->u.object.values[k].value->u.integer); + } + } else if (!strcmp(j->u.object.values[k].name,"relays")) { + if (j->u.object.values[k].value->type == json_array) { + std::map nodeIdToPhyAddress; + for(unsigned int kk=0;kku.object.values[k].value->u.array.length;++kk) { + json_value *relay = j->u.object.values[k].value->u.array.values[kk]; + const char *address = (const char *)0; + const char *phyAddress = (const char *)0; + if ((relay)&&(relay->type == json_object)) { + for(unsigned int rk=0;rku.object.length;++rk) { + if ((!strcmp(relay->u.object.values[rk].name,"address"))&&(relay->u.object.values[rk].value->type == json_string)) + address = relay->u.object.values[rk].value->u.string.ptr; + else if ((!strcmp(relay->u.object.values[rk].name,"phyAddress"))&&(relay->u.object.values[rk].value->type == json_string)) + phyAddress = relay->u.object.values[rk].value->u.string.ptr; + } + } + if ((address)&&(phyAddress)) + nodeIdToPhyAddress[Address(address)] = InetAddress(phyAddress); + } + + sqlite3_reset(_sDeleteRelaysForNetwork); + sqlite3_bind_text(_sDeleteRelaysForNetwork,1,nwids,16,SQLITE_STATIC); + sqlite3_step(_sDeleteRelaysForNetwork); + + for(std::map::iterator rl(nodeIdToPhyAddress.begin());rl!=nodeIdToPhyAddress.end();++rl) { + sqlite3_reset(_sCreateRelay); + sqlite3_bind_text(_sCreateRelay,1,nwids,16,SQLITE_STATIC); + std::string a(rl->first.toString()),b(rl->second.toString()); // don't destroy strings until sqlite3_step() + sqlite3_bind_text(_sCreateRelay,2,a.c_str(),-1,SQLITE_STATIC); + sqlite3_bind_text(_sCreateRelay,3,b.c_str(),-1,SQLITE_STATIC); + sqlite3_step(_sCreateRelay); + } + } + } else if (!strcmp(j->u.object.values[k].name,"gateways")) { + sqlite3_reset(_sDeleteGateways); + sqlite3_bind_text(_sDeleteGateways,1,nwids,16,SQLITE_STATIC); + sqlite3_step(_sDeleteGateways); + if (j->u.object.values[k].value->type == json_array) { + for(unsigned int kk=0;kku.object.values[k].value->u.array.length;++kk) { + json_value *gateway = j->u.object.values[k].value->u.array.values[kk]; + if ((gateway)&&(gateway->type == json_string)) { + InetAddress gwip(gateway->u.string.ptr); + sqlite3_reset(_sCreateGateway); + sqlite3_bind_text(_sCreateGateway,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_int(_sCreateGateway,4,(int)gwip.metric()); + if (gwip.ss_family == AF_INET) { + char ipBlob[16]; + memset(ipBlob,0,12); + memcpy(ipBlob + 12,gwip.rawIpData(),4); + sqlite3_bind_blob(_sCreateGateway,2,(const void *)ipBlob,16,SQLITE_STATIC); + sqlite3_bind_int(_sCreateGateway,3,4); + sqlite3_step(_sCreateGateway); + } else if (gwip.ss_family == AF_INET6) { + sqlite3_bind_blob(_sCreateGateway,2,gwip.rawIpData(),16,SQLITE_STATIC); + sqlite3_bind_int(_sCreateGateway,3,6); + sqlite3_step(_sCreateGateway); + } + } + } + } + } else if (!strcmp(j->u.object.values[k].name,"ipLocalRoutes")) { + sqlite3_reset(_sDeleteLocalRoutes); + sqlite3_bind_text(_sDeleteLocalRoutes,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_int(_sDeleteLocalRoutes,2,(int)ZT_IP_ASSIGNMENT_TYPE_NETWORK); + sqlite3_step(_sDeleteLocalRoutes); + if (j->u.object.values[k].value->type == json_array) { + for(unsigned int kk=0;kku.object.values[k].value->u.array.length;++kk) { + json_value *localRoute = j->u.object.values[k].value->u.array.values[kk]; + if ((localRoute)&&(localRoute->type == json_string)) { + InetAddress lr(localRoute->u.string.ptr); + if (lr.ss_family == AF_INET) { + char ipBlob[16]; + memset(ipBlob,0,12); + memcpy(ipBlob + 12,lr.rawIpData(),4); + sqlite3_reset(_sAllocateIp); + sqlite3_bind_text(_sAllocateIp,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_null(_sAllocateIp,2); + sqlite3_bind_int(_sAllocateIp,3,(int)ZT_IP_ASSIGNMENT_TYPE_NETWORK); + sqlite3_bind_blob(_sAllocateIp,4,(const void *)ipBlob,16,SQLITE_STATIC); + sqlite3_bind_int(_sAllocateIp,5,lr.netmaskBits()); + sqlite3_bind_int(_sAllocateIp,6,4); + sqlite3_step(_sAllocateIp); + } else if (lr.ss_family == AF_INET6) { + sqlite3_reset(_sAllocateIp); + sqlite3_bind_text(_sAllocateIp,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_null(_sAllocateIp,2); + sqlite3_bind_int(_sAllocateIp,3,(int)ZT_IP_ASSIGNMENT_TYPE_NETWORK); + sqlite3_bind_blob(_sAllocateIp,4,lr.rawIpData(),16,SQLITE_STATIC); + sqlite3_bind_int(_sAllocateIp,5,lr.netmaskBits()); + sqlite3_bind_int(_sAllocateIp,6,6); + sqlite3_step(_sAllocateIp); + } + } + } + } + } else if (!strcmp(j->u.object.values[k].name,"ipAssignmentPools")) { + if (j->u.object.values[k].value->type == json_array) { + std::vector< std::pair > pools; + for(unsigned int kk=0;kku.object.values[k].value->u.array.length;++kk) { + json_value *pool = j->u.object.values[k].value->u.array.values[kk]; + const char *iprs = (const char *)0; + const char *ipre = (const char *)0; + if ((pool)&&(pool->type == json_object)) { + for(unsigned int rk=0;rku.object.length;++rk) { + if ((!strcmp(pool->u.object.values[rk].name,"ipRangeStart"))&&(pool->u.object.values[rk].value->type == json_string)) + iprs = pool->u.object.values[rk].value->u.string.ptr; + else if ((!strcmp(pool->u.object.values[rk].name,"ipRangeEnd"))&&(pool->u.object.values[rk].value->type == json_string)) + ipre = pool->u.object.values[rk].value->u.string.ptr; + } + } + if ((iprs)&&(ipre)) { + InetAddress iprs2(iprs); + InetAddress ipre2(ipre); + if (iprs2.ss_family == ipre2.ss_family) { + iprs2.setPort(0); + ipre2.setPort(0); + pools.push_back(std::pair(iprs2,ipre2)); + } + } + } + std::sort(pools.begin(),pools.end()); + pools.erase(std::unique(pools.begin(),pools.end()),pools.end()); + + sqlite3_reset(_sDeleteIpAssignmentPoolsForNetwork); + sqlite3_bind_text(_sDeleteIpAssignmentPoolsForNetwork,1,nwids,16,SQLITE_STATIC); + sqlite3_step(_sDeleteIpAssignmentPoolsForNetwork); + + for(std::vector< std::pair >::const_iterator p(pools.begin());p!=pools.end();++p) { + char ipBlob1[16],ipBlob2[16]; + sqlite3_reset(_sCreateIpAssignmentPool); + sqlite3_bind_text(_sCreateIpAssignmentPool,1,nwids,16,SQLITE_STATIC); + if (p->first.ss_family == AF_INET) { + memset(ipBlob1,0,12); + memcpy(ipBlob1 + 12,p->first.rawIpData(),4); + memset(ipBlob2,0,12); + memcpy(ipBlob2 + 12,p->second.rawIpData(),4); + sqlite3_bind_blob(_sCreateIpAssignmentPool,2,(const void *)ipBlob1,16,SQLITE_STATIC); + sqlite3_bind_blob(_sCreateIpAssignmentPool,3,(const void *)ipBlob2,16,SQLITE_STATIC); + sqlite3_bind_int(_sCreateIpAssignmentPool,4,4); + } else if (p->first.ss_family == AF_INET6) { + sqlite3_bind_blob(_sCreateIpAssignmentPool,2,p->first.rawIpData(),16,SQLITE_STATIC); + sqlite3_bind_blob(_sCreateIpAssignmentPool,3,p->second.rawIpData(),16,SQLITE_STATIC); + sqlite3_bind_int(_sCreateIpAssignmentPool,4,6); + } else continue; + sqlite3_step(_sCreateIpAssignmentPool); + } + } + } else if (!strcmp(j->u.object.values[k].name,"rules")) { + if (j->u.object.values[k].value->type == json_array) { + sqlite3_reset(_sDeleteRulesForNetwork); + sqlite3_bind_text(_sDeleteRulesForNetwork,1,nwids,16,SQLITE_STATIC); + sqlite3_step(_sDeleteRulesForNetwork); + + for(unsigned int kk=0;kku.object.values[k].value->u.array.length;++kk) { + json_value *rj = j->u.object.values[k].value->u.array.values[kk]; + if ((rj)&&(rj->type == json_object)) { + struct { // NULL pointers indicate missing or NULL -- wildcards + const json_int_t *ruleNo; + const char *nodeId; + const char *sourcePort; + const char *destPort; + const json_int_t *vlanId; + const json_int_t *vlanPcp; + const json_int_t *etherType; + const char *macSource; + const char *macDest; + const char *ipSource; + const char *ipDest; + const json_int_t *ipTos; + const json_int_t *ipProtocol; + const json_int_t *ipSourcePort; + const json_int_t *ipDestPort; + const json_int_t *flags; + const json_int_t *invFlags; + const char *action; + } rule; + memset(&rule,0,sizeof(rule)); + + for(unsigned int rk=0;rku.object.length;++rk) { + if ((!strcmp(rj->u.object.values[rk].name,"ruleNo"))&&(rj->u.object.values[rk].value->type == json_integer)) + rule.ruleNo = &(rj->u.object.values[rk].value->u.integer); + else if ((!strcmp(rj->u.object.values[rk].name,"nodeId"))&&(rj->u.object.values[rk].value->type == json_string)) + rule.nodeId = rj->u.object.values[rk].value->u.string.ptr; + else if ((!strcmp(rj->u.object.values[rk].name,"sourcePort"))&&(rj->u.object.values[rk].value->type == json_string)) + rule.sourcePort = rj->u.object.values[rk].value->u.string.ptr; + else if ((!strcmp(rj->u.object.values[rk].name,"destPort"))&&(rj->u.object.values[rk].value->type == json_string)) + rule.destPort = rj->u.object.values[rk].value->u.string.ptr; + else if ((!strcmp(rj->u.object.values[rk].name,"vlanId"))&&(rj->u.object.values[rk].value->type == json_integer)) + rule.vlanId = &(rj->u.object.values[rk].value->u.integer); + else if ((!strcmp(rj->u.object.values[rk].name,"vlanPcp"))&&(rj->u.object.values[rk].value->type == json_integer)) + rule.vlanPcp = &(rj->u.object.values[rk].value->u.integer); + else if ((!strcmp(rj->u.object.values[rk].name,"etherType"))&&(rj->u.object.values[rk].value->type == json_integer)) + rule.etherType = &(rj->u.object.values[rk].value->u.integer); + else if ((!strcmp(rj->u.object.values[rk].name,"macSource"))&&(rj->u.object.values[rk].value->type == json_string)) + rule.macSource = rj->u.object.values[rk].value->u.string.ptr; + else if ((!strcmp(rj->u.object.values[rk].name,"macDest"))&&(rj->u.object.values[rk].value->type == json_string)) + rule.macDest = rj->u.object.values[rk].value->u.string.ptr; + else if ((!strcmp(rj->u.object.values[rk].name,"ipSource"))&&(rj->u.object.values[rk].value->type == json_string)) + rule.ipSource = rj->u.object.values[rk].value->u.string.ptr; + else if ((!strcmp(rj->u.object.values[rk].name,"ipDest"))&&(rj->u.object.values[rk].value->type == json_string)) + rule.ipDest = rj->u.object.values[rk].value->u.string.ptr; + else if ((!strcmp(rj->u.object.values[rk].name,"ipTos"))&&(rj->u.object.values[rk].value->type == json_integer)) + rule.ipTos = &(rj->u.object.values[rk].value->u.integer); + else if ((!strcmp(rj->u.object.values[rk].name,"ipProtocol"))&&(rj->u.object.values[rk].value->type == json_integer)) + rule.ipProtocol = &(rj->u.object.values[rk].value->u.integer); + else if ((!strcmp(rj->u.object.values[rk].name,"ipSourcePort"))&&(rj->u.object.values[rk].value->type == json_integer)) + rule.ipSourcePort = &(rj->u.object.values[rk].value->u.integer); + else if ((!strcmp(rj->u.object.values[rk].name,"ipDestPort"))&&(rj->u.object.values[rk].value->type == json_integer)) + rule.ipDestPort = &(rj->u.object.values[rk].value->u.integer); + else if ((!strcmp(rj->u.object.values[rk].name,"flags"))&&(rj->u.object.values[rk].value->type == json_integer)) + rule.flags = &(rj->u.object.values[rk].value->u.integer); + else if ((!strcmp(rj->u.object.values[rk].name,"invFlags"))&&(rj->u.object.values[rk].value->type == json_integer)) + rule.invFlags = &(rj->u.object.values[rk].value->u.integer); + else if ((!strcmp(rj->u.object.values[rk].name,"action"))&&(rj->u.object.values[rk].value->type == json_string)) + rule.action = rj->u.object.values[rk].value->u.string.ptr; + } + + if ((rule.ruleNo)&&(rule.action)&&(rule.action[0])) { + char mactmp1[16],mactmp2[16]; + sqlite3_reset(_sCreateRule); + sqlite3_bind_text(_sCreateRule,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_int64(_sCreateRule,2,*rule.ruleNo); + + // Optional values: null by default + for(int i=3;i<=18;++i) + sqlite3_bind_null(_sCreateRule,i); + if ((rule.nodeId)&&(strlen(rule.nodeId) == 10)) sqlite3_bind_text(_sCreateRule,3,rule.nodeId,10,SQLITE_STATIC); + if ((rule.sourcePort)&&(strlen(rule.sourcePort) == 10)) sqlite3_bind_text(_sCreateRule,4,rule.sourcePort,10,SQLITE_STATIC); + if ((rule.destPort)&&(strlen(rule.destPort) == 10)) sqlite3_bind_text(_sCreateRule,5,rule.destPort,10,SQLITE_STATIC); + if (rule.vlanId) sqlite3_bind_int(_sCreateRule,6,(int)*rule.vlanId); + if (rule.vlanPcp) sqlite3_bind_int(_sCreateRule,7,(int)*rule.vlanPcp); + if (rule.etherType) sqlite3_bind_int(_sCreateRule,8,(int)*rule.etherType & (int)0xffff); + if (rule.macSource) { + MAC m(rule.macSource); + Utils::snprintf(mactmp1,sizeof(mactmp1),"%.12llx",(unsigned long long)m.toInt()); + sqlite3_bind_text(_sCreateRule,9,mactmp1,-1,SQLITE_STATIC); + } + if (rule.macDest) { + MAC m(rule.macDest); + Utils::snprintf(mactmp2,sizeof(mactmp2),"%.12llx",(unsigned long long)m.toInt()); + sqlite3_bind_text(_sCreateRule,10,mactmp2,-1,SQLITE_STATIC); + } + if (rule.ipSource) sqlite3_bind_text(_sCreateRule,11,rule.ipSource,-1,SQLITE_STATIC); + if (rule.ipDest) sqlite3_bind_text(_sCreateRule,12,rule.ipDest,-1,SQLITE_STATIC); + if (rule.ipTos) sqlite3_bind_int(_sCreateRule,13,(int)*rule.ipTos); + if (rule.ipProtocol) sqlite3_bind_int(_sCreateRule,14,(int)*rule.ipProtocol); + if (rule.ipSourcePort) sqlite3_bind_int(_sCreateRule,15,(int)*rule.ipSourcePort & (int)0xffff); + if (rule.ipDestPort) sqlite3_bind_int(_sCreateRule,16,(int)*rule.ipDestPort & (int)0xffff); + if (rule.flags) sqlite3_bind_int64(_sCreateRule,17,(int64_t)*rule.flags); + if (rule.invFlags) sqlite3_bind_int64(_sCreateRule,18,(int64_t)*rule.invFlags); + + sqlite3_bind_text(_sCreateRule,19,rule.action,-1,SQLITE_STATIC); + sqlite3_step(_sCreateRule); + } + } + } + } + } + + if (stmt) { + sqlite3_bind_text(stmt,2,nwids,16,SQLITE_STATIC); + sqlite3_step(stmt); + sqlite3_finalize(stmt); + } + } + } + json_value_free(j); + } + + sqlite3_reset(_sSetNetworkRevision); + sqlite3_bind_int64(_sSetNetworkRevision,1,revision += 1); + sqlite3_bind_text(_sSetNetworkRevision,2,nwids,16,SQLITE_STATIC); + sqlite3_step(_sSetNetworkRevision); + + return _doCPGet(path_copy,urlArgs,headers,body,responseBody,responseContentType); + } + + } // else 404 + + } // else 404 + + return 404; +} + +unsigned int SqliteNetworkController::handleControlPlaneHttpDELETE( + const std::vector &path, + const std::map &urlArgs, + const std::map &headers, + const std::string &body, + std::string &responseBody, + std::string &responseContentType) +{ + if (path.empty()) + return 404; + Mutex::Lock _l(_lock); + + if (path[0] == "network") { + + if ((path.size() >= 2)&&(path[1].length() == 16)) { + uint64_t nwid = Utils::hexStrToU64(path[1].c_str()); + char nwids[24]; + Utils::snprintf(nwids,sizeof(nwids),"%.16llx",(unsigned long long)nwid); + + sqlite3_reset(_sGetNetworkById); + sqlite3_bind_text(_sGetNetworkById,1,nwids,16,SQLITE_STATIC); + if (sqlite3_step(_sGetNetworkById) != SQLITE_ROW) + return 404; + + if (path.size() >= 3) { + + if ((path.size() == 4)&&(path[2] == "member")&&(path[3].length() == 10)) { + uint64_t address = Utils::hexStrToU64(path[3].c_str()); + char addrs[24]; + Utils::snprintf(addrs,sizeof(addrs),"%.10llx",address); + + sqlite3_reset(_sGetMember); + sqlite3_bind_text(_sGetMember,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_text(_sGetMember,2,addrs,10,SQLITE_STATIC); + if (sqlite3_step(_sGetMember) != SQLITE_ROW) + return 404; + + sqlite3_reset(_sDeleteIpAllocations); + sqlite3_bind_text(_sDeleteIpAllocations,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_text(_sDeleteIpAllocations,2,addrs,10,SQLITE_STATIC); + sqlite3_bind_int(_sDeleteIpAllocations,3,(int)ZT_IP_ASSIGNMENT_TYPE_ADDRESS); + if (sqlite3_step(_sDeleteIpAllocations) == SQLITE_DONE) { + sqlite3_reset(_sDeleteMember); + sqlite3_bind_text(_sDeleteMember,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_text(_sDeleteMember,2,addrs,10,SQLITE_STATIC); + if (sqlite3_step(_sDeleteMember) != SQLITE_DONE) + return 500; + } else return 500; + + return 200; + } + + } else { + + sqlite3_reset(_sDeleteNetwork); + sqlite3_bind_text(_sDeleteNetwork,1,nwids,16,SQLITE_STATIC); + return ((sqlite3_step(_sDeleteNetwork) == SQLITE_DONE) ? 200 : 500); + + } + } // else 404 + + } // else 404 + + return 404; +} + +unsigned int SqliteNetworkController::_doCPGet( + const std::vector &path, + const std::map &urlArgs, + const std::map &headers, + const std::string &body, + std::string &responseBody, + std::string &responseContentType) +{ + // Assumes _lock is locked + char json[16384]; + + if ((path.size() > 0)&&(path[0] == "network")) { + + if ((path.size() >= 2)&&(path[1].length() == 16)) { + uint64_t nwid = Utils::hexStrToU64(path[1].c_str()); + char nwids[24]; + Utils::snprintf(nwids,sizeof(nwids),"%.16llx",(unsigned long long)nwid); + + if (path.size() >= 3) { + // /network//... + + if (path[2] == "member") { + + if (path.size() >= 4) { + // Get specific member info + + uint64_t address = Utils::hexStrToU64(path[3].c_str()); + char addrs[24]; + Utils::snprintf(addrs,sizeof(addrs),"%.10llx",address); + + sqlite3_reset(_sGetMember2); + sqlite3_bind_text(_sGetMember2,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_text(_sGetMember2,2,addrs,10,SQLITE_STATIC); + if (sqlite3_step(_sGetMember2) == SQLITE_ROW) { + Utils::snprintf(json,sizeof(json), + "{\n" + "\t\"nwid\": \"%s\",\n" + "\t\"address\": \"%s\",\n" + "\t\"controllerInstanceId\": \"%s\",\n" + "\t\"authorized\": %s,\n" + "\t\"activeBridge\": %s,\n" + "\t\"memberRevision\": %llu,\n" + "\t\"identity\": \"%s\",\n" + "\t\"ipAssignments\": [", + nwids, + addrs, + _instanceId.c_str(), + (sqlite3_column_int(_sGetMember2,0) > 0) ? "true" : "false", + (sqlite3_column_int(_sGetMember2,1) > 0) ? "true" : "false", + (unsigned long long)sqlite3_column_int64(_sGetMember2,2), + _jsonEscape((const char *)sqlite3_column_text(_sGetMember2,3)).c_str()); + responseBody = json; + + sqlite3_reset(_sGetIpAssignmentsForNode2); + sqlite3_bind_text(_sGetIpAssignmentsForNode2,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_text(_sGetIpAssignmentsForNode2,2,addrs,10,SQLITE_STATIC); + sqlite3_bind_int(_sGetIpAssignmentsForNode2,3,(int)ZT_IP_ASSIGNMENT_TYPE_ADDRESS); + bool firstIp = true; + while (sqlite3_step(_sGetIpAssignmentsForNode2) == SQLITE_ROW) { + int ipversion = sqlite3_column_int(_sGetIpAssignmentsForNode2,2); + char ipBlob[16]; + memcpy(ipBlob,(const void *)sqlite3_column_blob(_sGetIpAssignmentsForNode2,0),16); + InetAddress ip( + (const void *)(ipversion == 6 ? ipBlob : &ipBlob[12]), + (ipversion == 6 ? 16 : 4), + (unsigned int)sqlite3_column_int(_sGetIpAssignmentsForNode2,1) + ); + responseBody.append(firstIp ? "\"" : ",\""); + firstIp = false; + responseBody.append(_jsonEscape(ip.toString())); + responseBody.push_back('"'); + } + + responseBody.append("],\n\t\"recentLog\": ["); + + sqlite3_reset(_sGetRecentMemberLog); + sqlite3_bind_text(_sGetRecentMemberLog,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_text(_sGetRecentMemberLog,2,addrs,10,SQLITE_STATIC); + bool firstLog = true; + while (sqlite3_step(_sGetRecentMemberLog) == SQLITE_ROW) { + responseBody.append(firstLog ? "{" : ",{"); + firstLog = false; + responseBody.append("\"ts\":"); + responseBody.append(reinterpret_cast(sqlite3_column_text(_sGetRecentMemberLog,0))); + responseBody.append((sqlite3_column_int(_sGetRecentMemberLog,1) == 0) ? ",\"authorized\":false,\"version\":" : ",\"authorized\":true,\"version\":"); + const char *ver = reinterpret_cast(sqlite3_column_text(_sGetRecentMemberLog,2)); + if ((ver)&&(ver[0])) { + responseBody.push_back('"'); + responseBody.append(_jsonEscape(ver)); + responseBody.append("\",\"fromAddr\":"); + } else responseBody.append("null,\"fromAddr\":"); + const char *fa = reinterpret_cast(sqlite3_column_text(_sGetRecentMemberLog,3)); + if ((fa)&&(fa[0])) { + responseBody.push_back('"'); + responseBody.append(_jsonEscape(fa)); + responseBody.append("\"}"); + } else responseBody.append("null}"); + } + + responseBody.append("]\n}\n"); + + responseContentType = "application/json"; + return 200; + } // else 404 + + } else { + // List members + + sqlite3_reset(_sListNetworkMembers); + sqlite3_bind_text(_sListNetworkMembers,1,nwids,16,SQLITE_STATIC); + responseBody.append("{"); + bool firstMember = true; + while (sqlite3_step(_sListNetworkMembers) == SQLITE_ROW) { + responseBody.append(firstMember ? "\"" : ",\""); + firstMember = false; + responseBody.append((const char *)sqlite3_column_text(_sListNetworkMembers,0)); + responseBody.append("\":"); + responseBody.append((const char *)sqlite3_column_text(_sListNetworkMembers,1)); + } + responseBody.push_back('}'); + responseContentType = "application/json"; + return 200; + + } + + } // else 404 + + } else { + // get network info + sqlite3_reset(_sGetNetworkById); + sqlite3_bind_text(_sGetNetworkById,1,nwids,16,SQLITE_STATIC); + if (sqlite3_step(_sGetNetworkById) == SQLITE_ROW) { + Utils::snprintf(json,sizeof(json), + "{\n" + "\t\"nwid\": \"%s\",\n" + "\t\"controllerInstanceId\": \"%s\",\n" + "\t\"name\": \"%s\",\n" + "\t\"private\": %s,\n" + "\t\"enableBroadcast\": %s,\n" + "\t\"allowPassiveBridging\": %s,\n" + "\t\"v4AssignMode\": \"%s\",\n" + "\t\"v6AssignMode\": \"%s\",\n" + "\t\"multicastLimit\": %d,\n" + "\t\"creationTime\": %llu,\n" + "\t\"revision\": %llu,\n" + "\t\"memberRevisionCounter\": %llu,\n" + "\t\"relays\": [", + nwids, + _instanceId.c_str(), + _jsonEscape((const char *)sqlite3_column_text(_sGetNetworkById,0)).c_str(), + (sqlite3_column_int(_sGetNetworkById,1) > 0) ? "true" : "false", + (sqlite3_column_int(_sGetNetworkById,2) > 0) ? "true" : "false", + (sqlite3_column_int(_sGetNetworkById,3) > 0) ? "true" : "false", + _jsonEscape((const char *)sqlite3_column_text(_sGetNetworkById,4)).c_str(), + _jsonEscape((const char *)sqlite3_column_text(_sGetNetworkById,5)).c_str(), + sqlite3_column_int(_sGetNetworkById,6), + (unsigned long long)sqlite3_column_int64(_sGetNetworkById,7), + (unsigned long long)sqlite3_column_int64(_sGetNetworkById,8), + (unsigned long long)sqlite3_column_int64(_sGetNetworkById,9)); + responseBody = json; + + sqlite3_reset(_sGetRelays); + sqlite3_bind_text(_sGetRelays,1,nwids,16,SQLITE_STATIC); + bool firstRelay = true; + while (sqlite3_step(_sGetRelays) == SQLITE_ROW) { + responseBody.append(firstRelay ? "\n\t\t" : ",\n\t\t"); + firstRelay = false; + responseBody.append("{\"address\":\""); + responseBody.append((const char *)sqlite3_column_text(_sGetRelays,0)); + responseBody.append("\",\"phyAddress\":\""); + responseBody.append(_jsonEscape((const char *)sqlite3_column_text(_sGetRelays,1))); + responseBody.append("\"}"); + } + + responseBody.append("],\n\t\"gateways\": ["); + + sqlite3_reset(_sGetGateways); + sqlite3_bind_text(_sGetGateways,1,nwids,16,SQLITE_STATIC); + bool firstGateway = true; + while (sqlite3_step(_sGetGateways) == SQLITE_ROW) { + char tmp[128]; + const unsigned char *ip = (const unsigned char *)sqlite3_column_blob(_sGetGateways,0); + switch(sqlite3_column_int(_sGetGateways,1)) { // ipVersion + case 4: + Utils::snprintf(tmp,sizeof(tmp),"%s%d.%d.%d.%d/%d\"", + (firstGateway) ? "\"" : ",\"", + (int)ip[12], + (int)ip[13], + (int)ip[14], + (int)ip[15], + (int)sqlite3_column_int(_sGetGateways,2)); // metric + break; + case 6: + Utils::snprintf(tmp,sizeof(tmp),"%s%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x/%d\"", + (firstGateway) ? "\"" : ",\"", + (int)ip[0], + (int)ip[1], + (int)ip[2], + (int)ip[3], + (int)ip[4], + (int)ip[5], + (int)ip[6], + (int)ip[7], + (int)ip[8], + (int)ip[9], + (int)ip[10], + (int)ip[11], + (int)ip[12], + (int)ip[13], + (int)ip[14], + (int)ip[15], + (int)sqlite3_column_int(_sGetGateways,2)); // metric + break; + } + responseBody.append(tmp); + firstGateway = false; + } + + responseBody.append("],\n\t\"ipLocalRoutes\": ["); + + sqlite3_reset(_sGetLocalRoutes); + sqlite3_bind_text(_sGetLocalRoutes,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_int(_sGetLocalRoutes,2,(int)ZT_IP_ASSIGNMENT_TYPE_NETWORK); + bool firstLocalRoute = true; + while (sqlite3_step(_sGetLocalRoutes) == SQLITE_ROW) { + char tmp[128]; + const unsigned char *ip = (const unsigned char *)sqlite3_column_blob(_sGetLocalRoutes,0); + switch (sqlite3_column_int(_sGetLocalRoutes,2)) { + case 4: + Utils::snprintf(tmp,sizeof(tmp),"%s%d.%d.%d.%d/%d\"", + (firstLocalRoute) ? "\"" : ",\"", + (int)ip[12], + (int)ip[13], + (int)ip[14], + (int)ip[15], + (int)sqlite3_column_int(_sGetLocalRoutes,1)); // netmask bits + break; + case 6: + Utils::snprintf(tmp,sizeof(tmp),"%s%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x/%d\"", + (firstLocalRoute) ? "\"" : ",\"", + (int)ip[0], + (int)ip[1], + (int)ip[2], + (int)ip[3], + (int)ip[4], + (int)ip[5], + (int)ip[6], + (int)ip[7], + (int)ip[8], + (int)ip[9], + (int)ip[10], + (int)ip[11], + (int)ip[12], + (int)ip[13], + (int)ip[14], + (int)ip[15], + (int)sqlite3_column_int(_sGetLocalRoutes,1)); // netmask bits + break; + } + responseBody.append(tmp); + firstLocalRoute = false; + } + + responseBody.append("],\n\t\"ipAssignmentPools\": ["); + + sqlite3_reset(_sGetIpAssignmentPools2); + sqlite3_bind_text(_sGetIpAssignmentPools2,1,nwids,16,SQLITE_STATIC); + bool firstIpAssignmentPool = true; + while (sqlite3_step(_sGetIpAssignmentPools2) == SQLITE_ROW) { + const char *ipRangeStartB = reinterpret_cast(sqlite3_column_blob(_sGetIpAssignmentPools2,0)); + const char *ipRangeEndB = reinterpret_cast(sqlite3_column_blob(_sGetIpAssignmentPools2,1)); + if ((ipRangeStartB)&&(ipRangeEndB)) { + InetAddress ipps,ippe; + int ipVersion = sqlite3_column_int(_sGetIpAssignmentPools2,2); + if (ipVersion == 4) { + ipps.set((const void *)(ipRangeStartB + 12),4,0); + ippe.set((const void *)(ipRangeEndB + 12),4,0); + } else if (ipVersion == 6) { + ipps.set((const void *)ipRangeStartB,16,0); + ippe.set((const void *)ipRangeEndB,16,0); + } + if (ipps) { + responseBody.append(firstIpAssignmentPool ? "\n\t\t" : ",\n\t\t"); + firstIpAssignmentPool = false; + Utils::snprintf(json,sizeof(json),"{\"ipRangeStart\":\"%s\",\"ipRangeEnd\":\"%s\"}", + _jsonEscape(ipps.toIpString()).c_str(), + _jsonEscape(ippe.toIpString()).c_str()); + responseBody.append(json); + } + } + } + + responseBody.append("],\n\t\"rules\": ["); + + sqlite3_reset(_sListRules); + sqlite3_bind_text(_sListRules,1,nwids,16,SQLITE_STATIC); + bool firstRule = true; + while (sqlite3_step(_sListRules) == SQLITE_ROW) { + responseBody.append(firstRule ? "\n\t{\n" : ",{\n"); + firstRule = false; + Utils::snprintf(json,sizeof(json),"\t\t\"ruleNo\": %lld,\n",sqlite3_column_int64(_sListRules,0)); + responseBody.append(json); + if (sqlite3_column_type(_sListRules,1) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"nodeId\": \"%s\",\n",(const char *)sqlite3_column_text(_sListRules,1)); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,2) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"sourcePort\": \"%s\",\n",(const char *)sqlite3_column_text(_sListRules,2)); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,3) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"destPort\": \"%s\",\n",(const char *)sqlite3_column_text(_sListRules,3)); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,4) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"vlanId\": %d,\n",sqlite3_column_int(_sListRules,4)); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,5) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"vlanPcp\": %d,\n",sqlite3_column_int(_sListRules,5)); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,6) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"etherType\": %d,\n",sqlite3_column_int(_sListRules,6)); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,7) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"macSource\": \"%s\",\n",MAC((const char *)sqlite3_column_text(_sListRules,7)).toString().c_str()); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,8) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"macDest\": \"%s\",\n",MAC((const char *)sqlite3_column_text(_sListRules,8)).toString().c_str()); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,9) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"ipSource\": \"%s\",\n",_jsonEscape((const char *)sqlite3_column_text(_sListRules,9)).c_str()); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,10) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"ipDest\": \"%s\",\n",_jsonEscape((const char *)sqlite3_column_text(_sListRules,10)).c_str()); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,11) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"ipTos\": %d,\n",sqlite3_column_int(_sListRules,11)); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,12) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"ipProtocol\": %d,\n",sqlite3_column_int(_sListRules,12)); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,13) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"ipSourcePort\": %d,\n",sqlite3_column_int(_sListRules,13)); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,14) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"ipDestPort\": %d,\n",sqlite3_column_int(_sListRules,14)); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,15) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"flags\": %lu,\n",(unsigned long)sqlite3_column_int64(_sListRules,15)); + responseBody.append(json); + } + if (sqlite3_column_type(_sListRules,16) != SQLITE_NULL) { + Utils::snprintf(json,sizeof(json),"\t\t\"invFlags\": %lu,\n",(unsigned long)sqlite3_column_int64(_sListRules,16)); + responseBody.append(json); + } + responseBody.append("\t\t\"action\": \""); + responseBody.append(_jsonEscape( (sqlite3_column_type(_sListRules,17) == SQLITE_NULL) ? "drop" : (const char *)sqlite3_column_text(_sListRules,17) )); + responseBody.append("\"\n\t}"); + } + + responseBody.append("]\n}\n"); + responseContentType = "application/json"; + return 200; + } // else 404 + } + } else if (path.size() == 1) { + // list networks + sqlite3_reset(_sListNetworks); + responseContentType = "application/json"; + responseBody = "["; + bool first = true; + while (sqlite3_step(_sListNetworks) == SQLITE_ROW) { + if (first) { + first = false; + responseBody.push_back('"'); + } else responseBody.append(",\""); + responseBody.append((const char *)sqlite3_column_text(_sListNetworks,0)); + responseBody.push_back('"'); + } + responseBody.push_back(']'); + return 200; + } // else 404 + + } else { + // GET /controller returns status and API version if controller is supported + Utils::snprintf(json,sizeof(json),"{\n\t\"controller\": true,\n\t\"apiVersion\": %d,\n\t\"clock\": %llu,\n\t\"instanceId\": \"%s\"\n}\n",ZT_NETCONF_CONTROLLER_API_VERSION,(unsigned long long)OSUtils::now(),_instanceId.c_str()); + responseBody = json; + responseContentType = "applicaiton/json"; + return 200; + } + + return 404; +} + +} // namespace ZeroTier diff --git a/controller/SqliteNetworkController.hpp b/controller/SqliteNetworkController.hpp new file mode 100644 index 000000000..adfe09916 --- /dev/null +++ b/controller/SqliteNetworkController.hpp @@ -0,0 +1,156 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, 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 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#ifndef ZT_SQLITENETWORKCONTROLLER_HPP +#define ZT_SQLITENETWORKCONTROLLER_HPP + +#include + +#include + +#include +#include +#include + +#include "../node/Constants.hpp" +#include "../node/NetworkController.hpp" +#include "../node/Mutex.hpp" + +namespace ZeroTier { + +class SqliteNetworkController : public NetworkController +{ +public: + SqliteNetworkController(const char *dbPath); + virtual ~SqliteNetworkController(); + + virtual NetworkController::ResultCode doNetworkConfigRequest( + const InetAddress &fromAddr, + const Identity &signingId, + const Identity &identity, + uint64_t nwid, + const Dictionary &metaData, + uint64_t haveRevision, + Dictionary &netconf); + + unsigned int handleControlPlaneHttpGET( + const std::vector &path, + const std::map &urlArgs, + const std::map &headers, + const std::string &body, + std::string &responseBody, + std::string &responseContentType); + unsigned int handleControlPlaneHttpPOST( + const std::vector &path, + const std::map &urlArgs, + const std::map &headers, + const std::string &body, + std::string &responseBody, + std::string &responseContentType); + unsigned int handleControlPlaneHttpDELETE( + const std::vector &path, + const std::map &urlArgs, + const std::map &headers, + const std::string &body, + std::string &responseBody, + std::string &responseContentType); + +private: + enum IpAssignmentType { + // IP assignment is a static IP address + ZT_IP_ASSIGNMENT_TYPE_ADDRESS = 0, + // IP assignment is a network -- a route via this interface, not an address + ZT_IP_ASSIGNMENT_TYPE_NETWORK = 1 + }; + + unsigned int _doCPGet( + const std::vector &path, + const std::map &urlArgs, + const std::map &headers, + const std::string &body, + std::string &responseBody, + std::string &responseContentType); + + std::string _dbPath; + std::string _instanceId; + + std::map< std::pair,uint64_t > _lastRequestTime; + + sqlite3 *_db; + + sqlite3_stmt *_sGetNetworkById; + sqlite3_stmt *_sGetMember; + sqlite3_stmt *_sCreateMember; + sqlite3_stmt *_sGetNodeIdentity; + sqlite3_stmt *_sCreateNode; + sqlite3_stmt *_sUpdateNode; + sqlite3_stmt *_sUpdateNode2; + sqlite3_stmt *_sGetEtherTypesFromRuleTable; + sqlite3_stmt *_sGetActiveBridges; + sqlite3_stmt *_sGetIpAssignmentsForNode; + sqlite3_stmt *_sGetIpAssignmentPools; + sqlite3_stmt *_sGetLocalRoutes; + sqlite3_stmt *_sCheckIfIpIsAllocated; + sqlite3_stmt *_sAllocateIp; + sqlite3_stmt *_sDeleteIpAllocations; + sqlite3_stmt *_sDeleteLocalRoutes; + sqlite3_stmt *_sGetRelays; + sqlite3_stmt *_sListNetworks; + sqlite3_stmt *_sListNetworkMembers; + sqlite3_stmt *_sGetMember2; + sqlite3_stmt *_sGetIpAssignmentPools2; + sqlite3_stmt *_sListRules; + sqlite3_stmt *_sCreateRule; + sqlite3_stmt *_sCreateNetwork; + sqlite3_stmt *_sGetNetworkRevision; + sqlite3_stmt *_sSetNetworkRevision; + sqlite3_stmt *_sGetIpAssignmentsForNode2; + sqlite3_stmt *_sDeleteRelaysForNetwork; + sqlite3_stmt *_sCreateRelay; + sqlite3_stmt *_sDeleteIpAssignmentPoolsForNetwork; + sqlite3_stmt *_sDeleteRulesForNetwork; + sqlite3_stmt *_sCreateIpAssignmentPool; + sqlite3_stmt *_sUpdateMemberAuthorized; + sqlite3_stmt *_sUpdateMemberActiveBridge; + sqlite3_stmt *_sDeleteMember; + sqlite3_stmt *_sDeleteNetwork; + sqlite3_stmt *_sGetGateways; + sqlite3_stmt *_sDeleteGateways; + sqlite3_stmt *_sCreateGateway; + sqlite3_stmt *_sIncrementMemberRevisionCounter; + sqlite3_stmt *_sGetConfig; + sqlite3_stmt *_sSetConfig; + sqlite3_stmt *_sPutLog; + sqlite3_stmt *_sGetMemberLog; + sqlite3_stmt *_sGetRecentMemberLog; + + Mutex _lock; +}; + +} // namespace ZeroTier + +#endif diff --git a/controller/schema.sql b/controller/schema.sql new file mode 100644 index 000000000..48d5607cd --- /dev/null +++ b/controller/schema.sql @@ -0,0 +1,123 @@ +CREATE TABLE Config ( + k varchar(16) PRIMARY KEY NOT NULL, + v varchar(1024) NOT NULL +); + +CREATE TABLE Network ( + id char(16) PRIMARY KEY NOT NULL, + name varchar(128) NOT NULL, + private integer NOT NULL DEFAULT(1), + enableBroadcast integer NOT NULL DEFAULT(1), + allowPassiveBridging integer NOT NULL DEFAULT(0), + v4AssignMode varchar(8) NOT NULL DEFAULT('none'), + v6AssignMode varchar(8) NOT NULL DEFAULT('none'), + multicastLimit integer NOT NULL DEFAULT(32), + creationTime integer NOT NULL DEFAULT(0), + revision integer NOT NULL DEFAULT(1), + memberRevisionCounter integer NOT NULL DEFAULT(1) +); + +CREATE TABLE AuthToken ( + id integer PRIMARY KEY NOT NULL, + networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE, + authMode integer NOT NULL DEFAULT(1), + useCount integer NOT NULL DEFAULT(0), + maxUses integer NOT NULL DEFAULT(0), + expiresAt integer NOT NULL DEFAULT(0), + token varchar(256) NOT NULL +); + +CREATE INDEX AuthToken_networkId_token ON AuthToken(networkId,token); + +CREATE TABLE Node ( + id char(10) PRIMARY KEY NOT NULL, + identity varchar(4096) NOT NULL +); + +CREATE TABLE Gateway ( + networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE, + ip blob(16) NOT NULL, + ipVersion integer NOT NULL DEFAULT(4), + metric integer NOT NULL DEFAULT(0) +); + +CREATE UNIQUE INDEX Gateway_networkId_ip ON Gateway (networkId, ip); + +CREATE TABLE IpAssignment ( + networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE, + nodeId char(10) REFERENCES Node(id) ON DELETE CASCADE, + type integer NOT NULL DEFAULT(0), + ip blob(16) NOT NULL, + ipNetmaskBits integer NOT NULL DEFAULT(0), + ipVersion integer NOT NULL DEFAULT(4) +); + +CREATE UNIQUE INDEX IpAssignment_networkId_ip ON IpAssignment (networkId, ip); + +CREATE INDEX IpAssignment_networkId_nodeId ON IpAssignment (networkId, nodeId); + +CREATE TABLE IpAssignmentPool ( + networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE, + ipRangeStart blob(16) NOT NULL, + ipRangeEnd blob(16) NOT NULL, + ipVersion integer NOT NULL DEFAULT(4) +); + +CREATE UNIQUE INDEX IpAssignmentPool_networkId_ipRangeStart ON IpAssignmentPool (networkId,ipRangeStart); + +CREATE TABLE Member ( + networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE, + nodeId char(10) NOT NULL REFERENCES Node(id) ON DELETE CASCADE, + authorized integer NOT NULL DEFAULT(0), + activeBridge integer NOT NULL DEFAULT(0), + memberRevision integer NOT NULL DEFAULT(0), + PRIMARY KEY (networkId, nodeId) +); + +CREATE INDEX Member_networkId_activeBridge ON Member(networkId, activeBridge); +CREATE INDEX Member_networkId_memberRevision ON Member(networkId, memberRevision); + +CREATE TABLE Log ( + networkId char(16) NOT NULL, + nodeId char(10) NOT NULL, + ts integer NOT NULL, + authorized integer NOT NULL, + authTokenId integer, + version varchar(16), + fromAddr varchar(64) +); + +CREATE INDEX Log_networkId_nodeId ON Log(networkId, nodeId); +CREATE INDEX Log_ts ON Log(ts); + +CREATE TABLE Relay ( + networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE, + address char(10) NOT NULL, + phyAddress varchar(64) NOT NULL +); + +CREATE UNIQUE INDEX Relay_networkId_address ON Relay (networkId,address); + +CREATE TABLE Rule ( + networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE, + ruleNo integer NOT NULL, + nodeId char(10) REFERENCES Node(id), + sourcePort char(10), + destPort char(10), + vlanId integer, + vlanPcp integer, + etherType integer, + macSource char(12), + macDest char(12), + ipSource varchar(64), + ipDest varchar(64), + ipTos integer, + ipProtocol integer, + ipSourcePort integer, + ipDestPort integer, + flags integer, + invFlags integer, + "action" varchar(4096) NOT NULL DEFAULT('accept') +); + +CREATE UNIQUE INDEX Rule_networkId_ruleNo ON Rule (networkId, ruleNo); diff --git a/controller/schema.sql.c b/controller/schema.sql.c new file mode 100644 index 000000000..49c445486 --- /dev/null +++ b/controller/schema.sql.c @@ -0,0 +1,125 @@ +#define ZT_NETCONF_SCHEMA_SQL \ +"CREATE TABLE Config (\n"\ +" k varchar(16) PRIMARY KEY NOT NULL,\n"\ +" v varchar(1024) NOT NULL\n"\ +");\n"\ +"\n"\ +"CREATE TABLE Network (\n"\ +" id char(16) PRIMARY KEY NOT NULL,\n"\ +" name varchar(128) NOT NULL,\n"\ +" private integer NOT NULL DEFAULT(1),\n"\ +" enableBroadcast integer NOT NULL DEFAULT(1),\n"\ +" allowPassiveBridging integer NOT NULL DEFAULT(0),\n"\ +" v4AssignMode varchar(8) NOT NULL DEFAULT('none'),\n"\ +" v6AssignMode varchar(8) NOT NULL DEFAULT('none'),\n"\ +" multicastLimit integer NOT NULL DEFAULT(32),\n"\ +" creationTime integer NOT NULL DEFAULT(0),\n"\ +" revision integer NOT NULL DEFAULT(1),\n"\ +" memberRevisionCounter integer NOT NULL DEFAULT(1)\n"\ +");\n"\ +"\n"\ +"CREATE TABLE AuthToken (\n"\ +" id integer PRIMARY KEY NOT NULL,\n"\ +" networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,\n"\ +" authMode integer NOT NULL DEFAULT(1),\n"\ +" useCount integer NOT NULL DEFAULT(0),\n"\ +" maxUses integer NOT NULL DEFAULT(0),\n"\ +" expiresAt integer NOT NULL DEFAULT(0),\n"\ +" token varchar(256) NOT NULL\n"\ +");\n"\ +"\n"\ +"CREATE INDEX AuthToken_networkId_token ON AuthToken(networkId,token);\n"\ +"\n"\ +"CREATE TABLE Node (\n"\ +" id char(10) PRIMARY KEY NOT NULL,\n"\ +" identity varchar(4096) NOT NULL\n"\ +");\n"\ +"\n"\ +"CREATE TABLE Gateway (\n"\ +" networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,\n"\ +" ip blob(16) NOT NULL,\n"\ +" ipVersion integer NOT NULL DEFAULT(4),\n"\ +" metric integer NOT NULL DEFAULT(0)\n"\ +");\n"\ +"\n"\ +"CREATE UNIQUE INDEX Gateway_networkId_ip ON Gateway (networkId, ip);\n"\ +"\n"\ +"CREATE TABLE IpAssignment (\n"\ +" networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,\n"\ +" nodeId char(10) REFERENCES Node(id) ON DELETE CASCADE,\n"\ +" type integer NOT NULL DEFAULT(0),\n"\ +" ip blob(16) NOT NULL,\n"\ +" ipNetmaskBits integer NOT NULL DEFAULT(0),\n"\ +" ipVersion integer NOT NULL DEFAULT(4)\n"\ +");\n"\ +"\n"\ +"CREATE UNIQUE INDEX IpAssignment_networkId_ip ON IpAssignment (networkId, ip);\n"\ +"\n"\ +"CREATE INDEX IpAssignment_networkId_nodeId ON IpAssignment (networkId, nodeId);\n"\ +"\n"\ +"CREATE TABLE IpAssignmentPool (\n"\ +" networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,\n"\ +" ipRangeStart blob(16) NOT NULL,\n"\ +" ipRangeEnd blob(16) NOT NULL,\n"\ +" ipVersion integer NOT NULL DEFAULT(4)\n"\ +");\n"\ +"\n"\ +"CREATE UNIQUE INDEX IpAssignmentPool_networkId_ipRangeStart ON IpAssignmentPool (networkId,ipRangeStart);\n"\ +"\n"\ +"CREATE TABLE Member (\n"\ +" networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,\n"\ +" nodeId char(10) NOT NULL REFERENCES Node(id) ON DELETE CASCADE,\n"\ +" authorized integer NOT NULL DEFAULT(0),\n"\ +" activeBridge integer NOT NULL DEFAULT(0),\n"\ +" memberRevision integer NOT NULL DEFAULT(0),\n"\ +" PRIMARY KEY (networkId, nodeId)\n"\ +");\n"\ +"\n"\ +"CREATE INDEX Member_networkId_activeBridge ON Member(networkId, activeBridge);\n"\ +"CREATE INDEX Member_networkId_memberRevision ON Member(networkId, memberRevision);\n"\ +"\n"\ +"CREATE TABLE Log (\n"\ +" networkId char(16) NOT NULL,\n"\ +" nodeId char(10) NOT NULL,\n"\ +" ts integer NOT NULL,\n"\ +" authorized integer NOT NULL,\n"\ +" authTokenId integer,\n"\ +" version varchar(16),\n"\ +" fromAddr varchar(64)\n"\ +");\n"\ +"\n"\ +"CREATE INDEX Log_networkId_nodeId ON Log(networkId, nodeId);\n"\ +"CREATE INDEX Log_ts ON Log(ts);\n"\ +"\n"\ +"CREATE TABLE Relay (\n"\ +" networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,\n"\ +" address char(10) NOT NULL,\n"\ +" phyAddress varchar(64) NOT NULL\n"\ +");\n"\ +"\n"\ +"CREATE UNIQUE INDEX Relay_networkId_address ON Relay (networkId,address);\n"\ +"\n"\ +"CREATE TABLE Rule (\n"\ +" networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,\n"\ +" ruleNo integer NOT NULL,\n"\ +" nodeId char(10) REFERENCES Node(id),\n"\ +" sourcePort char(10),\n"\ +" destPort char(10),\n"\ +" vlanId integer,\n"\ +" vlanPcp integer,\n"\ +" etherType integer,\n"\ +" macSource char(12),\n"\ +" macDest char(12),\n"\ +" ipSource varchar(64),\n"\ +" ipDest varchar(64),\n"\ +" ipTos integer,\n"\ +" ipProtocol integer,\n"\ +" ipSourcePort integer,\n"\ +" ipDestPort integer,\n"\ +" flags integer,\n"\ +" invFlags integer,\n"\ +" \"action\" varchar(4096) NOT NULL DEFAULT('accept')\n"\ +");\n"\ +"\n"\ +"CREATE UNIQUE INDEX Rule_networkId_ruleNo ON Rule (networkId, ruleNo);\n"\ +"" diff --git a/controller/schema2c.sh b/controller/schema2c.sh new file mode 100755 index 000000000..4f4f1647c --- /dev/null +++ b/controller/schema2c.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Run this file to package the .sql file into a .c file whenever the SQL changes. + +rm -f schema.sql.c +echo '#define ZT_NETCONF_SCHEMA_SQL \' >schema.sql.c +cat schema.sql | sed 's/"/\\"/g' | sed 's/^/"/' | sed 's/$/\\n"\\/' >>schema.sql.c +echo '""' >>schema.sql.c diff --git a/cycle_controllers.sh b/cycle_controllers.sh deleted file mode 100755 index 34acacf4e..000000000 --- a/cycle_controllers.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/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 deleted file mode 100644 index fdc85f860..000000000 --- a/debian/changelog +++ /dev/null @@ -1,318 +0,0 @@ -zerotier-one (1.14.2) unstable; urgency=medium - - * See RELEASE-NOTES.md for release notes. - - -- Adam Ierymenko Wed, 23 Oct 2024 01:00:00 -0700 - -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 deleted file mode 100644 index 9a037142a..000000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -10 \ No newline at end of file diff --git a/debian/control b/debian/control deleted file mode 100644 index b0c178ab1..000000000 --- a/debian/control +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index fbbc40d93..000000000 --- a/debian/control.wheezy +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index da3678d52..000000000 --- a/debian/copyright +++ /dev/null @@ -1,18 +0,0 @@ -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 deleted file mode 100644 index b6e7471c4..000000000 --- a/debian/postinst +++ /dev/null @@ -1,11 +0,0 @@ -#!/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 deleted file mode 100644 index 81fde680b..000000000 --- a/debian/rules +++ /dev/null @@ -1,16 +0,0 @@ -#!/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 deleted file mode 100644 index 72c529552..000000000 --- a/debian/rules.static +++ /dev/null @@ -1,16 +0,0 @@ -#!/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 deleted file mode 100644 index 55e2647a2..000000000 --- a/debian/rules.wheezy +++ /dev/null @@ -1,11 +0,0 @@ -#!/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 deleted file mode 100644 index 0165be37e..000000000 --- a/debian/rules.wheezy.static +++ /dev/null @@ -1,11 +0,0 @@ -#!/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 deleted file mode 100644 index 46ebe0266..000000000 --- a/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) \ No newline at end of file diff --git a/debian/ufw-zerotier-one b/debian/ufw-zerotier-one deleted file mode 100644 index 7c2908941..000000000 --- a/debian/ufw-zerotier-one +++ /dev/null @@ -1,4 +0,0 @@ -[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 deleted file mode 100644 index 41a22a50d..000000000 --- a/debian/zerotier-one.init +++ /dev/null @@ -1,49 +0,0 @@ -#!/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.upstart b/debian/zerotier-one.upstart deleted file mode 100644 index 7753580a8..000000000 --- a/debian/zerotier-one.upstart +++ /dev/null @@ -1,14 +0,0 @@ -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 deleted file mode 100644 index 681954cc5..000000000 --- a/doc/README.md +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100755 index 9df72a333..000000000 --- a/doc/build.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/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 deleted file mode 100644 index dc7d6455c..000000000 --- a/doc/contact@zerotier.com.gpg +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Comment: GPGTools - https://gpgtools.org - -mQINBFdQq7oBEADEVhyRiaL8dEjMPlI/idO8tA7adjhfvejxrJ3Axxi9YIuIKhWU -5hNjDjZAiV9iSCMfJN3TjC3EDA+7nFyU6nDKeAMkXPbaPk7ti+Tb1nA4TJsBfBlm -CC14aGWLItpp8sI00FUzorxLWRmU4kOkrRUJCq2kAMzbYWmHs0hHkWmvj8gGu6mJ -WU3sDIjvdsm3hlgtqr9grPEnj+gA7xetGs3oIfp6YDKymGAV49HZmVAvSeoqfL1p -pEKlNQ1aO9uNfHLdx6+4pS1miyo7D1s7ru2IcqhTDhg40cHTL/VldC3d8vXRFLIi -Uo2tFZ6J1jyQP5c1K4rTpw3UNVne3ob7uCME+T1+ePeuM5Y/cpcCvAhJhO0rrlr0 -dP3lOKrVdZg4qhtFAspC85ivcuxWNWnfTOBrgnvxCA1fmBX+MLNUEDsuu55LBNQT -5+WyrSchSlsczq+9EdomILhixUflDCShHs+Efvh7li6Pg56fwjEfj9DJYFhRvEvQ -7GZ7xtysFzx4AYD4/g5kCDsMTbc9W4Jv+JrMt3JsXt2zqwI0P4R1cIAu0J6OZ4Xa -dJ7Ci1WisQuJRcCUtBTUxcYAClNGeors5Nhl4zDrNIM7zIJp+GfPYdWKVSuW10mC -r3OS9QctMSeVPX/KE85TexeRtmyd4zUdio49+WKgoBhM8Z9MpTaafn2OPQARAQAB -tFBaZXJvVGllciwgSW5jLiAoWmVyb1RpZXIgU3VwcG9ydCBhbmQgUmVsZWFzZSBT -aWduaW5nIEtleSkgPGNvbnRhY3RAemVyb3RpZXIuY29tPokCNwQTAQoAIQUCV1Cr -ugIbAwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRAWVxmII+UqYViGEACnC3+3 -lRzfv7f7JLWo23FSHjlF3IiWfYd+47BLDx706SDih1H6Qt8CqRy706bWbtictEJ/ -xTaWgTEDzY/lRalYO5NAFTgK9h2zBP1t8zdEA/rmtVPOWOzd6jr0q3l3pKQTeMF0 -6g+uaMDG1OkBz6MCwdg9counz6oa8OHK76tXNIBEnGOPBW375z1O+ExyddQOHDcS -IIsUlFmtIL1yBa7Q5NSfLofPLfS0/o2FItn0riSaAh866nXHynQemjTrqkUxf5On -65RLM+AJQaEkX17vDlsSljHrtYLKrhEueqeq50e89c2Ya4ucmSVeC9lrSqfyvGOO -P3aT/hrmeE9XBf7a9vozq7XhtViEC/ZSd1/z/oeypv4QYenfw8CtXP5bW1mKNK/M -8xnrnYwo9BUMclX2ZAvu1rTyiUvGre9fEGfhlS0rjmCgYfMgBZ+R/bFGiNdn6gAd -PSY/8fP8KFZl0xUzh2EnWe/bptoZ67CKkDbVZnfWtuKA0Ui7anitkjZiv+6wanv4 -+5A3k/H3D4JofIjRNgx/gdVPhJfWjAoutIgGeIWrkfcAP9EpsR5swyc4KuE6kJ/Y -wXXVDQiju0xE1EdNx/S1UOeq0EHhOFqazuu00ojATekUPWenNjPWIjBYQ0Ag4ycL -KU558PFLzqYaHphdWYgxfGR+XSgzVTN1r7lW87kCDQRXUKu6ARAA2wWOywNMzEiP -ZK6CqLYGZqrpfx+drOxSowwfwjP3odcK8shR/3sxOmYVqZi0XVZtb9aJVz578rNb -e4Vfugql1Yt6w3V84z/mtfj6ZbTOOU5yAGZQixm6fkXAnpG5Eer/C8Aw8dH1EreP -Na1gIVcUzlpg2Ql23qjr5LqvGtUB4BqJSF4X8efNi/y0hj/GaivUMqCF6+Vvh3GG -fhvzhgBPku/5wK2XwBL9BELqaQ/tWOXuztMw0xFH/De75IH3LIvQYCuv1pnM4hJL -XYnpAGAWfmFtmXNnPVon6g542Z6c0G/qi657xA5vr6OSSbazDJXNiHXhgBYEzRrH -napcohTQwFKEA3Q4iftrsTDX/eZVTrO9x6qKxwoBVTGwSE52InWAxkkcnZM6tkfV -n7Ukc0oixZ6E70Svls27zFgaWbUFJQ6JFoC6h+5AYbaga6DwKCYOP3AR+q0ZkcH/ -oJIdvKuhF9zDZbQhd76b4gK3YXnMpVsj9sQ9P23gh61RkAQ1HIlGOBrHS/XYcvpk -DcfIlJXKC3V1ggrG+BpKu46kiiYmRR1/yM0EXH2n99XhLNSxxFxxWhjyw8RcR6iG -ovDxWAULW+bJHjaNJdgb8Kab7j2nT2odUjUHMP42uLJgvS5LgRn39IvtzjoScAqg -8I817m8yLU/91D2f5qmJIwFI6ELwImkAEQEAAYkCHwQYAQoACQUCV1CrugIbDAAK -CRAWVxmII+UqYWSSEACxaR/hhr8xUIXkIV52BeD+2BOS8FNOi0aM67L4fEVplrsV -Op9fvAnUNmoiQo+RFdUdaD2Rpq+yUjQHHbj92mlk6Cmaon46wU+5bAWGYpV1Uf+o -wbKw1Xv83Uj9uHo7zv9WDtOUXUiTe/S792icTfRYrKbwkfI8iCltgNhTQNX0lFX/ -Sr2y1/dGCTCMEuA/ClqGKCm9lIYdu+4z32V9VXTSX85DsUjLOCO/hl9SHaelJgmi -IJzRY1XLbNDK4IH5eWtbaprkTNIGt00QhsnM5w+rn1tO80giSxXFpKBE+/pAx8PQ -RdVFzxHtTUGMCkZcgOJolk8y+DJWtX8fP+3a4Vq11a3qKJ19VXk3qnuC1aeW7OQF -j6ISyHsNNsnBw5BRaS5tdrpLXw6Z7TKr1eq+FylmoOK0pIw5xOdRmSVoFm4lVcI5 -e5EwB7IIRF00IFqrXe8dCT0oDT9RXc6CNh6GIs9D9YKwDPRD/NKQlYoegfa13Jz7 -S3RIXtOXudT1+A1kaBpGKnpXOYD3w7jW2l0zAd6a53AAGy4SnL1ac4cml76NIWiF -m2KYzvMJZBk5dAtFa0SgLK4fg8X6Ygoo9E0JsXxSrW9I1JVfo6Ia//YOBMtt4XuN -Awqahjkq87yxOYYTnJmr2OZtQuFboymfMhNqj3G2DYmZ/ZIXXPgwHx0fnd3R0Q== -=JgAv ------END PGP PUBLIC KEY BLOCK----- diff --git a/doc/manpage_encoding_declaration.UTF-8 b/doc/manpage_encoding_declaration.UTF-8 deleted file mode 100644 index 991db0a6a..000000000 --- a/doc/manpage_encoding_declaration.UTF-8 +++ /dev/null @@ -1 +0,0 @@ -'\" -*- coding: utf-8 -*- diff --git a/doc/zerotier-cli.1 b/doc/zerotier-cli.1 deleted file mode 100644 index 167109ec9..000000000 --- a/doc/zerotier-cli.1 +++ /dev/null @@ -1,83 +0,0 @@ -.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 deleted file mode 100644 index 6252d452f..000000000 --- a/doc/zerotier-cli.1.md +++ /dev/null @@ -1,68 +0,0 @@ -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 deleted file mode 100644 index fbc367a6a..000000000 --- a/doc/zerotier-idtool.1 +++ /dev/null @@ -1,84 +0,0 @@ -.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 deleted file mode 100644 index 52a586c11..000000000 --- a/doc/zerotier-idtool.1.md +++ /dev/null @@ -1,65 +0,0 @@ -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 deleted file mode 100644 index 4ad7a15d0..000000000 --- a/doc/zerotier-one.8 +++ /dev/null @@ -1,104 +0,0 @@ -.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 deleted file mode 100644 index 4f4655076..000000000 --- a/doc/zerotier-one.8.md +++ /dev/null @@ -1,95 +0,0 @@ -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 deleted file mode 100644 index da9b8f8c8..000000000 --- a/entrypoint.sh.release +++ /dev/null @@ -1,130 +0,0 @@ -#!/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 - echo "creating $file" - mkdir -p /var/lib/zerotier-one - echo -n "$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" - mkztfile metricstoken.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 - -if [ "x$ZEROTIER_LOCAL_CONF" != "x" ] -then - mkztfile local.conf 0644 "$ZEROTIER_LOCAL_CONF" -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 deleted file mode 100644 index 9e5989cd3..000000000 --- a/ext/arm32-neon-salsa2012-asm/salsa2012.s +++ /dev/null @@ -1,2231 +0,0 @@ - -# 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/miniupnpc/Changelog.txt b/ext/bin/miniupnpc/Changelog.txt similarity index 91% rename from ext/miniupnpc/Changelog.txt rename to ext/bin/miniupnpc/Changelog.txt index 37562c6af..bb2abb7ee 100644 --- a/ext/miniupnpc/Changelog.txt +++ b/ext/bin/miniupnpc/Changelog.txt @@ -1,64 +1,6 @@ -$Id: Changelog.txt,v 1.229 2017/12/12 11:26:25 nanard Exp $ +$Id: Changelog.txt,v 1.208 2015/07/15 12:18:59 nanard Exp $ miniUPnP client Changelog. -2017/12/11: - Fix buffer over run in minixml.c - Fix uninitialized variable access in upnpreplyparse.c - -2017/05/05: - Fix CVE-2017-8798 Thanks to tin/Team OSTStrom - -2016/11/11: - check strlen before memcmp in XML parsing portlistingparse.c - fix build under SOLARIS and CYGWIN - -2016/10/11: - Add python 3 compatibility to IGD test - -VERSION 2.0 : released 2016/04/19 - -2016/01/24: - change miniwget to return HTTP status code - increments API_VERSION to 16 - -2016/01/22: - Improve UPNPIGD_IsConnected() to check if WAN address is not private. - parse HTTP response status line in miniwget.c - -2015/10/26: - snprintf() overflow check. check overflow in simpleUPnPcommand2() - -2015/10/25: - fix compilation with old macs - fix compilation with mingw32 (for Appveyor) - fix python module for python <= 2.3 - -2015/10/08: - Change sameport to localport - see https://github.com/miniupnp/miniupnp/pull/120 - increments API_VERSION to 15 - -2015/09/15: - Fix buffer overflow in igd_desc_parse.c/IGDstartelt() - Discovered by Aleksandar Nikolic of Cisco Talos - -2015/08/28: - move ssdpDiscoverDevices() to minissdpc.c - -2015/08/27: - avoid unix socket leak in getDevicesFromMiniSSDPD() - -2015/08/16: - Also accept "Up" as ConnectionStatus value - -2015/07/23: - split getDevicesFromMiniSSDPD - add ttl argument to upnpDiscover() functions - increments API_VERSION to 14 - -2015/07/22: - Read USN from SSDP messages. - 2015/07/15: Check malloc/calloc diff --git a/ext/miniupnpc/LICENSE b/ext/bin/miniupnpc/LICENSE similarity index 97% rename from ext/miniupnpc/LICENSE rename to ext/bin/miniupnpc/LICENSE index 081673370..cb5a06044 100644 --- a/ext/miniupnpc/LICENSE +++ b/ext/bin/miniupnpc/LICENSE @@ -1,5 +1,5 @@ MiniUPnPc -Copyright (c) 2005-2016, Thomas BERNARD +Copyright (c) 2005-2015, Thomas BERNARD All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/ext/bin/miniupnpc/README.md b/ext/bin/miniupnpc/README.md new file mode 100644 index 000000000..c3d538ba9 --- /dev/null +++ b/ext/bin/miniupnpc/README.md @@ -0,0 +1,4 @@ +libminiupnpc binaries +====== + +This is a binary build of [libminiupnpc](http://miniupnp.free.fr) for certain architectures to faciliate easy building. Where possible the build flags were set for improved security by enabling options like stack protector (a.k.a. stack canary), ASLR support, etc. diff --git a/ext/bin/miniupnpc/VERSION b/ext/bin/miniupnpc/VERSION new file mode 100644 index 000000000..2e0e38c63 --- /dev/null +++ b/ext/bin/miniupnpc/VERSION @@ -0,0 +1 @@ +1.9 diff --git a/ext/miniupnpc/codelength.h b/ext/bin/miniupnpc/include/miniupnpc/codelength.h similarity index 100% rename from ext/miniupnpc/codelength.h rename to ext/bin/miniupnpc/include/miniupnpc/codelength.h diff --git a/ext/miniupnpc/connecthostport.h b/ext/bin/miniupnpc/include/miniupnpc/connecthostport.h similarity index 100% rename from ext/miniupnpc/connecthostport.h rename to ext/bin/miniupnpc/include/miniupnpc/connecthostport.h diff --git a/ext/miniupnpc/igd_desc_parse.h b/ext/bin/miniupnpc/include/miniupnpc/igd_desc_parse.h similarity index 100% rename from ext/miniupnpc/igd_desc_parse.h rename to ext/bin/miniupnpc/include/miniupnpc/igd_desc_parse.h diff --git a/ext/miniupnpc/minisoap.h b/ext/bin/miniupnpc/include/miniupnpc/minisoap.h similarity index 100% rename from ext/miniupnpc/minisoap.h rename to ext/bin/miniupnpc/include/miniupnpc/minisoap.h diff --git a/ext/bin/miniupnpc/include/miniupnpc/minissdpc.h b/ext/bin/miniupnpc/include/miniupnpc/minissdpc.h new file mode 100644 index 000000000..915b0026f --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/minissdpc.h @@ -0,0 +1,15 @@ +/* $Id: minissdpc.h,v 1.2 2012/09/27 15:42:10 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * Author: Thomas Bernard + * Copyright (c) 2005-2007 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef MINISSDPC_H_INCLUDED +#define MINISSDPC_H_INCLUDED + +struct UPNPDev * +getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath); + +#endif + diff --git a/ext/miniupnpc/miniupnpc.h b/ext/bin/miniupnpc/include/miniupnpc/miniupnpc.h similarity index 77% rename from ext/miniupnpc/miniupnpc.h rename to ext/bin/miniupnpc/include/miniupnpc/miniupnpc.h index 4a805b11f..0eeabc234 100644 --- a/ext/miniupnpc/miniupnpc.h +++ b/ext/bin/miniupnpc/include/miniupnpc/miniupnpc.h @@ -1,8 +1,8 @@ -/* $Id: miniupnpc.h,v 1.50 2016/04/19 21:06:21 nanard Exp $ */ +/* $Id: miniupnpc.h,v 1.42 2015/07/21 13:16:55 nanard Exp $ */ /* Project: miniupnp * http://miniupnp.free.fr/ * Author: Thomas Bernard - * Copyright (c) 2005-2016 Thomas Bernard + * Copyright (c) 2005-2015 Thomas Bernard * This software is subjects to the conditions detailed * in the LICENCE file provided within this distribution */ #ifndef MINIUPNPC_H_INCLUDED @@ -10,7 +10,6 @@ #include "miniupnpc_declspec.h" #include "igd_desc_parse.h" -#include "upnpdev.h" /* error codes : */ #define UPNPDISCOVER_SUCCESS (0) @@ -19,14 +18,8 @@ #define UPNPDISCOVER_MEMORY_ERROR (-102) /* versions : */ -#define MINIUPNPC_VERSION "2.0.20171212" -#define MINIUPNPC_API_VERSION 16 - -/* Source port: - Using "1" as an alias for 1900 for backwards compatability - (presuming one would have used that for the "sameport" parameter) */ -#define UPNP_LOCAL_PORT_ANY 0 -#define UPNP_LOCAL_PORT_SAME 1 +#define MINIUPNPC_VERSION "1.9.20150721" +#define MINIUPNPC_API_VERSION 13 #ifdef __cplusplus extern "C" { @@ -40,6 +33,14 @@ simpleUPnPcommand(int, const char *, const char *, const char *, struct UPNParg *, int *); +struct UPNPDev { + struct UPNPDev * pNext; + char * descURL; + char * st; + unsigned int scope_id; + char buffer[2]; +}; + /* upnpDiscover() * discover UPnP devices on the network. * The discovered devices are returned as a chained list. @@ -51,39 +52,40 @@ simpleUPnPcommand(int, const char *, const char *, * is NULL. * If multicastif is not NULL, it will be used instead of the default * multicast interface for sending SSDP discover packets. - * If localport is set to UPNP_LOCAL_PORT_SAME(1) SSDP packets will be sent - * from the source port 1900 (same as destination port), if set to - * UPNP_LOCAL_PORT_ANY(0) system assign a source port, any other value will - * be attempted as the source port. + * If sameport is not null, SSDP packets will be sent from the source port + * 1900 (same as destination port) otherwise system assign a source port. * "searchalltypes" parameter is useful when searching several types, - * if 0, the discovery will stop with the first type returning results. - * TTL should default to 2. */ + * if 0, the discovery will stop with the first type returning results. */ MINIUPNP_LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, + const char * minissdpdsock, int sameport, + int ipv6, int * error); MINIUPNP_LIBSPEC struct UPNPDev * upnpDiscoverAll(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, + const char * minissdpdsock, int sameport, + int ipv6, int * error); MINIUPNP_LIBSPEC struct UPNPDev * upnpDiscoverDevice(const char * device, int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, + const char * minissdpdsock, int sameport, + int ipv6, int * error); MINIUPNP_LIBSPEC struct UPNPDev * upnpDiscoverDevices(const char * const deviceTypes[], int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, + const char * minissdpdsock, int sameport, + int ipv6, int * error, int searchalltypes); +/* freeUPNPDevlist() + * free list returned by upnpDiscover() */ +MINIUPNP_LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist); + /* parserootdesc() : * parse root XML description of a UPnP device and fill the IGDdatas * structure. */ diff --git a/ext/miniupnpc/miniupnpc_declspec.h b/ext/bin/miniupnpc/include/miniupnpc/miniupnpc_declspec.h similarity index 100% rename from ext/miniupnpc/miniupnpc_declspec.h rename to ext/bin/miniupnpc/include/miniupnpc/miniupnpc_declspec.h diff --git a/ext/miniupnpc/miniupnpcstrings.h.in b/ext/bin/miniupnpc/include/miniupnpc/miniupnpcstrings.h similarity index 89% rename from ext/miniupnpc/miniupnpcstrings.h.in rename to ext/bin/miniupnpc/include/miniupnpc/miniupnpcstrings.h index 68bf4293d..80a1d757d 100644 --- a/ext/miniupnpc/miniupnpcstrings.h.in +++ b/ext/bin/miniupnpc/include/miniupnpc/miniupnpcstrings.h @@ -8,8 +8,8 @@ #ifndef MINIUPNPCSTRINGS_H_INCLUDED #define MINIUPNPCSTRINGS_H_INCLUDED -#define OS_STRING "OS/version" -#define MINIUPNPC_VERSION_STRING "version" +#define OS_STRING "Darwin/14.4.0" +#define MINIUPNPC_VERSION_STRING "1.9" #if 0 /* according to "UPnP Device Architecture 1.0" */ diff --git a/ext/miniupnpc/miniupnpctypes.h b/ext/bin/miniupnpc/include/miniupnpc/miniupnpctypes.h similarity index 100% rename from ext/miniupnpc/miniupnpctypes.h rename to ext/bin/miniupnpc/include/miniupnpc/miniupnpctypes.h diff --git a/ext/miniupnpc/miniwget.h b/ext/bin/miniupnpc/include/miniupnpc/miniwget.h similarity index 70% rename from ext/miniupnpc/miniwget.h rename to ext/bin/miniupnpc/include/miniupnpc/miniwget.h index 0701494d0..d6db71a85 100644 --- a/ext/miniupnpc/miniwget.h +++ b/ext/bin/miniupnpc/include/miniupnpc/miniwget.h @@ -1,7 +1,7 @@ -/* $Id: miniwget.h,v 1.12 2016/01/24 17:24:36 nanard Exp $ */ +/* $Id: miniwget.h,v 1.10 2015/07/21 13:16:55 nanard Exp $ */ /* Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2005-2016 Thomas Bernard + * Copyright (c) 2005-2015 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * */ @@ -14,11 +14,11 @@ extern "C" { #endif -MINIUPNP_LIBSPEC void * getHTTPResponse(int s, int * size, int * status_code); +MINIUPNP_LIBSPEC void * getHTTPResponse(int s, int * size); -MINIUPNP_LIBSPEC void * miniwget(const char *, int *, unsigned int, int *); +MINIUPNP_LIBSPEC void * miniwget(const char *, int *, unsigned int); -MINIUPNP_LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int, int *); +MINIUPNP_LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int); int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *); diff --git a/ext/miniupnpc/minixml.h b/ext/bin/miniupnpc/include/miniupnpc/minixml.h similarity index 100% rename from ext/miniupnpc/minixml.h rename to ext/bin/miniupnpc/include/miniupnpc/minixml.h diff --git a/ext/miniupnpc/portlistingparse.h b/ext/bin/miniupnpc/include/miniupnpc/portlistingparse.h similarity index 100% rename from ext/miniupnpc/portlistingparse.h rename to ext/bin/miniupnpc/include/miniupnpc/portlistingparse.h diff --git a/ext/miniupnpc/receivedata.h b/ext/bin/miniupnpc/include/miniupnpc/receivedata.h similarity index 100% rename from ext/miniupnpc/receivedata.h rename to ext/bin/miniupnpc/include/miniupnpc/receivedata.h diff --git a/ext/miniupnpc/upnpcommands.h b/ext/bin/miniupnpc/include/miniupnpc/upnpcommands.h similarity index 100% rename from ext/miniupnpc/upnpcommands.h rename to ext/bin/miniupnpc/include/miniupnpc/upnpcommands.h diff --git a/ext/miniupnpc/upnperrors.h b/ext/bin/miniupnpc/include/miniupnpc/upnperrors.h similarity index 100% rename from ext/miniupnpc/upnperrors.h rename to ext/bin/miniupnpc/include/miniupnpc/upnperrors.h diff --git a/ext/miniupnpc/upnpreplyparse.h b/ext/bin/miniupnpc/include/miniupnpc/upnpreplyparse.h similarity index 100% rename from ext/miniupnpc/upnpreplyparse.h rename to ext/bin/miniupnpc/include/miniupnpc/upnpreplyparse.h diff --git a/ext/bin/miniupnpc/linux-arm32/libminiupnpc.a b/ext/bin/miniupnpc/linux-arm32/libminiupnpc.a new file mode 100644 index 000000000..4983f6280 Binary files /dev/null and b/ext/bin/miniupnpc/linux-arm32/libminiupnpc.a differ diff --git a/ext/bin/miniupnpc/linux-x64/libminiupnpc.a b/ext/bin/miniupnpc/linux-x64/libminiupnpc.a new file mode 100644 index 000000000..270366e03 Binary files /dev/null and b/ext/bin/miniupnpc/linux-x64/libminiupnpc.a differ diff --git a/ext/bin/miniupnpc/linux-x86/libminiupnpc.a b/ext/bin/miniupnpc/linux-x86/libminiupnpc.a new file mode 100644 index 000000000..99cbef212 Binary files /dev/null and b/ext/bin/miniupnpc/linux-x86/libminiupnpc.a differ diff --git a/ext/bin/miniupnpc/mac-x64/libminiupnpc.a b/ext/bin/miniupnpc/mac-x64/libminiupnpc.a new file mode 100644 index 000000000..3c2e528d1 Binary files /dev/null and b/ext/bin/miniupnpc/mac-x64/libminiupnpc.a differ diff --git a/ext/bin/miniupnpc/windows-x64/miniupnpc.lib b/ext/bin/miniupnpc/windows-x64/miniupnpc.lib new file mode 100644 index 000000000..e05fefc88 Binary files /dev/null and b/ext/bin/miniupnpc/windows-x64/miniupnpc.lib differ diff --git a/ext/bin/miniupnpc/windows-x86/miniupnpc.lib b/ext/bin/miniupnpc/windows-x86/miniupnpc.lib new file mode 100644 index 000000000..a7fe41918 Binary files /dev/null and b/ext/bin/miniupnpc/windows-x86/miniupnpc.lib differ diff --git a/ext/bin/tap-mac/tap.kext/Contents/Info.plist b/ext/bin/tap-mac/tap.kext/Contents/Info.plist new file mode 100644 index 000000000..45c2839ad --- /dev/null +++ b/ext/bin/tap-mac/tap.kext/Contents/Info.plist @@ -0,0 +1,36 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + tap + CFBundleIdentifier + com.zerotier.tap + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + tap + CFBundlePackageType + KEXT + CFBundleShortVersionString + 20131028 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + OSBundleLibraries + + com.apple.kpi.mach + 8.0 + com.apple.kpi.bsd + 8.0 + com.apple.kpi.libkern + 8.0 + com.apple.kpi.unsupported + 8.0 + + + + diff --git a/ext/bin/tap-mac/tap.kext/Contents/MacOS/tap b/ext/bin/tap-mac/tap.kext/Contents/MacOS/tap new file mode 100755 index 000000000..6a9021a74 Binary files /dev/null and b/ext/bin/tap-mac/tap.kext/Contents/MacOS/tap differ diff --git a/ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeDirectory b/ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeDirectory new file mode 100644 index 000000000..58c421c29 Binary files /dev/null and b/ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeDirectory differ diff --git a/ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeRequirements b/ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeRequirements new file mode 100644 index 000000000..1df931292 Binary files /dev/null and b/ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeRequirements differ diff --git a/ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeResources b/ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeResources new file mode 100644 index 000000000..0710b4008 --- /dev/null +++ b/ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeResources @@ -0,0 +1,105 @@ + + + + + files + + files2 + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeSignature b/ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeSignature new file mode 100644 index 000000000..644297271 Binary files /dev/null and b/ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeSignature differ diff --git a/ext/bin/tap-windows-ndis5/x64/WdfCoinstaller01011.dll b/ext/bin/tap-windows-ndis5/x64/WdfCoinstaller01011.dll new file mode 100644 index 000000000..d49d29132 Binary files /dev/null and b/ext/bin/tap-windows-ndis5/x64/WdfCoinstaller01011.dll differ diff --git a/ext/bin/tap-windows-ndis5/x64/zttap200.cat b/ext/bin/tap-windows-ndis5/x64/zttap200.cat new file mode 100644 index 000000000..a3769e405 Binary files /dev/null and b/ext/bin/tap-windows-ndis5/x64/zttap200.cat differ diff --git a/ext/bin/tap-windows-ndis5/x64/zttap200.inf b/ext/bin/tap-windows-ndis5/x64/zttap200.inf new file mode 100644 index 000000000..dc1a74227 --- /dev/null +++ b/ext/bin/tap-windows-ndis5/x64/zttap200.inf @@ -0,0 +1,79 @@ +[Version] +Signature="$WINDOWS NT$" +Class=Net +ClassGuid={4d36e972-e325-11ce-bfc1-08002be10318} +Provider=%Provider% +CatalogFile=zttap200.cat +DriverVer=01/23/2014,15.19.17.816 + +[Strings] +DeviceDescription = "ZeroTier One Virtual Network Port" +Provider = "ZeroTier Networks LLC" + +; To build for x86, take NTamd64 off this and off the named section manually, build, then put it back! +[Manufacturer] +%Provider%=zttap200,NTamd64 + +[zttap200] +%DeviceDescription%=zttap200.ndi,zttap200 + +[ztTap200.NTamd64] +%DeviceDescription%=zttap200.ndi,zttap200 + +[zttap200.ndi] +CopyFiles = zttap200.driver,zttap200.files +AddReg = zttap200.reg +AddReg = zttap200.params.reg +Characteristics = 0x81 + +[zttap200.ndi.Services] +AddService = zttap200, 2, zttap200.service + +[zttap200.reg] +HKR, Ndi, Service, 0, "zttap200" +HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" +HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" +HKR, , Manufacturer, 0, "%Provider%" +HKR, , ProductName, 0, "%DeviceDescription%" + +[zttap200.params.reg] +HKR, Ndi\params\MTU, ParamDesc, 0, "MTU" +HKR, Ndi\params\MTU, Type, 0, "int" +HKR, Ndi\params\MTU, Default, 0, "2800" +HKR, Ndi\params\MTU, Optional, 0, "0" +HKR, Ndi\params\MTU, Min, 0, "100" +HKR, Ndi\params\MTU, Max, 0, "2800" +HKR, Ndi\params\MTU, Step, 0, "1" +HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status" +HKR, Ndi\params\MediaStatus, Type, 0, "enum" +HKR, Ndi\params\MediaStatus, Default, 0, "0" +HKR, Ndi\params\MediaStatus, Optional, 0, "0" +HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled" +HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected" +HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address" +HKR, Ndi\params\MAC, Type, 0, "edit" +HKR, Ndi\params\MAC, Optional, 0, "1" + +[zttap200.service] +DisplayName = %DeviceDescription% +ServiceType = 1 +StartType = 3 +ErrorControl = 1 +LoadOrderGroup = NDIS +ServiceBinary = %12%\zttap200.sys + +[SourceDisksNames] +1 = %DeviceDescription%, zttap200.sys + +[SourceDisksFiles] +zttap200.sys = 1 + +[DestinationDirs] +zttap200.files = 11 +zttap200.driver = 12 + +[zttap200.files] +; + +[zttap200.driver] +zttap200.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK diff --git a/ext/bin/tap-windows-ndis5/x64/zttap200.sys b/ext/bin/tap-windows-ndis5/x64/zttap200.sys new file mode 100644 index 000000000..339351fb3 Binary files /dev/null and b/ext/bin/tap-windows-ndis5/x64/zttap200.sys differ diff --git a/ext/bin/tap-windows-ndis5/x86/WdfCoinstaller01011.dll b/ext/bin/tap-windows-ndis5/x86/WdfCoinstaller01011.dll new file mode 100644 index 000000000..e943ea45e Binary files /dev/null and b/ext/bin/tap-windows-ndis5/x86/WdfCoinstaller01011.dll differ diff --git a/ext/bin/tap-windows-ndis5/x86/zttap200.cat b/ext/bin/tap-windows-ndis5/x86/zttap200.cat new file mode 100644 index 000000000..d90ecbbee Binary files /dev/null and b/ext/bin/tap-windows-ndis5/x86/zttap200.cat differ diff --git a/ext/bin/tap-windows-ndis5/x86/zttap200.inf b/ext/bin/tap-windows-ndis5/x86/zttap200.inf new file mode 100644 index 000000000..99aac9f2b --- /dev/null +++ b/ext/bin/tap-windows-ndis5/x86/zttap200.inf @@ -0,0 +1,76 @@ +[Version] +Signature="$WINDOWS NT$" +Class=Net +ClassGuid={4d36e972-e325-11ce-bfc1-08002be10318} +Provider=%Provider% +CatalogFile=zttap200.cat +DriverVer=01/24/2014,17.25.51.226 + +[Strings] +DeviceDescription = "ZeroTier One Virtual Network Port" +Provider = "ZeroTier Networks LLC" + +; To build for x86, take NTamd64 off this and off the named section manually, build, then put it back! +[Manufacturer] +%Provider%=zttap200 + +[zttap200] +%DeviceDescription%=zttap200.ndi,zttap200 + +[zttap200.ndi] +CopyFiles = zttap200.driver,zttap200.files +AddReg = zttap200.reg +AddReg = zttap200.params.reg +Characteristics = 0x81 + +[zttap200.ndi.Services] +AddService = zttap200, 2, zttap200.service + +[zttap200.reg] +HKR, Ndi, Service, 0, "zttap200" +HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" +HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" +HKR, , Manufacturer, 0, "%Provider%" +HKR, , ProductName, 0, "%DeviceDescription%" + +[zttap200.params.reg] +HKR, Ndi\params\MTU, ParamDesc, 0, "MTU" +HKR, Ndi\params\MTU, Type, 0, "int" +HKR, Ndi\params\MTU, Default, 0, "2800" +HKR, Ndi\params\MTU, Optional, 0, "0" +HKR, Ndi\params\MTU, Min, 0, "100" +HKR, Ndi\params\MTU, Max, 0, "2800" +HKR, Ndi\params\MTU, Step, 0, "1" +HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status" +HKR, Ndi\params\MediaStatus, Type, 0, "enum" +HKR, Ndi\params\MediaStatus, Default, 0, "0" +HKR, Ndi\params\MediaStatus, Optional, 0, "0" +HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled" +HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected" +HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address" +HKR, Ndi\params\MAC, Type, 0, "edit" +HKR, Ndi\params\MAC, Optional, 0, "1" + +[zttap200.service] +DisplayName = %DeviceDescription% +ServiceType = 1 +StartType = 3 +ErrorControl = 1 +LoadOrderGroup = NDIS +ServiceBinary = %12%\zttap200.sys + +[SourceDisksNames] +1 = %DeviceDescription%, zttap200.sys + +[SourceDisksFiles] +zttap200.sys = 1 + +[DestinationDirs] +zttap200.files = 11 +zttap200.driver = 12 + +[zttap200.files] +; + +[zttap200.driver] +zttap200.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK diff --git a/ext/bin/tap-windows-ndis5/x86/zttap200.sys b/ext/bin/tap-windows-ndis5/x86/zttap200.sys new file mode 100644 index 000000000..b7b11fbe8 Binary files /dev/null and b/ext/bin/tap-windows-ndis5/x86/zttap200.sys differ diff --git a/ext/bin/tap-windows-ndis6/arm64/zttap300.cat b/ext/bin/tap-windows-ndis6/arm64/zttap300.cat deleted file mode 100644 index 906a15a4b..000000000 Binary files a/ext/bin/tap-windows-ndis6/arm64/zttap300.cat and /dev/null differ diff --git a/ext/bin/tap-windows-ndis6/arm64/zttap300.inf b/ext/bin/tap-windows-ndis6/arm64/zttap300.inf deleted file mode 100644 index 8e74daab1..000000000 --- a/ext/bin/tap-windows-ndis6/arm64/zttap300.inf +++ /dev/null @@ -1,145 +0,0 @@ -; -; **************************************************************************** -; * Copyright (C) 2002-2014 OpenVPN Technologies, Inc. * -; * This program is free software; you can redistribute it and/or modify * -; * it under the terms of the GNU General Public License version 2 * -; * as published by the Free Software Foundation. * -; **************************************************************************** -; - -; -; ZeroTier One Virtual Network Port NDIS6 Driver -; -; Modified by ZeroTier, Inc. - https://www.zerotier.com/ -; -; (1) Comment out 'tun' functionality and related features such as DHCP -; emulation, since we don't use any of that. Just want straight 'tap'. -; (2) Added custom IOCTL to enumerate L2 multicast memberships. -; (3) Increase maximum number of multicast memberships to 128. -; (4) Set default and max device MTU to 2800. -; (5) Rename/rebrand driver as ZeroTier network port driver. -; -; Original copyright below. Modifications released under GPLv2 as well. - -[Version] -Signature = "$Windows NT$" -CatalogFile = zttap300.cat -ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318} -Provider = %Provider% -Class = Net -DriverVer=11/24/2020,3.00.00.1 - -[Strings] -DeviceDescription = "ZeroTier Virtual Port" -Provider = "ZeroTier" - -[Manufacturer] -%Provider%=zttap300,NTx86 -%Provider%=zttap300,NTamd64 -%Provider%=zttap300,NTarm64 - -[zttap300.NTx86] -%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated -%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy - -[zttap300.NTamd64] -%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated -%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy - -[zttap300.NTarm64] -%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated -%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy - -;----------------- Characteristics ------------ -; NCF_PHYSICAL = 0x04 -; NCF_VIRTUAL = 0x01 -; NCF_SOFTWARE_ENUMERATED = 0x02 -; NCF_HIDDEN = 0x08 -; NCF_NO_SERVICE = 0x10 -; NCF_HAS_UI = 0x80 -;----------------- Characteristics ------------ -[zttap300.ndi] -CopyFiles = zttap300.driver, zttap300.files -AddReg = zttap300.reg -AddReg = zttap300.params.reg -Characteristics = 0x81 -*IfType = 0x6 ; IF_TYPE_ETHERNET_CSMACD -*MediaType = 0x0 ; NdisMedium802_3 -*PhysicalMediaType = 14 ; NdisPhysicalMedium802_3 - -[zttap300.ndi.Services] -AddService = zttap300, 2, zttap300.service - -[zttap300.reg] -HKR, Ndi, Service, 0, "zttap300" -HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" ; yes, 'ndis5' is correct... yup, Windows. -HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" -HKR, , Manufacturer, 0, "%Provider%" -HKR, , ProductName, 0, "%DeviceDescription%" - -[zttap300.params.reg] -HKR, Ndi\params\MTU, ParamDesc, 0, "MTU" -HKR, Ndi\params\MTU, Type, 0, "int" -HKR, Ndi\params\MTU, Default, 0, "2800" -HKR, Ndi\params\MTU, Optional, 0, "0" -HKR, Ndi\params\MTU, Min, 0, "100" -HKR, Ndi\params\MTU, Max, 0, "2800" -HKR, Ndi\params\MTU, Step, 0, "1" -HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status" -HKR, Ndi\params\MediaStatus, Type, 0, "enum" -HKR, Ndi\params\MediaStatus, Default, 0, "0" -HKR, Ndi\params\MediaStatus, Optional, 0, "0" -HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled" -HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected" -HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address" -HKR, Ndi\params\MAC, Type, 0, "edit" -HKR, Ndi\params\MAC, Optional, 0, "1" -HKR, Ndi\params\AllowNonAdmin, ParamDesc, 0, "Non-Admin Access" -HKR, Ndi\params\AllowNonAdmin, Type, 0, "enum" -HKR, Ndi\params\AllowNonAdmin, Default, 0, "0" -HKR, Ndi\params\AllowNonAdmin, Optional, 0, "0" -HKR, Ndi\params\AllowNonAdmin\enum, "0", 0, "Not Allowed" -HKR, Ndi\params\AllowNonAdmin\enum, "1", 0, "Allowed" - -;---------- Service Type ------------- -; SERVICE_KERNEL_DRIVER = 0x01 -; SERVICE_WIN32_OWN_PROCESS = 0x10 -;---------- Service Type ------------- - -;---------- Start Mode --------------- -; SERVICE_BOOT_START = 0x0 -; SERVICE_SYSTEM_START = 0x1 -; SERVICE_AUTO_START = 0x2 -; SERVICE_DEMAND_START = 0x3 -; SERVICE_DISABLED = 0x4 -;---------- Start Mode --------------- - -[zttap300.service] -DisplayName = %DeviceDescription% -ServiceType = 1 -StartType = 3 -ErrorControl = 1 -LoadOrderGroup = NDIS -ServiceBinary = %12%\zttap300.sys - -;----------------- Copy Flags ------------ -; COPYFLG_NOSKIP = 0x02 -; COPYFLG_NOVERSIONCHECK = 0x04 -;----------------- Copy Flags ------------ - -[SourceDisksNames] -1 = %DeviceDescription%, zttap300.sys - -[SourceDisksFiles] -zttap300.sys = 1 - -[DestinationDirs] -zttap300.files = 11 -zttap300.driver = 12 - -[zttap300.files] -; - -[zttap300.driver] -zttap300.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK - diff --git a/ext/bin/tap-windows-ndis6/arm64/zttap300.sys b/ext/bin/tap-windows-ndis6/arm64/zttap300.sys deleted file mode 100644 index ae1a16f4b..000000000 Binary files a/ext/bin/tap-windows-ndis6/arm64/zttap300.sys and /dev/null differ diff --git a/ext/bin/tap-windows-ndis6/x64/WdfCoinstaller01011.dll b/ext/bin/tap-windows-ndis6/x64/WdfCoinstaller01011.dll new file mode 100644 index 000000000..d49d29132 Binary files /dev/null and b/ext/bin/tap-windows-ndis6/x64/WdfCoinstaller01011.dll differ diff --git a/ext/bin/tap-windows-ndis6/x64/ZeroTierOne_NDIS6_x64.msi b/ext/bin/tap-windows-ndis6/x64/ZeroTierOne_NDIS6_x64.msi new file mode 100644 index 000000000..7e6fc4267 Binary files /dev/null and b/ext/bin/tap-windows-ndis6/x64/ZeroTierOne_NDIS6_x64.msi differ diff --git a/ext/bin/tap-windows-ndis6/x64/zttap300.cat b/ext/bin/tap-windows-ndis6/x64/zttap300.cat index 6eef79ff8..f1f878a31 100644 Binary files a/ext/bin/tap-windows-ndis6/x64/zttap300.cat and b/ext/bin/tap-windows-ndis6/x64/zttap300.cat differ diff --git a/ext/bin/tap-windows-ndis6/x64/zttap300.inf b/ext/bin/tap-windows-ndis6/x64/zttap300.inf index e05038dae..9cc9ffc72 100644 --- a/ext/bin/tap-windows-ndis6/x64/zttap300.inf +++ b/ext/bin/tap-windows-ndis6/x64/zttap300.inf @@ -30,11 +30,11 @@ CatalogFile = zttap300.cat ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318} Provider = %Provider% Class = Net -DriverVer=11/24/2020,3.00.00.1 +DriverVer=04/25/2015,6.2.9200.20557 [Strings] -DeviceDescription = "ZeroTier Virtual Port" -Provider = "ZeroTier" +DeviceDescription = "ZeroTier One Virtual Port" +Provider = "ZeroTier Networks LLC" ; We're ZeroTier, Inc. now but kernel mode certs are $300+ so fuqdat. ; To build for x86, take NTamd64 off this and off the named section manually, build, then put it back! [Manufacturer] @@ -141,4 +141,3 @@ zttap300.driver = 12 [zttap300.driver] zttap300.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK - diff --git a/ext/bin/tap-windows-ndis6/x64/zttap300.sys b/ext/bin/tap-windows-ndis6/x64/zttap300.sys index 2c7922b39..060916f95 100644 Binary files a/ext/bin/tap-windows-ndis6/x64/zttap300.sys and b/ext/bin/tap-windows-ndis6/x64/zttap300.sys differ diff --git a/ext/bin/tap-windows-ndis6/x86/WdfCoinstaller01011.dll b/ext/bin/tap-windows-ndis6/x86/WdfCoinstaller01011.dll new file mode 100644 index 000000000..e943ea45e Binary files /dev/null and b/ext/bin/tap-windows-ndis6/x86/WdfCoinstaller01011.dll differ diff --git a/ext/bin/tap-windows-ndis6/x86/ZeroTierOne_NDIS6_x86.msi b/ext/bin/tap-windows-ndis6/x86/ZeroTierOne_NDIS6_x86.msi new file mode 100644 index 000000000..80b330a8a Binary files /dev/null and b/ext/bin/tap-windows-ndis6/x86/ZeroTierOne_NDIS6_x86.msi differ diff --git a/ext/bin/tap-windows-ndis6/x86/zttap300.cat b/ext/bin/tap-windows-ndis6/x86/zttap300.cat index f6021aa88..d899961e3 100644 Binary files a/ext/bin/tap-windows-ndis6/x86/zttap300.cat and b/ext/bin/tap-windows-ndis6/x86/zttap300.cat differ diff --git a/ext/bin/tap-windows-ndis6/x86/zttap300.inf b/ext/bin/tap-windows-ndis6/x86/zttap300.inf index a562e9d64..5f46dbfdc 100644 --- a/ext/bin/tap-windows-ndis6/x86/zttap300.inf +++ b/ext/bin/tap-windows-ndis6/x86/zttap300.inf @@ -1,15 +1,10 @@ -; -; **************************************************************************** -; * Copyright (C) 2002-2014 OpenVPN Technologies, Inc. * -; * This program is free software; you can redistribute it and/or modify * -; * it under the terms of the GNU General Public License version 2 * -; * as published by the Free Software Foundation. * -; **************************************************************************** -; - ; ; ZeroTier One Virtual Network Port NDIS6 Driver ; +; Based on the OpenVPN tap-windows6 driver version 9.21.1 git +; commit 48f027cfca52b16b5fd23d82e6016ed8a91fc4d3. +; See: https://github.com/OpenVPN/tap-windows6 +; ; Modified by ZeroTier, Inc. - https://www.zerotier.com/ ; ; (1) Comment out 'tun' functionality and related features such as DHCP @@ -20,6 +15,14 @@ ; (5) Rename/rebrand driver as ZeroTier network port driver. ; ; Original copyright below. Modifications released under GPLv2 as well. +; +; **************************************************************************** +; * Copyright (C) 2002-2014 OpenVPN Technologies, Inc. * +; * This program is free software; you can redistribute it and/or modify * +; * it under the terms of the GNU General Public License version 2 * +; * as published by the Free Software Foundation. * +; **************************************************************************** +; [Version] Signature = "$Windows NT$" @@ -27,21 +30,17 @@ CatalogFile = zttap300.cat ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318} Provider = %Provider% Class = Net -DriverVer=11/24/2020,3.00.00.1 +DriverVer=04/25/2015,6.2.9200.20557 [Strings] -DeviceDescription = "ZeroTier Virtual Port" -Provider = "ZeroTier" +DeviceDescription = "ZeroTier One Virtual Port" +Provider = "ZeroTier Networks LLC" ; We're ZeroTier, Inc. now but kernel mode certs are $300+ so fuqdat. +; To build for x86, take NTamd64 off this and off the named section manually, build, then put it back! [Manufacturer] -%Provider%=zttap300,NTx86 -;%Provider%=zttap300,NTamd64 +%Provider%=zttap300 -[zttap300.NTx86] -%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated -%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy - -[zttap300.NTamd64] +[zttap300] %DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated %DeviceDescription% = zttap300.ndi, zttap300 ; Legacy @@ -138,4 +137,3 @@ zttap300.driver = 12 [zttap300.driver] zttap300.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK - diff --git a/ext/bin/tap-windows-ndis6/x86/zttap300.sys b/ext/bin/tap-windows-ndis6/x86/zttap300.sys index 86e51a3ea..29933e3e2 100644 Binary files a/ext/bin/tap-windows-ndis6/x86/zttap300.sys and b/ext/bin/tap-windows-ndis6/x86/zttap300.sys differ diff --git a/ext/bin/win-ui-wrapper/ZeroTier One.exe b/ext/bin/win-ui-wrapper/ZeroTier One.exe new file mode 100644 index 000000000..622b5b361 Binary files /dev/null and b/ext/bin/win-ui-wrapper/ZeroTier One.exe differ diff --git a/ext/central-controller-docker/Dockerfile b/ext/central-controller-docker/Dockerfile deleted file mode 100644 index 29670ec68..000000000 --- a/ext/central-controller-docker/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -# Dockerfile for ZeroTier Central Controllers -FROM registry.zerotier.com/zerotier/ctlbuild:2025-07-14 AS builder -ADD . /ZeroTierOne -RUN export PATH=$PATH:~/.cargo/bin && cd ZeroTierOne && make clean && make central-controller -j8 - -FROM golang:bookworm AS go_base -RUN go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest - -FROM registry.zerotier.com/zerotier/ctlrun:2025-07-14 AS run_base -COPY --from=builder /ZeroTierOne/zerotier-one /usr/local/bin/zerotier-one -COPY --from=builder /ZeroTierOne/ext/opentelemetry-cpp-1.21.0/localinstall/lib/*.so /usr/local/lib64/ -COPY --from=go_base /go/bin/migrate /usr/local/bin/migrate -COPY ext/central-controller-docker/migrations /migrations - -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 deleted file mode 100644 index 6e10db887..000000000 --- a/ext/central-controller-docker/Dockerfile.builder +++ /dev/null @@ -1,34 +0,0 @@ -# Dockerfile for building ZeroTier Central Controllers -FROM debian:bookworm - -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 \ - libcurl4-openssl-dev \ - google-perftools \ - libgoogle-perftools-dev \ - protobuf-compiler \ - protobuf-compiler-grpc \ - protobuf-c-compiler \ - grpc-proto \ - libgrpc++1.51 \ - libgrpc++-dev \ - libgrpc-dev \ - libgrpc29 \ - cmake \ - git - - -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 deleted file mode 100644 index fb5d0e2d5..000000000 --- a/ext/central-controller-docker/Dockerfile.run_base +++ /dev/null @@ -1,19 +0,0 @@ -FROM debian:bookworm - - - -RUN apt update && apt upgrade -y -RUN apt -y install \ - netcat-traditional \ - postgresql-client \ - postgresql-client-common \ - libjemalloc2 \ - libpq5 \ - curl \ - binutils \ - perf-tools-unstable \ - google-perftools \ - gnupg \ - libgrpc++1.51 \ - libgrpc29 - diff --git a/ext/central-controller-docker/Makefile b/ext/central-controller-docker/Makefile deleted file mode 100644 index 2318d2903..000000000 --- a/ext/central-controller-docker/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -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:$(shell date +"%Y-%m-%d") -f Dockerfile.builder . --push - -controller-runbase: buildx - docker buildx build --no-cache --platform linux/amd64,linux/arm64 -t $(registry)/ctlrun:$(shell date +"%Y-%m-%d") -f Dockerfile.run_base . --push diff --git a/ext/central-controller-docker/README.md b/ext/central-controller-docker/README.md deleted file mode 100644 index a954b1c37..000000000 --- a/ext/central-controller-docker/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# 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 deleted file mode 100755 index b1c4b4cbc..000000000 --- a/ext/central-controller-docker/main.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/bin/bash - -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 -if [ -z "$ZT_DB_TYPE" ]; then - ZT_DB_TYPE="postgres" -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 -if [ -d "$ZT_IDENTITY_PATH" ]; then - echo '*** Using existing ZT identity from path $ZT_IDENTITY_PATH' - - 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 -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\": \"${ZT_DB_TYPE}: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\"], - \"otel\": { - \"exporterEndpoint\": \"${ZT_EXPORTER_ENDPOINT}\", - \"exporterSampleRate\": ${ZT_EXPORTER_SAMPLE_RATE:-0} - }, - ${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 [ "$ZT_DB_TYPE" == "cv2" ]; then - echo "Migrating database (if needed)..." - if [ -n "$DB_SERVER_CA" ]; then - /usr/local/bin/migrate -source file:///migrations -database "postgres://$ZT_DB_USER:$ZT_DB_PASSWORD@$ZT_DB_HOST:$ZT_DB_PORT/$ZT_DB_NAME?x-migrations-table=controller_migrations&sslmode=verify-full&sslrootcert=$DB_SERVER_CA&sslcert=$DB_CLIENT_CERT&sslkey=$DB_CLIENT_KEY" up - else - /usr/local/bin/migrate -source file:///migrations -database "postgres://$ZT_DB_USER:$ZT_DB_PASSWORD@$ZT_DB_HOST:$ZT_DB_PORT/$ZT_DB_NAME?x-migrations-table=controller_migrations&sslmode=disable" up - fi -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/central-controller-docker/migrations/0001_init.down.sql b/ext/central-controller-docker/migrations/0001_init.down.sql deleted file mode 100644 index 03dc63c81..000000000 --- a/ext/central-controller-docker/migrations/0001_init.down.sql +++ /dev/null @@ -1,3 +0,0 @@ -DROP TABLE IF EXISTS network_memberships_ctl; -DROP TABLE IF EXISTS networks_ctl; -DROP TABLE IF EXISTS controllers_ctl; \ No newline at end of file diff --git a/ext/central-controller-docker/migrations/0001_init.up.sql b/ext/central-controller-docker/migrations/0001_init.up.sql deleted file mode 100644 index 90d29e889..000000000 --- a/ext/central-controller-docker/migrations/0001_init.up.sql +++ /dev/null @@ -1,47 +0,0 @@ --- inits controller db schema - -CREATE TABLE IF NOT EXISTS controllers_ctl ( - id text NOT NULL PRIMARY KEY, - hostname text, - last_heartbeat timestamp with time zone, - public_identity text NOT NULL, - version text -); - -CREATE TABLE IF NOT EXISTS networks_ctl ( - id character varying(22) NOT NULL PRIMARY KEY, - name text NOT NULL, - configuration jsonb DEFAULT '{}'::jsonb NOT NULL, - controller_id text REFERENCES controllers_ctl(id), - revision integer DEFAULT 0 NOT NULL, - last_modified timestamp with time zone DEFAULT now(), - creation_time timestamp with time zone DEFAULT now() -); - -CREATE TABLE IF NOT EXISTS network_memberships_ctl ( - device_id character varying(22) NOT NULL, - network_id character varying(22) NOT NULL REFERENCES networks_ctl(id), - authorized boolean, - active_bridge boolean, - ip_assignments text[], - no_auto_assign_ips boolean, - sso_exempt boolean, - authentication_expiry_time timestamp with time zone, - capabilities jsonb, - creation_time timestamp with time zone DEFAULT now(), - last_modified timestamp with time zone DEFAULT now(), - identity text DEFAULT ''::text, - last_authorized_credential text, - last_authorized_time timestamp with time zone, - last_deauthorized_time timestamp with time zone, - last_seen jsonb DEFAULT '{}'::jsonb NOT NULL, -- in the context of the network - remote_trace_level integer DEFAULT 0 NOT NULL, - remote_trace_target text DEFAULT ''::text NOT NULL, - revision integer DEFAULT 0 NOT NULL, - tags jsonb, - version_major integer DEFAULT 0 NOT NULL, - version_minor integer DEFAULT 0 NOT NULL, - version_revision integer DEFAULT 0 NOT NULL, - version_protocol integer DEFAULT 0 NOT NULL, - PRIMARY KEY (device_id, network_id) -); diff --git a/ext/central-controller-docker/migrations/0002_os_arch.down.sql b/ext/central-controller-docker/migrations/0002_os_arch.down.sql deleted file mode 100644 index 3c90f0a2e..000000000 --- a/ext/central-controller-docker/migrations/0002_os_arch.down.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE network_memberships_ctl - DROP COLUMN os, - DROP COLUMN arch; \ No newline at end of file diff --git a/ext/central-controller-docker/migrations/0002_os_arch.up.sql b/ext/central-controller-docker/migrations/0002_os_arch.up.sql deleted file mode 100644 index 095f7c698..000000000 --- a/ext/central-controller-docker/migrations/0002_os_arch.up.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE network_memberships_ctl - ADD COLUMN os TEXT NOT NULL DEFAULT 'unknown', - ADD COLUMN arch TEXT NOT NULL DEFAULT 'unknown'; \ No newline at end of file diff --git a/ext/cpp-httplib/httplib.h b/ext/cpp-httplib/httplib.h deleted file mode 100644 index 862e97e9e..000000000 --- a/ext/cpp-httplib/httplib.h +++ /dev/null @@ -1,9442 +0,0 @@ -// -// 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; - - bool routing(Request &req, Response &res, Stream &strm); - -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 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 deleted file mode 100644 index 955392eac..000000000 --- a/ext/ed25519-amd64-asm/batch.c +++ /dev/null @@ -1,94 +0,0 @@ -#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 deleted file mode 100644 index c272383f6..000000000 --- a/ext/ed25519-amd64-asm/consts.s +++ /dev/null @@ -1,39 +0,0 @@ -.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 deleted file mode 100644 index 33ffabbe7..000000000 --- a/ext/ed25519-amd64-asm/fe25519.h +++ /dev/null @@ -1,64 +0,0 @@ -#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 deleted file mode 100644 index b2e562520..000000000 --- a/ext/ed25519-amd64-asm/fe25519_add.s +++ /dev/null @@ -1,189 +0,0 @@ - -# 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 deleted file mode 100644 index a003ec8f5..000000000 --- a/ext/ed25519-amd64-asm/fe25519_getparity.c +++ /dev/null @@ -1,8 +0,0 @@ -#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 deleted file mode 100644 index a46d141ff..000000000 --- a/ext/ed25519-amd64-asm/fe25519_invert.c +++ /dev/null @@ -1,60 +0,0 @@ -#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 deleted file mode 100644 index bf72f8c91..000000000 --- a/ext/ed25519-amd64-asm/fe25519_iseq.c +++ /dev/null @@ -1,14 +0,0 @@ -#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 deleted file mode 100644 index 99e4dafa7..000000000 --- a/ext/ed25519-amd64-asm/fe25519_iszero.c +++ /dev/null @@ -1,12 +0,0 @@ -#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 deleted file mode 100644 index 147842811..000000000 --- a/ext/ed25519-amd64-asm/fe25519_mul.s +++ /dev/null @@ -1,865 +0,0 @@ - -# 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 deleted file mode 100644 index 235b209dd..000000000 --- a/ext/ed25519-amd64-asm/fe25519_neg.c +++ /dev/null @@ -1,8 +0,0 @@ -#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 deleted file mode 100644 index caf518530..000000000 --- a/ext/ed25519-amd64-asm/fe25519_pack.c +++ /dev/null @@ -1,13 +0,0 @@ -#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 deleted file mode 100644 index 60042a0a1..000000000 --- a/ext/ed25519-amd64-asm/fe25519_pow2523.c +++ /dev/null @@ -1,55 +0,0 @@ -#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 deleted file mode 100644 index 585c4bdd5..000000000 --- a/ext/ed25519-amd64-asm/fe25519_setint.c +++ /dev/null @@ -1,9 +0,0 @@ -#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 deleted file mode 100644 index a74d9e888..000000000 --- a/ext/ed25519-amd64-asm/fe25519_square.s +++ /dev/null @@ -1,639 +0,0 @@ - -# 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 deleted file mode 100644 index 0b395bce7..000000000 --- a/ext/ed25519-amd64-asm/fe25519_sub.s +++ /dev/null @@ -1,189 +0,0 @@ - -# 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 deleted file mode 100644 index 0b15136b9..000000000 --- a/ext/ed25519-amd64-asm/ge25519.h +++ /dev/null @@ -1,95 +0,0 @@ -#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 deleted file mode 100644 index c4d1c68a4..000000000 --- a/ext/ed25519-amd64-asm/ge25519_add.c +++ /dev/null @@ -1,8 +0,0 @@ -#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 deleted file mode 100644 index 0cb138980..000000000 --- a/ext/ed25519-amd64-asm/ge25519_add_p1p1.s +++ /dev/null @@ -1,4554 +0,0 @@ - -# 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 deleted file mode 100644 index a7ae97864..000000000 --- a/ext/ed25519-amd64-asm/ge25519_base.c +++ /dev/null @@ -1,7 +0,0 @@ -#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 deleted file mode 100644 index 8e3300cf4..000000000 --- a/ext/ed25519-amd64-asm/ge25519_base_niels.data +++ /dev/null @@ -1,1536 +0,0 @@ -{{{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 deleted file mode 100644 index a31f6f2f0..000000000 --- a/ext/ed25519-amd64-asm/ge25519_base_niels_smalltables.data +++ /dev/null @@ -1,768 +0,0 @@ -{{{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 deleted file mode 100644 index 32a5d4747..000000000 --- a/ext/ed25519-amd64-asm/ge25519_base_slide_multiples.data +++ /dev/null @@ -1,96 +0,0 @@ -{{{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 deleted file mode 100644 index 265daf091..000000000 --- a/ext/ed25519-amd64-asm/ge25519_dbl_p1p1.s +++ /dev/null @@ -1,2975 +0,0 @@ - -# 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 deleted file mode 100644 index d55e2b4f8..000000000 --- a/ext/ed25519-amd64-asm/ge25519_double.c +++ /dev/null @@ -1,8 +0,0 @@ -#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 deleted file mode 100644 index 30c922af5..000000000 --- a/ext/ed25519-amd64-asm/ge25519_double_scalarmult.c +++ /dev/null @@ -1,102 +0,0 @@ -#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 deleted file mode 100644 index cf566dbae..000000000 --- a/ext/ed25519-amd64-asm/ge25519_isneutral.c +++ /dev/null @@ -1,9 +0,0 @@ -#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 deleted file mode 100644 index afc6aeae5..000000000 --- a/ext/ed25519-amd64-asm/ge25519_multi_scalarmult.c +++ /dev/null @@ -1,102 +0,0 @@ -#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 deleted file mode 100644 index 19d71f11a..000000000 --- a/ext/ed25519-amd64-asm/ge25519_nielsadd2.s +++ /dev/null @@ -1,5791 +0,0 @@ - -# 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 deleted file mode 100644 index b5629462a..000000000 --- a/ext/ed25519-amd64-asm/ge25519_nielsadd_p1p1.s +++ /dev/null @@ -1,3072 +0,0 @@ - -# 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 deleted file mode 100644 index beddbc791..000000000 --- a/ext/ed25519-amd64-asm/ge25519_p1p1_to_p2.s +++ /dev/null @@ -1,2236 +0,0 @@ - -# 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 deleted file mode 100644 index 82433fba5..000000000 --- a/ext/ed25519-amd64-asm/ge25519_p1p1_to_p3.s +++ /dev/null @@ -1,2926 +0,0 @@ - -# 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 deleted file mode 100644 index f289fe570..000000000 --- a/ext/ed25519-amd64-asm/ge25519_pack.c +++ /dev/null @@ -1,13 +0,0 @@ -#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 deleted file mode 100644 index aff2e75d2..000000000 --- a/ext/ed25519-amd64-asm/ge25519_pnielsadd_p1p1.s +++ /dev/null @@ -1,3662 +0,0 @@ - -# 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 deleted file mode 100644 index ffa6e2fa9..000000000 --- a/ext/ed25519-amd64-asm/ge25519_scalarmult_base.c +++ /dev/null @@ -1,68 +0,0 @@ -#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 deleted file mode 100644 index ff16fd200..000000000 --- a/ext/ed25519-amd64-asm/ge25519_unpackneg.c +++ /dev/null @@ -1,60 +0,0 @@ -#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 deleted file mode 100644 index 8fe385b47..000000000 --- a/ext/ed25519-amd64-asm/heap_rootreplaced.s +++ /dev/null @@ -1,476 +0,0 @@ - -# 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 deleted file mode 100644 index 488e9c52d..000000000 --- a/ext/ed25519-amd64-asm/heap_rootreplaced_1limb.s +++ /dev/null @@ -1,416 +0,0 @@ - -# 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 deleted file mode 100644 index f9259184c..000000000 --- a/ext/ed25519-amd64-asm/heap_rootreplaced_2limbs.s +++ /dev/null @@ -1,436 +0,0 @@ - -# 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 deleted file mode 100644 index dcf890ea6..000000000 --- a/ext/ed25519-amd64-asm/heap_rootreplaced_3limbs.s +++ /dev/null @@ -1,456 +0,0 @@ - -# 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 deleted file mode 100644 index 6f99fc62c..000000000 --- a/ext/ed25519-amd64-asm/hram.c +++ /dev/null @@ -1,16 +0,0 @@ -/*#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 deleted file mode 100644 index 1740c78a4..000000000 --- a/ext/ed25519-amd64-asm/hram.h +++ /dev/null @@ -1,8 +0,0 @@ -#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 deleted file mode 100644 index 9b5399a38..000000000 --- a/ext/ed25519-amd64-asm/implementors +++ /dev/null @@ -1,5 +0,0 @@ -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 deleted file mode 100644 index f29f7a289..000000000 --- a/ext/ed25519-amd64-asm/index_heap.c +++ /dev/null @@ -1,58 +0,0 @@ -#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 deleted file mode 100644 index 7dee91613..000000000 --- a/ext/ed25519-amd64-asm/index_heap.h +++ /dev/null @@ -1,31 +0,0 @@ -#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 deleted file mode 100644 index 7e0947104..000000000 --- a/ext/ed25519-amd64-asm/keypair.c +++ /dev/null @@ -1,25 +0,0 @@ -#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 deleted file mode 100644 index 104d48dc8..000000000 --- a/ext/ed25519-amd64-asm/open.c +++ /dev/null @@ -1,49 +0,0 @@ -#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 deleted file mode 100644 index 8ff1b1cad..000000000 --- a/ext/ed25519-amd64-asm/sc25519.h +++ /dev/null @@ -1,66 +0,0 @@ -#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 deleted file mode 100644 index d5b941cd6..000000000 --- a/ext/ed25519-amd64-asm/sc25519_add.s +++ /dev/null @@ -1,232 +0,0 @@ - -# 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 deleted file mode 100644 index 7eb56fadc..000000000 --- a/ext/ed25519-amd64-asm/sc25519_barrett.s +++ /dev/null @@ -1,1188 +0,0 @@ - -# 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 deleted file mode 100644 index 7f21e6868..000000000 --- a/ext/ed25519-amd64-asm/sc25519_from32bytes.c +++ /dev/null @@ -1,55 +0,0 @@ -#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 deleted file mode 100644 index 8e76a1b36..000000000 --- a/ext/ed25519-amd64-asm/sc25519_from64bytes.c +++ /dev/null @@ -1,7 +0,0 @@ -#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 deleted file mode 100644 index 3b8ff2fbd..000000000 --- a/ext/ed25519-amd64-asm/sc25519_from_shortsc.c +++ /dev/null @@ -1,9 +0,0 @@ -#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 deleted file mode 100644 index 21f593d77..000000000 --- a/ext/ed25519-amd64-asm/sc25519_iszero.c +++ /dev/null @@ -1,10 +0,0 @@ -#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 deleted file mode 100644 index 3ba431782..000000000 --- a/ext/ed25519-amd64-asm/sc25519_lt.s +++ /dev/null @@ -1,131 +0,0 @@ - -# 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 deleted file mode 100644 index 0c67250d7..000000000 --- a/ext/ed25519-amd64-asm/sc25519_mul_shortsc.c +++ /dev/null @@ -1,9 +0,0 @@ -#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 deleted file mode 100644 index 4e52010d5..000000000 --- a/ext/ed25519-amd64-asm/sc25519_slide.c +++ /dev/null @@ -1,49 +0,0 @@ -#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 deleted file mode 100644 index a347e7d44..000000000 --- a/ext/ed25519-amd64-asm/sc25519_sub_nored.s +++ /dev/null @@ -1,142 +0,0 @@ - -# 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 deleted file mode 100644 index 683a1d4b8..000000000 --- a/ext/ed25519-amd64-asm/sc25519_window4.c +++ /dev/null @@ -1,27 +0,0 @@ -#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 deleted file mode 100644 index 715feb5b7..000000000 --- a/ext/ed25519-amd64-asm/sign.c +++ /dev/null @@ -1,162 +0,0 @@ -#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 ECC::sign(const ECC::Private &myPrivate,const ECC::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 deleted file mode 100644 index 9f7b4fa26..000000000 --- a/ext/ed25519-amd64-asm/ull4_mul.s +++ /dev/null @@ -1,716 +0,0 @@ - -# 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 deleted file mode 100644 index db2ad032a..000000000 --- a/ext/hiredis-0.14.1/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/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 deleted file mode 100644 index faf2ce684..000000000 --- a/ext/hiredis-0.14.1/.travis.yml +++ /dev/null @@ -1,45 +0,0 @@ -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 deleted file mode 100644 index f8e577369..000000000 --- a/ext/hiredis-0.14.1/CHANGELOG.md +++ /dev/null @@ -1,190 +0,0 @@ -**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 deleted file mode 100644 index a5fc97395..000000000 --- a/ext/hiredis-0.14.1/COPYING +++ /dev/null @@ -1,29 +0,0 @@ -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 deleted file mode 100644 index d1f005af4..000000000 --- a/ext/hiredis-0.14.1/Makefile +++ /dev/null @@ -1,214 +0,0 @@ -# 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 deleted file mode 100644 index 50e2e6be6..000000000 --- a/ext/hiredis-0.14.1/README.md +++ /dev/null @@ -1,410 +0,0 @@ -[![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 deleted file mode 100644 index 03939928d..000000000 --- a/ext/hiredis-0.14.1/adapters/ae.h +++ /dev/null @@ -1,127 +0,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. - */ - -#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 deleted file mode 100644 index e0a6411d3..000000000 --- a/ext/hiredis-0.14.1/adapters/glib.h +++ /dev/null @@ -1,153 +0,0 @@ -#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 deleted file mode 100644 index 75616ee24..000000000 --- a/ext/hiredis-0.14.1/adapters/ivykis.h +++ /dev/null @@ -1,81 +0,0 @@ -#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 deleted file mode 100644 index abad43634..000000000 --- a/ext/hiredis-0.14.1/adapters/libev.h +++ /dev/null @@ -1,147 +0,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. - */ - -#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 deleted file mode 100644 index f2330d6f0..000000000 --- a/ext/hiredis-0.14.1/adapters/libevent.h +++ /dev/null @@ -1,108 +0,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. - */ - -#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 deleted file mode 100644 index ff08c25e1..000000000 --- a/ext/hiredis-0.14.1/adapters/libuv.h +++ /dev/null @@ -1,122 +0,0 @@ -#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 deleted file mode 100644 index 72121f606..000000000 --- a/ext/hiredis-0.14.1/adapters/macosx.h +++ /dev/null @@ -1,114 +0,0 @@ -// -// 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 deleted file mode 100644 index 5cc02e6ce..000000000 --- a/ext/hiredis-0.14.1/adapters/qt.h +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * 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 deleted file mode 100644 index 55c3020e7..000000000 --- a/ext/hiredis-0.14.1/alloc.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 deleted file mode 100644 index 2c9b04e35..000000000 --- a/ext/hiredis-0.14.1/alloc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 deleted file mode 100644 index 819efbd58..000000000 --- a/ext/hiredis-0.14.1/appveyor.yml +++ /dev/null @@ -1,23 +0,0 @@ -# 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 deleted file mode 100644 index e69d84090..000000000 --- a/ext/hiredis-0.14.1/async.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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 deleted file mode 100644 index 29cdc190f..000000000 --- a/ext/hiredis-0.14.1/dict.c +++ /dev/null @@ -1,339 +0,0 @@ -/* 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 deleted file mode 100644 index 95fcd280e..000000000 --- a/ext/hiredis-0.14.1/dict.h +++ /dev/null @@ -1,126 +0,0 @@ -/* 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 deleted file mode 100644 index 8efa7306a..000000000 --- a/ext/hiredis-0.14.1/examples/example-ae.c +++ /dev/null @@ -1,62 +0,0 @@ -#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 deleted file mode 100644 index d6e10f8e8..000000000 --- a/ext/hiredis-0.14.1/examples/example-glib.c +++ /dev/null @@ -1,73 +0,0 @@ -#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 deleted file mode 100644 index 67affcef3..000000000 --- a/ext/hiredis-0.14.1/examples/example-ivykis.c +++ /dev/null @@ -1,58 +0,0 @@ -#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 deleted file mode 100644 index cc8b166ec..000000000 --- a/ext/hiredis-0.14.1/examples/example-libev.c +++ /dev/null @@ -1,52 +0,0 @@ -#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 deleted file mode 100644 index d333c22b7..000000000 --- a/ext/hiredis-0.14.1/examples/example-libevent.c +++ /dev/null @@ -1,53 +0,0 @@ -#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 deleted file mode 100644 index a5462d410..000000000 --- a/ext/hiredis-0.14.1/examples/example-libuv.c +++ /dev/null @@ -1,53 +0,0 @@ -#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 deleted file mode 100644 index bc84ed5ba..000000000 --- a/ext/hiredis-0.14.1/examples/example-macosx.c +++ /dev/null @@ -1,66 +0,0 @@ -// -// 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 deleted file mode 100644 index f524c3f3d..000000000 --- a/ext/hiredis-0.14.1/examples/example-qt.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#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 deleted file mode 100644 index 374f47666..000000000 --- a/ext/hiredis-0.14.1/examples/example-qt.h +++ /dev/null @@ -1,32 +0,0 @@ -#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 deleted file mode 100644 index 4d494c55a..000000000 --- a/ext/hiredis-0.14.1/examples/example.c +++ /dev/null @@ -1,78 +0,0 @@ -#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 deleted file mode 100644 index 3227faafd..000000000 --- a/ext/hiredis-0.14.1/fmacros.h +++ /dev/null @@ -1,12 +0,0 @@ -#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 deleted file mode 100644 index 98f43c993..000000000 --- a/ext/hiredis-0.14.1/hiredis.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* - * 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 deleted file mode 100644 index d945bf204..000000000 --- a/ext/hiredis-0.14.1/hiredis.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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 deleted file mode 100644 index 2c9b04e35..000000000 --- a/ext/hiredis-0.14.1/include/hiredis/alloc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 deleted file mode 100644 index e69d84090..000000000 --- a/ext/hiredis-0.14.1/include/hiredis/async.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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 deleted file mode 100644 index 95fcd280e..000000000 --- a/ext/hiredis-0.14.1/include/hiredis/dict.h +++ /dev/null @@ -1,126 +0,0 @@ -/* 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 deleted file mode 100644 index 3227faafd..000000000 --- a/ext/hiredis-0.14.1/include/hiredis/fmacros.h +++ /dev/null @@ -1,12 +0,0 @@ -#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 deleted file mode 100644 index d945bf204..000000000 --- a/ext/hiredis-0.14.1/include/hiredis/hiredis.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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 deleted file mode 100644 index d9dc36257..000000000 --- a/ext/hiredis-0.14.1/include/hiredis/net.h +++ /dev/null @@ -1,49 +0,0 @@ -/* 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 deleted file mode 100644 index 2988aa453..000000000 --- a/ext/hiredis-0.14.1/include/hiredis/read.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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 deleted file mode 100644 index 13be75a9f..000000000 --- a/ext/hiredis-0.14.1/include/hiredis/sds.h +++ /dev/null @@ -1,273 +0,0 @@ -/* 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 deleted file mode 100644 index f43023c48..000000000 --- a/ext/hiredis-0.14.1/include/hiredis/sdsalloc.h +++ /dev/null @@ -1,42 +0,0 @@ -/* 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 deleted file mode 100644 index 1a27c18f2..000000000 --- a/ext/hiredis-0.14.1/include/hiredis/win32.h +++ /dev/null @@ -1,42 +0,0 @@ -#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 deleted file mode 100644 index 0b9638798..000000000 Binary files a/ext/hiredis-0.14.1/lib/centos8/libhiredis.a and /dev/null differ diff --git a/ext/hiredis-0.14.1/lib/macos/libhiredis.a b/ext/hiredis-0.14.1/lib/macos/libhiredis.a deleted file mode 100644 index 02bdb8808..000000000 Binary files a/ext/hiredis-0.14.1/lib/macos/libhiredis.a and /dev/null differ diff --git a/ext/hiredis-0.14.1/net.c b/ext/hiredis-0.14.1/net.c deleted file mode 100644 index d71bbcd57..000000000 --- a/ext/hiredis-0.14.1/net.c +++ /dev/null @@ -1,477 +0,0 @@ -/* 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 deleted file mode 100644 index d9dc36257..000000000 --- a/ext/hiredis-0.14.1/net.h +++ /dev/null @@ -1,49 +0,0 @@ -/* 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 deleted file mode 100644 index cc2126778..000000000 --- a/ext/hiredis-0.14.1/read.c +++ /dev/null @@ -1,598 +0,0 @@ -/* - * 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 deleted file mode 100644 index 2988aa453..000000000 --- a/ext/hiredis-0.14.1/read.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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 deleted file mode 100644 index 923ffd82f..000000000 --- a/ext/hiredis-0.14.1/sds.c +++ /dev/null @@ -1,1272 +0,0 @@ -/* 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 deleted file mode 100644 index 13be75a9f..000000000 --- a/ext/hiredis-0.14.1/sds.h +++ /dev/null @@ -1,273 +0,0 @@ -/* 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 deleted file mode 100644 index f43023c48..000000000 --- a/ext/hiredis-0.14.1/sdsalloc.h +++ /dev/null @@ -1,42 +0,0 @@ -/* 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 deleted file mode 100644 index 0f5bfe572..000000000 --- a/ext/hiredis-0.14.1/test.c +++ /dev/null @@ -1,923 +0,0 @@ -#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 deleted file mode 100644 index 1a27c18f2..000000000 --- a/ext/hiredis-0.14.1/win32.h +++ /dev/null @@ -1,42 +0,0 @@ -#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 deleted file mode 100644 index 056959ffe..000000000 --- a/ext/hiredis-1.0.2/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -/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 deleted file mode 100644 index f9a9460ff..000000000 --- a/ext/hiredis-1.0.2/.travis.yml +++ /dev/null @@ -1,131 +0,0 @@ -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 deleted file mode 100644 index 2a2bc314a..000000000 --- a/ext/hiredis-1.0.2/CHANGELOG.md +++ /dev/null @@ -1,364 +0,0 @@ -## [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 deleted file mode 100644 index f86c9b70b..000000000 --- a/ext/hiredis-1.0.2/CMakeLists.txt +++ /dev/null @@ -1,165 +0,0 @@ -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 deleted file mode 100644 index a5fc97395..000000000 --- a/ext/hiredis-1.0.2/COPYING +++ /dev/null @@ -1,29 +0,0 @@ -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 deleted file mode 100644 index a8d37a2eb..000000000 --- a/ext/hiredis-1.0.2/Makefile +++ /dev/null @@ -1,308 +0,0 @@ -# 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 deleted file mode 100644 index c544d5718..000000000 --- a/ext/hiredis-1.0.2/README.md +++ /dev/null @@ -1,664 +0,0 @@ -[![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 deleted file mode 100644 index 660d82eb0..000000000 --- a/ext/hiredis-1.0.2/adapters/ae.h +++ /dev/null @@ -1,130 +0,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. - */ - -#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 deleted file mode 100644 index ad59dd142..000000000 --- a/ext/hiredis-1.0.2/adapters/glib.h +++ /dev/null @@ -1,156 +0,0 @@ -#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 deleted file mode 100644 index 179f6ab52..000000000 --- a/ext/hiredis-1.0.2/adapters/ivykis.h +++ /dev/null @@ -1,84 +0,0 @@ -#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 deleted file mode 100644 index e1e7bbd99..000000000 --- a/ext/hiredis-1.0.2/adapters/libev.h +++ /dev/null @@ -1,179 +0,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. - */ - -#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 deleted file mode 100644 index 9150979bc..000000000 --- a/ext/hiredis-1.0.2/adapters/libevent.h +++ /dev/null @@ -1,175 +0,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. - */ - -#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 deleted file mode 100644 index c120b1b39..000000000 --- a/ext/hiredis-1.0.2/adapters/libuv.h +++ /dev/null @@ -1,117 +0,0 @@ -#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 deleted file mode 100644 index 3c87f1b2f..000000000 --- a/ext/hiredis-1.0.2/adapters/macosx.h +++ /dev/null @@ -1,115 +0,0 @@ -// -// 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 deleted file mode 100644 index 5cc02e6ce..000000000 --- a/ext/hiredis-1.0.2/adapters/qt.h +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * 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 deleted file mode 100644 index 7fb6b35e7..000000000 --- a/ext/hiredis-1.0.2/alloc.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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 deleted file mode 100644 index 34a05f49f..000000000 --- a/ext/hiredis-1.0.2/alloc.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 deleted file mode 100644 index 5b43fdbeb..000000000 --- a/ext/hiredis-1.0.2/appveyor.yml +++ /dev/null @@ -1,24 +0,0 @@ -# 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 deleted file mode 100644 index b1d2cb263..000000000 --- a/ext/hiredis-1.0.2/async.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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 deleted file mode 100644 index b9d23fffd..000000000 --- a/ext/hiredis-1.0.2/async_private.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 deleted file mode 100644 index 34a33ead9..000000000 --- a/ext/hiredis-1.0.2/dict.c +++ /dev/null @@ -1,352 +0,0 @@ -/* 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 deleted file mode 100644 index 95fcd280e..000000000 --- a/ext/hiredis-1.0.2/dict.h +++ /dev/null @@ -1,126 +0,0 @@ -/* 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 deleted file mode 100644 index 1d5bc56e0..000000000 --- a/ext/hiredis-1.0.2/examples/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -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 deleted file mode 100644 index 8efa7306a..000000000 --- a/ext/hiredis-1.0.2/examples/example-ae.c +++ /dev/null @@ -1,62 +0,0 @@ -#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 deleted file mode 100644 index d6e10f8e8..000000000 --- a/ext/hiredis-1.0.2/examples/example-glib.c +++ /dev/null @@ -1,73 +0,0 @@ -#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 deleted file mode 100644 index f57dc3887..000000000 --- a/ext/hiredis-1.0.2/examples/example-ivykis.c +++ /dev/null @@ -1,60 +0,0 @@ -#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 deleted file mode 100644 index ec474306b..000000000 --- a/ext/hiredis-1.0.2/examples/example-libev.c +++ /dev/null @@ -1,54 +0,0 @@ -#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 deleted file mode 100644 index 7d99af1ba..000000000 --- a/ext/hiredis-1.0.2/examples/example-libevent-ssl.c +++ /dev/null @@ -1,90 +0,0 @@ -#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 deleted file mode 100644 index 49bddd0c2..000000000 --- a/ext/hiredis-1.0.2/examples/example-libevent.c +++ /dev/null @@ -1,67 +0,0 @@ -#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 deleted file mode 100644 index cbde452b9..000000000 --- a/ext/hiredis-1.0.2/examples/example-libuv.c +++ /dev/null @@ -1,56 +0,0 @@ -#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 deleted file mode 100644 index bc84ed5ba..000000000 --- a/ext/hiredis-1.0.2/examples/example-macosx.c +++ /dev/null @@ -1,66 +0,0 @@ -// -// 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 deleted file mode 100644 index 2d4ab4dc0..000000000 --- a/ext/hiredis-1.0.2/examples/example-push.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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 deleted file mode 100644 index f524c3f3d..000000000 --- a/ext/hiredis-1.0.2/examples/example-qt.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#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 deleted file mode 100644 index 374f47666..000000000 --- a/ext/hiredis-1.0.2/examples/example-qt.h +++ /dev/null @@ -1,32 +0,0 @@ -#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 deleted file mode 100644 index c754177cf..000000000 --- a/ext/hiredis-1.0.2/examples/example-ssl.c +++ /dev/null @@ -1,110 +0,0 @@ -#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 deleted file mode 100644 index 15dacbd18..000000000 --- a/ext/hiredis-1.0.2/examples/example.c +++ /dev/null @@ -1,91 +0,0 @@ -#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 deleted file mode 100644 index 3227faafd..000000000 --- a/ext/hiredis-1.0.2/fmacros.h +++ /dev/null @@ -1,12 +0,0 @@ -#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 deleted file mode 100644 index 98851dcee..000000000 --- a/ext/hiredis-1.0.2/hiredis-config.cmake.in +++ /dev/null @@ -1,13 +0,0 @@ -@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 deleted file mode 100644 index ab0e39822..000000000 --- a/ext/hiredis-1.0.2/hiredis.c +++ /dev/null @@ -1,1174 +0,0 @@ -/* - * 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 deleted file mode 100644 index 3bc46d992..000000000 --- a/ext/hiredis-1.0.2/hiredis.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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 deleted file mode 100644 index 91b773183..000000000 --- a/ext/hiredis-1.0.2/hiredis.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -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 deleted file mode 100644 index 9a283dfc2..000000000 --- a/ext/hiredis-1.0.2/hiredis_ssl-config.cmake.in +++ /dev/null @@ -1,13 +0,0 @@ -@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 deleted file mode 100644 index 604efe0c1..000000000 --- a/ext/hiredis-1.0.2/hiredis_ssl.h +++ /dev/null @@ -1,127 +0,0 @@ - -/* - * 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 deleted file mode 100644 index 588a978a5..000000000 --- a/ext/hiredis-1.0.2/hiredis_ssl.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -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 deleted file mode 100644 index 34a05f49f..000000000 --- a/ext/hiredis-1.0.2/include/hiredis/alloc.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 deleted file mode 100644 index b1d2cb263..000000000 --- a/ext/hiredis-1.0.2/include/hiredis/async.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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 deleted file mode 100644 index b9d23fffd..000000000 --- a/ext/hiredis-1.0.2/include/hiredis/async_private.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 deleted file mode 100644 index 95fcd280e..000000000 --- a/ext/hiredis-1.0.2/include/hiredis/dict.h +++ /dev/null @@ -1,126 +0,0 @@ -/* 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 deleted file mode 100644 index 3227faafd..000000000 --- a/ext/hiredis-1.0.2/include/hiredis/fmacros.h +++ /dev/null @@ -1,12 +0,0 @@ -#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 deleted file mode 100644 index 3bc46d992..000000000 --- a/ext/hiredis-1.0.2/include/hiredis/hiredis.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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 deleted file mode 100644 index 604efe0c1..000000000 --- a/ext/hiredis-1.0.2/include/hiredis/hiredis_ssl.h +++ /dev/null @@ -1,127 +0,0 @@ - -/* - * 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 deleted file mode 100644 index 9f43283a5..000000000 --- a/ext/hiredis-1.0.2/include/hiredis/net.h +++ /dev/null @@ -1,56 +0,0 @@ -/* 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 deleted file mode 100644 index 2d74d77a5..000000000 --- a/ext/hiredis-1.0.2/include/hiredis/read.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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 deleted file mode 100644 index eda8833b5..000000000 --- a/ext/hiredis-1.0.2/include/hiredis/sds.h +++ /dev/null @@ -1,278 +0,0 @@ -/* 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 deleted file mode 100644 index 5538dd94c..000000000 --- a/ext/hiredis-1.0.2/include/hiredis/sdsalloc.h +++ /dev/null @@ -1,44 +0,0 @@ -/* 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 deleted file mode 100644 index 85810e848..000000000 --- a/ext/hiredis-1.0.2/include/hiredis/sockcompat.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 deleted file mode 100644 index 04289c696..000000000 --- a/ext/hiredis-1.0.2/include/hiredis/win32.h +++ /dev/null @@ -1,56 +0,0 @@ -#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 deleted file mode 100644 index af1314f01..000000000 Binary files a/ext/hiredis-1.0.2/lib/ubuntu22.04/amd64/libhiredis.a and /dev/null differ 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 deleted file mode 100644 index 081c92705..000000000 Binary files a/ext/hiredis-1.0.2/lib/ubuntu22.04/arm64/libhiredis.a and /dev/null differ diff --git a/ext/hiredis-1.0.2/net.c b/ext/hiredis-1.0.2/net.c deleted file mode 100644 index c6b0e5d8e..000000000 --- a/ext/hiredis-1.0.2/net.c +++ /dev/null @@ -1,612 +0,0 @@ -/* 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 deleted file mode 100644 index 9f43283a5..000000000 --- a/ext/hiredis-1.0.2/net.h +++ /dev/null @@ -1,56 +0,0 @@ -/* 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 deleted file mode 100644 index 09524692b..000000000 --- a/ext/hiredis-1.0.2/read.c +++ /dev/null @@ -1,739 +0,0 @@ -/* - * 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 deleted file mode 100644 index 2d74d77a5..000000000 --- a/ext/hiredis-1.0.2/read.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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 deleted file mode 100644 index 49d2096b7..000000000 --- a/ext/hiredis-1.0.2/sds.c +++ /dev/null @@ -1,1289 +0,0 @@ -/* 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 deleted file mode 100644 index eda8833b5..000000000 --- a/ext/hiredis-1.0.2/sds.h +++ /dev/null @@ -1,278 +0,0 @@ -/* 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 deleted file mode 100644 index 5538dd94c..000000000 --- a/ext/hiredis-1.0.2/sdsalloc.h +++ /dev/null @@ -1,44 +0,0 @@ -/* 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 deleted file mode 100644 index f99d14b05..000000000 --- a/ext/hiredis-1.0.2/sockcompat.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * 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 deleted file mode 100644 index 85810e848..000000000 --- a/ext/hiredis-1.0.2/sockcompat.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 deleted file mode 100644 index 7df58fbde..000000000 --- a/ext/hiredis-1.0.2/ssl.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * 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 deleted file mode 100644 index 397f5640e..000000000 --- a/ext/hiredis-1.0.2/test.c +++ /dev/null @@ -1,1401 +0,0 @@ -#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 deleted file mode 100755 index c72bcb0dc..000000000 --- a/ext/hiredis-1.0.2/test.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/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 index 5323b685c..29cdbb16d 100644 --- a/ext/http-parser/AUTHORS +++ b/ext/http-parser/AUTHORS @@ -61,8 +61,3 @@ 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/README.md b/ext/http-parser/README.md deleted file mode 100644 index 439b30998..000000000 --- a/ext/http-parser/README.md +++ /dev/null @@ -1,246 +0,0 @@ -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 index 895bf0c73..aa6310f74 100644 --- a/ext/http-parser/http_parser.c +++ b/ext/http-parser/http_parser.c @@ -123,7 +123,7 @@ do { \ 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) @@ -400,8 +400,6 @@ enum http_host_state , 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 }; @@ -435,12 +433,6 @@ enum http_host_state (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) @@ -645,7 +637,6 @@ size_t http_parser_execute (http_parser *parser, 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) { @@ -966,23 +957,21 @@ reexecute: 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 'L': parser->method = HTTP_LOCK; 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 'R': parser->method = HTTP_REPORT; 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; + case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break; default: SET_ERRNO(HPE_INVALID_METHOD); goto error; @@ -1007,40 +996,69 @@ reexecute: 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: + } else if (parser->method == HTTP_CONNECT) { + if (parser->index == 1 && ch == 'H') { + parser->method = HTTP_CHECKOUT; + } else if (parser->index == 2 && ch == 'P') { + parser->method = HTTP_COPY; + } else { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + } else if (parser->method == HTTP_MKCOL) { + if (parser->index == 1 && ch == 'O') { + parser->method = HTTP_MOVE; + } else if (parser->index == 1 && ch == 'E') { + parser->method = HTTP_MERGE; + } else if (parser->index == 1 && ch == '-') { + parser->method = HTTP_MSEARCH; + } else if (parser->index == 2 && ch == 'A') { + parser->method = HTTP_MKACTIVITY; + } else if (parser->index == 3 && ch == 'A') { + parser->method = HTTP_MKCALENDAR; + } else { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + } else if (parser->method == HTTP_SUBSCRIBE) { + if (parser->index == 1 && ch == 'E') { + parser->method = HTTP_SEARCH; + } else { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + } else if (parser->index == 1 && parser->method == HTTP_POST) { + if (ch == 'R') { + parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */ + } else if (ch == 'U') { + parser->method = HTTP_PUT; /* or HTTP_PURGE */ + } else if (ch == 'A') { + parser->method = HTTP_PATCH; + } else { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + } else if (parser->index == 2) { + if (parser->method == HTTP_PUT) { + if (ch == 'R') { + parser->method = HTTP_PURGE; + } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; + } + } else if (parser->method == HTTP_UNLOCK) { + if (ch == 'S') { + parser->method = HTTP_UNSUBSCRIBE; + } else { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + } else { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; } - } else if (ch == '-' && - parser->index == 1 && - parser->method == HTTP_MKCOL) { - parser->method = HTTP_MSEARCH; + } else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') { + parser->method = HTTP_PROPPATCH; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; @@ -1469,12 +1487,6 @@ reexecute: 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; @@ -1524,11 +1536,6 @@ reexecute: REEXECUTE(); } - if (!lenient && !IS_HEADER_CHAR(ch)) { - SET_ERRNO(HPE_INVALID_HEADER_TOKEN); - goto error; - } - c = LOWER(ch); switch (h_state) { @@ -1696,10 +1703,7 @@ reexecute: case s_header_almost_done: { - if (UNLIKELY(ch != LF)) { - SET_ERRNO(HPE_LF_EXPECTED); - goto error; - } + STRICT_CHECK(ch != LF); UPDATE_STATE(s_header_value_lws); break; @@ -1778,17 +1782,9 @@ reexecute: 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(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + break; } UPDATE_STATE(s_headers_done); @@ -1813,9 +1809,6 @@ reexecute: case 0: break; - case 2: - parser->upgrade = 1; - case 1: parser->flags |= F_SKIPBODY; break; @@ -1835,16 +1828,12 @@ 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. */ + /* Exit, the rest of the connect is in a different protocol. */ + if (parser->upgrade) { UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); RETURN((p - data) + 1); @@ -1865,7 +1854,8 @@ reexecute: /* Content-Length header given and non-zero */ UPDATE_STATE(s_body_identity); } else { - if (!http_message_needs_eof(parser)) { + if (parser->type == HTTP_REQUEST || + !http_message_needs_eof(parser)) { /* Assume content-length 0 - read the next */ UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); @@ -1925,10 +1915,6 @@ reexecute: 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: @@ -2008,7 +1994,6 @@ reexecute: } else { UPDATE_STATE(s_chunk_data); } - CALLBACK_NOTIFY(chunk_header); break; } @@ -2048,7 +2033,6 @@ reexecute: STRICT_CHECK(ch != LF); parser->nread = 0; UPDATE_STATE(s_chunk_size_start); - CALLBACK_NOTIFY(chunk_complete); break; default: @@ -2160,13 +2144,13 @@ http_parser_settings_init(http_parser_settings *settings) const char * http_errno_name(enum http_errno err) { - assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); + assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0]))); return http_strerror_tab[err].name; } const char * http_errno_description(enum http_errno err) { - assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); + assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0]))); return http_strerror_tab[err].description; } @@ -2219,23 +2203,6 @@ http_parse_host_char(enum http_host_state s, const char 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: @@ -2259,8 +2226,6 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { 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; @@ -2287,11 +2252,6 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { 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; @@ -2321,8 +2281,6 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { 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: @@ -2334,11 +2292,6 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { 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) @@ -2412,12 +2365,7 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect, /* 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 ((u->field_set & ((1 << UF_SCHEMA) | (1 << UF_HOST))) != 0) { if (http_parse_host(buf, u, found_at) != 0) { return 1; } diff --git a/ext/http-parser/http_parser.h b/ext/http-parser/http_parser.h index 45c72a078..99c533ae4 100644 --- a/ext/http-parser/http_parser.h +++ b/ext/http-parser/http_parser.h @@ -26,12 +26,11 @@ extern "C" { /* 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 +#define HTTP_PARSER_VERSION_MINOR 4 +#define HTTP_PARSER_VERSION_PATCH 2 #include -#if defined(_WIN32) && !defined(__MINGW32__) && \ - (!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__) +#if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600) #include #include typedef __int8 int8_t; @@ -77,11 +76,6 @@ typedef struct http_parser_settings http_parser_settings; * 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. @@ -90,76 +84,6 @@ 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) \ @@ -171,7 +95,7 @@ enum http_status XX(5, CONNECT, CONNECT) \ XX(6, OPTIONS, OPTIONS) \ XX(7, TRACE, TRACE) \ - /* WebDAV */ \ + /* webdav */ \ XX(8, COPY, COPY) \ XX(9, LOCK, LOCK) \ XX(10, MKCOL, MKCOL) \ @@ -180,28 +104,21 @@ enum http_status 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) \ + XX(16, REPORT, REPORT) \ + XX(17, MKACTIVITY, MKACTIVITY) \ + XX(18, CHECKOUT, CHECKOUT) \ + XX(19, MERGE, MERGE) \ /* upnp */ \ - XX(24, MSEARCH, M-SEARCH) \ - XX(25, NOTIFY, NOTIFY) \ - XX(26, SUBSCRIBE, SUBSCRIBE) \ - XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ + XX(20, MSEARCH, M-SEARCH) \ + XX(21, NOTIFY, NOTIFY) \ + XX(22, SUBSCRIBE, SUBSCRIBE) \ + XX(23, UNSUBSCRIBE, UNSUBSCRIBE) \ /* RFC-5789 */ \ - XX(28, PATCH, PATCH) \ - XX(29, PURGE, PURGE) \ + XX(24, PATCH, PATCH) \ + XX(25, PURGE, PURGE) \ /* CalDAV */ \ - XX(30, MKCALENDAR, MKCALENDAR) \ - /* RFC-2068, section 19.6.1.2 */ \ - XX(31, LINK, LINK) \ - XX(32, UNLINK, UNLINK) \ + XX(26, MKCALENDAR, MKCALENDAR) \ enum http_method { @@ -223,12 +140,11 @@ enum flags , 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) \ @@ -244,8 +160,6 @@ enum flags 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") \ @@ -266,8 +180,6 @@ enum flags 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") \ @@ -292,11 +204,10 @@ enum 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 flags : 7; /* 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; + unsigned int header_state : 8; /* enum header_state from http_parser.c */ + unsigned int index : 8; /* index into current matcher */ uint32_t nread; /* # bytes read in various scenarios */ uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */ @@ -329,11 +240,6 @@ struct http_parser_settings { 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; }; @@ -412,9 +318,6 @@ 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, diff --git a/ext/inja/LICENSE b/ext/inja/LICENSE deleted file mode 100644 index 9e06bea07..000000000 --- a/ext/inja/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -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 deleted file mode 100644 index 9d66a2c28..000000000 --- a/ext/inja/README.md +++ /dev/null @@ -1,391 +0,0 @@ -[
](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 deleted file mode 100644 index 5b469745f..000000000 --- a/ext/inja/inja.hpp +++ /dev/null @@ -1,2949 +0,0 @@ -/* - ___ _ 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/pkg/asustor/zerotier/CONTROL/pre-install.sh b/ext/installfiles/linux/DEBIAN/conffiles old mode 100755 new mode 100644 similarity index 100% rename from pkg/asustor/zerotier/CONTROL/pre-install.sh rename to ext/installfiles/linux/DEBIAN/conffiles diff --git a/ext/installfiles/linux/DEBIAN/control.in b/ext/installfiles/linux/DEBIAN/control.in new file mode 100644 index 000000000..d774b61e9 --- /dev/null +++ b/ext/installfiles/linux/DEBIAN/control.in @@ -0,0 +1,10 @@ +Package: zerotier-one +Architecture: __ARCH__ +Maintainer: ZeroTier, Inc. +Priority: optional +Version: __VERSION__ +Homepage: https://github.com/zerotier/ZeroTierOne +Description: ZeroTier One network virtualization service + ZeroTier One is a fast, secure, and easy to use peer to peer network + virtualization engine. Visit https://www.zerotier.com/ for more + information. diff --git a/ext/installfiles/linux/RPM/zerotier-one.spec.in b/ext/installfiles/linux/RPM/zerotier-one.spec.in new file mode 100644 index 000000000..a5445ba53 --- /dev/null +++ b/ext/installfiles/linux/RPM/zerotier-one.spec.in @@ -0,0 +1,34 @@ +Name: zerotier-one +Summary: ZeroTier One network virtualization service +Version: __VERSION__ +Release: 1%{?dist} +License: GPLv3 +URL: https://www.zerotier.com/ + +%description +ZeroTier One creates virtual Ethernet networks that work anywhere and everywhere. +Visit https://www.zerotier.com/ for more information. + +%prep +mkdir -p $RPM_BUILD_ROOT/var/lib/zerotier-one/updates.d +cp -f $OLDPWD/__INSTALLER__ $RPM_BUILD_ROOT/var/lib/zerotier-one/updates.d + +%pre +mkdir -p /var/lib/zerotier-one/updates.d + +%files +/var/lib/zerotier-one/updates.d/__INSTALLER__ + +%post +chmod 0755 /var/lib/zerotier-one/updates.d/__INSTALLER__ +/var/lib/zerotier-one/updates.d/__INSTALLER__ + +%preun +if [ "$1" -lt 1 ]; then + /var/lib/zerotier-one/uninstall.sh +fi + +%clean +cp -f %{_rpmdir}/%{_arch}/%{name}-%{version}-%{release}.%{_arch}.rpm $OLDPWD +rm -f %{_rpmdir}/%{_arch}/%{name}-%{version}-%{release}.%{_arch}.rpm +rm -rf $RPM_BUILD_ROOT diff --git a/ext/installfiles/linux/buildinstaller.sh b/ext/installfiles/linux/buildinstaller.sh new file mode 100755 index 000000000..4f661b8d5 --- /dev/null +++ b/ext/installfiles/linux/buildinstaller.sh @@ -0,0 +1,134 @@ +#!/bin/bash + +# This script builds the installer for *nix systems. Windows must do everything +# completely differently, as usual. + +export PATH=/bin:/usr/bin:/sbin:/usr/sbin + +if [ ! -f zerotier-one ]; then + echo "Could not find 'zerotier-one' binary, please build before running this script." + exit 2 +fi + +machine=`uname -m` +system=`uname -s` + +vmajor=`cat version.h | grep -F ZEROTIER_ONE_VERSION_MAJOR | cut -d ' ' -f 3` +vminor=`cat version.h | grep -F ZEROTIER_ONE_VERSION_MINOR | cut -d ' ' -f 3` +revision=`cat version.h | grep -F ZEROTIER_ONE_VERSION_REVISION | cut -d ' ' -f 3` + +if [ -z "$vmajor" -o -z "$vminor" -o -z "$revision" ]; then + echo "Unable to extract version info from version.h, aborting installer build." + exit 2 +fi + +rm -rf build-installer +mkdir build-installer + +case "$system" in + + Linux) + # Canonicalize $machine for some architectures... we use x86 + # and x64 for Intel stuff. ARM and others should be fine if + # we ever ship officially for those. + debian_arch=$machine + case "$machine" in + i386|i486|i586|i686) + machine="x86" + debian_arch="i386" + ;; + x86_64|amd64|x64) + machine="x64" + debian_arch="amd64" + ;; + armv6l|arm|armhf) + machine="armv6l" + debian_arch="armhf" + ;; + esac + + echo "Assembling Linux installer for $machine and version $vmajor.$vminor.$revision" + + mkdir -p 'build-installer/var/lib/zerotier-one/ui' + cp -fp 'ext/installfiles/linux/uninstall.sh' 'build-installer/var/lib/zerotier-one' + cp -fp 'zerotier-one' 'build-installer/var/lib/zerotier-one' + for f in ui/*.html ui/*.js ui/*.css ui/*.jsx ; do + cp -fp "$f" 'build-installer/var/lib/zerotier-one/ui' + done + mkdir -p 'build-installer/tmp' + cp -fp 'ext/installfiles/linux/init.d/zerotier-one' 'build-installer/tmp/init.d_zerotier-one' + cp -fp 'ext/installfiles/linux/systemd/zerotier-one.service' 'build-installer/tmp/systemd_zerotier-one.service' + + targ="ZeroTierOneInstaller-linux-${machine}-${vmajor}_${vminor}_${revision}" + # Use gzip in Linux since some minimal Linux systems do not have bunzip2 + rm -f build-installer-tmp.tar.gz + cd build-installer + tar -cf - * | gzip -9 >../build-installer-tmp.tar.gz + cd .. + rm -f $targ + cat ext/installfiles/linux/install.tmpl.sh build-installer-tmp.tar.gz >$targ + chmod 0755 $targ + rm -f build-installer-tmp.tar.gz + ls -l $targ + + if [ -f /usr/bin/dpkg-deb -a "$UID" -eq 0 ]; then + echo + echo Found dpkg-deb and you are root, trying to build Debian package. + + rm -rf build-installer-deb + + debbase="build-installer-deb/zerotier-one_${vmajor}.${vminor}.${revision}_$debian_arch" + debfolder="${debbase}/DEBIAN" + mkdir -p $debfolder + + cat 'ext/installfiles/linux/DEBIAN/control.in' | sed "s/__VERSION__/${vmajor}.${vminor}.${revision}/" | sed "s/__ARCH__/${debian_arch}/" >$debfolder/control + cat $debfolder/control + cp -f 'ext/installfiles/linux/DEBIAN/conffiles' "${debfolder}/conffiles" + + mkdir -p "${debbase}/var/lib/zerotier-one/updates.d" + cp -f $targ "${debbase}/var/lib/zerotier-one/updates.d" + + rm -f "${debfolder}/postinst" "${debfolder}/prerm" + + echo '#!/bin/bash' >${debfolder}/postinst + echo "/var/lib/zerotier-one/updates.d/${targ}" >>${debfolder}/postinst + echo "/bin/rm -f /var/lib/zerotier-one/updates.d/*" >>${debfolder}/postinst + chmod a+x ${debfolder}/postinst + + echo '#!/bin/bash' >${debfolder}/prerm + echo 'export PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin' >>${debfolder}/prerm + echo 'if [ "$1" != "upgrade" ]; then' >>${debfolder}/prerm + echo ' /var/lib/zerotier-one/uninstall.sh' >>${debfolder}/prerm + echo 'fi' >>${debfolder}/prerm + chmod a+x ${debfolder}/prerm + + dpkg-deb --build $debbase + + mv -f build-installer-deb/*.deb . + rm -rf build-installer-deb + fi + + if [ -f /usr/bin/rpmbuild ]; then + echo + echo Found rpmbuild, trying to build RedHat/CentOS package. + + rm -f /tmp/zerotier-one.spec + curr_dir=`pwd` + cat ext/installfiles/linux/RPM/zerotier-one.spec.in | sed "s/__VERSION__/${vmajor}.${vminor}.${revision}/g" | sed "s/__INSTALLER__/${targ}/g" >/tmp/zerotier-one.spec + + rpmbuild -ba /tmp/zerotier-one.spec + + rm -f /tmp/zerotier-one.spec + fi + + ;; + + *) + echo "Unsupported platform: $system" + exit 2 + +esac + +rm -rf build-installer + +exit 0 diff --git a/ext/installfiles/linux/init.d/zerotier-one b/ext/installfiles/linux/init.d/zerotier-one new file mode 100755 index 000000000..c8e7615e1 --- /dev/null +++ b/ext/installfiles/linux/init.d/zerotier-one @@ -0,0 +1,114 @@ +#!/bin/sh +# +# zerotier-one Virtual distributed Ethernet service +# +# chkconfig: 2345 11 89 +# description: ZeroTier One provides public and private distributed ethernet \ +# networks. See https://www.zerotier.com/ for more information. + +### BEGIN INIT INFO +# Provides: zerotier-one +# Required-Start: $local_fs $network +# Required-Stop: $local_fs +# Default-Start: 2345 +# Default-Stop: 90 +# Short-Description: start ZeroTier One +# Description: ZeroTier One provides public and private distributed ethernet \ +# networks. See https://www.zerotier.com/ for more information. +### END INIT INFO + +# +# This script is written to avoid distro-specific dependencies, so it does not +# use the rc bash script libraries found on some systems. It should work on +# just about anything, even systems using Upstart. Upstart native support may +# come in the future. +# + +zthome=/var/lib/zerotier-one + +# Add $zthome to path so we can invoke zerotier-one naked, makes it look +# better in a ps listing. +export PATH=/bin:/usr/bin:/sbin:/usr/sbin:$zthome + +if [ "`id -u`" -ne 0 ]; then + echo "Init script must be called as root." + exit 4 +fi + +if [ ! -f "$zthome/zerotier-one" ]; then + echo "ZeroTier One is not installed in $zthome." + exit 5 +fi + +pid=0 +if [ -f "$zthome/zerotier-one.pid" ]; then + pid=`cat $zthome/zerotier-one.pid` +fi + +running=0 +if [ "$pid" -gt 0 ]; then + exepath=`readlink /proc/$pid/exe 2>/dev/null | grep zerotier-one` + if [ -n "$exepath" ]; then + running=1 + fi +fi + +case "$1" in + start) + if [ $running -gt 0 ]; then + echo "ZeroTier One already running." + exit 0 + fi + echo "Starting ZeroTier One..." + zerotier-one -d + ;; + stop) + if [ $running -gt 0 ]; then + echo "Stopping ZeroTier One..." + kill -TERM $pid + sleep 0.25 + if [ -f "$zthome/zerotier-one.pid" ]; then + sleep 0.5 + fi + if [ -f "$zthome/zerotier-one.pid" ]; then + sleep 1 + fi + if [ -f "$zthome/zerotier-one.pid" ]; then + kill -KILL $pid >>/dev/null 2>&1 + rm -f "$zthome/zerotier-one.pid" + fi + else + echo "ZeroTier One is not running." + fi + ;; + restart|reload|force-reload|condrestart|try-restart) + echo "Restarting ZeroTier One..." + if [ $running -gt 0 ]; then + kill -TERM $pid >>/dev/null 2>&1 + fi + sleep 0.25 + if [ -f "$zthome/zerotier-one.pid" ]; then + sleep 0.5 + fi + if [ -f "$zthome/zerotier-one.pid" ]; then + sleep 1 + fi + if [ -f "$zthome/zerotier-one.pid" ]; then + kill -KILL $pid >>/dev/null 2>&1 + rm -f "$zthome/zerotier-one.pid" + fi + zerotier-one -d + ;; + status) + if [ $running -gt 0 ]; then + exit 0 + else + exit 3 + fi + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" + exit 2 +esac + +exit 0 diff --git a/ext/installfiles/linux/install.tmpl.sh b/ext/installfiles/linux/install.tmpl.sh new file mode 100644 index 000000000..24425cbb0 --- /dev/null +++ b/ext/installfiles/linux/install.tmpl.sh @@ -0,0 +1,182 @@ +#!/bin/bash + +export PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin +shopt -s expand_aliases + +dryRun=0 + +echo "*** ZeroTier One install/update ***" +echo + +if [ "$UID" -ne 0 ]; then + echo "Not running as root so doing dry run (no modifications to system)..." + dryRun=1 +fi + +if [ $dryRun -gt 0 ]; then + alias ln="echo '>> ln'" + alias rm="echo '>> rm'" + alias mv="echo '>> mv'" + alias cp="echo '>> cp'" + alias chown="echo '>> chown'" + alias chgrp="echo '>> chgrp'" + alias chmod="echo '>> chmod'" + alias chkconfig="echo '>> chkconfig'" + alias zerotier-cli="echo '>> zerotier-cli'" + alias service="echo '>> service'" + alias systemctl="echo '>> systemctl'" +fi + +scriptPath="`dirname "$0"`/`basename "$0"`" +if [ ! -r "$scriptPath" ]; then + scriptPath="$0" + if [ ! -r "$scriptPath" ]; then + echo "Installer cannot determine its own path; $scriptPath is not readable." + exit 2 + fi +fi + +# Check for systemd vs. old school SysV init +SYSTEMDUNITDIR= +if [ -e /bin/systemctl -o -e /usr/bin/systemctl -o -e /usr/local/bin/systemctl -o -e /sbin/systemctl -o -e /usr/sbin/systemctl ]; then + # Second check: test if systemd appears to actually be running. Apparently Ubuntu + # thought it was a good idea to ship with systemd installed but not used. Issue #133 + if [ -d /var/run/systemd/system -o -d /run/systemd/system ]; then + if [ -e /usr/bin/pkg-config ]; then + SYSTEMDUNITDIR=`/usr/bin/pkg-config systemd --variable=systemdsystemunitdir` + fi + if [ -z "$SYSTEMDUNITDIR" -o ! -d "$SYSTEMDUNITDIR" ]; then + if [ -d /usr/lib/systemd/system ]; then + SYSTEMDUNITDIR=/usr/lib/systemd/system + fi + if [ -d /etc/systemd/system ]; then + SYSTEMDUNITDIR=/etc/systemd/system + fi + fi + fi +fi + +# Find the end of this script, which is where we have appended binary data. +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 + +echo -n 'Getting version of existing install... ' +origVersion=NONE +if [ -x /var/lib/zerotier-one/zerotier-one ]; then + origVersion=`/var/lib/zerotier-one/zerotier-one -v` +fi +echo $origVersion + +echo 'Extracting files...' +if [ $dryRun -gt 0 ]; then + echo ">> tail -c +$blobStart \"$scriptPath\" | gunzip -c | tar -xvop -C / -f -" + tail -c +$blobStart "$scriptPath" | gunzip -c | tar -t -f - | sed 's/^/>> /' +else + tail -c +$blobStart "$scriptPath" | gunzip -c | tar -xvop --no-overwrite-dir -C / -f - +fi + +if [ $dryRun -eq 0 -a ! -x "/var/lib/zerotier-one/zerotier-one" ]; then + echo 'Archive extraction failed, cannot find zerotier-one binary in "/var/lib/zerotier-one".' + exit 2 +fi + +echo -n 'Getting version of new install... ' +newVersion=`/var/lib/zerotier-one/zerotier-one -v` +echo $newVersion + +echo 'Creating symlinks...' + +rm -f /usr/bin/zerotier-cli /usr/bin/zerotier-idtool +ln -sf /var/lib/zerotier-one/zerotier-one /usr/bin/zerotier-cli +ln -sf /var/lib/zerotier-one/zerotier-one /usr/bin/zerotier-idtool + +echo 'Installing zerotier-one service...' + +if [ -n "$SYSTEMDUNITDIR" -a -d "$SYSTEMDUNITDIR" ]; then + # SYSTEMD + + # If this was updated or upgraded from an init.d based system, clean up the old + # init.d stuff before installing directly via systemd. + if [ -f /etc/init.d/zerotier-one ]; then + if [ -e /sbin/chkconfig -o -e /usr/sbin/chkconfig -o -e /bin/chkconfig -o -e /usr/bin/chkconfig ]; then + chkconfig zerotier-one off + fi + rm -f /etc/init.d/zerotier-one + fi + + cp -f /tmp/systemd_zerotier-one.service "$SYSTEMDUNITDIR/zerotier-one.service" + chown 0 "$SYSTEMDUNITDIR/zerotier-one.service" + chgrp 0 "$SYSTEMDUNITDIR/zerotier-one.service" + chmod 0755 "$SYSTEMDUNITDIR/zerotier-one.service" + rm -f /tmp/systemd_zerotier-one.service /tmp/init.d_zerotier-one + + systemctl enable zerotier-one.service + + echo + echo 'Done! Installed and service configured to start at system boot.' + echo + echo "To start now or restart the service if it's already running:" + echo ' sudo systemctl restart zerotier-one.service' +else + # SYSV INIT -- also covers upstart which supports SysVinit backward compatibility + + cp -f /tmp/init.d_zerotier-one /etc/init.d/zerotier-one + chmod 0755 /etc/init.d/zerotier-one + rm -f /tmp/systemd_zerotier-one.service /tmp/init.d_zerotier-one + + if [ -f /sbin/chkconfig -o -f /usr/sbin/chkconfig -o -f /usr/bin/chkconfig -o -f /bin/chkconfig ]; then + chkconfig zerotier-one on + else + # Yes Virginia, some systems lack chkconfig. + if [ -d /etc/rc0.d ]; then + rm -f /etc/rc0.d/???zerotier-one + ln -sf /etc/init.d/zerotier-one /etc/rc0.d/K89zerotier-one + fi + if [ -d /etc/rc1.d ]; then + rm -f /etc/rc1.d/???zerotier-one + ln -sf /etc/init.d/zerotier-one /etc/rc1.d/K89zerotier-one + fi + if [ -d /etc/rc2.d ]; then + rm -f /etc/rc2.d/???zerotier-one + ln -sf /etc/init.d/zerotier-one /etc/rc2.d/S11zerotier-one + fi + if [ -d /etc/rc3.d ]; then + rm -f /etc/rc3.d/???zerotier-one + ln -sf /etc/init.d/zerotier-one /etc/rc3.d/S11zerotier-one + fi + if [ -d /etc/rc4.d ]; then + rm -f /etc/rc4.d/???zerotier-one + ln -sf /etc/init.d/zerotier-one /etc/rc4.d/S11zerotier-one + fi + if [ -d /etc/rc5.d ]; then + rm -f /etc/rc5.d/???zerotier-one + ln -sf /etc/init.d/zerotier-one /etc/rc5.d/S11zerotier-one + fi + if [ -d /etc/rc6.d ]; then + rm -f /etc/rc6.d/???zerotier-one + ln -sf /etc/init.d/zerotier-one /etc/rc6.d/K89zerotier-one + fi + fi + + echo + echo 'Done! Installed and service configured to start at system boot.' + echo + echo "To start now or restart the service if it's already running:" + echo ' sudo service zerotier-one restart' +fi + +exit 0 + +# 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. + +################ \ No newline at end of file diff --git a/debian/zerotier-one.service b/ext/installfiles/linux/systemd/zerotier-one.service similarity index 52% rename from debian/zerotier-one.service rename to ext/installfiles/linux/systemd/zerotier-one.service index 9d6a21b0a..c4a1c4d29 100644 --- a/debian/zerotier-one.service +++ b/ext/installfiles/linux/systemd/zerotier-one.service @@ -1,10 +1,9 @@ [Unit] Description=ZeroTier One -After=network-online.target network.target -Wants=network-online.target +After=network.target [Service] -ExecStart=/usr/sbin/zerotier-one +ExecStart=/var/lib/zerotier-one/zerotier-one Restart=always KillMode=process diff --git a/ext/installfiles/linux/uninstall.sh b/ext/installfiles/linux/uninstall.sh new file mode 100755 index 000000000..bfc7ee6b5 --- /dev/null +++ b/ext/installfiles/linux/uninstall.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +export PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin + +if [ "$UID" -ne 0 ]; then + echo "Must be run as root; try: sudo $0" + exit 1 +fi + +# Detect systemd vs. regular init +SYSTEMDUNITDIR= +if [ -e /bin/systemctl -o -e /usr/bin/systemctl -o -e /usr/local/bin/systemctl -o -e /sbin/systemctl -o -e /usr/sbin/systemctl ]; then + if [ -e /usr/bin/pkg-config ]; then + SYSTEMDUNITDIR=`/usr/bin/pkg-config systemd --variable=systemdsystemunitdir` + fi + if [ -z "$SYSTEMDUNITDIR" -o ! -d "$SYSTEMDUNITDIR" ]; then + if [ -d /usr/lib/systemd/system ]; then + SYSTEMDUNITDIR=/usr/lib/systemd/system + fi + if [ -d /etc/systemd/system ]; then + SYSTEMDUNITDIR=/etc/systemd/system + fi + fi +fi + +echo "Killing any running zerotier-one service..." +if [ -n "$SYSTEMDUNITDIR" -a -d "$SYSTEMDUNITDIR" ]; then + systemctl stop zerotier-one.service + systemctl disable zerotier-one.service +else + if [ -f /sbin/service -o -f /usr/sbin/service -o -f /bin/service -o -f /usr/bin/service ]; then + service zerotier-one stop + fi +fi + +sleep 1 +if [ -f /var/lib/zerotier-one/zerotier-one.pid ]; then + kill -TERM `cat /var/lib/zerotier-one/zerotier-one.pid` + sleep 1 +fi +if [ -f /var/lib/zerotier-one/zerotier-one.pid ]; then + kill -KILL `cat /var/lib/zerotier-one/zerotier-one.pid` +fi + +if [ -f /etc/init.d/zerotier-one ]; then + echo "Removing SysV init items..." + if [ -f /sbin/chkconfig -o -f /usr/sbin/chkconfig -o -f /bin/chkconfig -o -f /usr/bin/chkconfig ]; then + chkconfig zerotier-one off + fi + rm -f /etc/init.d/zerotier-one + find /etc/rc*.d -type f -name '???zerotier-one' -print0 | xargs -0 rm -f +fi + +if [ -n "$SYSTEMDUNITDIR" -a -d "$SYSTEMDUNITDIR" -a -f "$SYSTEMDUNITDIR/zerotier-one.service" ]; then + echo "Removing systemd service..." + rm -f "$SYSTEMDUNITDIR/zerotier-one.service" +fi + +echo "Erasing binary and support files..." +if [ -d /var/lib/zerotier-one ]; then + cd /var/lib/zerotier-one + rm -rf zerotier-one *.persist identity.public *.log *.pid *.sh updates.d networks.d iddb.d root-topology +fi + +echo "Erasing anything installed into system bin directories..." +rm -f /usr/local/bin/zerotier-cli /usr/bin/zerotier-cli /usr/local/bin/zerotier-idtool /usr/bin/zerotier-idtool + +echo "Done." +echo +echo "Your ZeroTier One identity is still preserved in /var/lib/zerotier-one" +echo "as identity.secret and can be manually deleted if you wish. Save it if" +echo "you wish to re-use the address of this node, as it cannot be regenerated." + +echo + +exit 0 diff --git a/ext/installfiles/linux/zerotier-containerized/Dockerfile b/ext/installfiles/linux/zerotier-containerized/Dockerfile deleted file mode 100644 index 7758faf3a..000000000 --- a/ext/installfiles/linux/zerotier-containerized/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -## 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 deleted file mode 100755 index a33890392..000000000 --- a/ext/installfiles/linux/zerotier-containerized/main.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/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 deleted file mode 100755 index 3ff2f18e3..000000000 --- a/ext/installfiles/linux/zerotier-one.init.rhel6 +++ /dev/null @@ -1,138 +0,0 @@ -#!/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 deleted file mode 100644 index 978df0b10..000000000 --- a/ext/installfiles/linux/zerotier-one.te +++ /dev/null @@ -1,14 +0,0 @@ - -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 deleted file mode 100644 index 0b07f6d90..000000000 --- a/ext/installfiles/mac-update/updater.tmpl.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/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/ZeroTierOne-update.pkg -tail -c +$blobStart "$scriptPath" >/tmp/ZeroTierOne-update.pkg -chmod 0600 /tmp/ZeroTierOne-update.pkg - -if [ -s /tmp/ZeroTierOne-update.pkg ]; then - rm -f '/Library/Application Support/ZeroTier/One/latest-update.exe' '/Library/Application Support/ZeroTier/One/latest-update.json' /tmp/ZeroTierOne-update.log - installer -verbose -pkg /tmp/ZeroTierOne-update.pkg -target / >/tmp/ZeroTierOne-update.log 2>&1 - rm -f /tmp/ZeroTierOne-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. - -################ \ No newline at end of file diff --git a/ext/installfiles/mac/ZeroTier One.pkgproj b/ext/installfiles/mac/ZeroTier One.pkgproj index 70cedf9f9..c917d8243 100755 --- a/ext/installfiles/mac/ZeroTier One.pkgproj +++ b/ext/installfiles/mac/ZeroTier One.pkgproj @@ -2,715 +2,765 @@ - 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/ZeroTier.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 - ../../../zerotier-one - PATH_TYPE - 1 - PERMISSIONS - 493 - TYPE - 3 - UID - 0 - - - GID - 80 - PATH - One - PATH_TYPE - 0 - PERMISSIONS - 493 - TYPE - 2 - UID - 0 - - - GID - 80 - PATH - ZeroTier - 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.zerotier.one.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.zerotier.pkg.ZeroTierOne - LOCATION - 0 - NAME - ZeroTier One - OVERWRITE_PERMISSIONS - - PAYLOAD_SIZE - -1 - REFERENCE_PATH - - RELOCATABLE - - USE_HFS+_COMPRESSION - - VERSION - 1.14.2 - - TYPE - 0 - UUID - 1B6AFC3A-9EA5-4401-83D4-37F06CD13CD6 - - PROJECT + PACKAGE_FILES + + DEFAULT_INSTALL_LOCATION + / + HIERARCHY + + CHILDREN + + + CHILDREN + + + CHILDREN + + GID + 80 + PATH + Utilities + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 80 + PATH + ../../mac-ui-macgap1-wrapper/bin/ZeroTier One.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 + 0 + PATH + ../../bin/tap-mac/tap.kext + PATH_TYPE + 1 + PERMISSIONS + 493 + TYPE + 3 + UID + 0 + + + CHILDREN + + + CHILDREN + + GID + 0 + PATH + ../../../ui/index.html + PATH_TYPE + 1 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + ../../../ui/main.js + PATH_TYPE + 1 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + ../../../ui/react.min.js + PATH_TYPE + 1 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + ../../../ui/simpleajax.min.js + PATH_TYPE + 1 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + ../../../ui/zerotier.css + PATH_TYPE + 1 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + ../../../ui/ztui.min.js + PATH_TYPE + 1 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + GID + 0 + PATH + ui + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 2 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + uninstall.sh + PATH_TYPE + 1 + PERMISSIONS + 493 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + ../../../zerotier-one + PATH_TYPE + 1 + PERMISSIONS + 493 + TYPE + 3 + UID + 0 + + + GID + 80 + PATH + One + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 2 + UID + 0 + + + GID + 80 + PATH + ZeroTier + 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.zerotier.one.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 + 493 + 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 + + + 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 + VERSION + 3 + + 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 + IDENTIFIER + com.zerotier.pkg.ZeroTierOne + OVERWRITE_PERMISSIONS + + VERSION + 1.0.3 + PROJECT_COMMENTS NOTES @@ -723,206 +773,30 @@ ZW50LVN0eWxlLVR5cGUiIGNvbnRlbnQ9InRleHQvY3NzIj4KPHRp dGxlPjwvdGl0bGU+CjxtZXRhIG5hbWU9IkdlbmVyYXRvciIgY29u dGVudD0iQ29jb2EgSFRNTCBXcml0ZXIiPgo8bWV0YSBuYW1lPSJD - b2NvYVZlcnNpb24iIGNvbnRlbnQ9IjE1MDQuNzYiPgo8c3R5bGUg + b2NvYVZlcnNpb24iIGNvbnRlbnQ9IjEzNDcuNTciPgo8c3R5bGUg 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= + MHB4IDAuMHB4IDAuMHB4OyBmb250OiAxMi4wcHggSGVsdmV0aWNh + OyBjb2xvcjogIzAwMDAwMDsgLXdlYmtpdC10ZXh0LXN0cm9rZTog + IzAwMDAwMH0Kc3Bhbi5zMSB7Zm9udC1rZXJuaW5nOiBub25lfQo8 + L3N0eWxlPgo8L2hlYWQ+Cjxib2R5Pgo8cCBjbGFzcz0icDEiPjxz + cGFuIGNsYXNzPSJzMSI+WmVyb1RpZXIgT25lIC0gTmV0d29yayBW + aXJ0dWFsaXphdGlvbiBFdmVyeXdoZXJlPC9zcGFuPjwvcD4KPHAg + Y2xhc3M9InAxIj48c3BhbiBjbGFzcz0iczEiPihjKTIwMTEtMjAx + NSBaZXJvVGllciwgSW5jLjwvc3Bhbj48L3A+CjxwIGNsYXNzPSJw + MSI+PHNwYW4gY2xhc3M9InMxIj5jb250YWN0QHplcm90aWVyLmNv + bTwvc3Bhbj48L3A+CjxwIGNsYXNzPSJwMSI+PHNwYW4gY2xhc3M9 + InMxIj48YnI+Cjwvc3Bhbj48L3A+CjxwIGNsYXNzPSJwMSI+PHNw + YW4gY2xhc3M9InMxIj5UbyB1bmluc3RhbGwgbWFudWFsbHksIHR5 + cGUgdGhlIGZvbGxvd2luZyBpbiBhIHRlcm1pbmFsIHdpbmRvdzo8 + L3NwYW4+PC9wPgo8cCBjbGFzcz0icDEiPjxzcGFuIGNsYXNzPSJz + MSI+PGJyPgo8L3NwYW4+PC9wPgo8cCBjbGFzcz0icDEiPjxzcGFu + IGNsYXNzPSJzMSI+c3VkbyAiL0xpYnJhcnkvQXBwbGljYXRpb24g + U3VwcG9ydC9aZXJvVGllci9PbmUvdW5pbnN0YWxsLnNoIjwvc3Bh + bj48L3A+CjwvYm9keT4KPC9odG1sPgo= - 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 @@ -1100,19 +974,10 @@
NAME ZeroTier One - PAYLOAD_ONLY - - TREAT_MISSING_PRESENTATION_DOCUMENTS_AS_WARNING - - SHARED_GLOBAL_DATA - - IC_REQUIREMENT_JAVASCRIPT_SHARED_SOURCE_CODE - - TYPE - 0 + 1 VERSION 2 diff --git a/ext/installfiles/mac/launch.sh b/ext/installfiles/mac/launch.sh index ab274cbfb..ef22ccbd0 100755 --- a/ext/installfiles/mac/launch.sh +++ b/ext/installfiles/mac/launch.sh @@ -1,4 +1,15 @@ #!/bin/bash -export PATH="/Library/Application Support/ZeroTier/One:/bin:/usr/bin:/sbin:/usr/sbin" -/usr/bin/killall MacEthernetTapAgent >>/dev/null 2>&1 + +zthome="/Library/Application Support/ZeroTier/One" +export PATH="/bin:/usr/bin:/sbin:/usr/sbin:$zthome" + +# If the app has been deleted, uninstall the service +cd "$zthome" +if [ -L './shutdownIfUnreadable' -a ! -f "`readlink ./shutdownIfUnreadable`" ]; then + rm -f /tmp/ZeroTierOneUninstall.log + /bin/bash "$zthome/uninstall.sh" >/tmp/ZeroTierOneUninstall.log 2>&1 + exit 0 +fi + +# Launch ZeroTier One (not as daemon... launchd monitors it) exec zerotier-one diff --git a/ext/installfiles/mac/postinst.sh b/ext/installfiles/mac/postinst.sh index 707b46701..7d3d516fd 100755 --- a/ext/installfiles/mac/postinst.sh +++ b/ext/installfiles/mac/postinst.sh @@ -1,51 +1,26 @@ #!/bin/bash -export PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin +export PATH=/bin:/usr/bin:/sbin:/usr/sbin + +launchctl unload /Library/LaunchDaemons/com.zerotier.one.plist >>/dev/null 2>&1 cd "/Library/Application Support/ZeroTier/One" - +rm -rf node.log node.log.old root-topology shutdownIfUnreadable autoupdate.log updates.d if [ ! -f authtoken.secret ]; then - head -c 1024 /dev/urandom | md5 | head -c 24 >authtoken.secret - chown 0 authtoken.secret - chgrp 0 authtoken.secret + head -c 4096 /dev/urandom | md5 | head -c 24 >authtoken.secret + chown root authtoken.secret + chgrp wheel authtoken.secret chmod 0600 authtoken.secret fi - -if [ -f zerotier-one.pid ]; then - kill `cat zerotier-one.pid` - sleep 1 - killall MacEthernetTapAgent - sleep 1 - killall -9 MacEthernetTapAgent - sleep 1 - if [ -f zerotier-one.pid ]; then - kill -9 `cat zerotier-one.pid` - rm -f zerotier-one.pid - fi -fi -launchctl load /Library/LaunchDaemons/com.zerotier.one.plist >>/dev/null 2>&1 -sleep 1 - rm -f zerotier-cli zerotier-idtool ln -sf zerotier-one zerotier-cli ln -sf zerotier-one zerotier-idtool -if [ ! -d /usr/local/bin ]; then - mkdir -p /usr/local/bin -fi -cd /usr/local/bin + +cd /usr/bin rm -f zerotier-cli zerotier-idtool ln -sf "/Library/Application Support/ZeroTier/One/zerotier-one" zerotier-cli ln -sf "/Library/Application Support/ZeroTier/One/zerotier-one" zerotier-idtool -if [ -f /tmp/zt1-gui-restart.tmp ]; then - for u in `cat /tmp/zt1-gui-restart.tmp`; do - if [ -f '/Applications/ZeroTier One.app/Contents/MacOS/ZeroTier One' ]; then - su $u -c '/usr/bin/open /Applications/ZeroTier\ One.app &' >>/dev/null 2>&1 & - else - su $u -c '/usr/bin/open /Applications/ZeroTier.app &' >>/dev/null 2>&1 & - fi - done -fi -rm -f /tmp/zt1-gui-restart.tmp +launchctl load /Library/LaunchDaemons/com.zerotier.one.plist >>/dev/null 2>&1 exit 0 diff --git a/ext/installfiles/mac/preinst.sh b/ext/installfiles/mac/preinst.sh index d2df6a3a8..c2cb494b1 100755 --- a/ext/installfiles/mac/preinst.sh +++ b/ext/installfiles/mac/preinst.sh @@ -2,38 +2,25 @@ 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/ZeroTier,One.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 +if [ -f /Library/LaunchDaemons/com.zerotier.one.plist ]; then + launchctl unload /Library/LaunchDaemons/com.zerotier.one.plist >>/dev/null 2>&1 +fi + +sleep 1 + +if [ -d "/Library/Application Support/ZeroTier/One" ]; then + cd "/Library/Application Support/ZeroTier/One" + if [ -f "zerotier-one.pid" ]; then + ztpid=`cat zerotier-one.pid` + if [ "$ztpid" -gt "0" ]; then + kill `cat zerotier-one.pid` + fi fi -done -for i in `ps axuwww | tr -s ' ' ',' | grep -F '/Applications/ZeroTier.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 +fi + +sleep 1 cd "/Applications" rm -rf "ZeroTier One.app" -rm -rf "ZeroTier.app" - -if [ -d '/Library/Application Support/ZeroTier/One' ]; then - cd '/Library/Application Support/ZeroTier/One' - # ensure that file locking doesn't cause issues with replacing the binary - rm -f zerotier-one - rm -f MacEthernetTapAgent -fi exit 0 diff --git a/ext/installfiles/mac/uninstall.sh b/ext/installfiles/mac/uninstall.sh index 4b6abe13a..d1effb933 100755 --- a/ext/installfiles/mac/uninstall.sh +++ b/ext/installfiles/mac/uninstall.sh @@ -21,16 +21,20 @@ killall -TERM zerotier-one >>/dev/null 2>&1 sleep 1 killall -KILL zerotier-one >>/dev/null 2>&1 +echo "Making sure kext is unloaded..." +kextunload '/Library/Application Support/ZeroTier/One/tap.kext' >>/dev/null 2>&1 + echo "Removing ZeroTier One files..." rm -rf '/Applications/ZeroTier One.app' -rm -rf '/Applications/ZeroTier.app' -rm -f '/usr/local/bin/zerotier-one' '/usr/local/bin/zerotier-idtool' '/usr/local/bin/zerotier-cli' '/Library/LaunchDaemons/com.zerotier.one.plist' - -cd '/Library/Application Support/ZeroTier/One' -if [ "`pwd`" = '/Library/Application Support/ZeroTier/One' ]; then - rm -rf *.d *.sh *.log *.old *.kext *.conf *.pkg *.dmg *.pid *.port *.save *.bin planet zerotier-* devicemap -fi +rm -f '/usr/bin/zerotier-one' '/usr/bin/zerotier-idtool' '/usr/bin/zerotier-cli' '/Library/LaunchDaemons/com.zerotier.one.plist' +mkdir -p /tmp/ZeroTierOne_uninstall_tmp +cp "/Library/Application Support/ZeroTier/One/*.secret" /tmp/ZeroTierOne_uninstall_tmp +rm -rf '/Library/Application Support/ZeroTier/One' +mkdir -p '/Library/Application Support/ZeroTier/One' +cp "/tmp/ZeroTierOne_uninstall_tmp/*.secret" '/Library/Application Support/ZeroTier/One' +chmod 0600 "/Library/Application Support/ZeroTier/One/*.secret" +rm -rf /tmp/ZeroTierOne_uninstall_tmp echo 'Uninstall complete.' echo 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 index 3c3d6a417..744a32c58 100644 --- a/ext/installfiles/windows/ZeroTier One Virtual Network Port (NDIS6_x64).aip +++ b/ext/installfiles/windows/ZeroTier One Virtual Network Port (NDIS6_x64).aip @@ -1,187 +1,156 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 index 50d5f5575..5936875ad 100644 --- a/ext/installfiles/windows/ZeroTier One Virtual Network Port (NDIS6_x86).aip +++ b/ext/installfiles/windows/ZeroTier One Virtual Network Port (NDIS6_x86).aip @@ -1,188 +1,157 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/installfiles/windows/ZeroTier One.aip b/ext/installfiles/windows/ZeroTier One.aip index 3066eb788..6f98c32ad 100644 --- a/ext/installfiles/windows/ZeroTier One.aip +++ b/ext/installfiles/windows/ZeroTier One.aip @@ -1,545 +1,362 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/installfiles/windows/ZeroTier One.back.aip b/ext/installfiles/windows/ZeroTier One.back.aip deleted file mode 100644 index 9ad818277..000000000 --- a/ext/installfiles/windows/ZeroTier One.back.aip +++ /dev/null @@ -1,558 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ext/json-parser/LICENSE b/ext/json-parser/LICENSE new file mode 100644 index 000000000..1aee375e0 --- /dev/null +++ b/ext/json-parser/LICENSE @@ -0,0 +1,26 @@ + + Copyright (C) 2012, 2013 James McLaughlin et al. All rights reserved. + + 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 THE 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 THE 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. + diff --git a/ext/json-parser/json.c b/ext/json-parser/json.c new file mode 100644 index 000000000..166cdcb60 --- /dev/null +++ b/ext/json-parser/json.c @@ -0,0 +1,1012 @@ +/* vim: set et ts=3 sw=3 sts=3 ft=c: + * + * Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved. + * https://github.com/udp/json-parser + * + * 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 THE 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 THE 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. + */ + +#include "json.h" + +#ifdef _MSC_VER + #ifndef _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS + #endif + #pragma warning(disable:4996) +#endif + +const struct _json_value json_value_none; + +#include +#include +#include +#include + +typedef unsigned int json_uchar; + +static unsigned char hex_value (json_char c) +{ + if (isdigit(c)) + return c - '0'; + + switch (c) { + case 'a': case 'A': return 0x0A; + case 'b': case 'B': return 0x0B; + case 'c': case 'C': return 0x0C; + case 'd': case 'D': return 0x0D; + case 'e': case 'E': return 0x0E; + case 'f': case 'F': return 0x0F; + default: return 0xFF; + } +} + +typedef struct +{ + unsigned long used_memory; + + unsigned int uint_max; + unsigned long ulong_max; + + json_settings settings; + int first_pass; + + const json_char * ptr; + unsigned int cur_line, cur_col; + +} json_state; + +static void * default_alloc (size_t size, int zero, void * user_data) +{ + return zero ? calloc (1, size) : malloc (size); +} + +static void default_free (void * ptr, void * user_data) +{ + free (ptr); +} + +static void * json_alloc (json_state * state, unsigned long size, int zero) +{ + if ((state->ulong_max - state->used_memory) < size) + return 0; + + if (state->settings.max_memory + && (state->used_memory += size) > state->settings.max_memory) + { + return 0; + } + + return state->settings.mem_alloc (size, zero, state->settings.user_data); +} + +static int new_value (json_state * state, + json_value ** top, json_value ** root, json_value ** alloc, + json_type type) +{ + json_value * value; + int values_size; + + if (!state->first_pass) + { + value = *top = *alloc; + *alloc = (*alloc)->_reserved.next_alloc; + + if (!*root) + *root = value; + + switch (value->type) + { + case json_array: + + if (value->u.array.length == 0) + break; + + if (! (value->u.array.values = (json_value **) json_alloc + (state, value->u.array.length * sizeof (json_value *), 0)) ) + { + return 0; + } + + value->u.array.length = 0; + break; + + case json_object: + + if (value->u.object.length == 0) + break; + + values_size = sizeof (*value->u.object.values) * value->u.object.length; + + if (! (value->u.object.values = (json_object_entry *) json_alloc + (state, values_size + ((unsigned long) value->u.object.values), 0)) ) + { + return 0; + } + + value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size; + + value->u.object.length = 0; + break; + + case json_string: + + if (! (value->u.string.ptr = (json_char *) json_alloc + (state, (value->u.string.length + 1) * sizeof (json_char), 0)) ) + { + return 0; + } + + value->u.string.length = 0; + break; + + default: + break; + }; + + return 1; + } + + if (! (value = (json_value *) json_alloc + (state, sizeof (json_value) + state->settings.value_extra, 1))) + { + return 0; + } + + if (!*root) + *root = value; + + value->type = type; + value->parent = *top; + + #ifdef JSON_TRACK_SOURCE + value->line = state->cur_line; + value->col = state->cur_col; + #endif + + if (*alloc) + (*alloc)->_reserved.next_alloc = value; + + *alloc = *top = value; + + return 1; +} + +#define whitespace \ + case '\n': ++ state.cur_line; state.cur_col = 0; \ + case ' ': case '\t': case '\r' + +#define string_add(b) \ + do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0); + +#define line_and_col \ + state.cur_line, state.cur_col + +static const long + flag_next = 1 << 0, + flag_reproc = 1 << 1, + flag_need_comma = 1 << 2, + flag_seek_value = 1 << 3, + flag_escaped = 1 << 4, + flag_string = 1 << 5, + flag_need_colon = 1 << 6, + flag_done = 1 << 7, + flag_num_negative = 1 << 8, + flag_num_zero = 1 << 9, + flag_num_e = 1 << 10, + flag_num_e_got_sign = 1 << 11, + flag_num_e_negative = 1 << 12, + flag_line_comment = 1 << 13, + flag_block_comment = 1 << 14; + +json_value * json_parse_ex (json_settings * settings, + const json_char * json, + size_t length, + char * error_buf) +{ + json_char error [json_error_max]; + const json_char * end; + json_value * top, * root, * alloc = 0; + json_state state = { 0 }; + long flags; + long num_digits = 0, num_e = 0; + json_int_t num_fraction = 0; + + /* Skip UTF-8 BOM + */ + if (length >= 3 && ((unsigned char) json [0]) == 0xEF + && ((unsigned char) json [1]) == 0xBB + && ((unsigned char) json [2]) == 0xBF) + { + json += 3; + length -= 3; + } + + error[0] = '\0'; + end = (json + length); + + memcpy (&state.settings, settings, sizeof (json_settings)); + + if (!state.settings.mem_alloc) + state.settings.mem_alloc = default_alloc; + + if (!state.settings.mem_free) + state.settings.mem_free = default_free; + + memset (&state.uint_max, 0xFF, sizeof (state.uint_max)); + memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max)); + + state.uint_max -= 8; /* limit of how much can be added before next check */ + state.ulong_max -= 8; + + for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass) + { + json_uchar uchar; + unsigned char uc_b1, uc_b2, uc_b3, uc_b4; + json_char * string = 0; + unsigned int string_length = 0; + + top = root = 0; + flags = flag_seek_value; + + state.cur_line = 1; + + for (state.ptr = json ;; ++ state.ptr) + { + json_char b = (state.ptr == end ? 0 : *state.ptr); + + if (flags & flag_string) + { + if (!b) + { sprintf (error, "Unexpected EOF in string (at %d:%d)", line_and_col); + goto e_failed; + } + + if (string_length > state.uint_max) + goto e_overflow; + + if (flags & flag_escaped) + { + flags &= ~ flag_escaped; + + switch (b) + { + case 'b': string_add ('\b'); break; + case 'f': string_add ('\f'); break; + case 'n': string_add ('\n'); break; + case 'r': string_add ('\r'); break; + case 't': string_add ('\t'); break; + case 'u': + + if (end - state.ptr < 4 || + (uc_b1 = hex_value (*++ state.ptr)) == 0xFF || + (uc_b2 = hex_value (*++ state.ptr)) == 0xFF || + (uc_b3 = hex_value (*++ state.ptr)) == 0xFF || + (uc_b4 = hex_value (*++ state.ptr)) == 0xFF) + { + sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col); + goto e_failed; + } + + uc_b1 = (uc_b1 << 4) | uc_b2; + uc_b2 = (uc_b3 << 4) | uc_b4; + uchar = (uc_b1 << 8) | uc_b2; + + if ((uchar & 0xF800) == 0xD800) { + json_uchar uchar2; + + if (end - state.ptr < 6 || (*++ state.ptr) != '\\' || (*++ state.ptr) != 'u' || + (uc_b1 = hex_value (*++ state.ptr)) == 0xFF || + (uc_b2 = hex_value (*++ state.ptr)) == 0xFF || + (uc_b3 = hex_value (*++ state.ptr)) == 0xFF || + (uc_b4 = hex_value (*++ state.ptr)) == 0xFF) + { + sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col); + goto e_failed; + } + + uc_b1 = (uc_b1 << 4) | uc_b2; + uc_b2 = (uc_b3 << 4) | uc_b4; + uchar2 = (uc_b1 << 8) | uc_b2; + + uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF); + } + + if (sizeof (json_char) >= sizeof (json_uchar) || (uchar <= 0x7F)) + { + string_add ((json_char) uchar); + break; + } + + if (uchar <= 0x7FF) + { + if (state.first_pass) + string_length += 2; + else + { string [string_length ++] = 0xC0 | (uchar >> 6); + string [string_length ++] = 0x80 | (uchar & 0x3F); + } + + break; + } + + if (uchar <= 0xFFFF) { + if (state.first_pass) + string_length += 3; + else + { string [string_length ++] = 0xE0 | (uchar >> 12); + string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F); + string [string_length ++] = 0x80 | (uchar & 0x3F); + } + + break; + } + + if (state.first_pass) + string_length += 4; + else + { string [string_length ++] = 0xF0 | (uchar >> 18); + string [string_length ++] = 0x80 | ((uchar >> 12) & 0x3F); + string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F); + string [string_length ++] = 0x80 | (uchar & 0x3F); + } + + break; + + default: + string_add (b); + }; + + continue; + } + + if (b == '\\') + { + flags |= flag_escaped; + continue; + } + + if (b == '"') + { + if (!state.first_pass) + string [string_length] = 0; + + flags &= ~ flag_string; + string = 0; + + switch (top->type) + { + case json_string: + + top->u.string.length = string_length; + flags |= flag_next; + + break; + + case json_object: + + if (state.first_pass) + (*(json_char **) &top->u.object.values) += string_length + 1; + else + { + top->u.object.values [top->u.object.length].name + = (json_char *) top->_reserved.object_mem; + + top->u.object.values [top->u.object.length].name_length + = string_length; + + (*(json_char **) &top->_reserved.object_mem) += string_length + 1; + } + + flags |= flag_seek_value | flag_need_colon; + continue; + + default: + break; + }; + } + else + { + string_add (b); + continue; + } + } + + if (state.settings.settings & json_enable_comments) + { + if (flags & (flag_line_comment | flag_block_comment)) + { + if (flags & flag_line_comment) + { + if (b == '\r' || b == '\n' || !b) + { + flags &= ~ flag_line_comment; + -- state.ptr; /* so null can be reproc'd */ + } + + continue; + } + + if (flags & flag_block_comment) + { + if (!b) + { sprintf (error, "%d:%d: Unexpected EOF in block comment", line_and_col); + goto e_failed; + } + + if (b == '*' && state.ptr < (end - 1) && state.ptr [1] == '/') + { + flags &= ~ flag_block_comment; + ++ state.ptr; /* skip closing sequence */ + } + + continue; + } + } + else if (b == '/') + { + if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object) + { sprintf (error, "%d:%d: Comment not allowed here", line_and_col); + goto e_failed; + } + + if (++ state.ptr == end) + { sprintf (error, "%d:%d: EOF unexpected", line_and_col); + goto e_failed; + } + + switch (b = *state.ptr) + { + case '/': + flags |= flag_line_comment; + continue; + + case '*': + flags |= flag_block_comment; + continue; + + default: + sprintf (error, "%d:%d: Unexpected `%c` in comment opening sequence", line_and_col, b); + goto e_failed; + }; + } + } + + if (flags & flag_done) + { + if (!b) + break; + + switch (b) + { + whitespace: + continue; + + default: + + sprintf (error, "%d:%d: Trailing garbage: `%c`", + state.cur_line, state.cur_col, b); + + goto e_failed; + }; + } + + if (flags & flag_seek_value) + { + switch (b) + { + whitespace: + continue; + + case ']': + + if (top && top->type == json_array) + flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next; + else + { sprintf (error, "%d:%d: Unexpected ]", line_and_col); + goto e_failed; + } + + break; + + default: + + if (flags & flag_need_comma) + { + if (b == ',') + { flags &= ~ flag_need_comma; + continue; + } + else + { + sprintf (error, "%d:%d: Expected , before %c", + state.cur_line, state.cur_col, b); + + goto e_failed; + } + } + + if (flags & flag_need_colon) + { + if (b == ':') + { flags &= ~ flag_need_colon; + continue; + } + else + { + sprintf (error, "%d:%d: Expected : before %c", + state.cur_line, state.cur_col, b); + + goto e_failed; + } + } + + flags &= ~ flag_seek_value; + + switch (b) + { + case '{': + + if (!new_value (&state, &top, &root, &alloc, json_object)) + goto e_alloc_failure; + + continue; + + case '[': + + if (!new_value (&state, &top, &root, &alloc, json_array)) + goto e_alloc_failure; + + flags |= flag_seek_value; + continue; + + case '"': + + if (!new_value (&state, &top, &root, &alloc, json_string)) + goto e_alloc_failure; + + flags |= flag_string; + + string = top->u.string.ptr; + string_length = 0; + + continue; + + case 't': + + if ((end - state.ptr) < 3 || *(++ state.ptr) != 'r' || + *(++ state.ptr) != 'u' || *(++ state.ptr) != 'e') + { + goto e_unknown_value; + } + + if (!new_value (&state, &top, &root, &alloc, json_boolean)) + goto e_alloc_failure; + + top->u.boolean = 1; + + flags |= flag_next; + break; + + case 'f': + + if ((end - state.ptr) < 4 || *(++ state.ptr) != 'a' || + *(++ state.ptr) != 'l' || *(++ state.ptr) != 's' || + *(++ state.ptr) != 'e') + { + goto e_unknown_value; + } + + if (!new_value (&state, &top, &root, &alloc, json_boolean)) + goto e_alloc_failure; + + flags |= flag_next; + break; + + case 'n': + + if ((end - state.ptr) < 3 || *(++ state.ptr) != 'u' || + *(++ state.ptr) != 'l' || *(++ state.ptr) != 'l') + { + goto e_unknown_value; + } + + if (!new_value (&state, &top, &root, &alloc, json_null)) + goto e_alloc_failure; + + flags |= flag_next; + break; + + default: + + if (isdigit (b) || b == '-') + { + if (!new_value (&state, &top, &root, &alloc, json_integer)) + goto e_alloc_failure; + + if (!state.first_pass) + { + while (isdigit (b) || b == '+' || b == '-' + || b == 'e' || b == 'E' || b == '.') + { + if ( (++ state.ptr) == end) + { + b = 0; + break; + } + + b = *state.ptr; + } + + flags |= flag_next | flag_reproc; + break; + } + + flags &= ~ (flag_num_negative | flag_num_e | + flag_num_e_got_sign | flag_num_e_negative | + flag_num_zero); + + num_digits = 0; + num_fraction = 0; + num_e = 0; + + if (b != '-') + { + flags |= flag_reproc; + break; + } + + flags |= flag_num_negative; + continue; + } + else + { sprintf (error, "%d:%d: Unexpected %c when seeking value", line_and_col, b); + goto e_failed; + } + }; + }; + } + else + { + switch (top->type) + { + case json_object: + + switch (b) + { + whitespace: + continue; + + case '"': + + if (flags & flag_need_comma) + { sprintf (error, "%d:%d: Expected , before \"", line_and_col); + goto e_failed; + } + + flags |= flag_string; + + string = (json_char *) top->_reserved.object_mem; + string_length = 0; + + break; + + case '}': + + flags = (flags & ~ flag_need_comma) | flag_next; + break; + + case ',': + + if (flags & flag_need_comma) + { + flags &= ~ flag_need_comma; + break; + } + + default: + sprintf (error, "%d:%d: Unexpected `%c` in object", line_and_col, b); + goto e_failed; + }; + + break; + + case json_integer: + case json_double: + + if (isdigit (b)) + { + ++ num_digits; + + if (top->type == json_integer || flags & flag_num_e) + { + if (! (flags & flag_num_e)) + { + if (flags & flag_num_zero) + { sprintf (error, "%d:%d: Unexpected `0` before `%c`", line_and_col, b); + goto e_failed; + } + + if (num_digits == 1 && b == '0') + flags |= flag_num_zero; + } + else + { + flags |= flag_num_e_got_sign; + num_e = (num_e * 10) + (b - '0'); + continue; + } + + top->u.integer = (top->u.integer * 10) + (b - '0'); + continue; + } + + num_fraction = (num_fraction * 10) + (b - '0'); + continue; + } + + if (b == '+' || b == '-') + { + if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign)) + { + flags |= flag_num_e_got_sign; + + if (b == '-') + flags |= flag_num_e_negative; + + continue; + } + } + else if (b == '.' && top->type == json_integer) + { + if (!num_digits) + { sprintf (error, "%d:%d: Expected digit before `.`", line_and_col); + goto e_failed; + } + + top->type = json_double; + top->u.dbl = (double) top->u.integer; + + num_digits = 0; + continue; + } + + if (! (flags & flag_num_e)) + { + if (top->type == json_double) + { + if (!num_digits) + { sprintf (error, "%d:%d: Expected digit after `.`", line_and_col); + goto e_failed; + } + + top->u.dbl += ((double) num_fraction) / (pow (10.0, (double) num_digits)); + } + + if (b == 'e' || b == 'E') + { + flags |= flag_num_e; + + if (top->type == json_integer) + { + top->type = json_double; + top->u.dbl = (double) top->u.integer; + } + + num_digits = 0; + flags &= ~ flag_num_zero; + + continue; + } + } + else + { + if (!num_digits) + { sprintf (error, "%d:%d: Expected digit after `e`", line_and_col); + goto e_failed; + } + + top->u.dbl *= pow (10.0, (double) + (flags & flag_num_e_negative ? - num_e : num_e)); + } + + if (flags & flag_num_negative) + { + if (top->type == json_integer) + top->u.integer = - top->u.integer; + else + top->u.dbl = - top->u.dbl; + } + + flags |= flag_next | flag_reproc; + break; + + default: + break; + }; + } + + if (flags & flag_reproc) + { + flags &= ~ flag_reproc; + -- state.ptr; + } + + if (flags & flag_next) + { + flags = (flags & ~ flag_next) | flag_need_comma; + + if (!top->parent) + { + /* root value done */ + + flags |= flag_done; + continue; + } + + if (top->parent->type == json_array) + flags |= flag_seek_value; + + if (!state.first_pass) + { + json_value * parent = top->parent; + + switch (parent->type) + { + case json_object: + + parent->u.object.values + [parent->u.object.length].value = top; + + break; + + case json_array: + + parent->u.array.values + [parent->u.array.length] = top; + + break; + + default: + break; + }; + } + + if ( (++ top->parent->u.array.length) > state.uint_max) + goto e_overflow; + + top = top->parent; + + continue; + } + } + + alloc = root; + } + + return root; + +e_unknown_value: + + sprintf (error, "%d:%d: Unknown value", line_and_col); + goto e_failed; + +e_alloc_failure: + + strcpy (error, "Memory allocation failure"); + goto e_failed; + +e_overflow: + + sprintf (error, "%d:%d: Too long (caught overflow)", line_and_col); + goto e_failed; + +e_failed: + + if (error_buf) + { + if (*error) + strcpy (error_buf, error); + else + strcpy (error_buf, "Unknown error"); + } + + if (state.first_pass) + alloc = root; + + while (alloc) + { + top = alloc->_reserved.next_alloc; + state.settings.mem_free (alloc, state.settings.user_data); + alloc = top; + } + + if (!state.first_pass) + json_value_free_ex (&state.settings, root); + + return 0; +} + +json_value * json_parse (const json_char * json, size_t length) +{ + json_settings settings = { 0 }; + return json_parse_ex (&settings, json, length, 0); +} + +void json_value_free_ex (json_settings * settings, json_value * value) +{ + json_value * cur_value; + + if (!value) + return; + + value->parent = 0; + + while (value) + { + switch (value->type) + { + case json_array: + + if (!value->u.array.length) + { + settings->mem_free (value->u.array.values, settings->user_data); + break; + } + + value = value->u.array.values [-- value->u.array.length]; + continue; + + case json_object: + + if (!value->u.object.length) + { + settings->mem_free (value->u.object.values, settings->user_data); + break; + } + + value = value->u.object.values [-- value->u.object.length].value; + continue; + + case json_string: + + settings->mem_free (value->u.string.ptr, settings->user_data); + break; + + default: + break; + }; + + cur_value = value; + value = value->parent; + settings->mem_free (cur_value, settings->user_data); + } +} + +void json_value_free (json_value * value) +{ + json_settings settings = { 0 }; + settings.mem_free = default_free; + json_value_free_ex (&settings, value); +} + diff --git a/ext/json-parser/json.h b/ext/json-parser/json.h new file mode 100644 index 000000000..f6549ec4e --- /dev/null +++ b/ext/json-parser/json.h @@ -0,0 +1,283 @@ + +/* vim: set et ts=3 sw=3 sts=3 ft=c: + * + * Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved. + * https://github.com/udp/json-parser + * + * 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 THE 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 THE 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 _JSON_H +#define _JSON_H + +#ifndef json_char + #define json_char char +#endif + +#ifndef json_int_t + #ifndef _MSC_VER + #include + #define json_int_t int64_t + #else + #define json_int_t __int64 + #endif +#endif + +#include + +#ifdef __cplusplus + + #include + + extern "C" + { + +#endif + +typedef struct +{ + unsigned long max_memory; + int settings; + + /* Custom allocator support (leave null to use malloc/free) + */ + + void * (* mem_alloc) (size_t, int zero, void * user_data); + void (* mem_free) (void *, void * user_data); + + void * user_data; /* will be passed to mem_alloc and mem_free */ + + size_t value_extra; /* how much extra space to allocate for values? */ + +} json_settings; + +#define json_enable_comments 0x01 + +typedef enum +{ + json_none, + json_object, + json_array, + json_integer, + json_double, + json_string, + json_boolean, + json_null + +} json_type; + +extern const struct _json_value json_value_none; + +typedef struct _json_object_entry +{ + json_char * name; + unsigned int name_length; + + struct _json_value * value; + +} json_object_entry; + +typedef struct _json_value +{ + struct _json_value * parent; + + json_type type; + + union + { + int boolean; + json_int_t integer; + double dbl; + + struct + { + unsigned int length; + json_char * ptr; /* null terminated */ + + } string; + + struct + { + unsigned int length; + + json_object_entry * values; + + #if defined(__cplusplus) && __cplusplus >= 201103L + decltype(values) begin () const + { return values; + } + decltype(values) end () const + { return values + length; + } + #endif + + } object; + + struct + { + unsigned int length; + struct _json_value ** values; + + #if defined(__cplusplus) && __cplusplus >= 201103L + decltype(values) begin () const + { return values; + } + decltype(values) end () const + { return values + length; + } + #endif + + } array; + + } u; + + union + { + struct _json_value * next_alloc; + void * object_mem; + + } _reserved; + + #ifdef JSON_TRACK_SOURCE + + /* Location of the value in the source JSON + */ + unsigned int line, col; + + #endif + + + /* Some C++ operator sugar */ + + #ifdef __cplusplus + + public: + + inline _json_value () + { memset (this, 0, sizeof (_json_value)); + } + + inline const struct _json_value &operator [] (int index) const + { + if (type != json_array || index < 0 + || ((unsigned int) index) >= u.array.length) + { + return json_value_none; + } + + return *u.array.values [index]; + } + + inline const struct _json_value &operator [] (const char * index) const + { + if (type != json_object) + return json_value_none; + + for (unsigned int i = 0; i < u.object.length; ++ i) + if (!strcmp (u.object.values [i].name, index)) + return *u.object.values [i].value; + + return json_value_none; + } + + inline operator const char * () const + { + switch (type) + { + case json_string: + return u.string.ptr; + + default: + return ""; + }; + } + + inline operator json_int_t () const + { + switch (type) + { + case json_integer: + return u.integer; + + case json_double: + return (json_int_t) u.dbl; + + default: + return 0; + }; + } + + inline operator bool () const + { + if (type != json_boolean) + return false; + + return u.boolean != 0; + } + + inline operator double () const + { + switch (type) + { + case json_integer: + return (double) u.integer; + + case json_double: + return u.dbl; + + default: + return 0; + }; + } + + #endif + +} json_value; + +json_value * json_parse (const json_char * json, + size_t length); + +#define json_error_max 128 +json_value * json_parse_ex (json_settings * settings, + const json_char * json, + size_t length, + char * error); + +void json_value_free (json_value *); + + +/* Not usually necessary, unless you used a custom mem_alloc and now want to + * use a custom mem_free. + */ +void json_value_free_ex (json_settings * settings, + json_value *); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif + + diff --git a/ext/libnatpmp/Changelog.txt b/ext/libnatpmp/Changelog.txt deleted file mode 100644 index be75a0b6d..000000000 --- a/ext/libnatpmp/Changelog.txt +++ /dev/null @@ -1,98 +0,0 @@ -$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 deleted file mode 100644 index 0379c1821..000000000 --- a/ext/libnatpmp/JavaTest.java +++ /dev/null @@ -1,42 +0,0 @@ -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 deleted file mode 100644 index 7fff2c26a..000000000 --- a/ext/libnatpmp/LICENSE +++ /dev/null @@ -1,26 +0,0 @@ -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 deleted file mode 100644 index b67b3e85c..000000000 --- a/ext/libnatpmp/Makefile +++ /dev/null @@ -1,177 +0,0 @@ -# $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 deleted file mode 100644 index 269392d2a..000000000 --- a/ext/libnatpmp/README +++ /dev/null @@ -1,7 +0,0 @@ -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 deleted file mode 100644 index 2d2f27cd7..000000000 --- a/ext/libnatpmp/build.bat +++ /dev/null @@ -1,30 +0,0 @@ -@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 deleted file mode 100644 index a76be021c..000000000 --- a/ext/libnatpmp/declspec.h +++ /dev/null @@ -1,21 +0,0 @@ -#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 deleted file mode 100644 index 5491d9408..000000000 --- a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/LibraryExtractor.java +++ /dev/null @@ -1,238 +0,0 @@ -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 deleted file mode 100644 index 2f1ddd3d4..000000000 --- a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmp.java +++ /dev/null @@ -1,50 +0,0 @@ -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 deleted file mode 100644 index 35c87eab0..000000000 --- a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmpResponse.java +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index 5b419ab3a..000000000 --- a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/URLUtils.java +++ /dev/null @@ -1,81 +0,0 @@ -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 deleted file mode 100644 index 0f06e1dc2..000000000 --- a/ext/libnatpmp/getgateway.c +++ /dev/null @@ -1,575 +0,0 @@ -/* $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 deleted file mode 100644 index 5d3df7312..000000000 --- a/ext/libnatpmp/getgateway.h +++ /dev/null @@ -1,49 +0,0 @@ -/* $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 deleted file mode 100644 index 0fd9914b5..000000000 --- a/ext/libnatpmp/libnatpmpmodule.c +++ /dev/null @@ -1,281 +0,0 @@ -/* $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 deleted file mode 100644 index ac746d415..000000000 --- a/ext/libnatpmp/msvc/libnatpmp.sln +++ /dev/null @@ -1,29 +0,0 @@ - -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 deleted file mode 100644 index 9bae5c185..000000000 --- a/ext/libnatpmp/msvc/libnatpmp.vcproj +++ /dev/null @@ -1,195 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ext/libnatpmp/msvc/natpmpc-static.vcproj b/ext/libnatpmp/msvc/natpmpc-static.vcproj deleted file mode 100644 index c2052d982..000000000 --- a/ext/libnatpmp/msvc/natpmpc-static.vcproj +++ /dev/null @@ -1,195 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ext/libnatpmp/natpmp-jni.c b/ext/libnatpmp/natpmp-jni.c deleted file mode 100644 index feec1cea6..000000000 --- a/ext/libnatpmp/natpmp-jni.c +++ /dev/null @@ -1,157 +0,0 @@ -#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 deleted file mode 100644 index 9843c41e1..000000000 --- a/ext/libnatpmp/natpmp.c +++ /dev/null @@ -1,383 +0,0 @@ -/* $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 deleted file mode 100644 index cd110033f..000000000 --- a/ext/libnatpmp/natpmp.def +++ /dev/null @@ -1,11 +0,0 @@ -LIBRARY -; libnatpmp library - -EXPORTS - initnatpmp - closenatpmp - sendpublicaddressrequest - sendnewportmappingrequest - getnatpmprequesttimeout - readnatpmpresponseorretry - strnatpmperr diff --git a/ext/libnatpmp/natpmp.h b/ext/libnatpmp/natpmp.h deleted file mode 100644 index 7889d206f..000000000 --- a/ext/libnatpmp/natpmp.h +++ /dev/null @@ -1,219 +0,0 @@ -/* $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 deleted file mode 100644 index 5f0003da6..000000000 --- a/ext/libnatpmp/natpmpc.1 +++ /dev/null @@ -1,19 +0,0 @@ -.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 deleted file mode 100644 index 611bd2d1a..000000000 --- a/ext/libnatpmp/natpmpc.c +++ /dev/null @@ -1,244 +0,0 @@ -/* $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 deleted file mode 100644 index aa774ee73..000000000 --- a/ext/libnatpmp/setup.py +++ /dev/null @@ -1,18 +0,0 @@ -#! /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 deleted file mode 100644 index d02fdfcaa..000000000 --- a/ext/libnatpmp/setupmingw32.py +++ /dev/null @@ -1,17 +0,0 @@ -#! /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 deleted file mode 100644 index 24cbe7d05..000000000 --- a/ext/libnatpmp/testgetgateway.c +++ /dev/null @@ -1,57 +0,0 @@ -/* $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 deleted file mode 100644 index cb730e17d..000000000 --- a/ext/libnatpmp/wingettimeofday.c +++ /dev/null @@ -1,60 +0,0 @@ -/* $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 deleted file mode 100644 index 1d18d9fac..000000000 --- a/ext/libnatpmp/wingettimeofday.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $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 deleted file mode 100644 index 038d7adb0..000000000 --- a/ext/libpqxx-7.7.3/.circleci/config.yml +++ /dev/null @@ -1,60 +0,0 @@ -# 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 deleted file mode 100644 index 97823d8ff..000000000 --- a/ext/libpqxx-7.7.3/.clang-format +++ /dev/null @@ -1,71 +0,0 @@ -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 deleted file mode 100644 index af00ef936..000000000 --- a/ext/libpqxx-7.7.3/.cmake-format +++ /dev/null @@ -1,184 +0,0 @@ -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 deleted file mode 100644 index 0983a3e54..000000000 --- a/ext/libpqxx-7.7.3/.github/workflows/stale.yml +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index d798c9dca..000000000 --- a/ext/libpqxx-7.7.3/.gitignore +++ /dev/null @@ -1,49 +0,0 @@ -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 deleted file mode 100644 index d53664eb4..000000000 --- a/ext/libpqxx-7.7.3/.lgtm.yml +++ /dev/null @@ -1,9 +0,0 @@ -# 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 deleted file mode 100644 index 8c6c7a103..000000000 --- a/ext/libpqxx-7.7.3/.lift/ignoreFiles +++ /dev/null @@ -1,3 +0,0 @@ -# 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 deleted file mode 100644 index 6a922e950..000000000 --- a/ext/libpqxx-7.7.3/AUTHORS +++ /dev/null @@ -1,4 +0,0 @@ -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 deleted file mode 100644 index 48b1e7930..000000000 --- a/ext/libpqxx-7.7.3/BUILDING-cmake.md +++ /dev/null @@ -1,272 +0,0 @@ -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 deleted file mode 100644 index 7c63f5b4c..000000000 --- a/ext/libpqxx-7.7.3/BUILDING-configure.md +++ /dev/null @@ -1,275 +0,0 @@ -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 deleted file mode 100644 index 55b3c4d44..000000000 --- a/ext/libpqxx-7.7.3/CMakeLists.txt +++ /dev/null @@ -1,66 +0,0 @@ -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 deleted file mode 100644 index 8a566aabe..000000000 --- a/ext/libpqxx-7.7.3/COPYING +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index cd93a57ef..000000000 --- a/ext/libpqxx-7.7.3/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -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 deleted file mode 100644 index f6798aa75..000000000 --- a/ext/libpqxx-7.7.3/Makefile.in +++ /dev/null @@ -1,1253 +0,0 @@ -# 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 deleted file mode 100644 index 102716c2e..000000000 --- a/ext/libpqxx-7.7.3/NEWS +++ /dev/null @@ -1,1040 +0,0 @@ -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 deleted file mode 100644 index 3a1c17ded..000000000 --- a/ext/libpqxx-7.7.3/README.md +++ /dev/null @@ -1,199 +0,0 @@ -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 deleted file mode 100644 index d92ba80de..000000000 --- a/ext/libpqxx-7.7.3/VERSION +++ /dev/null @@ -1 +0,0 @@ -7.7.3 diff --git a/ext/libpqxx-7.7.3/aclocal.m4 b/ext/libpqxx-7.7.3/aclocal.m4 deleted file mode 100644 index 2c938cff6..000000000 --- a/ext/libpqxx-7.7.3/aclocal.m4 +++ /dev/null @@ -1,1187 +0,0 @@ -# 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 deleted file mode 100644 index 110bd75ad..000000000 --- a/ext/libpqxx-7.7.3/appveyor.yml +++ /dev/null @@ -1,30 +0,0 @@ -# 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 deleted file mode 100755 index a09cb5ae7..000000000 --- a/ext/libpqxx-7.7.3/autogen.sh +++ /dev/null @@ -1,44 +0,0 @@ -#! /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 deleted file mode 100644 index 816ee4474..000000000 --- a/ext/libpqxx-7.7.3/cmake/config.cmake +++ /dev/null @@ -1,157 +0,0 @@ -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 deleted file mode 100644 index cb25a05f2..000000000 --- a/ext/libpqxx-7.7.3/cmake/libpqxx-config.cmake +++ /dev/null @@ -1,4 +0,0 @@ -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 deleted file mode 100644 index 1304e8aa8..000000000 --- a/ext/libpqxx-7.7.3/compile_flags.in +++ /dev/null @@ -1 +0,0 @@ -@CPPFLAGS@ @CXXFLAGS@ diff --git a/ext/libpqxx-7.7.3/config-tests/README.md b/ext/libpqxx-7.7.3/config-tests/README.md deleted file mode 100644 index b3865d0f0..000000000 --- a/ext/libpqxx-7.7.3/config-tests/README.md +++ /dev/null @@ -1,22 +0,0 @@ -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 deleted file mode 100644 index bc5d973e3..000000000 --- a/ext/libpqxx-7.7.3/config-tests/charconv_float.cxx +++ /dev/null @@ -1,16 +0,0 @@ -// 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 deleted file mode 100644 index 076ee0de3..000000000 --- a/ext/libpqxx-7.7.3/config-tests/charconv_int.cxx +++ /dev/null @@ -1,16 +0,0 @@ -// 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 deleted file mode 100644 index 7f5abaa5d..000000000 --- a/ext/libpqxx-7.7.3/config-tests/cmp.cxx +++ /dev/null @@ -1,8 +0,0 @@ -// 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 deleted file mode 100644 index 5589b4e58..000000000 --- a/ext/libpqxx-7.7.3/config-tests/concepts.cxx +++ /dev/null @@ -1,21 +0,0 @@ -// 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 deleted file mode 100644 index 4d4ee7e6b..000000000 --- a/ext/libpqxx-7.7.3/config-tests/cxa_demangle.cxx +++ /dev/null @@ -1,19 +0,0 @@ -// 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 deleted file mode 100644 index d93d37f5d..000000000 --- a/ext/libpqxx-7.7.3/config-tests/fs.cxx +++ /dev/null @@ -1,9 +0,0 @@ -// 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 deleted file mode 100644 index 4edd267c6..000000000 --- a/ext/libpqxx-7.7.3/config-tests/gcc_pure.cxx +++ /dev/null @@ -1,10 +0,0 @@ -// 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 deleted file mode 100644 index 23d0111d7..000000000 --- a/ext/libpqxx-7.7.3/config-tests/gcc_visibility.cxx +++ /dev/null @@ -1,12 +0,0 @@ -// 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 deleted file mode 100644 index 9d0eca8d3..000000000 --- a/ext/libpqxx-7.7.3/config-tests/likely.cxx +++ /dev/null @@ -1,15 +0,0 @@ -// 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 deleted file mode 100644 index f75d1aa7a..000000000 --- a/ext/libpqxx-7.7.3/config-tests/multidim-subscript.cxx +++ /dev/null @@ -1,14 +0,0 @@ -// 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 deleted file mode 100644 index 041c46b43..000000000 --- a/ext/libpqxx-7.7.3/config-tests/need_fslib.cxx +++ /dev/null @@ -1,21 +0,0 @@ -// 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 deleted file mode 100644 index d67cef55d..000000000 --- a/ext/libpqxx-7.7.3/config-tests/poll.cxx +++ /dev/null @@ -1,7 +0,0 @@ -// 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 deleted file mode 100644 index f081fe0e5..000000000 --- a/ext/libpqxx-7.7.3/config-tests/sleep_for.cxx +++ /dev/null @@ -1,28 +0,0 @@ -// 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 deleted file mode 100644 index 8c13b97c9..000000000 --- a/ext/libpqxx-7.7.3/config-tests/span.cxx +++ /dev/null @@ -1,8 +0,0 @@ -// 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 deleted file mode 100644 index 604d3b899..000000000 --- a/ext/libpqxx-7.7.3/config-tests/strerror_r.cxx +++ /dev/null @@ -1,14 +0,0 @@ -// 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 deleted file mode 100644 index f6f99a7a5..000000000 --- a/ext/libpqxx-7.7.3/config-tests/strerror_s.cxx +++ /dev/null @@ -1,11 +0,0 @@ -// 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 deleted file mode 100644 index b5a98b7b8..000000000 --- a/ext/libpqxx-7.7.3/config-tests/thread_local.cxx +++ /dev/null @@ -1,15 +0,0 @@ -// 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 deleted file mode 100644 index dbe543b55..000000000 --- a/ext/libpqxx-7.7.3/config-tests/year_month_day.cxx +++ /dev/null @@ -1,7 +0,0 @@ -// 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 deleted file mode 100644 index f34b3107d..000000000 --- a/ext/libpqxx-7.7.3/config/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -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 deleted file mode 100644 index bf7aa004a..000000000 --- a/ext/libpqxx-7.7.3/config/Makefile.in +++ /dev/null @@ -1,470 +0,0 @@ -# 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 deleted file mode 100755 index df363c8fb..000000000 --- a/ext/libpqxx-7.7.3/config/compile +++ /dev/null @@ -1,348 +0,0 @@ -#! /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 deleted file mode 100755 index 2e9ad7fe8..000000000 --- a/ext/libpqxx-7.7.3/config/config.guess +++ /dev/null @@ -1,1462 +0,0 @@ -#! /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 deleted file mode 100755 index dd2ca93c6..000000000 --- a/ext/libpqxx-7.7.3/config/config.sub +++ /dev/null @@ -1,1825 +0,0 @@ -#! /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 deleted file mode 100755 index 715e34311..000000000 --- a/ext/libpqxx-7.7.3/config/depcomp +++ /dev/null @@ -1,791 +0,0 @@ -#! /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 deleted file mode 100755 index 6781b987b..000000000 --- a/ext/libpqxx-7.7.3/config/install-sh +++ /dev/null @@ -1,520 +0,0 @@ -#!/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 deleted file mode 100755 index 21e5e0784..000000000 --- a/ext/libpqxx-7.7.3/config/ltmain.sh +++ /dev/null @@ -1,11251 +0,0 @@ -#! /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 deleted file mode 100644 index c5dd1572f..000000000 --- a/ext/libpqxx-7.7.3/config/m4/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -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 deleted file mode 100644 index c4c02946d..000000000 --- a/ext/libpqxx-7.7.3/config/m4/libtool.m4 +++ /dev/null @@ -1,8394 +0,0 @@ -# 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 deleted file mode 100644 index 94b082976..000000000 --- a/ext/libpqxx-7.7.3/config/m4/ltoptions.m4 +++ /dev/null @@ -1,437 +0,0 @@ -# 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 deleted file mode 100644 index 48bc9344a..000000000 --- a/ext/libpqxx-7.7.3/config/m4/ltsugar.m4 +++ /dev/null @@ -1,124 +0,0 @@ -# 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 deleted file mode 100644 index fa04b52a3..000000000 --- a/ext/libpqxx-7.7.3/config/m4/ltversion.m4 +++ /dev/null @@ -1,23 +0,0 @@ -# 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 deleted file mode 100644 index c6b26f88f..000000000 --- a/ext/libpqxx-7.7.3/config/m4/lt~obsolete.m4 +++ /dev/null @@ -1,99 +0,0 @@ -# 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 deleted file mode 100755 index 1fe1611f1..000000000 --- a/ext/libpqxx-7.7.3/config/missing +++ /dev/null @@ -1,215 +0,0 @@ -#! /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 deleted file mode 100755 index 6b3b5fc5d..000000000 --- a/ext/libpqxx-7.7.3/config/mkinstalldirs +++ /dev/null @@ -1,40 +0,0 @@ -#! /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 deleted file mode 100755 index 8e575b017..000000000 --- a/ext/libpqxx-7.7.3/config/test-driver +++ /dev/null @@ -1,148 +0,0 @@ -#! /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 deleted file mode 100644 index e6f3925ef..000000000 --- a/ext/libpqxx-7.7.3/configitems +++ /dev/null @@ -1,26 +0,0 @@ -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 deleted file mode 100755 index 4c58f19c2..000000000 --- a/ext/libpqxx-7.7.3/configure +++ /dev/null @@ -1,20443 +0,0 @@ -#! /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 deleted file mode 100644 index d6351faf2..000000000 --- a/ext/libpqxx-7.7.3/configure.ac +++ /dev/null @@ -1,738 +0,0 @@ -# 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 deleted file mode 100644 index d48d2a6f0..000000000 --- a/ext/libpqxx-7.7.3/doc/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -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 deleted file mode 100644 index f349fe80c..000000000 --- a/ext/libpqxx-7.7.3/doc/Doxyfile.in +++ /dev/null @@ -1,1280 +0,0 @@ -# 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 deleted file mode 100644 index 38caa9181..000000000 --- a/ext/libpqxx-7.7.3/doc/Makefile.am +++ /dev/null @@ -1,51 +0,0 @@ -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 deleted file mode 100644 index 835845bf7..000000000 --- a/ext/libpqxx-7.7.3/doc/Makefile.in +++ /dev/null @@ -1,507 +0,0 @@ -# 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 deleted file mode 100644 index 1cac1c2ca..000000000 --- a/ext/libpqxx-7.7.3/doc/conf.py +++ /dev/null @@ -1,199 +0,0 @@ -# -*- 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 deleted file mode 100644 index 30f2cfdc1..000000000 --- a/ext/libpqxx-7.7.3/doc/index.rst +++ /dev/null @@ -1,20 +0,0 @@ -.. 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 deleted file mode 100644 index 263dd2e9e..000000000 --- a/ext/libpqxx-7.7.3/include/CMakeLists.txt +++ /dev/null @@ -1,68 +0,0 @@ -# ############################################################################## -# 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 deleted file mode 100644 index 5ebc6664e..000000000 --- a/ext/libpqxx-7.7.3/include/CMakeLists.txt.template +++ /dev/null @@ -1,23 +0,0 @@ -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 deleted file mode 100644 index 83d2b1970..000000000 --- a/ext/libpqxx-7.7.3/include/Makefile.am +++ /dev/null @@ -1,79 +0,0 @@ -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 deleted file mode 100644 index 6b9eac914..000000000 --- a/ext/libpqxx-7.7.3/include/Makefile.in +++ /dev/null @@ -1,802 +0,0 @@ -# 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 deleted file mode 100644 index c7f68813d..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -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 deleted file mode 100644 index 4b02fb771..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/Makefile.in +++ /dev/null @@ -1,556 +0,0 @@ -# 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 deleted file mode 100644 index 689f5b27b..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/array +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 8440a244f..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/array.hxx +++ /dev/null @@ -1,103 +0,0 @@ -/* 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 deleted file mode 100644 index 77551d9f7..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/binarystring +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 47c82a035..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/binarystring.hxx +++ /dev/null @@ -1,236 +0,0 @@ -/* 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 deleted file mode 100644 index 3fd0afac9..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/blob +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 6d77be724..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/blob.hxx +++ /dev/null @@ -1,351 +0,0 @@ -/* 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 deleted file mode 100644 index 2bfa7ade9..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/composite +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 439b133a8..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/composite.hxx +++ /dev/null @@ -1,149 +0,0 @@ -#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 deleted file mode 100644 index 743579967..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/config.h.in +++ /dev/null @@ -1,121 +0,0 @@ -/* 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 deleted file mode 100644 index 82ff43aa5..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/connection +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 92454bb47..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/connection.hxx +++ /dev/null @@ -1,1261 +0,0 @@ -/* 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 deleted file mode 100644 index e20b3a4fa..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/cursor +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index b392e2407..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/cursor.hxx +++ /dev/null @@ -1,483 +0,0 @@ -/* 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 deleted file mode 100644 index fa8d26476..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/dbtransaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index d85cb170f..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/dbtransaction.hxx +++ /dev/null @@ -1,70 +0,0 @@ -/* 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 deleted file mode 100644 index 920fb6f3b..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/doc/accessing-results.md +++ /dev/null @@ -1,157 +0,0 @@ -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 deleted file mode 100644 index 20da8dc0c..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/doc/binary-data.md +++ /dev/null @@ -1,56 +0,0 @@ -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 deleted file mode 100644 index bc14c8b90..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/doc/datatypes.md +++ /dev/null @@ -1,373 +0,0 @@ -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 deleted file mode 100644 index 2ad9fe3db..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/doc/escaping.md +++ /dev/null @@ -1,74 +0,0 @@ -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 deleted file mode 100644 index 1b87b881f..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/doc/getting-started.md +++ /dev/null @@ -1,142 +0,0 @@ -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 deleted file mode 100644 index 5d4b8f9b2..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index d5afb2427..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md.template +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index 7ac792025..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/doc/parameters.md +++ /dev/null @@ -1,90 +0,0 @@ -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 deleted file mode 100644 index 6c403684f..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/doc/performance.md +++ /dev/null @@ -1,24 +0,0 @@ -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 deleted file mode 100644 index 5193866a6..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/doc/prepared-statement.md +++ /dev/null @@ -1,125 +0,0 @@ -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 deleted file mode 100644 index 3df4d6126..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/doc/streams.md +++ /dev/null @@ -1,107 +0,0 @@ -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 deleted file mode 100644 index 07c7f9984..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/doc/thread-safety.md +++ /dev/null @@ -1,29 +0,0 @@ -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 deleted file mode 100644 index ea572ee79..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/errorhandler +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 2ffb5703c..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/errorhandler.hxx +++ /dev/null @@ -1,92 +0,0 @@ -/* 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 deleted file mode 100644 index e5dd508bf..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/except +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 24f959437..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/except.hxx +++ /dev/null @@ -1,447 +0,0 @@ -/* 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 deleted file mode 100644 index 37cb69e84..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/field +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index b8b869fe4..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/field.hxx +++ /dev/null @@ -1,542 +0,0 @@ -/* 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 deleted file mode 100644 index d2b6603e5..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/array-composite.hxx +++ /dev/null @@ -1,305 +0,0 @@ -#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 deleted file mode 100644 index 42f7703e3..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/callgate.hxx +++ /dev/null @@ -1,70 +0,0 @@ -#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 deleted file mode 100644 index cd28bde7c..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/concat.hxx +++ /dev/null @@ -1,45 +0,0 @@ -#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 deleted file mode 100644 index 1df4fdead..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/conversions.hxx +++ /dev/null @@ -1,1188 +0,0 @@ -#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 deleted file mode 100644 index e17736e5b..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/encoding_group.hxx +++ /dev/null @@ -1,60 +0,0 @@ -/** 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 deleted file mode 100644 index ba7fecc70..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/encodings.hxx +++ /dev/null @@ -1,90 +0,0 @@ -/** 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 deleted file mode 100644 index ffc12a6cf..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-errorhandler.hxx +++ /dev/null @@ -1,26 +0,0 @@ -#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 deleted file mode 100644 index 49feaf9e6..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-largeobject.hxx +++ /dev/null @@ -1,35 +0,0 @@ -#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 deleted file mode 100644 index 0bcb2db17..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-notification_receiver.hxx +++ /dev/null @@ -1,29 +0,0 @@ -#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 deleted file mode 100644 index c6ae6e17a..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-pipeline.hxx +++ /dev/null @@ -1,23 +0,0 @@ -#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 deleted file mode 100644 index 51a889844..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-sql_cursor.hxx +++ /dev/null @@ -1,19 +0,0 @@ -#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 deleted file mode 100644 index 8961e7146..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_from.hxx +++ /dev/null @@ -1,15 +0,0 @@ -#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 deleted file mode 100644 index a6974fb21..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_to.hxx +++ /dev/null @@ -1,17 +0,0 @@ -#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 deleted file mode 100644 index 74d659253..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-transaction.hxx +++ /dev/null @@ -1,44 +0,0 @@ -#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 deleted file mode 100644 index 5560cedec..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/errorhandler-connection.hxx +++ /dev/null @@ -1,13 +0,0 @@ -#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 deleted file mode 100644 index 296d22145..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx +++ /dev/null @@ -1,24 +0,0 @@ -#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 deleted file mode 100644 index 56056d5ef..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx +++ /dev/null @@ -1,32 +0,0 @@ -#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 deleted file mode 100644 index daa0808c0..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-connection.hxx +++ /dev/null @@ -1,14 +0,0 @@ -#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 deleted file mode 100644 index 3d9205f2c..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-creation.hxx +++ /dev/null @@ -1,24 +0,0 @@ -#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 deleted file mode 100644 index 3ebe436d2..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-pipeline.hxx +++ /dev/null @@ -1,16 +0,0 @@ -#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 deleted file mode 100644 index 78b450739..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-sql_cursor.hxx +++ /dev/null @@ -1,13 +0,0 @@ -#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 deleted file mode 100644 index 4ed78dc93..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-sql_cursor.hxx +++ /dev/null @@ -1,10 +0,0 @@ -#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 deleted file mode 100644 index ca7939a99..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-transaction_focus.hxx +++ /dev/null @@ -1,30 +0,0 @@ -#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 deleted file mode 100644 index ff6bf8986..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/header-post.hxx +++ /dev/null @@ -1,22 +0,0 @@ -/* 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 deleted file mode 100644 index abc1a398d..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/header-pre.hxx +++ /dev/null @@ -1,169 +0,0 @@ -/* 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 deleted file mode 100644 index cebcf0594..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-post.hxx +++ /dev/null @@ -1,15 +0,0 @@ -/// 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 deleted file mode 100644 index 8ac57afaa..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-pre.hxx +++ /dev/null @@ -1,28 +0,0 @@ -/** 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 deleted file mode 100644 index 9e74f79ec..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/libpq-forward.hxx +++ /dev/null @@ -1,31 +0,0 @@ -/** 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 deleted file mode 100644 index 1fa1f7d8a..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/result_iter.hxx +++ /dev/null @@ -1,124 +0,0 @@ -/** 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 deleted file mode 100644 index 3f27a1d3f..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/result_iterator.hxx +++ /dev/null @@ -1,389 +0,0 @@ -/* 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 deleted file mode 100644 index a26d06306..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/sql_cursor.hxx +++ /dev/null @@ -1,118 +0,0 @@ -/** 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 deleted file mode 100644 index b078bf6e0..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/statement_parameters.hxx +++ /dev/null @@ -1,131 +0,0 @@ -/** 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 deleted file mode 100644 index f240dcfa7..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/stream_iterator.hxx +++ /dev/null @@ -1,105 +0,0 @@ -/** 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 deleted file mode 100644 index 7a82e6553..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/internal/wait.hxx +++ /dev/null @@ -1,18 +0,0 @@ -#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 deleted file mode 100644 index 1b801329b..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/isolation +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 0698c6ab4..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/isolation.hxx +++ /dev/null @@ -1,75 +0,0 @@ -/* 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 deleted file mode 100644 index 1f2f94790..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/largeobject +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index ebafc51d8..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/largeobject.hxx +++ /dev/null @@ -1,735 +0,0 @@ -/* 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 deleted file mode 100644 index bb5b79724..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/nontransaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index c50715594..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/nontransaction.hxx +++ /dev/null @@ -1,76 +0,0 @@ -/* 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 deleted file mode 100644 index a0bd1c73e..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/notification +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index b59b8567a..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/notification.hxx +++ /dev/null @@ -1,94 +0,0 @@ -/* 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 deleted file mode 100644 index 4098782aa..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/params +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 2d29cdfed..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/params.hxx +++ /dev/null @@ -1,383 +0,0 @@ -/* 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 deleted file mode 100644 index bf828843a..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/pipeline +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 049dcdd58..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/pipeline.hxx +++ /dev/null @@ -1,237 +0,0 @@ -/* 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 deleted file mode 100644 index 17a8eaa9c..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/pqxx +++ /dev/null @@ -1,28 +0,0 @@ -/// 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 deleted file mode 100644 index 674be7090..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/prepared_statement +++ /dev/null @@ -1,3 +0,0 @@ -/// @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 deleted file mode 100644 index 674be7090..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/prepared_statement.hxx +++ /dev/null @@ -1,3 +0,0 @@ -/// @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 deleted file mode 100644 index 11985eca4..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/range +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index dc480e4b7..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/range.hxx +++ /dev/null @@ -1,515 +0,0 @@ -#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 deleted file mode 100644 index 523394b72..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/result +++ /dev/null @@ -1,16 +0,0 @@ -/** 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 deleted file mode 100644 index 6c41cc096..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/result.hxx +++ /dev/null @@ -1,335 +0,0 @@ -/* 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 deleted file mode 100644 index 04b71d7cc..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/robusttransaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index faf6dbf5e..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/robusttransaction.hxx +++ /dev/null @@ -1,120 +0,0 @@ -/* 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 deleted file mode 100644 index 62a950ac8..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/row +++ /dev/null @@ -1,11 +0,0 @@ -/** 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 deleted file mode 100644 index 5be5132e3..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/row.hxx +++ /dev/null @@ -1,561 +0,0 @@ -/* 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 deleted file mode 100644 index 1bdf51c6a..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/separated_list +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index d4230ea08..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/separated_list.hxx +++ /dev/null @@ -1,142 +0,0 @@ -/* 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 deleted file mode 100644 index aa2c40ed5..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/strconv +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 863711228..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/strconv.hxx +++ /dev/null @@ -1,468 +0,0 @@ -/* 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 deleted file mode 100644 index 972762443..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/stream_from +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index ff4a93d2e..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/stream_from.hxx +++ /dev/null @@ -1,361 +0,0 @@ -/* 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 deleted file mode 100644 index 8760cf1f4..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/stream_to +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 2a49d8f85..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/stream_to.hxx +++ /dev/null @@ -1,455 +0,0 @@ -/* 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 deleted file mode 100644 index e0d154903..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/subtransaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index e66b7a7a8..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/subtransaction.hxx +++ /dev/null @@ -1,96 +0,0 @@ -/* 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 deleted file mode 100644 index 85df05744..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/time +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index effed05e0..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/time.hxx +++ /dev/null @@ -1,88 +0,0 @@ -/** 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 deleted file mode 100644 index a7ae39d43..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/transaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index e90917e38..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/transaction.hxx +++ /dev/null @@ -1,108 +0,0 @@ -/* 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 deleted file mode 100644 index c39219aac..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/transaction_base +++ /dev/null @@ -1,9 +0,0 @@ -/** 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 deleted file mode 100644 index 4363cc56a..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/transaction_base.hxx +++ /dev/null @@ -1,810 +0,0 @@ -/* 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 deleted file mode 100644 index fe78a9bcc..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/transaction_focus +++ /dev/null @@ -1,7 +0,0 @@ -/** - * 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 deleted file mode 100644 index 0707e3cc4..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/transaction_focus.hxx +++ /dev/null @@ -1,89 +0,0 @@ -/** 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 deleted file mode 100644 index 29d1b9640..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/transactor +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index eefd04ba1..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/transactor.hxx +++ /dev/null @@ -1,147 +0,0 @@ -/* 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 deleted file mode 100644 index 23a5caae1..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/types +++ /dev/null @@ -1,7 +0,0 @@ -/** - * 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 deleted file mode 100644 index f95b598f8..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/types.hxx +++ /dev/null @@ -1,173 +0,0 @@ -/* 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 deleted file mode 100644 index 6d85ab611..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/util +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 4aa5ecf57..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/util.hxx +++ /dev/null @@ -1,521 +0,0 @@ -/* 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 deleted file mode 100644 index 8dd5e48d4..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/version +++ /dev/null @@ -1,7 +0,0 @@ -/** 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 deleted file mode 100644 index a159f1bed..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/version.hxx +++ /dev/null @@ -1,55 +0,0 @@ -/* 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 deleted file mode 100644 index 40837f16a..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/version.hxx.template +++ /dev/null @@ -1,55 +0,0 @@ -/* 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 deleted file mode 100644 index 66ea2a625..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/zview +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 36a779f51..000000000 --- a/ext/libpqxx-7.7.3/include/pqxx/zview.hxx +++ /dev/null @@ -1,163 +0,0 @@ -/* 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 deleted file mode 100644 index 689f5b27b..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/array +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 8440a244f..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/array.hxx +++ /dev/null @@ -1,103 +0,0 @@ -/* 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 deleted file mode 100644 index 77551d9f7..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/binarystring +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 47c82a035..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/binarystring.hxx +++ /dev/null @@ -1,236 +0,0 @@ -/* 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 deleted file mode 100644 index 3fd0afac9..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/blob +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 6d77be724..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/blob.hxx +++ /dev/null @@ -1,351 +0,0 @@ -/* 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 deleted file mode 100644 index 2bfa7ade9..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/composite +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 439b133a8..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/composite.hxx +++ /dev/null @@ -1,149 +0,0 @@ -#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 deleted file mode 100644 index 3668a10f8..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/config-public-compiler.h +++ /dev/null @@ -1,81 +0,0 @@ -/* 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 deleted file mode 100644 index 82ff43aa5..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/connection +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 92454bb47..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/connection.hxx +++ /dev/null @@ -1,1261 +0,0 @@ -/* 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 deleted file mode 100644 index e20b3a4fa..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/cursor +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index b392e2407..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/cursor.hxx +++ /dev/null @@ -1,483 +0,0 @@ -/* 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 deleted file mode 100644 index fa8d26476..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/dbtransaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index d85cb170f..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/dbtransaction.hxx +++ /dev/null @@ -1,70 +0,0 @@ -/* 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 deleted file mode 100644 index ea572ee79..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/errorhandler +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 2ffb5703c..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/errorhandler.hxx +++ /dev/null @@ -1,92 +0,0 @@ -/* 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 deleted file mode 100644 index e5dd508bf..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/except +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 24f959437..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/except.hxx +++ /dev/null @@ -1,447 +0,0 @@ -/* 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 deleted file mode 100644 index 37cb69e84..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/field +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index b8b869fe4..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/field.hxx +++ /dev/null @@ -1,542 +0,0 @@ -/* 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 deleted file mode 100644 index d2b6603e5..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/array-composite.hxx +++ /dev/null @@ -1,305 +0,0 @@ -#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 deleted file mode 100644 index 42f7703e3..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/callgate.hxx +++ /dev/null @@ -1,70 +0,0 @@ -#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 deleted file mode 100644 index cd28bde7c..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/concat.hxx +++ /dev/null @@ -1,45 +0,0 @@ -#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 deleted file mode 100644 index 1df4fdead..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/conversions.hxx +++ /dev/null @@ -1,1188 +0,0 @@ -#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 deleted file mode 100644 index e17736e5b..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/encoding_group.hxx +++ /dev/null @@ -1,60 +0,0 @@ -/** 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 deleted file mode 100644 index ba7fecc70..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/encodings.hxx +++ /dev/null @@ -1,90 +0,0 @@ -/** 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 deleted file mode 100644 index ffc12a6cf..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-errorhandler.hxx +++ /dev/null @@ -1,26 +0,0 @@ -#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 deleted file mode 100644 index 49feaf9e6..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-largeobject.hxx +++ /dev/null @@ -1,35 +0,0 @@ -#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 deleted file mode 100644 index 0bcb2db17..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-notification_receiver.hxx +++ /dev/null @@ -1,29 +0,0 @@ -#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 deleted file mode 100644 index c6ae6e17a..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-pipeline.hxx +++ /dev/null @@ -1,23 +0,0 @@ -#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 deleted file mode 100644 index 51a889844..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-sql_cursor.hxx +++ /dev/null @@ -1,19 +0,0 @@ -#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 deleted file mode 100644 index 8961e7146..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-stream_from.hxx +++ /dev/null @@ -1,15 +0,0 @@ -#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 deleted file mode 100644 index a6974fb21..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-stream_to.hxx +++ /dev/null @@ -1,17 +0,0 @@ -#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 deleted file mode 100644 index 74d659253..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-transaction.hxx +++ /dev/null @@ -1,44 +0,0 @@ -#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 deleted file mode 100644 index 5560cedec..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/errorhandler-connection.hxx +++ /dev/null @@ -1,13 +0,0 @@ -#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 deleted file mode 100644 index 296d22145..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx +++ /dev/null @@ -1,24 +0,0 @@ -#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 deleted file mode 100644 index 56056d5ef..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx +++ /dev/null @@ -1,32 +0,0 @@ -#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 deleted file mode 100644 index daa0808c0..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-connection.hxx +++ /dev/null @@ -1,14 +0,0 @@ -#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 deleted file mode 100644 index 3d9205f2c..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-creation.hxx +++ /dev/null @@ -1,24 +0,0 @@ -#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 deleted file mode 100644 index 3ebe436d2..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-pipeline.hxx +++ /dev/null @@ -1,16 +0,0 @@ -#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 deleted file mode 100644 index 78b450739..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-sql_cursor.hxx +++ /dev/null @@ -1,13 +0,0 @@ -#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 deleted file mode 100644 index 4ed78dc93..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/transaction-sql_cursor.hxx +++ /dev/null @@ -1,10 +0,0 @@ -#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 deleted file mode 100644 index ca7939a99..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/transaction-transaction_focus.hxx +++ /dev/null @@ -1,30 +0,0 @@ -#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 deleted file mode 100644 index ff6bf8986..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/header-post.hxx +++ /dev/null @@ -1,22 +0,0 @@ -/* 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 deleted file mode 100644 index abc1a398d..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/header-pre.hxx +++ /dev/null @@ -1,169 +0,0 @@ -/* 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 deleted file mode 100644 index cebcf0594..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/ignore-deprecated-post.hxx +++ /dev/null @@ -1,15 +0,0 @@ -/// 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 deleted file mode 100644 index 8ac57afaa..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/ignore-deprecated-pre.hxx +++ /dev/null @@ -1,28 +0,0 @@ -/** 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 deleted file mode 100644 index 9e74f79ec..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/libpq-forward.hxx +++ /dev/null @@ -1,31 +0,0 @@ -/** 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 deleted file mode 100644 index 1fa1f7d8a..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/result_iter.hxx +++ /dev/null @@ -1,124 +0,0 @@ -/** 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 deleted file mode 100644 index 3f27a1d3f..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/result_iterator.hxx +++ /dev/null @@ -1,389 +0,0 @@ -/* 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 deleted file mode 100644 index a26d06306..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/sql_cursor.hxx +++ /dev/null @@ -1,118 +0,0 @@ -/** 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 deleted file mode 100644 index b078bf6e0..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/statement_parameters.hxx +++ /dev/null @@ -1,131 +0,0 @@ -/** 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 deleted file mode 100644 index f240dcfa7..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/stream_iterator.hxx +++ /dev/null @@ -1,105 +0,0 @@ -/** 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 deleted file mode 100644 index 7a82e6553..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/wait.hxx +++ /dev/null @@ -1,18 +0,0 @@ -#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 deleted file mode 100644 index 1b801329b..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/isolation +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 0698c6ab4..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/isolation.hxx +++ /dev/null @@ -1,75 +0,0 @@ -/* 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 deleted file mode 100644 index 1f2f94790..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/largeobject +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index ebafc51d8..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/largeobject.hxx +++ /dev/null @@ -1,735 +0,0 @@ -/* 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 deleted file mode 100644 index bb5b79724..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/nontransaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index c50715594..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/nontransaction.hxx +++ /dev/null @@ -1,76 +0,0 @@ -/* 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 deleted file mode 100644 index a0bd1c73e..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/notification +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index b59b8567a..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/notification.hxx +++ /dev/null @@ -1,94 +0,0 @@ -/* 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 deleted file mode 100644 index 4098782aa..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/params +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 2d29cdfed..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/params.hxx +++ /dev/null @@ -1,383 +0,0 @@ -/* 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 deleted file mode 100644 index bf828843a..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pipeline +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 049dcdd58..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pipeline.hxx +++ /dev/null @@ -1,237 +0,0 @@ -/* 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 deleted file mode 100644 index 17a8eaa9c..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pqxx +++ /dev/null @@ -1,28 +0,0 @@ -/// 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 deleted file mode 100644 index 674be7090..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/prepared_statement +++ /dev/null @@ -1,3 +0,0 @@ -/// @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 deleted file mode 100644 index 674be7090..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/prepared_statement.hxx +++ /dev/null @@ -1,3 +0,0 @@ -/// @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 deleted file mode 100644 index 11985eca4..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/range +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index dc480e4b7..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/range.hxx +++ /dev/null @@ -1,515 +0,0 @@ -#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 deleted file mode 100644 index 523394b72..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/result +++ /dev/null @@ -1,16 +0,0 @@ -/** 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 deleted file mode 100644 index 6c41cc096..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/result.hxx +++ /dev/null @@ -1,335 +0,0 @@ -/* 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 deleted file mode 100644 index 04b71d7cc..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/robusttransaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index faf6dbf5e..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/robusttransaction.hxx +++ /dev/null @@ -1,120 +0,0 @@ -/* 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 deleted file mode 100644 index 62a950ac8..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/row +++ /dev/null @@ -1,11 +0,0 @@ -/** 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 deleted file mode 100644 index 5be5132e3..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/row.hxx +++ /dev/null @@ -1,561 +0,0 @@ -/* 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 deleted file mode 100644 index 1bdf51c6a..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/separated_list +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index d4230ea08..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/separated_list.hxx +++ /dev/null @@ -1,142 +0,0 @@ -/* 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 deleted file mode 100644 index aa2c40ed5..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/strconv +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 863711228..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/strconv.hxx +++ /dev/null @@ -1,468 +0,0 @@ -/* 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 deleted file mode 100644 index 972762443..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_from +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index ff4a93d2e..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_from.hxx +++ /dev/null @@ -1,361 +0,0 @@ -/* 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 deleted file mode 100644 index 8760cf1f4..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_to +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 2a49d8f85..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_to.hxx +++ /dev/null @@ -1,455 +0,0 @@ -/* 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 deleted file mode 100644 index e0d154903..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/subtransaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index e66b7a7a8..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/subtransaction.hxx +++ /dev/null @@ -1,96 +0,0 @@ -/* 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 deleted file mode 100644 index 85df05744..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/time +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index effed05e0..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/time.hxx +++ /dev/null @@ -1,88 +0,0 @@ -/** 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 deleted file mode 100644 index a7ae39d43..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index e90917e38..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction.hxx +++ /dev/null @@ -1,108 +0,0 @@ -/* 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 deleted file mode 100644 index c39219aac..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_base +++ /dev/null @@ -1,9 +0,0 @@ -/** 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 deleted file mode 100644 index 4363cc56a..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_base.hxx +++ /dev/null @@ -1,810 +0,0 @@ -/* 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 deleted file mode 100644 index fe78a9bcc..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_focus +++ /dev/null @@ -1,7 +0,0 @@ -/** - * 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 deleted file mode 100644 index 0707e3cc4..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_focus.hxx +++ /dev/null @@ -1,89 +0,0 @@ -/** 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 deleted file mode 100644 index 29d1b9640..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transactor +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index eefd04ba1..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transactor.hxx +++ /dev/null @@ -1,147 +0,0 @@ -/* 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 deleted file mode 100644 index 23a5caae1..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/types +++ /dev/null @@ -1,7 +0,0 @@ -/** - * 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 deleted file mode 100644 index f95b598f8..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/types.hxx +++ /dev/null @@ -1,173 +0,0 @@ -/* 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 deleted file mode 100644 index 6d85ab611..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/util +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 4aa5ecf57..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/util.hxx +++ /dev/null @@ -1,521 +0,0 @@ -/* 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 deleted file mode 100644 index 8dd5e48d4..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/version +++ /dev/null @@ -1,7 +0,0 @@ -/** 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 deleted file mode 100644 index a159f1bed..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/version.hxx +++ /dev/null @@ -1,55 +0,0 @@ -/* 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 deleted file mode 100644 index 66ea2a625..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/zview +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 36a779f51..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/zview.hxx +++ /dev/null @@ -1,163 +0,0 @@ -/* 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 deleted file mode 100644 index c47d6956d..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-config-version.cmake +++ /dev/null @@ -1,70 +0,0 @@ -# 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 deleted file mode 100644 index cb25a05f2..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-config.cmake +++ /dev/null @@ -1,4 +0,0 @@ -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 deleted file mode 100644 index 980f46098..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake +++ /dev/null @@ -1,19 +0,0 @@ -#---------------------------------------------------------------- -# 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 deleted file mode 100644 index 4716fb7b2..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-targets.cmake +++ /dev/null @@ -1,99 +0,0 @@ -# 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 deleted file mode 100644 index fb941debb..000000000 Binary files a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/libpqxx-7.7.a and /dev/null differ diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/libpqxx.a b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/libpqxx.a deleted file mode 120000 index d9fcdab85..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/libpqxx.a +++ /dev/null @@ -1 +0,0 @@ -libpqxx-7.7.a \ No newline at end of file diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/accessing-results.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/accessing-results.md deleted file mode 100644 index 920fb6f3b..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/accessing-results.md +++ /dev/null @@ -1,157 +0,0 @@ -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/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 deleted file mode 100644 index 20da8dc0c..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/binary-data.md +++ /dev/null @@ -1,56 +0,0 @@ -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 deleted file mode 100644 index bc14c8b90..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/datatypes.md +++ /dev/null @@ -1,373 +0,0 @@ -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 deleted file mode 100644 index 2ad9fe3db..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/escaping.md +++ /dev/null @@ -1,74 +0,0 @@ -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 deleted file mode 100644 index 1b87b881f..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/getting-started.md +++ /dev/null @@ -1,142 +0,0 @@ -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 deleted file mode 100644 index 5d4b8f9b2..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/mainpage.md +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index 7ac792025..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/parameters.md +++ /dev/null @@ -1,90 +0,0 @@ -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 deleted file mode 100644 index 6c403684f..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/performance.md +++ /dev/null @@ -1,24 +0,0 @@ -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 deleted file mode 100644 index 5193866a6..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/prepared-statement.md +++ /dev/null @@ -1,125 +0,0 @@ -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 deleted file mode 100644 index 3df4d6126..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/streams.md +++ /dev/null @@ -1,107 +0,0 @@ -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 deleted file mode 100644 index 07c7f9984..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/thread-safety.md +++ /dev/null @@ -1,29 +0,0 @@ -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 deleted file mode 100644 index 689f5b27b..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/array +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 8440a244f..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/array.hxx +++ /dev/null @@ -1,103 +0,0 @@ -/* 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 deleted file mode 100644 index 77551d9f7..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/binarystring +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 47c82a035..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/binarystring.hxx +++ /dev/null @@ -1,236 +0,0 @@ -/* 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 deleted file mode 100644 index 3fd0afac9..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/blob +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 6d77be724..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/blob.hxx +++ /dev/null @@ -1,351 +0,0 @@ -/* 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 deleted file mode 100644 index 2bfa7ade9..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/composite +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 439b133a8..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/composite.hxx +++ /dev/null @@ -1,149 +0,0 @@ -#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 deleted file mode 100644 index 3668a10f8..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/config-public-compiler.h +++ /dev/null @@ -1,81 +0,0 @@ -/* 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 deleted file mode 100644 index 82ff43aa5..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/connection +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 92454bb47..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/connection.hxx +++ /dev/null @@ -1,1261 +0,0 @@ -/* 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 deleted file mode 100644 index e20b3a4fa..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/cursor +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index b392e2407..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/cursor.hxx +++ /dev/null @@ -1,483 +0,0 @@ -/* 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 deleted file mode 100644 index fa8d26476..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/dbtransaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index d85cb170f..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/dbtransaction.hxx +++ /dev/null @@ -1,70 +0,0 @@ -/* 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 deleted file mode 100644 index ea572ee79..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/errorhandler +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 2ffb5703c..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/errorhandler.hxx +++ /dev/null @@ -1,92 +0,0 @@ -/* 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 deleted file mode 100644 index e5dd508bf..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/except +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 24f959437..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/except.hxx +++ /dev/null @@ -1,447 +0,0 @@ -/* 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 deleted file mode 100644 index 37cb69e84..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/field +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index b8b869fe4..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/field.hxx +++ /dev/null @@ -1,542 +0,0 @@ -/* 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 deleted file mode 100644 index d2b6603e5..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/array-composite.hxx +++ /dev/null @@ -1,305 +0,0 @@ -#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 deleted file mode 100644 index 42f7703e3..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/callgate.hxx +++ /dev/null @@ -1,70 +0,0 @@ -#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 deleted file mode 100644 index cd28bde7c..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/concat.hxx +++ /dev/null @@ -1,45 +0,0 @@ -#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 deleted file mode 100644 index 1df4fdead..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/conversions.hxx +++ /dev/null @@ -1,1188 +0,0 @@ -#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 deleted file mode 100644 index e17736e5b..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/encoding_group.hxx +++ /dev/null @@ -1,60 +0,0 @@ -/** 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 deleted file mode 100644 index ba7fecc70..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/encodings.hxx +++ /dev/null @@ -1,90 +0,0 @@ -/** 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 deleted file mode 100644 index ffc12a6cf..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-errorhandler.hxx +++ /dev/null @@ -1,26 +0,0 @@ -#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 deleted file mode 100644 index 49feaf9e6..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-largeobject.hxx +++ /dev/null @@ -1,35 +0,0 @@ -#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 deleted file mode 100644 index 0bcb2db17..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-notification_receiver.hxx +++ /dev/null @@ -1,29 +0,0 @@ -#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 deleted file mode 100644 index c6ae6e17a..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-pipeline.hxx +++ /dev/null @@ -1,23 +0,0 @@ -#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 deleted file mode 100644 index 51a889844..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-sql_cursor.hxx +++ /dev/null @@ -1,19 +0,0 @@ -#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 deleted file mode 100644 index 8961e7146..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-stream_from.hxx +++ /dev/null @@ -1,15 +0,0 @@ -#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 deleted file mode 100644 index a6974fb21..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-stream_to.hxx +++ /dev/null @@ -1,17 +0,0 @@ -#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 deleted file mode 100644 index 74d659253..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-transaction.hxx +++ /dev/null @@ -1,44 +0,0 @@ -#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 deleted file mode 100644 index 5560cedec..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/errorhandler-connection.hxx +++ /dev/null @@ -1,13 +0,0 @@ -#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 deleted file mode 100644 index 296d22145..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx +++ /dev/null @@ -1,24 +0,0 @@ -#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 deleted file mode 100644 index 56056d5ef..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx +++ /dev/null @@ -1,32 +0,0 @@ -#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 deleted file mode 100644 index daa0808c0..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-connection.hxx +++ /dev/null @@ -1,14 +0,0 @@ -#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 deleted file mode 100644 index 3d9205f2c..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-creation.hxx +++ /dev/null @@ -1,24 +0,0 @@ -#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 deleted file mode 100644 index 3ebe436d2..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-pipeline.hxx +++ /dev/null @@ -1,16 +0,0 @@ -#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 deleted file mode 100644 index 78b450739..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-sql_cursor.hxx +++ /dev/null @@ -1,13 +0,0 @@ -#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 deleted file mode 100644 index 4ed78dc93..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/transaction-sql_cursor.hxx +++ /dev/null @@ -1,10 +0,0 @@ -#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 deleted file mode 100644 index ca7939a99..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/transaction-transaction_focus.hxx +++ /dev/null @@ -1,30 +0,0 @@ -#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 deleted file mode 100644 index ff6bf8986..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/header-post.hxx +++ /dev/null @@ -1,22 +0,0 @@ -/* 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 deleted file mode 100644 index abc1a398d..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/header-pre.hxx +++ /dev/null @@ -1,169 +0,0 @@ -/* 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 deleted file mode 100644 index cebcf0594..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/ignore-deprecated-post.hxx +++ /dev/null @@ -1,15 +0,0 @@ -/// 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 deleted file mode 100644 index 8ac57afaa..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/ignore-deprecated-pre.hxx +++ /dev/null @@ -1,28 +0,0 @@ -/** 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 deleted file mode 100644 index 9e74f79ec..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/libpq-forward.hxx +++ /dev/null @@ -1,31 +0,0 @@ -/** 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 deleted file mode 100644 index 1fa1f7d8a..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/result_iter.hxx +++ /dev/null @@ -1,124 +0,0 @@ -/** 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 deleted file mode 100644 index 3f27a1d3f..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/result_iterator.hxx +++ /dev/null @@ -1,389 +0,0 @@ -/* 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 deleted file mode 100644 index a26d06306..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/sql_cursor.hxx +++ /dev/null @@ -1,118 +0,0 @@ -/** 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 deleted file mode 100644 index b078bf6e0..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/statement_parameters.hxx +++ /dev/null @@ -1,131 +0,0 @@ -/** 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 deleted file mode 100644 index f240dcfa7..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/stream_iterator.hxx +++ /dev/null @@ -1,105 +0,0 @@ -/** 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 deleted file mode 100644 index 7a82e6553..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/wait.hxx +++ /dev/null @@ -1,18 +0,0 @@ -#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 deleted file mode 100644 index 1b801329b..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/isolation +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 0698c6ab4..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/isolation.hxx +++ /dev/null @@ -1,75 +0,0 @@ -/* 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 deleted file mode 100644 index 1f2f94790..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/largeobject +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index ebafc51d8..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/largeobject.hxx +++ /dev/null @@ -1,735 +0,0 @@ -/* 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 deleted file mode 100644 index bb5b79724..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/nontransaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index c50715594..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/nontransaction.hxx +++ /dev/null @@ -1,76 +0,0 @@ -/* 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 deleted file mode 100644 index a0bd1c73e..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/notification +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index b59b8567a..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/notification.hxx +++ /dev/null @@ -1,94 +0,0 @@ -/* 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 deleted file mode 100644 index 4098782aa..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/params +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 2d29cdfed..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/params.hxx +++ /dev/null @@ -1,383 +0,0 @@ -/* 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 deleted file mode 100644 index bf828843a..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pipeline +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 049dcdd58..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pipeline.hxx +++ /dev/null @@ -1,237 +0,0 @@ -/* 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 deleted file mode 100644 index 17a8eaa9c..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pqxx +++ /dev/null @@ -1,28 +0,0 @@ -/// 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 deleted file mode 100644 index 674be7090..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/prepared_statement +++ /dev/null @@ -1,3 +0,0 @@ -/// @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 deleted file mode 100644 index 674be7090..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/prepared_statement.hxx +++ /dev/null @@ -1,3 +0,0 @@ -/// @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 deleted file mode 100644 index 11985eca4..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/range +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index dc480e4b7..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/range.hxx +++ /dev/null @@ -1,515 +0,0 @@ -#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 deleted file mode 100644 index 523394b72..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/result +++ /dev/null @@ -1,16 +0,0 @@ -/** 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 deleted file mode 100644 index 6c41cc096..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/result.hxx +++ /dev/null @@ -1,335 +0,0 @@ -/* 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 deleted file mode 100644 index 04b71d7cc..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/robusttransaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index faf6dbf5e..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/robusttransaction.hxx +++ /dev/null @@ -1,120 +0,0 @@ -/* 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 deleted file mode 100644 index 62a950ac8..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/row +++ /dev/null @@ -1,11 +0,0 @@ -/** 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 deleted file mode 100644 index 5be5132e3..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/row.hxx +++ /dev/null @@ -1,561 +0,0 @@ -/* 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 deleted file mode 100644 index 1bdf51c6a..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/separated_list +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index d4230ea08..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/separated_list.hxx +++ /dev/null @@ -1,142 +0,0 @@ -/* 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 deleted file mode 100644 index aa2c40ed5..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/strconv +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 863711228..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/strconv.hxx +++ /dev/null @@ -1,468 +0,0 @@ -/* 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 deleted file mode 100644 index 972762443..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_from +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index ff4a93d2e..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_from.hxx +++ /dev/null @@ -1,361 +0,0 @@ -/* 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 deleted file mode 100644 index 8760cf1f4..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_to +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index 2a49d8f85..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_to.hxx +++ /dev/null @@ -1,455 +0,0 @@ -/* 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 deleted file mode 100644 index e0d154903..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/subtransaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index e66b7a7a8..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/subtransaction.hxx +++ /dev/null @@ -1,96 +0,0 @@ -/* 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 deleted file mode 100644 index 85df05744..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/time +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index effed05e0..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/time.hxx +++ /dev/null @@ -1,88 +0,0 @@ -/** 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 deleted file mode 100644 index a7ae39d43..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index e90917e38..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction.hxx +++ /dev/null @@ -1,108 +0,0 @@ -/* 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 deleted file mode 100644 index c39219aac..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_base +++ /dev/null @@ -1,9 +0,0 @@ -/** 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 deleted file mode 100644 index 4363cc56a..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_base.hxx +++ /dev/null @@ -1,810 +0,0 @@ -/* 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 deleted file mode 100644 index fe78a9bcc..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_focus +++ /dev/null @@ -1,7 +0,0 @@ -/** - * 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 deleted file mode 100644 index 0707e3cc4..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_focus.hxx +++ /dev/null @@ -1,89 +0,0 @@ -/** 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 deleted file mode 100644 index 29d1b9640..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transactor +++ /dev/null @@ -1,8 +0,0 @@ -/** 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 deleted file mode 100644 index eefd04ba1..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transactor.hxx +++ /dev/null @@ -1,147 +0,0 @@ -/* 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 deleted file mode 100644 index 23a5caae1..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/types +++ /dev/null @@ -1,7 +0,0 @@ -/** - * 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 deleted file mode 100644 index f95b598f8..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/types.hxx +++ /dev/null @@ -1,173 +0,0 @@ -/* 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 deleted file mode 100644 index 6d85ab611..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/util +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 4aa5ecf57..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/util.hxx +++ /dev/null @@ -1,521 +0,0 @@ -/* 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 deleted file mode 100644 index 8dd5e48d4..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/version +++ /dev/null @@ -1,7 +0,0 @@ -/** 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 deleted file mode 100644 index a159f1bed..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/version.hxx +++ /dev/null @@ -1,55 +0,0 @@ -/* 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 deleted file mode 100644 index 66ea2a625..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/zview +++ /dev/null @@ -1,6 +0,0 @@ -/** 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 deleted file mode 100644 index 36a779f51..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/zview.hxx +++ /dev/null @@ -1,163 +0,0 @@ -/* 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 deleted file mode 100644 index c47d6956d..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-config-version.cmake +++ /dev/null @@ -1,70 +0,0 @@ -# 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 deleted file mode 100644 index cb25a05f2..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-config.cmake +++ /dev/null @@ -1,4 +0,0 @@ -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 deleted file mode 100644 index 980f46098..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake +++ /dev/null @@ -1,19 +0,0 @@ -#---------------------------------------------------------------- -# 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 deleted file mode 100644 index c7b525b18..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-targets.cmake +++ /dev/null @@ -1,99 +0,0 @@ -# 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 deleted file mode 100644 index 2cb705a34..000000000 Binary files a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/libpqxx-7.7.a and /dev/null differ diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/libpqxx.a b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/libpqxx.a deleted file mode 120000 index d9fcdab85..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/libpqxx.a +++ /dev/null @@ -1 +0,0 @@ -libpqxx-7.7.a \ No newline at end of file diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/accessing-results.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/accessing-results.md deleted file mode 100644 index 920fb6f3b..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/accessing-results.md +++ /dev/null @@ -1,157 +0,0 @@ -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/install/ubuntu22.04/arm64/share/doc/libpqxx/binary-data.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/binary-data.md deleted file mode 100644 index 20da8dc0c..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/binary-data.md +++ /dev/null @@ -1,56 +0,0 @@ -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/arm64/share/doc/libpqxx/datatypes.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/datatypes.md deleted file mode 100644 index bc14c8b90..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/datatypes.md +++ /dev/null @@ -1,373 +0,0 @@ -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/arm64/share/doc/libpqxx/escaping.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/escaping.md deleted file mode 100644 index 2ad9fe3db..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/escaping.md +++ /dev/null @@ -1,74 +0,0 @@ -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/arm64/share/doc/libpqxx/getting-started.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/getting-started.md deleted file mode 100644 index 1b87b881f..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/getting-started.md +++ /dev/null @@ -1,142 +0,0 @@ -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/arm64/share/doc/libpqxx/mainpage.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/mainpage.md deleted file mode 100644 index 5d4b8f9b2..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/mainpage.md +++ /dev/null @@ -1,28 +0,0 @@ -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/arm64/share/doc/libpqxx/parameters.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/parameters.md deleted file mode 100644 index 7ac792025..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/parameters.md +++ /dev/null @@ -1,90 +0,0 @@ -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/arm64/share/doc/libpqxx/performance.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/performance.md deleted file mode 100644 index 6c403684f..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/performance.md +++ /dev/null @@ -1,24 +0,0 @@ -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/arm64/share/doc/libpqxx/prepared-statement.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/prepared-statement.md deleted file mode 100644 index 5193866a6..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/prepared-statement.md +++ /dev/null @@ -1,125 +0,0 @@ -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/arm64/share/doc/libpqxx/streams.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/streams.md deleted file mode 100644 index 3df4d6126..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/streams.md +++ /dev/null @@ -1,107 +0,0 @@ -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/arm64/share/doc/libpqxx/thread-safety.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/thread-safety.md deleted file mode 100644 index 07c7f9984..000000000 --- a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/thread-safety.md +++ /dev/null @@ -1,29 +0,0 @@ -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/libpqxx.pc.in b/ext/libpqxx-7.7.3/libpqxx.pc.in deleted file mode 100644 index eb7dcff49..000000000 --- a/ext/libpqxx-7.7.3/libpqxx.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libpqxx -Description: C++ client API for the PostgreSQL database management system. -Version: @VERSION@ -Libs: -L${libdir} -lpqxx -Cflags: -I${includedir} diff --git a/ext/libpqxx-7.7.3/requirements.json b/ext/libpqxx-7.7.3/requirements.json deleted file mode 100644 index 28f8f8ad1..000000000 --- a/ext/libpqxx-7.7.3/requirements.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "description": "Minimum versions needed of various things.", - "c++": "17", - "libpq": "9.6", - "postgresql": "9.6", - "gcc": "8", - "clang": "11", - "msvc": "2019" -} diff --git a/ext/libpqxx-7.7.3/src/CMakeLists.txt b/ext/libpqxx-7.7.3/src/CMakeLists.txt deleted file mode 100644 index 1d697ab7c..000000000 --- a/ext/libpqxx-7.7.3/src/CMakeLists.txt +++ /dev/null @@ -1,91 +0,0 @@ -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() - -# When setting up the include paths, mention the binary tree's include -# directory *before* the source tree's include directory. If the source tree -# happens to contain autoconf-generated config headers, we should still prefer -# the ones in the binary tree. -macro(library_target_setup tgt) - target_include_directories(${tgt} - PUBLIC - $ - $ - $ - PRIVATE - ${PostgreSQL_INCLUDE_DIRS} - ) - target_link_libraries(${tgt} PRIVATE ${PostgreSQL_LIBRARIES}) - if(WIN32) - target_link_libraries(${tgt} PUBLIC wsock32 ws2_32) - endif() - install(TARGETS ${tgt} EXPORT libpqxx-targets - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) - - get_target_property(name ${tgt} NAME) - get_target_property(output_name ${tgt} OUTPUT_NAME) - if(NOT CMAKE_HOST_WIN32) - # Create library symlink - get_target_property(target_type ${tgt} TYPE) - if(target_type STREQUAL "SHARED_LIBRARY") - set(library_prefix ${CMAKE_SHARED_LIBRARY_PREFIX}) - set(library_suffix ${CMAKE_SHARED_LIBRARY_SUFFIX}) - elseif(target_type STREQUAL "STATIC_LIBRARY") - set(library_prefix ${CMAKE_STATIC_LIBRARY_PREFIX}) - set(library_suffix ${CMAKE_STATIC_LIBRARY_SUFFIX}) - endif() - - list(APPEND noop_command "${CMAKE_COMMAND}" "-E" "true") - list(APPEND create_symlink_command "${CMAKE_COMMAND}" "-E" "create_symlink" "${library_prefix}${output_name}${library_suffix}" "${library_prefix}${name}${library_suffix}") - # `add_custom_command()` does nothing if the `OUTPUT_NAME` and `NAME` - # properties are equal, otherwise it creates library symlink. - add_custom_command(TARGET ${tgt} POST_BUILD - COMMAND "$,${noop_command},${create_symlink_command}>" - VERBATIM - COMMAND_EXPAND_LISTS - ) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${library_prefix}${name}${library_suffix} - DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) - endif() -endmacro() - -file(GLOB CXX_SOURCES *.cxx) - -add_library(pqxx ${CXX_SOURCES}) - -get_target_property(pqxx_target_type pqxx TYPE) -if(pqxx_target_type STREQUAL "SHARED_LIBRARY") - target_compile_definitions(pqxx PUBLIC PQXX_SHARED) -endif() - -set_target_properties( - pqxx PROPERTIES - OUTPUT_NAME $,pqxx,pqxx-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}> -) -library_target_setup(pqxx) - -# install pkg-config file -set(prefix ${CMAKE_INSTALL_PREFIX}) -set(exec_prefix \${prefix}) -set(libdir "\${prefix}/${CMAKE_INSTALL_LIBDIR}") -set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") -set(VERSION ${PROJECT_VERSION}) -configure_file(${PROJECT_SOURCE_DIR}/libpqxx.pc.in ${PROJECT_BINARY_DIR}/libpqxx.pc) -install(FILES ${PROJECT_BINARY_DIR}/libpqxx.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig -) diff --git a/ext/libpqxx-7.7.3/src/Makefile.am b/ext/libpqxx-7.7.3/src/Makefile.am deleted file mode 100644 index dfd520941..000000000 --- a/ext/libpqxx-7.7.3/src/Makefile.am +++ /dev/null @@ -1,44 +0,0 @@ -lib_LTLIBRARIES = libpqxx.la -libpqxx_la_SOURCES = \ - array.cxx \ - binarystring.cxx \ - blob.cxx \ - connection.cxx \ - cursor.cxx \ - encodings.cxx \ - errorhandler.cxx \ - except.cxx \ - field.cxx \ - largeobject.cxx \ - notification.cxx \ - params.cxx \ - pipeline.cxx \ - result.cxx \ - robusttransaction.cxx \ - sql_cursor.cxx \ - strconv.cxx \ - stream_from.cxx \ - stream_to.cxx \ - subtransaction.cxx \ - time.cxx \ - transaction.cxx \ - transaction_base.cxx \ - row.cxx \ - util.cxx \ - version.cxx \ - wait.cxx - -libpqxx_version = -release $(PQXX_ABI) - -libpqxx_la_LDFLAGS = $(libpqxx_version) \ - -rpath $(libdir) \ - ${POSTGRES_LIB} - -AM_CPPFLAGS = \ - -I$(top_srcdir)/include -I$(top_builddir)/include ${POSTGRES_INCLUDE} - -# Override automatically generated list of default includes. It contains only -# unnecessary entries, and incorrectly mentions include/pqxx directly. -DEFAULT_INCLUDES= - -MAINTAINERCLEANFILES=Makefile.in diff --git a/ext/libpqxx-7.7.3/src/Makefile.in b/ext/libpqxx-7.7.3/src/Makefile.in deleted file mode 100644 index 3c0152727..000000000 --- a/ext/libpqxx-7.7.3/src/Makefile.in +++ /dev/null @@ -1,809 +0,0 @@ -# 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 = src -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__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)$(libdir)" -LTLIBRARIES = $(lib_LTLIBRARIES) -libpqxx_la_LIBADD = -am_libpqxx_la_OBJECTS = array.lo binarystring.lo blob.lo connection.lo \ - cursor.lo encodings.lo errorhandler.lo except.lo field.lo \ - largeobject.lo notification.lo params.lo pipeline.lo result.lo \ - robusttransaction.lo sql_cursor.lo strconv.lo stream_from.lo \ - stream_to.lo subtransaction.lo time.lo transaction.lo \ - transaction_base.lo row.lo util.lo version.lo wait.lo -libpqxx_la_OBJECTS = $(am_libpqxx_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -libpqxx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(libpqxx_la_LDFLAGS) $(LDFLAGS) -o $@ -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 = -depcomp = $(SHELL) $(top_srcdir)/config/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/array.Plo \ - ./$(DEPDIR)/binarystring.Plo ./$(DEPDIR)/blob.Plo \ - ./$(DEPDIR)/connection.Plo ./$(DEPDIR)/cursor.Plo \ - ./$(DEPDIR)/encodings.Plo ./$(DEPDIR)/errorhandler.Plo \ - ./$(DEPDIR)/except.Plo ./$(DEPDIR)/field.Plo \ - ./$(DEPDIR)/largeobject.Plo ./$(DEPDIR)/notification.Plo \ - ./$(DEPDIR)/params.Plo ./$(DEPDIR)/pipeline.Plo \ - ./$(DEPDIR)/result.Plo ./$(DEPDIR)/robusttransaction.Plo \ - ./$(DEPDIR)/row.Plo ./$(DEPDIR)/sql_cursor.Plo \ - ./$(DEPDIR)/strconv.Plo ./$(DEPDIR)/stream_from.Plo \ - ./$(DEPDIR)/stream_to.Plo ./$(DEPDIR)/subtransaction.Plo \ - ./$(DEPDIR)/time.Plo ./$(DEPDIR)/transaction.Plo \ - ./$(DEPDIR)/transaction_base.Plo ./$(DEPDIR)/util.Plo \ - ./$(DEPDIR)/version.Plo ./$(DEPDIR)/wait.Plo -am__mv = mv -f -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -AM_V_CXX = $(am__v_CXX_@AM_V@) -am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) -am__v_CXX_0 = @echo " CXX " $@; -am__v_CXX_1 = -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) -am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) -am__v_CXXLD_0 = @echo " CXXLD " $@; -am__v_CXXLD_1 = -SOURCES = $(libpqxx_la_SOURCES) -DIST_SOURCES = $(libpqxx_la_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) -# 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 $(top_srcdir)/config/depcomp \ - $(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@ -lib_LTLIBRARIES = libpqxx.la -libpqxx_la_SOURCES = \ - array.cxx \ - binarystring.cxx \ - blob.cxx \ - connection.cxx \ - cursor.cxx \ - encodings.cxx \ - errorhandler.cxx \ - except.cxx \ - field.cxx \ - largeobject.cxx \ - notification.cxx \ - params.cxx \ - pipeline.cxx \ - result.cxx \ - robusttransaction.cxx \ - sql_cursor.cxx \ - strconv.cxx \ - stream_from.cxx \ - stream_to.cxx \ - subtransaction.cxx \ - time.cxx \ - transaction.cxx \ - transaction_base.cxx \ - row.cxx \ - util.cxx \ - version.cxx \ - wait.cxx - -libpqxx_version = -release $(PQXX_ABI) -libpqxx_la_LDFLAGS = $(libpqxx_version) \ - -rpath $(libdir) \ - ${POSTGRES_LIB} - -AM_CPPFLAGS = \ - -I$(top_srcdir)/include -I$(top_builddir)/include ${POSTGRES_INCLUDE} - - -# Override automatically generated list of default includes. It contains only -# unnecessary entries, and incorrectly mentions include/pqxx directly. -DEFAULT_INCLUDES = -MAINTAINERCLEANFILES = Makefile.in -all: all-am - -.SUFFIXES: -.SUFFIXES: .cxx .lo .o .obj -$(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 src/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/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): - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libpqxx.la: $(libpqxx_la_OBJECTS) $(libpqxx_la_DEPENDENCIES) $(EXTRA_libpqxx_la_DEPENDENCIES) - $(AM_V_CXXLD)$(libpqxx_la_LINK) -rpath $(libdir) $(libpqxx_la_OBJECTS) $(libpqxx_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/binarystring.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blob.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cursor.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encodings.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errorhandler.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/except.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/field.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/largeobject.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/notification.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/params.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pipeline.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/result.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/robusttransaction.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/row.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sql_cursor.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strconv.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_from.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_to.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subtransaction.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transaction.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transaction_base.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wait.Plo@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.cxx.o: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< - -.cxx.obj: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.cxx.lo: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) -installdirs: - for dir in "$(DESTDIR)$(libdir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -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-libLTLIBRARIES clean-libtool \ - mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/array.Plo - -rm -f ./$(DEPDIR)/binarystring.Plo - -rm -f ./$(DEPDIR)/blob.Plo - -rm -f ./$(DEPDIR)/connection.Plo - -rm -f ./$(DEPDIR)/cursor.Plo - -rm -f ./$(DEPDIR)/encodings.Plo - -rm -f ./$(DEPDIR)/errorhandler.Plo - -rm -f ./$(DEPDIR)/except.Plo - -rm -f ./$(DEPDIR)/field.Plo - -rm -f ./$(DEPDIR)/largeobject.Plo - -rm -f ./$(DEPDIR)/notification.Plo - -rm -f ./$(DEPDIR)/params.Plo - -rm -f ./$(DEPDIR)/pipeline.Plo - -rm -f ./$(DEPDIR)/result.Plo - -rm -f ./$(DEPDIR)/robusttransaction.Plo - -rm -f ./$(DEPDIR)/row.Plo - -rm -f ./$(DEPDIR)/sql_cursor.Plo - -rm -f ./$(DEPDIR)/strconv.Plo - -rm -f ./$(DEPDIR)/stream_from.Plo - -rm -f ./$(DEPDIR)/stream_to.Plo - -rm -f ./$(DEPDIR)/subtransaction.Plo - -rm -f ./$(DEPDIR)/time.Plo - -rm -f ./$(DEPDIR)/transaction.Plo - -rm -f ./$(DEPDIR)/transaction_base.Plo - -rm -f ./$(DEPDIR)/util.Plo - -rm -f ./$(DEPDIR)/version.Plo - -rm -f ./$(DEPDIR)/wait.Plo - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-libLTLIBRARIES - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/array.Plo - -rm -f ./$(DEPDIR)/binarystring.Plo - -rm -f ./$(DEPDIR)/blob.Plo - -rm -f ./$(DEPDIR)/connection.Plo - -rm -f ./$(DEPDIR)/cursor.Plo - -rm -f ./$(DEPDIR)/encodings.Plo - -rm -f ./$(DEPDIR)/errorhandler.Plo - -rm -f ./$(DEPDIR)/except.Plo - -rm -f ./$(DEPDIR)/field.Plo - -rm -f ./$(DEPDIR)/largeobject.Plo - -rm -f ./$(DEPDIR)/notification.Plo - -rm -f ./$(DEPDIR)/params.Plo - -rm -f ./$(DEPDIR)/pipeline.Plo - -rm -f ./$(DEPDIR)/result.Plo - -rm -f ./$(DEPDIR)/robusttransaction.Plo - -rm -f ./$(DEPDIR)/row.Plo - -rm -f ./$(DEPDIR)/sql_cursor.Plo - -rm -f ./$(DEPDIR)/strconv.Plo - -rm -f ./$(DEPDIR)/stream_from.Plo - -rm -f ./$(DEPDIR)/stream_to.Plo - -rm -f ./$(DEPDIR)/subtransaction.Plo - -rm -f ./$(DEPDIR)/time.Plo - -rm -f ./$(DEPDIR)/transaction.Plo - -rm -f ./$(DEPDIR)/transaction_base.Plo - -rm -f ./$(DEPDIR)/util.Plo - -rm -f ./$(DEPDIR)/version.Plo - -rm -f ./$(DEPDIR)/wait.Plo - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-libLTLIBRARIES - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-libLTLIBRARIES install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES - -.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/src/array.cxx b/ext/libpqxx-7.7.3/src/array.cxx deleted file mode 100644 index e35aaddce..000000000 --- a/ext/libpqxx-7.7.3/src/array.cxx +++ /dev/null @@ -1,240 +0,0 @@ -/** Handling of SQL arrays. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include -#include -#include -#include - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/array.hxx" -#include "pqxx/except.hxx" -#include "pqxx/internal/array-composite.hxx" -#include "pqxx/internal/concat.hxx" -#include "pqxx/strconv.hxx" -#include "pqxx/util.hxx" - -#include "pqxx/internal/header-post.hxx" - - -namespace pqxx -{ -/// Scan to next glyph in the buffer. Assumes there is one. -[[nodiscard]] std::string::size_type -array_parser::scan_glyph(std::string::size_type pos) const -{ - return m_scan(std::data(m_input), std::size(m_input), pos); -} - - -/// Scan to next glyph in a substring. Assumes there is one. -std::string::size_type array_parser::scan_glyph( - std::string::size_type pos, std::string::size_type end) const -{ - return m_scan(std::data(m_input), end, pos); -} - - -/// Find the end of a single-quoted SQL string in an SQL array. -/** Call this while pointed at the opening quote. - * - * Returns the offset of the first character after the closing quote. - */ -std::string::size_type array_parser::scan_single_quoted_string() const -{ - assert(m_input[m_pos] == '\''); - auto const sz{std::size(m_input)}; - auto here{pqxx::internal::find_char<'\\', '\''>(m_scan, m_input, m_pos + 1)}; - while (here < sz) - { - char const c{m_input[here]}; - // Consume the slash or quote that we found. - ++here; - if (c == '\'') - { - // Single quote. - - // At end? - if (here >= sz) - return here; - - // SQL escapes single quotes by doubling them. Terrible idea, but it's - // what we have. Inspect the next character to find out whether this - // is the closing quote, or an escaped one inside the string. - if (m_input[here] != '\'') - return here; - // Check against embedded "'" byte in a multichar byte. If we do have a - // multibyte char, then we're still out of the string. - if (scan_glyph(here, sz) > here + 1) - PQXX_UNLIKELY return here; - - // We have a second quote. Consume it as well. - ++here; - } - else - { - assert(c == '\\'); - // Backslash escape. Skip ahead by one more character. - here = scan_glyph(here, sz); - } - // Race on to the next quote or backslash. - here = pqxx::internal::find_char<'\\', '\''>(m_scan, m_input, here); - } - throw argument_error{internal::concat("Null byte in SQL string: ", m_input)}; -} - - -/// Parse a single-quoted SQL string: un-quote it and un-escape it. -std::string -array_parser::parse_single_quoted_string(std::string::size_type end) const -{ - std::string output; - // Maximum output size is same as the input size, minus the opening and - // closing quotes. In the worst case, the real number could be half that. - // Usually it'll be a pretty close estimate. - output.reserve(end - m_pos - 2); - // XXX: find_char<'\\', '\''>(). - for (auto here = m_pos + 1, next = scan_glyph(here, end); here < end - 1; - here = next, next = scan_glyph(here, end)) - { - if (next - here == 1 and (m_input[here] == '\'' or m_input[here] == '\\')) - { - // Skip escape. (Performance-wise, we bet that these are relatively - // rare.) - PQXX_UNLIKELY - here = next; - next = scan_glyph(here, end); - } - - output.append(std::data(m_input) + here, std::data(m_input) + next); - } - - return output; -} - - -/// Find the end of a double-quoted SQL string in an SQL array. -std::string::size_type array_parser::scan_double_quoted_string() const -{ - return pqxx::internal::scan_double_quoted_string( - std::data(m_input), std::size(m_input), m_pos, m_scan); -} - - -/// Parse a double-quoted SQL string: un-quote it and un-escape it. -std::string -array_parser::parse_double_quoted_string(std::string::size_type end) const -{ - return pqxx::internal::parse_double_quoted_string( - std::data(m_input), end, m_pos, m_scan); -} - - -/// Find the end of an unquoted string in an SQL array. -/** Assumes UTF-8 or an ASCII-superset single-byte encoding. - */ -std::string::size_type array_parser::scan_unquoted_string() const -{ - return pqxx::internal::scan_unquoted_string<',', ';', '}'>( - std::data(m_input), std::size(m_input), m_pos, m_scan); -} - - -/// Parse an unquoted SQL string. -/** Here, the special unquoted value NULL means a null value, not a string - * that happens to spell "NULL". - */ -std::string -array_parser::parse_unquoted_string(std::string::size_type end) const -{ - return pqxx::internal::parse_unquoted_string( - std::data(m_input), end, m_pos, m_scan); -} - - -array_parser::array_parser( - std::string_view input, internal::encoding_group enc) : - m_input(input), m_scan(internal::get_glyph_scanner(enc)) -{} - - -std::pair array_parser::get_next() -{ - std::string value; - - if (m_pos >= std::size(m_input)) - return std::make_pair(juncture::done, value); - - juncture found; - std::string::size_type end; - - if (scan_glyph(m_pos) - m_pos > 1) - { - // Non-ASCII unquoted string. - end = scan_unquoted_string(); - value = parse_unquoted_string(end); - found = juncture::string_value; - } - else - switch (m_input[m_pos]) - { - case '\0': throw failure{"Unexpected zero byte in array."}; - case '{': - found = juncture::row_start; - end = scan_glyph(m_pos); - break; - case '}': - found = juncture::row_end; - end = scan_glyph(m_pos); - break; - case '\'': - found = juncture::string_value; - end = scan_single_quoted_string(); - value = parse_single_quoted_string(end); - break; - case '"': - found = juncture::string_value; - end = scan_double_quoted_string(); - value = parse_double_quoted_string(end); - break; - default: - end = scan_unquoted_string(); - value = parse_unquoted_string(end); - if (value == "NULL") - { - // In this one situation, as a special case, NULL means a null field, - // not a string that happens to spell "NULL". - value.clear(); - found = juncture::null_value; - } - else - { - // The normal case: we just parsed an unquoted string. The value is - // what we need. - PQXX_LIKELY - found = juncture::string_value; - } - break; - } - - // Skip a trailing field separator, if present. - if (end < std::size(m_input)) - { - auto next{scan_glyph(end)}; - if (next - end == 1 and (m_input[end] == ',' or m_input[end] == ';')) - PQXX_UNLIKELY - end = next; - } - - m_pos = end; - return std::make_pair(found, value); -} -} // namespace pqxx diff --git a/ext/libpqxx-7.7.3/src/binarystring.cxx b/ext/libpqxx-7.7.3/src/binarystring.cxx deleted file mode 100644 index 936437006..000000000 --- a/ext/libpqxx-7.7.3/src/binarystring.cxx +++ /dev/null @@ -1,108 +0,0 @@ -/** Implementation of bytea (binary string) conversions. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include -#include -#include -#include -#include -#include - -extern "C" -{ -#include -} - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/binarystring.hxx" -#include "pqxx/field.hxx" -#include "pqxx/strconv.hxx" - -#include "pqxx/internal/header-post.hxx" - - -namespace -{ -/// Copy data to a heap-allocated buffer. -std::shared_ptr - PQXX_COLD copy_to_buffer(void const *data, std::size_t len) -{ - void *const output{malloc(len + 1)}; - if (output == nullptr) - throw std::bad_alloc{}; - static_cast(output)[len] = '\0'; - memcpy(static_cast(output), data, len); - return {static_cast(output), std::free}; -} -} // namespace - - -PQXX_COLD pqxx::binarystring::binarystring(field const &F) -{ - unsigned char const *data{ - reinterpret_cast(F.c_str())}; - m_buf = - std::shared_ptr{PQunescapeBytea(data, &m_size), PQfreemem}; - if (m_buf == nullptr) - throw std::bad_alloc{}; -} - - -pqxx::binarystring::binarystring(std::string_view s) : - m_buf{copy_to_buffer(std::data(s), std::size(s))}, m_size{std::size(s)} -{} - - -pqxx::binarystring::binarystring(void const *binary_data, std::size_t len) : - m_buf{copy_to_buffer(binary_data, len)}, m_size{len} -{} - - -bool pqxx::binarystring::operator==(binarystring const &rhs) const noexcept -{ - return (std::size(rhs) == size()) and - (std::memcmp(data(), std::data(rhs), size()) == 0); -} - - -pqxx::binarystring & -pqxx::binarystring::operator=(binarystring const &rhs) = default; - -PQXX_COLD pqxx::binarystring::const_reference -pqxx::binarystring::at(size_type n) const -{ - if (n >= m_size) - { - if (m_size == 0) - throw std::out_of_range{"Accessing empty binarystring"}; - throw std::out_of_range{ - "binarystring index out of range: " + to_string(n) + - " (should be below " + to_string(m_size) + ")"}; - } - return data()[n]; -} - - -PQXX_COLD void pqxx::binarystring::swap(binarystring &rhs) -{ - m_buf.swap(rhs.m_buf); - - // This part very obviously can't go wrong, so do it last - auto const s{m_size}; - m_size = rhs.m_size; - rhs.m_size = s; -} - - -std::string pqxx::binarystring::str() const -{ - return std::string{get(), m_size}; -} diff --git a/ext/libpqxx-7.7.3/src/blob.cxx b/ext/libpqxx-7.7.3/src/blob.cxx deleted file mode 100644 index 1492d9107..000000000 --- a/ext/libpqxx-7.7.3/src/blob.cxx +++ /dev/null @@ -1,337 +0,0 @@ -#include "pqxx-source.hxx" - -#include -#include -#include - -#include - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/blob.hxx" -#include "pqxx/except.hxx" -#include "pqxx/internal/concat.hxx" -#include "pqxx/internal/gates/connection-largeobject.hxx" - -#include "pqxx/internal/header-post.hxx" - - -namespace -{ -constexpr int INV_WRITE{0x00020000}, INV_READ{0x00040000}; -} // namespace - - -pqxx::internal::pq::PGconn * -pqxx::blob::raw_conn(pqxx::connection *conn) noexcept -{ - pqxx::internal::gate::connection_largeobject gate{*conn}; - return gate.raw_connection(); -} - - -pqxx::internal::pq::PGconn * -pqxx::blob::raw_conn(pqxx::dbtransaction const &tx) noexcept -{ - return raw_conn(&tx.conn()); -} - - -std::string pqxx::blob::errmsg(connection const *conn) -{ - pqxx::internal::gate::const_connection_largeobject gate{*conn}; - return gate.error_message(); -} - - -pqxx::blob pqxx::blob::open_internal(dbtransaction &tx, oid id, int mode) -{ - auto &conn{tx.conn()}; - int fd{lo_open(raw_conn(&conn), id, mode)}; - if (fd == -1) - throw pqxx::failure{internal::concat( - "Could not open binary large object ", id, ": ", errmsg(&conn))}; - return {conn, fd}; -} - - -pqxx::oid pqxx::blob::create(dbtransaction &tx, oid id) -{ - oid actual_id{lo_create(raw_conn(tx), id)}; - if (actual_id == 0) - throw failure{internal::concat( - "Could not create binary large object: ", errmsg(&tx.conn()))}; - return actual_id; -} - - -void pqxx::blob::remove(dbtransaction &tx, oid id) -{ - if (id == 0) - throw usage_error{"Trying to delete binary large object without an ID."}; - if (lo_unlink(raw_conn(tx), id) == -1) - throw failure{internal::concat( - "Could not delete large object ", id, ": ", errmsg(&tx.conn()))}; -} - - -pqxx::blob pqxx::blob::open_r(dbtransaction &tx, oid id) -{ - return open_internal(tx, id, INV_READ); -} - - -pqxx::blob pqxx::blob::open_w(dbtransaction &tx, oid id) -{ - return open_internal(tx, id, INV_WRITE); -} - - -pqxx::blob pqxx::blob::open_rw(dbtransaction &tx, oid id) -{ - return open_internal(tx, id, INV_READ | INV_WRITE); -} - - -pqxx::blob::blob(blob &&other) : - m_conn{std::exchange(other.m_conn, nullptr)}, - m_fd{std::exchange(other.m_fd, -1)} -{} - - -pqxx::blob &pqxx::blob::operator=(blob &&other) -{ - if (m_fd != -1) - lo_close(raw_conn(m_conn), m_fd); - m_conn = std::exchange(other.m_conn, nullptr); - m_fd = std::exchange(other.m_fd, -1); - return *this; -} - - -pqxx::blob::~blob() -{ - try - { - close(); - } - catch (std::exception const &e) - { - if (m_conn != nullptr) - PQXX_UNLIKELY - m_conn->process_notice(internal::concat( - "Failure while closing binary large object: ", e.what(), "\n")); - } -} - - -void pqxx::blob::close() -{ - if (m_fd != -1) - { - lo_close(raw_conn(m_conn), m_fd); - m_fd = -1; - m_conn = nullptr; - } -} - - -std::size_t pqxx::blob::raw_read(std::byte buf[], std::size_t size) -{ - if (m_conn == nullptr) - throw usage_error{"Attempt to read from a closed binary large object."}; - if (size > chunk_limit) - throw range_error{ - "Reads from a binary large object must be less than 2 GB at once."}; - auto data{reinterpret_cast(buf)}; - int received{lo_read(raw_conn(m_conn), m_fd, data, size)}; - if (received < 0) - throw failure{ - internal::concat("Could not read from binary large object: ", errmsg())}; - return static_cast(received); -} - - -std::size_t -pqxx::blob::read(std::basic_string &buf, std::size_t size) -{ - buf.resize(size); - auto const received{raw_read(std::data(buf), size)}; - buf.resize(received); - return static_cast(received); -} - - -void pqxx::blob::raw_write(std::byte const buf[], std::size_t size) -{ - if (m_conn == nullptr) - throw usage_error{"Attempt to write to a closed binary large object."}; - if (size > chunk_limit) - throw range_error{ - "Writes to a binary large object must be less than 2 GB at once."}; - auto ptr{reinterpret_cast(buf)}; - int written{lo_write(raw_conn(m_conn), m_fd, ptr, size)}; - if (written < 0) - throw failure{ - internal::concat("Write to binary large object failed: ", errmsg())}; -} - - -void pqxx::blob::resize(std::int64_t size) -{ - if (m_conn == nullptr) - throw usage_error{"Attempt to resize a closed binary large object."}; - if (lo_truncate64(raw_conn(m_conn), m_fd, size) < 0) - throw failure{ - internal::concat("Binary large object truncation failed: ", errmsg())}; -} - - -std::int64_t pqxx::blob::tell() const -{ - if (m_conn == nullptr) - throw usage_error{"Attempt to tell() a closed binary large object."}; - std::int64_t offset{lo_tell64(raw_conn(m_conn), m_fd)}; - if (offset < 0) - throw failure{internal::concat( - "Error reading binary large object position: ", errmsg())}; - return offset; -} - - -std::int64_t pqxx::blob::seek(std::int64_t offset, int whence) -{ - if (m_conn == nullptr) - throw usage_error{"Attempt to seek() a closed binary large object."}; - std::int64_t seek_result{lo_lseek64(raw_conn(m_conn), m_fd, offset, whence)}; - if (seek_result < 0) - throw failure{internal::concat( - "Error during seek on binary large object: ", errmsg())}; - return seek_result; -} - - -std::int64_t pqxx::blob::seek_abs(std::int64_t offset) -{ - return this->seek(offset, SEEK_SET); -} - - -std::int64_t pqxx::blob::seek_rel(std::int64_t offset) -{ - return this->seek(offset, SEEK_CUR); -} - - -std::int64_t pqxx::blob::seek_end(std::int64_t offset) -{ - return this->seek(offset, SEEK_END); -} - - -pqxx::oid pqxx::blob::from_buf( - dbtransaction &tx, std::basic_string_view data, oid id) -{ - oid actual_id{create(tx, id)}; - try - { - open_w(tx, actual_id).write(data); - } - catch (std::exception const &) - { - try - { - remove(tx, id); - } - catch (std::exception const &e) - { - try - { - tx.conn().process_notice(internal::concat( - "Could not clean up partially created large object ", id, ": ", - e.what())); - } - catch (std::exception const &) - {} - } - throw; - } - return actual_id; -} - - -void pqxx::blob::append_from_buf( - dbtransaction &tx, std::basic_string_view data, oid id) -{ - if (std::size(data) > chunk_limit) - throw range_error{ - "Writes to a binary large object must be less than 2 GB at once."}; - blob b{open_w(tx, id)}; - b.seek_end(); - b.write(data); -} - - -void pqxx::blob::to_buf( - dbtransaction &tx, oid id, std::basic_string &buf, - std::size_t max_size) -{ - open_r(tx, id).read(buf, max_size); -} - - -std::size_t pqxx::blob::append_to_buf( - dbtransaction &tx, oid id, std::int64_t offset, - std::basic_string &buf, std::size_t append_max) -{ - if (append_max > chunk_limit) - throw range_error{ - "Reads from a binary large object must be less than 2 GB at once."}; - auto b{open_r(tx, id)}; - b.seek_abs(offset); - auto const org_size{std::size(buf)}; - buf.resize(org_size + append_max); - try - { - auto here{reinterpret_cast(std::data(buf) + org_size)}; - auto chunk{static_cast( - lo_read(b.raw_conn(b.m_conn), b.m_fd, here, append_max))}; - buf.resize(org_size + chunk); - return chunk; - } - catch (std::exception const &) - { - buf.resize(org_size); - throw; - } -} - - -pqxx::oid pqxx::blob::from_file(dbtransaction &tx, char const path[]) -{ - auto id{lo_import(raw_conn(tx), path)}; - if (id == 0) - throw failure{internal::concat( - "Could not import '", path, "' as a binary large object: ", errmsg(tx))}; - return id; -} - - -pqxx::oid pqxx::blob::from_file(dbtransaction &tx, char const path[], oid id) -{ - auto actual_id{lo_import_with_oid(raw_conn(tx), path, id)}; - if (actual_id == 0) - throw failure{internal::concat( - "Could not import '", path, "' as binary large object ", id, ": ", - errmsg(tx))}; - return actual_id; -} - - -void pqxx::blob::to_file(dbtransaction &tx, oid id, char const path[]) -{ - if (lo_export(raw_conn(tx), id, path) < 0) - throw failure{internal::concat( - "Could not export binary large object ", id, " to file '", path, - "': ", errmsg(tx))}; -} diff --git a/ext/libpqxx-7.7.3/src/connection.cxx b/ext/libpqxx-7.7.3/src/connection.cxx deleted file mode 100644 index bef8c79aa..000000000 --- a/ext/libpqxx-7.7.3/src/connection.cxx +++ /dev/null @@ -1,1274 +0,0 @@ -/** Implementation of the pqxx::connection class. - * - * pqxx::connection encapsulates a connection to a database. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// For fcntl(). -#if __has_include() -# include -#endif -#if __has_include() -# include -#endif - -// For ioctlsocket(). -#if defined(_WIN32) && __has_include() -# include -#endif - -extern "C" -{ -#include -} - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/binarystring.hxx" -#include "pqxx/internal/wait.hxx" -#include "pqxx/nontransaction.hxx" -#include "pqxx/notification.hxx" -#include "pqxx/pipeline.hxx" -#include "pqxx/result.hxx" -#include "pqxx/strconv.hxx" -#include "pqxx/transaction.hxx" - -#include "pqxx/internal/gates/errorhandler-connection.hxx" -#include "pqxx/internal/gates/result-connection.hxx" -#include "pqxx/internal/gates/result-creation.hxx" - -#include "pqxx/internal/header-post.hxx" - - -extern "C" -{ - // The PQnoticeProcessor that receives an error or warning from libpq and - // sends it to the appropriate connection for processing. - void pqxx_notice_processor(void *conn, char const *msg) noexcept - { - reinterpret_cast(conn)->process_notice(msg); - } - - - // There's no way in libpq to disable a connection's notice processor. So, - // set an inert one to get the same effect. - void inert_notice_processor(void *, char const *) noexcept {} -} // extern "C" - -using namespace std::literals; - -std::string PQXX_COLD -pqxx::encrypt_password(char const user[], char const password[]) -{ - std::unique_ptr> p{ - PQencryptPassword(password, user), PQfreemem}; - return {p.get()}; -} - - -pqxx::connection::connection(connection &&rhs) : - m_conn{rhs.m_conn}, m_unique_id{rhs.m_unique_id} -{ - rhs.check_movable(); - rhs.m_conn = nullptr; -} - - -pqxx::connection::connection( - connection::connect_mode, zview connection_string) : - m_conn{PQconnectStart(connection_string.c_str())} -{ - if (m_conn == nullptr) - throw std::bad_alloc{}; - if (status() == CONNECTION_BAD) - throw pqxx::broken_connection{PQerrorMessage(m_conn)}; -} - - -std::pair pqxx::connection::poll_connect() -{ - switch (PQconnectPoll(m_conn)) - { - case PGRES_POLLING_FAILED: - throw pqxx::broken_connection{PQerrorMessage(m_conn)}; - case PGRES_POLLING_READING: return std::make_pair(true, false); - case PGRES_POLLING_WRITING: return std::make_pair(false, true); - case PGRES_POLLING_OK: - if (not is_open()) - throw pqxx::broken_connection{PQerrorMessage(m_conn)}; - return std::make_pair(false, false); - case PGRES_POLLING_ACTIVE: - throw internal_error{ - "Nonblocking connection poll returned obsolete 'active' state."}; - default: - throw internal_error{ - "Nonblocking connection poll returned unknown value."}; - } -} - -void pqxx::connection::complete_init() -{ - if (m_conn == nullptr) - throw std::bad_alloc{}; - try - { - if (not is_open()) - throw broken_connection{PQerrorMessage(m_conn)}; - - set_up_state(); - } - catch (std::exception const &) - { - PQfinish(m_conn); - m_conn = nullptr; - throw; - } -} - - -void pqxx::connection::init(char const options[]) -{ - m_conn = PQconnectdb(options); - complete_init(); -} - - -void pqxx::connection::init(char const *params[], char const *values[]) -{ - m_conn = PQconnectdbParams(params, values, 0); - complete_init(); -} - - -void pqxx::connection::check_movable() const -{ - if (m_trans) - throw pqxx::usage_error{"Moving a connection with a transaction open."}; - if (not std::empty(m_errorhandlers)) - throw pqxx::usage_error{ - "Moving a connection with error handlers registered."}; - if (not std::empty(m_receivers)) - throw pqxx::usage_error{ - "Moving a connection with notification receivers registered."}; -} - - -void pqxx::connection::check_overwritable() const -{ - if (m_trans) - throw pqxx::usage_error{ - "Moving a connection onto one with a transaction open."}; - if (not std::empty(m_errorhandlers)) - throw pqxx::usage_error{ - "Moving a connection onto one with error handlers registered."}; - if (not std::empty(m_receivers)) - throw usage_error{ - "Moving a connection onto one " - "with notification receivers registered."}; -} - - -pqxx::connection &pqxx::connection::operator=(connection &&rhs) -{ - check_overwritable(); - rhs.check_movable(); - - close(); - - m_conn = std::exchange(rhs.m_conn, nullptr); - m_unique_id = rhs.m_unique_id; - - return *this; -} - - -pqxx::result pqxx::connection::make_result( - internal::pq::PGresult *pgr, std::shared_ptr const &query, - std::string_view desc) -{ - if (pgr == nullptr) - { - if (is_open()) - throw failure(err_msg()); - else - throw broken_connection{"Lost connection to the database server."}; - } - internal::encoding_group enc; - try - { - enc = internal::enc_group(encoding_id()); - } - catch (std::exception const &) - { - // Don't let the PGresult leak. - // TODO: Can we just accept a unique_ptr instead? - internal::clear_result(pgr); - throw; - } - auto const r{pqxx::internal::gate::result_creation::create(pgr, query, enc)}; - pqxx::internal::gate::result_creation{r}.check_status(desc); - return r; -} - - -int PQXX_COLD pqxx::connection::backendpid() const &noexcept -{ - return (m_conn == nullptr) ? 0 : PQbackendPID(m_conn); -} - - -namespace -{ -PQXX_PURE int socket_of(::pqxx::internal::pq::PGconn const *c) noexcept -{ - return (c == nullptr) ? -1 : PQsocket(c); -} -} // namespace - - -int pqxx::connection::sock() const &noexcept -{ - return socket_of(m_conn); -} - - -int PQXX_COLD pqxx::connection::protocol_version() const noexcept -{ - return (m_conn == nullptr) ? 0 : PQprotocolVersion(m_conn); -} - - -int PQXX_COLD pqxx::connection::server_version() const noexcept -{ - return PQserverVersion(m_conn); -} - - -void pqxx::connection::set_variable( - std::string_view var, std::string_view value) & -{ - exec(internal::concat("SET ", quote_name(var), "=", value)); -} - - -std::string pqxx::connection::get_variable(std::string_view var) -{ - return exec(internal::concat("SHOW ", quote_name(var))) - .at(0) - .at(0) - .as(std::string{}); -} - - -std::string pqxx::connection::get_var(std::string_view var) -{ - // (Variables can't be null, so far as I can make out.) - return exec(internal::concat("SHOW "sv, quote_name(var)))[0][0] - .as(); -} - - -/** Set up various parts of logical connection state that may need to be - * recovered because the physical connection to the database was lost and is - * being reset, or that may not have been initialized yet. - */ -void pqxx::connection::set_up_state() -{ - if (auto const proto_ver{protocol_version()}; proto_ver < 3) - { - if (proto_ver == 0) - throw broken_connection{"No connection."}; - else - throw feature_not_supported{ - "Unsupported frontend/backend protocol version; 3.0 is the minimum."}; - } - - if (server_version() <= 90000) - throw feature_not_supported{ - "Unsupported server version; 9.0 is the minimum."}; - - // The default notice processor in libpq writes to stderr. Ours does - // nothing. - // If the caller registers an error handler, this gets replaced with an - // error handler that walks down the connection's chain of handlers. We - // don't do that by default because there's a danger: libpq may call the - // notice processor via a result object, even after the connection has been - // destroyed and the handlers list no longer exists. - PQXX_LIKELY - PQsetNoticeProcessor(m_conn, inert_notice_processor, nullptr); -} - - -bool pqxx::connection::is_open() const noexcept -{ - return status() == CONNECTION_OK; -} - - -void pqxx::connection::process_notice_raw(char const msg[]) noexcept -{ - if ((msg == nullptr) or (*msg == '\0')) - return; - auto const rbegin = std::crbegin(m_errorhandlers), - rend = std::crend(m_errorhandlers); - for (auto i{rbegin}; (i != rend) and (**i)(msg); ++i) - ; -} - - -void pqxx::connection::process_notice(char const msg[]) noexcept -{ - if (msg == nullptr) - return; - zview const view{msg}; - if (std::empty(view)) - return; - else if (msg[std::size(view) - 1] == '\n') - process_notice_raw(msg); - else - // Newline is missing. Let the zview version of the code add it. - PQXX_UNLIKELY - process_notice(view); -} - - -void pqxx::connection::process_notice(zview msg) noexcept -{ - if (std::empty(msg)) - return; - else if (msg[std::size(msg) - 1] == '\n') - process_notice_raw(msg.c_str()); - else - try - { - // Add newline. - std::string buf; - buf.reserve(std::size(msg) + 1); - buf.assign(msg); - buf.push_back('\n'); - process_notice_raw(buf.c_str()); - } - catch (std::exception const &) - { - // If nothing else works, try writing the message without the newline. - PQXX_UNLIKELY - process_notice_raw(msg.c_str()); - } -} - - -void PQXX_COLD pqxx::connection::trace(FILE *out) noexcept -{ - if (m_conn) - { - if (out) - PQtrace(m_conn, out); - else - PQuntrace(m_conn); - } -} - - -void PQXX_COLD pqxx::connection::add_receiver(pqxx::notification_receiver *n) -{ - if (n == nullptr) - throw argument_error{"Null receiver registered"}; - - // Add to receiver list and attempt to start listening. - auto const p{m_receivers.find(n->channel())}; - auto const new_value{receiver_list::value_type{n->channel(), n}}; - - if (p == std::end(m_receivers)) - { - // Not listening on this event yet, start doing so. - auto const lq{std::make_shared( - internal::concat("LISTEN ", quote_name(n->channel())))}; - make_result(PQexec(m_conn, lq->c_str()), lq, *lq); - m_receivers.insert(new_value); - } - else - { - m_receivers.insert(p, new_value); - } -} - - -void PQXX_COLD -pqxx::connection::remove_receiver(pqxx::notification_receiver *T) noexcept -{ - if (T == nullptr) - return; - - try - { - auto needle{ - std::pair{T->channel(), T}}; - auto R{m_receivers.equal_range(needle.first)}; - auto i{find(R.first, R.second, needle)}; - - if (i == R.second) - { - PQXX_UNLIKELY - process_notice(internal::concat( - "Attempt to remove unknown receiver '", needle.first, "'")); - } - else - { - // Erase first; otherwise a notification for the same receiver may yet - // come in and wreak havoc. Thanks Dragan Milenkovic. - bool const gone{R.second == ++R.first}; - m_receivers.erase(i); - if (gone) - exec(internal::concat("UNLISTEN ", quote_name(needle.first)).c_str()); - } - } - catch (std::exception const &e) - { - PQXX_UNLIKELY - process_notice(e.what()); - } -} - - -bool pqxx::connection::consume_input() noexcept -{ - return PQconsumeInput(m_conn) != 0; -} - - -bool pqxx::connection::is_busy() const noexcept -{ - return PQisBusy(m_conn) != 0; -} - - -void PQXX_COLD pqxx::connection::cancel_query() -{ - using pointer = std::unique_ptr>; - pointer cancel{PQgetCancel(m_conn), PQfreeCancel}; - if (cancel == nullptr) - PQXX_UNLIKELY - throw std::bad_alloc{}; - - std::array errbuf; - auto const err{errbuf.data()}; - auto const c{ - PQcancel(cancel.get(), err, static_cast(std::size(errbuf)))}; - if (c == 0) - PQXX_UNLIKELY - throw pqxx::sql_error{std::string{err, std::size(errbuf)}, "[cancel]"}; -} - - -namespace -{ -// C++20: std::span? -/// Get error string for a given @c errno value. -template -char const *PQXX_COLD -error_string(int err_num, std::array &buffer) -{ - // Not entirely clear whether strerror_s will be in std or global namespace. - using namespace std; - -#if defined(PQXX_HAVE_STERROR_S) || defined(PQXX_HAVE_STRERROR_R) -# if defined(PQXX_HAVE_STRERROR_S) - auto const err_result{strerror_s(std::data(buffer), BYTES, err_num)}; -# else - auto const err_result{strerror_r(err_num, std::data(buffer), BYTES)}; -# endif - if constexpr (std::is_same_v, char *>) - { - // GNU version of strerror_r; returns the error string, which may or may - // not reside within buffer. - return err_result; - } - else - { - // Either strerror_s or POSIX strerror_r; returns an error code. - // Sorry for being lazy here: Not reporting error string for the case - // where we can't retrieve an error string. - if (err_result == 0) - return std::data(buffer); - else - return "Compound errors."; - } - -#else - // Fallback case, hopefully for no actual platforms out there. - pqxx::ignore_unused(err_num, buffer); - return "(No error information available.)"; -#endif -} -} // namespace - - -#if defined(_WIN32) || __has_include() -void pqxx::connection::set_blocking(bool block) & -{ - auto const fd{sock()}; -# if defined _WIN32 - unsigned long mode{not block}; - if (::ioctlsocket(fd, FIONBIO, &mode) != 0) - { - std::array errbuf; - char const *err{error_string(WSAGetLastError(), errbuf)}; - throw broken_connection{ - internal::concat("Could not set socket's blocking mode: ", err)}; - } -# else // _WIN32 - std::array errbuf; - auto flags{::fcntl(fd, F_GETFL, 0)}; - if (flags == -1) - { - char const *const err{error_string(errno, errbuf)}; - throw broken_connection{ - internal::concat("Could not get socket state: ", err)}; - } - if (block) - flags |= O_NONBLOCK; - else - flags &= ~O_NONBLOCK; - if (::fcntl(fd, F_SETFL, flags) == -1) - { - char const *const err{error_string(errno, errbuf)}; - throw broken_connection{ - internal::concat("Could not set socket's blocking mode: ", err)}; - } -# endif // _WIN32 -} -#endif // defined(_WIN32) || __has_include() - - -void PQXX_COLD -pqxx::connection::set_verbosity(error_verbosity verbosity) &noexcept -{ - PQsetErrorVerbosity(m_conn, static_cast(verbosity)); -} - - -namespace -{ -/// Unique pointer to PGnotify. -using notify_ptr = std::unique_ptr>; - - -/// Get one notification from a connection, or null. -notify_ptr get_notif(pqxx::internal::pq::PGconn *conn) -{ - return notify_ptr(PQnotifies(conn), PQfreemem); -} -} // namespace - - -int pqxx::connection::get_notifs() -{ - if (not consume_input()) - throw broken_connection{"Connection lost."}; - - // Even if somehow we receive notifications during our transaction, don't - // deliver them. - if (m_trans) - PQXX_UNLIKELY - return 0; - - int notifs = 0; - for (auto N{get_notif(m_conn)}; N.get(); N = get_notif(m_conn)) - { - notifs++; - - auto const Hit{m_receivers.equal_range(std::string{N->relname})}; - if (Hit.second != Hit.first) - { - std::string payload{N->extra}; - for (auto i{Hit.first}; i != Hit.second; ++i) try - { - (*i->second)(payload, N->be_pid); - } - catch (std::exception const &e) - { - try - { - process_notice(internal::concat( - "Exception in notification receiver '", i->first, - "': ", e.what(), "\n")); - } - catch (std::bad_alloc const &) - { - // Out of memory. Try to get the message out in a more robust way. - process_notice( - "Exception in notification receiver, " - "and also ran out of memory\n"); - } - catch (std::exception const &) - { - process_notice( - "Exception in notification receiver " - "(compounded by other error)\n"); - } - } - } - - N.reset(); - } - return notifs; -} - - -char const *PQXX_COLD pqxx::connection::dbname() const -{ - return PQdb(m_conn); -} - - -char const *PQXX_COLD pqxx::connection::username() const -{ - return PQuser(m_conn); -} - - -char const *PQXX_COLD pqxx::connection::hostname() const -{ - return PQhost(m_conn); -} - - -char const *PQXX_COLD pqxx::connection::port() const -{ - return PQport(m_conn); -} - - -char const *pqxx::connection::err_msg() const noexcept -{ - return (m_conn == nullptr) ? "No connection to database" : - PQerrorMessage(m_conn); -} - - -void PQXX_COLD pqxx::connection::register_errorhandler(errorhandler *handler) -{ - // Set notice processor on demand, i.e. only when the caller actually - // registers an error handler. - // We do this just to make it less likely that users fall into the trap - // where a result object may hold a notice processor derived from its parent - // connection which has already been destroyed. Our notice processor goes - // through the connection's list of error handlers. If the connection object - // has already been destroyed though, that list no longer exists. - // By setting the notice processor on demand, we absolve users who never - // register an error handler from ahving to care about this nasty subtlety. - if (std::empty(m_errorhandlers)) - PQsetNoticeProcessor(m_conn, pqxx_notice_processor, this); - m_errorhandlers.push_back(handler); -} - - -void PQXX_COLD -pqxx::connection::unregister_errorhandler(errorhandler *handler) noexcept -{ - // The errorhandler itself will take care of nulling its pointer to this - // connection. - m_errorhandlers.remove(handler); - if (std::empty(m_errorhandlers)) - PQsetNoticeProcessor(m_conn, inert_notice_processor, nullptr); -} - - -std::vector - PQXX_COLD pqxx::connection::get_errorhandlers() const -{ - return {std::begin(m_errorhandlers), std::end(m_errorhandlers)}; -} - - -pqxx::result -pqxx::connection::exec(std::string_view query, std::string_view desc) -{ - return exec(std::make_shared(query), desc); -} - - -pqxx::result pqxx::connection::exec( - std::shared_ptr query, std::string_view desc) -{ - auto const res{make_result(PQexec(m_conn, query->c_str()), query, desc)}; - get_notifs(); - return res; -} - - -std::string pqxx::connection::encrypt_password( - char const user[], char const password[], char const *algorithm) -{ -#if defined(PQXX_HAVE_PQENCRYPTPASSWORDCONN) - { - auto const buf{PQencryptPasswordConn(m_conn, password, user, algorithm)}; - std::unique_ptr> ptr{ - buf, [](char const *x) { PQfreemem(const_cast(x)); }}; - return std::string(ptr.get()); - } -#else - { - // No PQencryptPasswordConn. Fall back on the old PQencryptPassword... - // unless the caller selects a different algorithm. - if (algorithm != nullptr and std::strcmp(algorithm, "md5") != 0) - throw feature_not_supported{ - "Could not encrypt password: available libpq version does not support " - "algorithms other than md5."}; -# include "pqxx/internal/ignore-deprecated-pre.hxx" - return pqxx::encrypt_password(user, password); -# include "pqxx/internal/ignore-deprecated-post.hxx" - } -#endif // PQXX_HAVE_PQENCRYPTPASSWORDCONN -} - - -void pqxx::connection::prepare(char const name[], char const definition[]) & -{ - auto const q{std::make_shared( - pqxx::internal::concat("[PREPARE ", name, "]"))}; - - auto const r{ - make_result(PQprepare(m_conn, name, definition, 0, nullptr), q, *q)}; -} - - -void pqxx::connection::prepare(char const definition[]) & -{ - this->prepare("", definition); -} - - -void pqxx::connection::unprepare(std::string_view name) -{ - exec(internal::concat("DEALLOCATE ", quote_name(name))); -} - - -pqxx::result pqxx::connection::exec_prepared( - std::string_view statement, internal::c_params const &args) -{ - auto const q{std::make_shared(statement)}; - auto const pq_result{PQexecPrepared( - m_conn, q->c_str(), - check_cast(std::size(args.values), "exec_prepared"sv), - args.values.data(), args.lengths.data(), - reinterpret_cast(args.formats.data()), - static_cast(format::text))}; - auto const r{make_result(pq_result, q, statement)}; - get_notifs(); - return r; -} - - -void pqxx::connection::close() -{ - try - { - if (m_trans) - PQXX_UNLIKELY - process_notice(internal::concat( - "Closing connection while ", - internal::describe_object("transaction"sv, m_trans->name()), - " is still open.")); - - if (not std::empty(m_receivers)) - { - PQXX_UNLIKELY - process_notice("Closing connection with outstanding receivers."); - m_receivers.clear(); - } - - std::list old_handlers; - m_errorhandlers.swap(old_handlers); - auto const rbegin{std::crbegin(old_handlers)}, - rend{std::crend(old_handlers)}; - for (auto i{rbegin}; i != rend; ++i) - pqxx::internal::gate::errorhandler_connection{**i}.unregister(); - - PQfinish(m_conn); - m_conn = nullptr; - } - catch (std::exception const &) - { - m_conn = nullptr; - throw; - } -} - - -int pqxx::connection::status() const noexcept -{ - return PQstatus(m_conn); -} - - -namespace -{ -/// Return a name for t, if t is non-null and has a name; or empty string. -std::string_view get_name(pqxx::transaction_base const *t) -{ - return (t == nullptr) ? ""sv : t->name(); -} -} // namespace - - -void pqxx::connection::register_transaction(transaction_base *t) -{ - internal::check_unique_register( - m_trans, "transaction", get_name(m_trans), t, "transaction", get_name(t)); - m_trans = t; -} - - -void pqxx::connection::unregister_transaction(transaction_base *t) noexcept -{ - try - { - internal::check_unique_unregister( - m_trans, "transaction", get_name(m_trans), t, "transaction", - get_name(t)); - } - catch (std::exception const &e) - { - process_notice(e.what()); - } - m_trans = nullptr; -} - - -std::pair>, std::size_t> -pqxx::connection::read_copy_line() -{ - char *buf{nullptr}; - - // Allocate once, re-use across invocations. - static auto const q{std::make_shared("[END COPY]")}; - - auto const line_len{PQgetCopyData(m_conn, &buf, false)}; - switch (line_len) - { - case -2: // Error. - throw failure{ - internal::concat("Reading of table data failed: ", err_msg())}; - - case -1: // End of COPY. - make_result(PQgetResult(m_conn), q, *q); - return {}; - - case 0: // "Come back later." - throw internal_error{"table read inexplicably went asynchronous"}; - - default: // Success, got buffer size. - // Line size includes a trailing zero, which we ignore. - auto const text_len{static_cast(line_len) - 1}; - return std::make_pair( - std::unique_ptr>{buf, PQfreemem}, - text_len); - } -} - - -void pqxx::connection::write_copy_line(std::string_view line) -{ - static std::string const err_prefix{"Error writing to table: "}; - auto const size{check_cast( - internal::ssize(line), "Line in stream_to is too long to process."sv)}; - if (PQputCopyData(m_conn, line.data(), size) <= 0) - PQXX_UNLIKELY - throw failure{err_prefix + err_msg()}; - if (PQputCopyData(m_conn, "\n", 1) <= 0) - PQXX_UNLIKELY - throw failure{err_prefix + err_msg()}; -} - - -void pqxx::connection::end_copy_write() -{ - int res{PQputCopyEnd(m_conn, nullptr)}; - switch (res) - { - case -1: - throw failure{internal::concat("Write to table failed: ", err_msg())}; - case 0: throw internal_error{"table write is inexplicably asynchronous"}; - case 1: - // Normal termination. Retrieve result object. - break; - - default: - throw internal_error{ - internal::concat("unexpected result ", res, " from PQputCopyEnd()")}; - } - - static auto const q{std::make_shared("[END COPY]")}; - make_result(PQgetResult(m_conn), q, *q); -} - - -void pqxx::connection::start_exec(char const query[]) -{ - if (PQsendQuery(m_conn, query) == 0) - PQXX_UNLIKELY - throw failure{err_msg()}; -} - - -pqxx::internal::pq::PGresult *pqxx::connection::get_result() -{ - return PQgetResult(m_conn); -} - - -size_t pqxx::connection::esc_to_buf(std::string_view text, char *buf) const -{ - int err{0}; - auto const copied{ - PQescapeStringConn(m_conn, buf, text.data(), std::size(text), &err)}; - if (err) - PQXX_UNLIKELY - throw argument_error{err_msg()}; - return copied; -} - - -std::string pqxx::connection::esc(std::string_view text) const -{ - std::string buf; - buf.resize(2 * std::size(text) + 1); - auto const copied{esc_to_buf(text, buf.data())}; - buf.resize(copied); - return buf; -} - - -std::string PQXX_COLD -pqxx::connection::esc_raw(unsigned char const bin[], std::size_t len) const -{ - return pqxx::internal::esc_bin(binary_cast(bin, len)); -} - - -std::string -pqxx::connection::esc_raw(std::basic_string_view bin) const -{ - return pqxx::internal::esc_bin(bin); -} - - -std::string PQXX_COLD pqxx::connection::unesc_raw(char const text[]) const -{ - if (text[0] == '\\' and text[1] == 'x') - { - // Hex-escaped format. - std::string buf; - buf.resize(pqxx::internal::size_unesc_bin(std::strlen(text))); - pqxx::internal::unesc_bin( - std::string_view{text}, reinterpret_cast(buf.data())); - return buf; - } - else - { - // Legacy escape format. - // TODO: Remove legacy support. - std::size_t len; - auto bytes{const_cast( - reinterpret_cast(text))}; - std::unique_ptr> const - ptr{PQunescapeBytea(bytes, &len), PQfreemem}; - return std::string{ptr.get(), ptr.get() + len}; - } -} - - -std::string PQXX_COLD -pqxx::connection::quote_raw(unsigned char const bin[], std::size_t len) const -{ - return internal::concat("'", esc_raw(binary_cast(bin, len)), "'::bytea"); -} - - -std::string -pqxx::connection::quote_raw(std::basic_string_view bytes) const -{ - return internal::concat("'", esc_raw(bytes), "'::bytea"); -} - - -std::string PQXX_COLD pqxx::connection::quote(binarystring const &b) const -{ - return quote(b.bytes_view()); -} - - -std::string pqxx::connection::quote(std::basic_string_view b) const -{ - return internal::concat("'", esc_raw(b), "'::bytea"); -} - - -std::string pqxx::connection::quote_name(std::string_view identifier) const -{ - std::unique_ptr> buf{ - PQescapeIdentifier(m_conn, identifier.data(), std::size(identifier)), - PQfreemem}; - if (buf.get() == nullptr) - PQXX_UNLIKELY - throw failure{err_msg()}; - return std::string{buf.get()}; -} - - -std::string pqxx::connection::quote_table(std::string_view table_name) const -{ - return this->quote_name(table_name); -} - - -std::string pqxx::connection::quote_table(table_path path) const -{ - return separated_list( - ".", std::begin(path), std::end(path), - [this](auto name) { return this->quote_name(*name); }); -} - - -std::string -pqxx::connection::esc_like(std::string_view text, char escape_char) const -{ - std::string out; - out.reserve(std::size(text)); - internal::for_glyphs( - internal::enc_group(encoding_id()), - [&out, escape_char](char const *gbegin, char const *gend) { - if ((gend - gbegin == 1) and (*gbegin == '_' or *gbegin == '%')) - // We're not expecting a lot of wildcards in a string. Usually. - PQXX_UNLIKELY - out.push_back(escape_char); - - for (; gbegin != gend; ++gbegin) out.push_back(*gbegin); - }, - text.data(), std::size(text)); - return out; -} - - -int pqxx::connection::await_notification() -{ - int notifs = get_notifs(); - if (notifs == 0) - { - PQXX_LIKELY - internal::wait_fd(socket_of(m_conn), true, false, 10, 0); - notifs = get_notifs(); - } - return notifs; -} - - -int pqxx::connection::await_notification( - std::time_t seconds, long microseconds) -{ - int notifs = get_notifs(); - if (notifs == 0) - { - PQXX_LIKELY - internal::wait_fd( - socket_of(m_conn), true, false, - check_cast(seconds, "Seconds out of range."), - check_cast(microseconds, "Microseconds out of range.")); - return get_notifs(); - } - return notifs; -} - - -std::string pqxx::connection::adorn_name(std::string_view n) -{ - auto const id{to_string(++m_unique_id)}; - if (std::empty(n)) - return pqxx::internal::concat("x", id); - else - return pqxx::internal::concat(n, "_", id); -} - - -std::string pqxx::connection::get_client_encoding() const -{ - return internal::name_encoding(encoding_id()); -} - - -void PQXX_COLD pqxx::connection::set_client_encoding(char const encoding[]) & -{ - switch (auto const retval{PQsetClientEncoding(m_conn, encoding)}; retval) - { - case 0: - // OK. - PQXX_LIKELY - break; - case -1: - PQXX_UNLIKELY - if (is_open()) - throw failure{"Setting client encoding failed."}; - else - throw broken_connection{"Lost connection to the database server."}; - default: - PQXX_UNLIKELY - throw internal_error{internal::concat( - "Unexpected result from PQsetClientEncoding: ", retval)}; - } -} - - -int pqxx::connection::encoding_id() const -{ - int const enc{PQclientEncoding(m_conn)}; - if (enc == -1) - { - // PQclientEncoding does not query the database, but it does check for - // broken connections. And unfortunately, we check the encoding right - // *before* checking a query result for failure. So, we need to handle - // connection failure here and it will apply in lots of places. - // TODO: Make pqxx::result::result(...) do all the checking. - PQXX_UNLIKELY - if (is_open()) - throw failure{"Could not obtain client encoding."}; - else - throw broken_connection{"Lost connection to the database server."}; - } - PQXX_LIKELY - return enc; -} - - -pqxx::result pqxx::connection::exec_params( - std::string_view query, internal::c_params const &args) -{ - auto const q{std::make_shared(query)}; - auto const pq_result{PQexecParams( - m_conn, q->c_str(), - check_cast(std::size(args.values), "exec_params"sv), nullptr, - args.values.data(), args.lengths.data(), - reinterpret_cast(args.formats.data()), - static_cast(format::text))}; - auto const r{make_result(pq_result, q)}; - get_notifs(); - return r; -} - - -namespace -{ -/// Get the prevailing default value for a connection parameter. -char const *get_default(PQconninfoOption const &opt) noexcept -{ - if (opt.envvar == nullptr) - { - // There's no environment variable for this setting. The only default is - // the one that was compiled in. - return opt.compiled; - } - // As of C++11, std::getenv() uses thread-local storage, so it should be - // thread-safe. MSVC still warns about it though. -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4996) -#endif - char const *var{std::getenv(opt.envvar)}; -#if defined(_MSC_VER) -# pragma warning(pop) -#endif - if (var == nullptr) - { - // There's an environment variable for this setting, but it's not set. - return opt.compiled; - } - - // The environment variable is the prevailing default. - return var; -} -} // namespace - - -std::string pqxx::connection::connection_string() const -{ - if (m_conn == nullptr) - PQXX_UNLIKELY - throw usage_error{"Can't get connection string: connection is not open."}; - - std::unique_ptr< - PQconninfoOption, std::function> const params{ - PQconninfo(m_conn), PQconninfoFree}; - if (params.get() == nullptr) - PQXX_UNLIKELY - throw std::bad_alloc{}; - - std::string buf; - for (std::size_t i{0}; params.get()[i].keyword != nullptr; ++i) - { - auto const param{params.get()[i]}; - if (param.val != nullptr) - { - auto const default_val{get_default(param)}; - if ( - (default_val == nullptr) or (std::strcmp(param.val, default_val) != 0)) - { - if (not std::empty(buf)) - buf.push_back(' '); - buf += param.keyword; - buf.push_back('='); - buf += param.val; - } - } - } - return buf; -} - - -#if defined(_WIN32) || __has_include() -pqxx::connecting::connecting(zview connection_string) : - m_conn{connection::connect_nonblocking, connection_string} -{} -#endif // defined(_WIN32) || __has_include( - - -#if defined(_WIN32) || __has_include() -void pqxx::connecting::process() & -{ - auto const [reading, writing]{m_conn.poll_connect()}; - m_reading = reading; - m_writing = writing; -} -#endif // defined(_WIN32) || __has_include( - - -#if defined(_WIN32) || __has_include() -pqxx::connection pqxx::connecting::produce() && -{ - if (!done()) - throw usage_error{ - "Tried to produce a nonblocking connection before it was done."}; - m_conn.complete_init(); - return std::move(m_conn); -} -#endif // defined(_WIN32) || __has_include( diff --git a/ext/libpqxx-7.7.3/src/cursor.cxx b/ext/libpqxx-7.7.3/src/cursor.cxx deleted file mode 100644 index 28e8ba42f..000000000 --- a/ext/libpqxx-7.7.3/src/cursor.cxx +++ /dev/null @@ -1,339 +0,0 @@ -/** Implementation of libpqxx STL-style cursor classes. - * - * These classes wrap SQL cursors in STL-like interfaces. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/cursor.hxx" -#include "pqxx/internal/gates/icursor_iterator-icursorstream.hxx" -#include "pqxx/internal/gates/icursorstream-icursor_iterator.hxx" -#include "pqxx/result.hxx" -#include "pqxx/strconv.hxx" -#include "pqxx/transaction.hxx" - -#include "pqxx/internal/header-post.hxx" - - -pqxx::cursor_base::difference_type pqxx::cursor_base::all() noexcept -{ - // Implemented out-of-line so we don't fall afoul of Visual Studio defining - // min() and max() macros, which turn this expression into malformed code: - return std::numeric_limits::max() - 1; -} - - -pqxx::cursor_base::difference_type pqxx::cursor_base::backward_all() noexcept -{ - // Implemented out-of-line so we don't fall afoul of Visual Studio defining - // min() and max() macros, which turn this expression into malformed code: - return std::numeric_limits::min() + 1; -} - - -pqxx::cursor_base::cursor_base( - connection &context, std::string_view Name, bool embellish_name) : - m_name{embellish_name ? context.adorn_name(Name) : Name} -{} - - -pqxx::result::size_type -pqxx::internal::obtain_stateless_cursor_size(sql_cursor &cur) -{ - if (cur.endpos() == -1) - cur.move(cursor_base::all()); - return result::size_type(cur.endpos() - 1); -} - - -pqxx::result pqxx::internal::stateless_cursor_retrieve( - sql_cursor &cur, result::difference_type size, - result::difference_type begin_pos, result::difference_type end_pos) -{ - if (begin_pos < 0 or begin_pos > size) - throw range_error{"Starting position out of range"}; - - if (end_pos < -1) - end_pos = -1; - else if (end_pos > size) - end_pos = size; - - if (begin_pos == end_pos) - return cur.empty_result(); - - int const direction{((begin_pos < end_pos) ? 1 : -1)}; - cur.move((begin_pos - direction) - (cur.pos() - 1)); - return cur.fetch(end_pos - begin_pos); -} - - -pqxx::icursorstream::icursorstream( - transaction_base &context, std::string_view query, std::string_view basename, - difference_type sstride) : - m_cur{ - context, - query, - basename, - cursor_base::forward_only, - cursor_base::read_only, - cursor_base::owned, - false}, - m_stride{sstride}, - m_realpos{0}, - m_reqpos{0}, - m_iterators{nullptr}, - m_done{false} -{ - set_stride(sstride); -} - - -pqxx::icursorstream::icursorstream( - transaction_base &context, field const &cname, difference_type sstride, - cursor_base::ownership_policy op) : - m_cur{context, cname.c_str(), op}, - m_stride{sstride}, - m_realpos{0}, - m_reqpos{0}, - m_iterators{nullptr}, - m_done{false} -{ - set_stride(sstride); -} - - -void pqxx::icursorstream::set_stride(difference_type stride) & -{ - if (stride < 1) - throw argument_error{ - internal::concat("Attempt to set cursor stride to ", stride)}; - m_stride = stride; -} - - -pqxx::result pqxx::icursorstream::fetchblock() -{ - result const r{m_cur.fetch(m_stride)}; - m_realpos += std::size(r); - if (std::empty(r)) - m_done = true; - return r; -} - - -pqxx::icursorstream &pqxx::icursorstream::ignore(std::streamsize n) & -{ - auto offset{m_cur.move(difference_type(n))}; - m_realpos += offset; - if (offset < n) - m_done = true; - return *this; -} - - -pqxx::icursorstream::size_type pqxx::icursorstream::forward(size_type n) -{ - m_reqpos += difference_type(n) * m_stride; - return icursorstream::size_type(m_reqpos); -} - - -void pqxx::icursorstream::insert_iterator(icursor_iterator *i) noexcept -{ - pqxx::internal::gate::icursor_iterator_icursorstream{*i}.set_next( - m_iterators); - if (m_iterators != nullptr) - pqxx::internal::gate::icursor_iterator_icursorstream{*m_iterators} - .set_prev(i); - m_iterators = i; -} - - -void pqxx::icursorstream::remove_iterator(icursor_iterator *i) const noexcept -{ - pqxx::internal::gate::icursor_iterator_icursorstream igate{*i}; - if (i == m_iterators) - { - m_iterators = igate.get_next(); - if (m_iterators != nullptr) - pqxx::internal::gate::icursor_iterator_icursorstream{*m_iterators} - .set_prev(nullptr); - } - else - { - auto prev{igate.get_prev()}, next{igate.get_next()}; - pqxx::internal::gate::icursor_iterator_icursorstream{*prev}.set_next(next); - if (next != nullptr) - pqxx::internal::gate::icursor_iterator_icursorstream{*next}.set_prev( - prev); - } - igate.set_prev(nullptr); - igate.set_next(nullptr); -} - - -void pqxx::icursorstream::service_iterators(difference_type topos) -{ - if (topos < m_realpos) - return; - - using todolist = std::multimap; - todolist todo; - for (icursor_iterator *i{m_iterators}, *next; i != nullptr; i = next) - { - pqxx::internal::gate::icursor_iterator_icursorstream gate{*i}; - auto const ipos{gate.pos()}; - if (ipos >= m_realpos and ipos <= topos) - todo.insert(todolist::value_type(ipos, i)); - next = gate.get_next(); - } - auto const todo_end = std::end(todo); - for (auto i{std::begin(todo)}; i != todo_end;) - { - auto const readpos{i->first}; - if (readpos > m_realpos) - ignore(readpos - m_realpos); - result const r{fetchblock()}; - for (; i != todo_end and i->first == readpos; ++i) - pqxx::internal::gate::icursor_iterator_icursorstream{*i->second}.fill(r); - } -} - - -pqxx::icursor_iterator::icursor_iterator() noexcept : m_pos{0} {} - - -pqxx::icursor_iterator::icursor_iterator(istream_type &s) noexcept : - m_stream{&s}, - m_pos{difference_type( - pqxx::internal::gate::icursorstream_icursor_iterator(s).forward(0))} -{ - pqxx::internal::gate::icursorstream_icursor_iterator{*m_stream} - .insert_iterator(this); -} - - -pqxx::icursor_iterator::icursor_iterator(icursor_iterator const &rhs) noexcept - : - m_stream{rhs.m_stream}, m_here{rhs.m_here}, m_pos{rhs.m_pos} -{ - if (m_stream != nullptr) - pqxx::internal::gate::icursorstream_icursor_iterator{*m_stream} - .insert_iterator(this); -} - - -pqxx::icursor_iterator::~icursor_iterator() noexcept -{ - if (m_stream != nullptr) - pqxx::internal::gate::icursorstream_icursor_iterator{*m_stream} - .remove_iterator(this); -} - - -pqxx::icursor_iterator pqxx::icursor_iterator::operator++(int) -{ - icursor_iterator old{*this}; - m_pos = difference_type( - pqxx::internal::gate::icursorstream_icursor_iterator{*m_stream}.forward()); - m_here.clear(); - return old; -} - - -pqxx::icursor_iterator &pqxx::icursor_iterator::operator++() -{ - m_pos = difference_type( - pqxx::internal::gate::icursorstream_icursor_iterator{*m_stream}.forward()); - m_here.clear(); - return *this; -} - - -pqxx::icursor_iterator &pqxx::icursor_iterator::operator+=(difference_type n) -{ - if (n <= 0) - { - PQXX_UNLIKELY - if (n == 0) - return *this; - throw argument_error{"Advancing icursor_iterator by negative offset."}; - } - PQXX_LIKELY - m_pos = difference_type( - pqxx::internal::gate::icursorstream_icursor_iterator{*m_stream}.forward( - icursorstream::size_type(n))); - m_here.clear(); - return *this; -} - - -pqxx::icursor_iterator & -pqxx::icursor_iterator::operator=(icursor_iterator const &rhs) noexcept -{ - if (rhs.m_stream == m_stream) - { - PQXX_UNLIKELY - m_here = rhs.m_here; - m_pos = rhs.m_pos; - } - else - { - PQXX_LIKELY - if (m_stream != nullptr) - pqxx::internal::gate::icursorstream_icursor_iterator{*m_stream} - .remove_iterator(this); - m_here = rhs.m_here; - m_pos = rhs.m_pos; - m_stream = rhs.m_stream; - if (m_stream != nullptr) - pqxx::internal::gate::icursorstream_icursor_iterator{*m_stream} - .insert_iterator(this); - } - return *this; -} - - -bool pqxx::icursor_iterator::operator==(icursor_iterator const &rhs) const -{ - if (m_stream == rhs.m_stream) - return pos() == rhs.pos(); - if (m_stream != nullptr and rhs.m_stream != nullptr) - return false; - refresh(); - rhs.refresh(); - return std::empty(m_here) and std::empty(rhs.m_here); -} - - -bool pqxx::icursor_iterator::operator<(icursor_iterator const &rhs) const -{ - if (m_stream == rhs.m_stream) - return pos() < rhs.pos(); - refresh(); - rhs.refresh(); - return not std::empty(m_here); -} - - -void pqxx::icursor_iterator::refresh() const -{ - if (m_stream != nullptr) - pqxx::internal::gate::icursorstream_icursor_iterator{*m_stream} - .service_iterators(pos()); -} - - -void pqxx::icursor_iterator::fill(result const &r) -{ - m_here = r; -} diff --git a/ext/libpqxx-7.7.3/src/encodings.cxx b/ext/libpqxx-7.7.3/src/encodings.cxx deleted file mode 100644 index 99f038724..000000000 --- a/ext/libpqxx-7.7.3/src/encodings.cxx +++ /dev/null @@ -1,839 +0,0 @@ -/** Implementation of string encodings support - * - * 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. - */ -#include "pqxx-source.hxx" - -#include -#include -#include -#include - -extern "C" -{ -#include -} - - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/except.hxx" -#include "pqxx/internal/concat.hxx" -#include "pqxx/internal/encodings.hxx" -#include "pqxx/strconv.hxx" - -#include "pqxx/internal/header-post.hxx" - - -namespace pqxx -{ -PQXX_DECLARE_ENUM_CONVERSION(pqxx::internal::encoding_group); -} - - -// Internal helper functions -namespace -{ -/// Extract byte from buffer, return as unsigned char. -constexpr PQXX_PURE unsigned char -get_byte(char const buffer[], std::size_t offset) noexcept -{ - return static_cast(buffer[offset]); -} - - -[[noreturn]] void throw_for_encoding_error( - char const *encoding_name, char const buffer[], std::size_t start, - std::size_t count) -{ - std::stringstream s; - s << "Invalid byte sequence for encoding " << encoding_name << " at byte " - << start << ": " << std::hex << std::setw(2) << std::setfill('0'); - for (std::size_t i{0}; i < count; ++i) - { - s << "0x" << static_cast(get_byte(buffer, start + i)); - if (i + 1 < count) - s << " "; - } - throw pqxx::argument_error{s.str()}; -} - - -/// Does value lie between bottom and top, inclusive? -constexpr PQXX_PURE bool -between_inc(unsigned char value, unsigned bottom, unsigned top) -{ - return value >= bottom and value <= top; -} - - -/* -EUC-JP and EUC-JIS-2004 represent slightly different code points but iterate -the same: - * https://en.wikipedia.org/wiki/Extended_Unix_Code#EUC-JP - * http://x0213.org/codetable/index.en.html -*/ -PQXX_PURE std::size_t next_seq_for_euc_jplike( - char const buffer[], std::size_t buffer_len, std::size_t start, - char const encoding_name[]) -{ - if (start >= buffer_len) - return std::string::npos; - - auto const byte1{get_byte(buffer, start)}; - if (byte1 < 0x80) - return start + 1; - - if (start + 2 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error(encoding_name, buffer, start, 1); - - auto const byte2{get_byte(buffer, start + 1)}; - if (byte1 == 0x8e) - { - if (not between_inc(byte2, 0xa1, 0xfe)) - PQXX_UNLIKELY - throw_for_encoding_error(encoding_name, buffer, start, 2); - - return start + 2; - } - - if (between_inc(byte1, 0xa1, 0xfe)) - { - if (not between_inc(byte2, 0xa1, 0xfe)) - PQXX_UNLIKELY - throw_for_encoding_error(encoding_name, buffer, start, 2); - - return start + 2; - } - - if (byte1 == 0x8f and start + 3 <= buffer_len) - { - auto const byte3{get_byte(buffer, start + 2)}; - if ( - not between_inc(byte2, 0xa1, 0xfe) or not between_inc(byte3, 0xa1, 0xfe)) - PQXX_UNLIKELY - throw_for_encoding_error(encoding_name, buffer, start, 3); - - return start + 3; - } - - throw_for_encoding_error(encoding_name, buffer, start, 1); -} - -/* -As far as I can tell, for the purposes of iterating the only difference between -SJIS and SJIS-2004 is increased range in the first byte of two-byte sequences -(0xEF increased to 0xFC). Officially, that is; apparently the version of SJIS -used by Postgres has the same range as SJIS-2004. They both have increased -range over the documented versions, not having the even/odd restriction for the -first byte in 2-byte sequences. -*/ -// https://en.wikipedia.org/wiki/Shift_JIS#Shift_JIS_byte_map -// http://x0213.org/codetable/index.en.html -PQXX_PURE std::size_t next_seq_for_sjislike( - char const buffer[], std::size_t buffer_len, std::size_t start, - char const *encoding_name) -{ - if (start >= buffer_len) - return std::string::npos; - - auto const byte1{get_byte(buffer, start)}; - if (byte1 < 0x80 or between_inc(byte1, 0xa1, 0xdf)) - return start + 1; - - if ( - not between_inc(byte1, 0x81, 0x9f) and not between_inc(byte1, 0xe0, 0xfc)) - PQXX_UNLIKELY - throw_for_encoding_error(encoding_name, buffer, start, 1); - - if (start + 2 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error(encoding_name, buffer, start, buffer_len - start); - - auto const byte2{get_byte(buffer, start + 1)}; - if (byte2 == 0x7f) - PQXX_UNLIKELY - throw_for_encoding_error(encoding_name, buffer, start, 2); - - if (between_inc(byte2, 0x40, 0x9e) or between_inc(byte2, 0x9f, 0xfc)) - return start + 2; - - PQXX_UNLIKELY - throw_for_encoding_error(encoding_name, buffer, start, 2); -} -} // namespace - - -// Implement template specializations first. -namespace pqxx::internal -{ -template struct glyph_scanner -{ - PQXX_PURE static std::size_t - call(char const buffer[], std::size_t buffer_len, std::size_t start); -}; - -template<> struct glyph_scanner -{ - static PQXX_PURE constexpr std::size_t - call(char const /* buffer */[], std::size_t buffer_len, std::size_t start) - { - if (start >= buffer_len) - return std::string::npos; - else - return start + 1; - } -}; - -// https://en.wikipedia.org/wiki/Big5#Organization -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - if (start >= buffer_len) - return std::string::npos; - - auto const byte1{get_byte(buffer, start)}; - if (byte1 < 0x80) - return start + 1; - - if (not between_inc(byte1, 0x81, 0xfe) or (start + 2 > buffer_len)) - PQXX_UNLIKELY - throw_for_encoding_error("BIG5", buffer, start, 1); - - auto const byte2{get_byte(buffer, start + 1)}; - if ( - not between_inc(byte2, 0x40, 0x7e) and not between_inc(byte2, 0xa1, 0xfe)) - PQXX_UNLIKELY - throw_for_encoding_error("BIG5", buffer, start, 2); - - return start + 2; -} - -/* -The PostgreSQL documentation claims that the EUC_* encodings are 1-3 bytes -each, but other documents explain that the EUC sets can contain 1-(2,3,4) bytes -depending on the specific extension: - EUC_CN : 1-2 - EUC_JP : 1-3 - EUC_JIS_2004: 1-2 - EUC_KR : 1-2 - EUC_TW : 1-4 -*/ - -// https://en.wikipedia.org/wiki/GB_2312#EUC-CN -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - if (start >= buffer_len) - return std::string::npos; - - auto const byte1{get_byte(buffer, start)}; - if (byte1 < 0x80) - return start + 1; - - if (not between_inc(byte1, 0xa1, 0xf7) or start + 2 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("EUC_CN", buffer, start, 1); - - auto const byte2{get_byte(buffer, start + 1)}; - if (not between_inc(byte2, 0xa1, 0xfe)) - PQXX_UNLIKELY - throw_for_encoding_error("EUC_CN", buffer, start, 2); - - return start + 2; -} - - -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - return next_seq_for_euc_jplike(buffer, buffer_len, start, "EUC_JP"); -} - - -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - return next_seq_for_euc_jplike(buffer, buffer_len, start, "EUC_JIS_2004"); -} - - -// https://en.wikipedia.org/wiki/Extended_Unix_Code#EUC-KR -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - if (start >= buffer_len) - return std::string::npos; - - auto const byte1{get_byte(buffer, start)}; - if (byte1 < 0x80) - return start + 1; - - if (not between_inc(byte1, 0xa1, 0xfe) or start + 2 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("EUC_KR", buffer, start, 1); - - auto const byte2{get_byte(buffer, start + 1)}; - if (not between_inc(byte2, 0xa1, 0xfe)) - PQXX_UNLIKELY - throw_for_encoding_error("EUC_KR", buffer, start, 1); - - return start + 2; -} - -// https://en.wikipedia.org/wiki/Extended_Unix_Code#EUC-TW -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - if (start >= buffer_len) - PQXX_UNLIKELY - return std::string::npos; - - auto const byte1{get_byte(buffer, start)}; - if (byte1 < 0x80) - return start + 1; - - if (start + 2 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("EUC_KR", buffer, start, 1); - - auto const byte2{get_byte(buffer, start + 1)}; - if (between_inc(byte1, 0xa1, 0xfe)) - { - if (not between_inc(byte2, 0xa1, 0xfe)) - PQXX_UNLIKELY - throw_for_encoding_error("EUC_KR", buffer, start, 2); - - return start + 2; - } - - if (byte1 != 0x8e or start + 4 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("EUC_KR", buffer, start, 1); - - if ( - between_inc(byte2, 0xa1, 0xb0) and - between_inc(get_byte(buffer, start + 2), 0xa1, 0xfe) and - between_inc(get_byte(buffer, start + 3), 0xa1, 0xfe)) - return start + 4; - - PQXX_UNLIKELY - throw_for_encoding_error("EUC_KR", buffer, start, 4); -} - -// https://en.wikipedia.org/wiki/GB_18030#Mapping -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - if (start >= buffer_len) - return std::string::npos; - - auto const byte1{get_byte(buffer, start)}; - if (byte1 < 0x80) - return start + 1; - if (byte1 == 0x80) - throw_for_encoding_error("GB18030", buffer, start, buffer_len - start); - - if (start + 2 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("GB18030", buffer, start, buffer_len - start); - - auto const byte2{get_byte(buffer, start + 1)}; - if (between_inc(byte2, 0x40, 0xfe)) - { - if (byte2 == 0x7f) - PQXX_UNLIKELY - throw_for_encoding_error("GB18030", buffer, start, 2); - - return start + 2; - } - - if (start + 4 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("GB18030", buffer, start, buffer_len - start); - - if ( - between_inc(byte2, 0x30, 0x39) and - between_inc(get_byte(buffer, start + 2), 0x81, 0xfe) and - between_inc(get_byte(buffer, start + 3), 0x30, 0x39)) - return start + 4; - - PQXX_UNLIKELY - throw_for_encoding_error("GB18030", buffer, start, 4); -} - -// https://en.wikipedia.org/wiki/GBK_(character_encoding)#Encoding -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - if (start >= buffer_len) - return std::string::npos; - - auto const byte1{get_byte(buffer, start)}; - if (byte1 < 0x80) - return start + 1; - - if (start + 2 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("GBK", buffer, start, 1); - - auto const byte2{get_byte(buffer, start + 1)}; - if ( - (between_inc(byte1, 0xa1, 0xa9) and between_inc(byte2, 0xa1, 0xfe)) or - (between_inc(byte1, 0xb0, 0xf7) and between_inc(byte2, 0xa1, 0xfe)) or - (between_inc(byte1, 0x81, 0xa0) and between_inc(byte2, 0x40, 0xfe) and - byte2 != 0x7f) or - (between_inc(byte1, 0xaa, 0xfe) and between_inc(byte2, 0x40, 0xa0) and - byte2 != 0x7f) or - (between_inc(byte1, 0xa8, 0xa9) and between_inc(byte2, 0x40, 0xa0) and - byte2 != 0x7f) or - (between_inc(byte1, 0xaa, 0xaf) and between_inc(byte2, 0xa1, 0xfe)) or - (between_inc(byte1, 0xf8, 0xfe) and between_inc(byte2, 0xa1, 0xfe)) or - (between_inc(byte1, 0xa1, 0xa7) and between_inc(byte2, 0x40, 0xa0) and - byte2 != 0x7f)) - return start + 2; - - PQXX_UNLIKELY - throw_for_encoding_error("GBK", buffer, start, 2); -} - -/* -The PostgreSQL documentation claims that the JOHAB encoding is 1-3 bytes, but -"CJKV Information Processing" describes it (actually just the Hangul portion) -as "three five-bit segments" that reside inside 16 bits (2 bytes). - -CJKV Information Processing by Ken Lunde, pg. 269: - - https://bit.ly/2BEOu5V -*/ -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - if (start >= buffer_len) - return std::string::npos; - - auto const byte1{get_byte(buffer, start)}; - if (byte1 < 0x80) - return start + 1; - - if (start + 2 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("JOHAB", buffer, start, 1); - - auto const byte2{get_byte(buffer, start)}; - if ( - (between_inc(byte1, 0x84, 0xd3) and - (between_inc(byte2, 0x41, 0x7e) or between_inc(byte2, 0x81, 0xfe))) or - ((between_inc(byte1, 0xd8, 0xde) or between_inc(byte1, 0xe0, 0xf9)) and - (between_inc(byte2, 0x31, 0x7e) or between_inc(byte2, 0x91, 0xfe)))) - return start + 2; - - PQXX_UNLIKELY - throw_for_encoding_error("JOHAB", buffer, start, 2); -} - -/* -PostgreSQL's MULE_INTERNAL is the emacs rather than Xemacs implementation; -see the server/mb/pg_wchar.h PostgreSQL header file. -This is implemented according to the description in said header file, but I was -unable to get it to successfully iterate a MULE-encoded test CSV generated -using PostgreSQL 9.2.23. Use this at your own risk. -*/ -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - if (start >= buffer_len) - return std::string::npos; - - auto const byte1{get_byte(buffer, start)}; - if (byte1 < 0x80) - return start + 1; - - if (start + 2 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("MULE_INTERNAL", buffer, start, 1); - - auto const byte2{get_byte(buffer, start + 1)}; - if (between_inc(byte1, 0x81, 0x8d) and byte2 >= 0xa0) - return start + 2; - - if (start + 3 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("MULE_INTERNAL", buffer, start, 2); - - if ( - ((byte1 == 0x9a and between_inc(byte2, 0xa0, 0xdf)) or - (byte1 == 0x9b and between_inc(byte2, 0xe0, 0xef)) or - (between_inc(byte1, 0x90, 0x99) and byte2 >= 0xa0)) and - (byte2 >= 0xa0)) - return start + 3; - - if (start + 4 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("MULE_INTERNAL", buffer, start, 3); - - if ( - ((byte1 == 0x9c and between_inc(byte2, 0xf0, 0xf4)) or - (byte1 == 0x9d and between_inc(byte2, 0xf5, 0xfe))) and - get_byte(buffer, start + 2) >= 0xa0 and - get_byte(buffer, start + 4) >= 0xa0) - return start + 4; - - PQXX_UNLIKELY - throw_for_encoding_error("MULE_INTERNAL", buffer, start, 4); -} - -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - return next_seq_for_sjislike(buffer, buffer_len, start, "SJIS"); -} - -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - return next_seq_for_sjislike(buffer, buffer_len, start, "SHIFT_JIS_2004"); -} - -// https://en.wikipedia.org/wiki/Unified_Hangul_Code -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - if (start >= buffer_len) - return std::string::npos; - - auto const byte1{get_byte(buffer, start)}; - if (byte1 < 0x80) - return start + 1; - - if (start + 2 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("UHC", buffer, start, buffer_len - start); - - auto const byte2{get_byte(buffer, start + 1)}; - if (between_inc(byte1, 0x80, 0xc6)) - { - if ( - between_inc(byte2, 0x41, 0x5a) or between_inc(byte2, 0x61, 0x7a) or - between_inc(byte2, 0x80, 0xfe)) - return start + 2; - - PQXX_UNLIKELY - throw_for_encoding_error("UHC", buffer, start, 2); - } - - if (between_inc(byte1, 0xa1, 0xfe)) - { - if (not between_inc(byte2, 0xa1, 0xfe)) - PQXX_UNLIKELY - throw_for_encoding_error("UHC", buffer, start, 2); - - return start + 2; - } - - throw_for_encoding_error("UHC", buffer, start, 1); -} - -// https://en.wikipedia.org/wiki/UTF-8#Description -template<> -PQXX_PURE std::size_t glyph_scanner::call( - char const buffer[], std::size_t buffer_len, std::size_t start) -{ - if (start >= buffer_len) - return std::string::npos; - - auto const byte1{get_byte(buffer, start)}; - if (byte1 < 0x80) - return start + 1; - - if (start + 2 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("UTF8", buffer, start, buffer_len - start); - - auto const byte2{get_byte(buffer, start + 1)}; - if (between_inc(byte1, 0xc0, 0xdf)) - { - if (not between_inc(byte2, 0x80, 0xbf)) - PQXX_UNLIKELY - throw_for_encoding_error("UTF8", buffer, start, 2); - - return start + 2; - } - - if (start + 3 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("UTF8", buffer, start, buffer_len - start); - - auto const byte3{get_byte(buffer, start + 2)}; - if (between_inc(byte1, 0xe0, 0xef)) - { - if (between_inc(byte2, 0x80, 0xbf) and between_inc(byte3, 0x80, 0xbf)) - return start + 3; - - PQXX_UNLIKELY - throw_for_encoding_error("UTF8", buffer, start, 3); - } - - if (start + 4 > buffer_len) - PQXX_UNLIKELY - throw_for_encoding_error("UTF8", buffer, start, buffer_len - start); - - if (between_inc(byte1, 0xf0, 0xf7)) - { - if ( - between_inc(byte2, 0x80, 0xbf) and between_inc(byte3, 0x80, 0xbf) and - between_inc(get_byte(buffer, start + 3), 0x80, 0xbf)) - return start + 4; - - PQXX_UNLIKELY - throw_for_encoding_error("UTF8", buffer, start, 4); - } - - PQXX_UNLIKELY - throw_for_encoding_error("UTF8", buffer, start, 1); -} - - -PQXX_PURE char const *name_encoding(int encoding_id) -{ - return pg_encoding_to_char(encoding_id); -} - - -encoding_group enc_group(int libpq_enc_id) -{ - return enc_group(name_encoding(libpq_enc_id)); -} - - -encoding_group enc_group(std::string_view encoding_name) -{ - struct mapping - { - std::string_view const name; - encoding_group const group; - constexpr mapping(std::string_view n, encoding_group g) : name{n}, group{g} - {} - constexpr bool operator<(mapping const &rhs) const - { - return name < rhs.name; - } - }; - - // C++20: Once compilers are ready, go full constexpr, leave to the compiler. - auto const sz{std::size(encoding_name)}; - if (sz > 0u) - switch (encoding_name[0]) - { - case 'B': - if (encoding_name == "BIG5"sv) - return encoding_group::BIG5; - PQXX_UNLIKELY - break; - case 'E': - // C++20: Use string_view::starts_with(). - if ((sz >= 6u) and (encoding_name.substr(0, 4) == "EUC_"sv)) - { - auto const subtype{encoding_name.substr(4)}; - static constexpr std::array subtypes{ - mapping{"CN"sv, encoding_group::EUC_CN}, - mapping{"JIS_2004"sv, encoding_group::EUC_JIS_2004}, - mapping{"JP"sv, encoding_group::EUC_JP}, - mapping{"KR"sv, encoding_group::EUC_KR}, - mapping{"TW"sv, encoding_group::EUC_TW}, - }; - for (auto const &m : subtypes) - if (m.name == subtype) - return m.group; - } - PQXX_UNLIKELY - break; - case 'G': - if (encoding_name == "GB18030"sv) - return encoding_group::GB18030; - else if (encoding_name == "GBK"sv) - return encoding_group::GBK; - PQXX_UNLIKELY - break; - case 'I': - // We know iso-8859-X, where 5 <= X < 9. They're all monobyte encodings. - if ((sz == 10) and (encoding_name.substr(0, 9) == "ISO_8859_"sv)) - { - char const subtype{encoding_name[9]}; - if (('5' <= subtype) and (subtype < '9')) - return encoding_group::MONOBYTE; - } - PQXX_UNLIKELY - break; - case 'J': - if (encoding_name == "JOHAB"sv) - return encoding_group::JOHAB; - PQXX_UNLIKELY - break; - case 'K': - if ((encoding_name == "KOI8R"sv) or (encoding_name == "KOI8U"sv)) - return encoding_group::MONOBYTE; - PQXX_UNLIKELY - break; - case 'L': - // We know LATIN1 through LATIN10. - if (encoding_name.substr(0, 5) == "LATIN"sv) - { - auto const subtype{encoding_name.substr(5)}; - if (subtype.size() == 1) - { - char const n{subtype[0]}; - if (('1' <= n) and (n <= '9')) - return encoding_group::MONOBYTE; - } - else if (subtype == "10"sv) - { - return encoding_group::MONOBYTE; - } - } - PQXX_UNLIKELY - break; - case 'M': - if (encoding_name == "MULE_INTERNAL"sv) - return encoding_group::MULE_INTERNAL; - PQXX_UNLIKELY - break; - case 'S': - if (encoding_name == "SHIFT_JIS_2004"sv) - return encoding_group::SHIFT_JIS_2004; - else if (encoding_name == "SJIS"sv) - return encoding_group::SJIS; - else if (encoding_name == "SQL_ASCII"sv) - return encoding_group::MONOBYTE; - PQXX_UNLIKELY - break; - case 'U': - if (encoding_name == "UHC"sv) - return encoding_group::UHC; - else if (encoding_name == "UTF8"sv) - return encoding_group::UTF8; - PQXX_UNLIKELY - break; - case 'W': - if (encoding_name.substr(0, 3) == "WIN"sv) - { - auto const subtype{encoding_name.substr(3)}; - static constexpr std::array subtypes{ - "866"sv, "874"sv, "1250"sv, "1251"sv, "1252"sv, "1253"sv, - "1254"sv, "1255"sv, "1256"sv, "1257"sv, "1258"sv, - }; - for (auto const n : subtypes) - if (n == subtype) - return encoding_group::MONOBYTE; - } - PQXX_UNLIKELY - break; - default: PQXX_UNLIKELY break; - } - PQXX_UNLIKELY - throw std::invalid_argument{ - internal::concat("Unrecognized encoding: '", encoding_name, "'.")}; -} - - -/// Look up instantiation @c T::call at runtime. -/** Here, "T" is a struct template with a static member function "call", whose - * type is "F". - * - * The return value is a pointer to the "call" member function for the - * instantiation of T for encoding group enc. - */ -template class T, typename F> -constexpr inline F *for_encoding(encoding_group enc) -{ -#define CASE_GROUP(ENC) \ - case encoding_group::ENC: return T::call - - switch (enc) - { - PQXX_LIKELY CASE_GROUP(MONOBYTE); - CASE_GROUP(BIG5); - CASE_GROUP(EUC_CN); - CASE_GROUP(EUC_JP); - CASE_GROUP(EUC_JIS_2004); - CASE_GROUP(EUC_KR); - CASE_GROUP(EUC_TW); - CASE_GROUP(GB18030); - CASE_GROUP(GBK); - CASE_GROUP(JOHAB); - CASE_GROUP(MULE_INTERNAL); - CASE_GROUP(SJIS); - CASE_GROUP(SHIFT_JIS_2004); - CASE_GROUP(UHC); - PQXX_LIKELY CASE_GROUP(UTF8); - } - PQXX_UNLIKELY - throw pqxx::usage_error{ - internal::concat("Unsupported encoding group code ", enc, ".")}; - -#undef CASE_GROUP -} - - -PQXX_PURE glyph_scanner_func *get_glyph_scanner(encoding_group enc) -{ - return for_encoding(enc); -} - - -template struct char_finder -{ - constexpr static PQXX_PURE std::size_t - call(std::string_view haystack, char needle, std::size_t start) - { - auto const buffer{std::data(haystack)}; - auto const size{std::size(haystack)}; - for (auto here{start}; here + 1 <= size; - here = glyph_scanner::call(buffer, size, here)) - { - if (haystack[here] == needle) - return here; - } - return std::string::npos; - } -}; - - -template struct string_finder -{ - PQXX_PURE constexpr static PQXX_PURE std::size_t - call(std::string_view haystack, std::string_view needle, std::size_t start) - { - auto const buffer{std::data(haystack)}; - auto const size{std::size(haystack)}; - auto const needle_size{std::size(needle)}; - for (auto here{start}; here + needle_size <= size; - here = glyph_scanner::call(buffer, size, here)) - { - if (std::memcmp(buffer + here, std::data(needle), needle_size) == 0) - return here; - } - return std::string::npos; - } -}; - -#undef DISPATCH_ENCODING_OPERATION -} // namespace pqxx::internal diff --git a/ext/libpqxx-7.7.3/src/errorhandler.cxx b/ext/libpqxx-7.7.3/src/errorhandler.cxx deleted file mode 100644 index de120ff3d..000000000 --- a/ext/libpqxx-7.7.3/src/errorhandler.cxx +++ /dev/null @@ -1,43 +0,0 @@ -/** Implementation of pqxx::errorhandler and helpers. - * - * pqxx::errorhandler allows programs to receive errors and warnings. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/connection.hxx" -#include "pqxx/errorhandler.hxx" -#include "pqxx/internal/gates/connection-errorhandler.hxx" - -#include "pqxx/internal/header-post.hxx" - - -pqxx::errorhandler::errorhandler(connection &conn) : m_home{&conn} -{ - pqxx::internal::gate::connection_errorhandler{*m_home}.register_errorhandler( - this); -} - - -pqxx::errorhandler::~errorhandler() -{ - unregister(); -} - - -void pqxx::errorhandler::unregister() noexcept -{ - if (m_home != nullptr) - { - pqxx::internal::gate::connection_errorhandler connection_gate{*m_home}; - m_home = nullptr; - connection_gate.unregister_errorhandler(this); - } -} diff --git a/ext/libpqxx-7.7.3/src/except.cxx b/ext/libpqxx-7.7.3/src/except.cxx deleted file mode 100644 index 4974e8ac0..000000000 --- a/ext/libpqxx-7.7.3/src/except.cxx +++ /dev/null @@ -1,126 +0,0 @@ -/** Implementation of libpqxx exception classes. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/except.hxx" -#include "pqxx/internal/concat.hxx" - -#include "pqxx/internal/header-post.hxx" - -pqxx::failure::failure(std::string const &whatarg) : - std::runtime_error{whatarg} -{} - - -pqxx::broken_connection::broken_connection() : - failure{"Connection to database failed."} -{} - - -pqxx::broken_connection::broken_connection(std::string const &whatarg) : - failure{whatarg} -{} - - -pqxx::variable_set_to_null::variable_set_to_null() : - variable_set_to_null{ - "Attempt to set a variable to null. This is not allowed."} -{} - - -pqxx::variable_set_to_null::variable_set_to_null(std::string const &whatarg) : - failure{whatarg} -{} - - -pqxx::sql_error::sql_error( - std::string const &whatarg, std::string const &Q, char const sqlstate[]) : - failure{whatarg}, m_query{Q}, m_sqlstate{sqlstate ? sqlstate : ""} -{} - - -pqxx::sql_error::~sql_error() noexcept = default; - - -PQXX_PURE std::string const &pqxx::sql_error::query() const noexcept -{ - return m_query; -} - - -PQXX_PURE std::string const &pqxx::sql_error::sqlstate() const noexcept -{ - return m_sqlstate; -} - - -pqxx::in_doubt_error::in_doubt_error(std::string const &whatarg) : - failure{whatarg} -{} - - -pqxx::transaction_rollback::transaction_rollback( - std::string const &whatarg, std::string const &q, char const sqlstate[]) : - sql_error{whatarg, q, sqlstate} -{} - - -pqxx::serialization_failure::serialization_failure( - std::string const &whatarg, std::string const &q, char const sqlstate[]) : - transaction_rollback{whatarg, q, sqlstate} -{} - - -pqxx::statement_completion_unknown::statement_completion_unknown( - std::string const &whatarg, std::string const &q, char const sqlstate[]) : - transaction_rollback{whatarg, q, sqlstate} -{} - - -pqxx::deadlock_detected::deadlock_detected( - std::string const &whatarg, std::string const &q, char const sqlstate[]) : - transaction_rollback{whatarg, q, sqlstate} -{} - - -pqxx::internal_error::internal_error(std::string const &whatarg) : - std::logic_error{internal::concat("libpqxx internal error: ", whatarg)} -{} - - -pqxx::usage_error::usage_error(std::string const &whatarg) : - std::logic_error{whatarg} -{} - - -pqxx::argument_error::argument_error(std::string const &whatarg) : - invalid_argument{whatarg} -{} - - -pqxx::conversion_error::conversion_error(std::string const &whatarg) : - domain_error{whatarg} -{} - - -pqxx::conversion_overrun::conversion_overrun(std::string const &whatarg) : - conversion_error{whatarg} -{} - - -pqxx::range_error::range_error(std::string const &whatarg) : - out_of_range{whatarg} -{} - - -pqxx::blob_already_exists::blob_already_exists(std::string const &whatarg) : - failure{whatarg} -{} diff --git a/ext/libpqxx-7.7.3/src/field.cxx b/ext/libpqxx-7.7.3/src/field.cxx deleted file mode 100644 index f5026ced2..000000000 --- a/ext/libpqxx-7.7.3/src/field.cxx +++ /dev/null @@ -1,80 +0,0 @@ -/** Implementation of the pqxx::field class. - * - * pqxx::field refers to a field in a query result. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/field.hxx" -#include "pqxx/internal/libpq-forward.hxx" -#include "pqxx/result.hxx" -#include "pqxx/row.hxx" - -#include "pqxx/internal/header-post.hxx" - - -pqxx::field::field(pqxx::row const &r, pqxx::row::size_type c) noexcept : - m_col{c}, m_home{r.m_result}, m_row{r.m_index} -{} - - -bool PQXX_COLD pqxx::field::operator==(field const &rhs) const -{ - if (is_null() and rhs.is_null()) - return true; - if (is_null() != rhs.is_null()) - return false; - auto const s{size()}; - return (s == std::size(rhs)) and (std::memcmp(c_str(), rhs.c_str(), s) == 0); -} - - -char const *pqxx::field::name() const & -{ - return home().column_name(col()); -} - - -pqxx::oid pqxx::field::type() const -{ - return home().column_type(col()); -} - - -pqxx::oid pqxx::field::table() const -{ - return home().column_table(col()); -} - - -pqxx::row::size_type pqxx::field::table_column() const -{ - return home().table_column(col()); -} - - -char const *pqxx::field::c_str() const & -{ - return home().get_value(idx(), col()); -} - - -bool pqxx::field::is_null() const noexcept -{ - return home().get_is_null(idx(), col()); -} - - -pqxx::field::size_type pqxx::field::size() const noexcept -{ - return home().get_length(idx(), col()); -} diff --git a/ext/libpqxx-7.7.3/src/largeobject.cxx b/ext/libpqxx-7.7.3/src/largeobject.cxx deleted file mode 100644 index c57de3c73..000000000 --- a/ext/libpqxx-7.7.3/src/largeobject.cxx +++ /dev/null @@ -1,322 +0,0 @@ -/** Implementation of the Large Objects interface. - * - * Allows direct access to large objects, as well as though I/O streams. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include -#include -#include - -extern "C" -{ -#include -} - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/connection.hxx" -#include "pqxx/internal/concat.hxx" -#include "pqxx/internal/gates/connection-largeobject.hxx" -#include "pqxx/largeobject.hxx" - -#include "pqxx/internal/header-post.hxx" - -#include "pqxx/internal/ignore-deprecated-pre.hxx" - -namespace -{ -constexpr inline int PQXX_COLD std_mode_to_pq_mode(std::ios::openmode mode) -{ - /// Mode bits, copied from libpq-fs.h so that we no longer need that header. - constexpr int INV_WRITE{0x00020000}, INV_READ{0x00040000}; - - return ((mode & std::ios::in) ? INV_READ : 0) | - ((mode & std::ios::out) ? INV_WRITE : 0); -} - - -constexpr int PQXX_COLD std_dir_to_pq_dir(std::ios::seekdir dir) noexcept -{ - if constexpr ( - static_cast(std::ios::beg) == int(SEEK_SET) and - static_cast(std::ios::cur) == int(SEEK_CUR) and - static_cast(std::ios::end) == int(SEEK_END)) - { - // Easy optimisation: they're the same constants. This is actually the - // case for the gcc I'm using. - return dir; - } - else - switch (dir) - { - case std::ios::beg: return SEEK_SET; break; - case std::ios::cur: return SEEK_CUR; break; - case std::ios::end: return SEEK_END; break; - - // Shouldn't happen, but may silence compiler warning. - default: return dir; break; - } -} -} // namespace - - -PQXX_COLD pqxx::largeobject::largeobject(dbtransaction &t) -{ - // (Mode is ignored as of postgres 8.1.) - m_id = lo_creat(raw_connection(t), 0); - if (m_id == oid_none) - { - int const err{errno}; - if (err == ENOMEM) - throw std::bad_alloc{}; - throw failure{internal::concat( - "Could not create large object: ", reason(t.conn(), err))}; - } -} - - -PQXX_COLD -pqxx::largeobject::largeobject(dbtransaction &t, std::string_view file) -{ - m_id = lo_import(raw_connection(t), std::data(file)); - if (m_id == oid_none) - { - int const err{errno}; - if (err == ENOMEM) - throw std::bad_alloc{}; - throw failure{internal::concat( - "Could not import file '", file, - "' to large object: ", reason(t.conn(), err))}; - } -} - - -PQXX_COLD pqxx::largeobject::largeobject(largeobjectaccess const &o) noexcept : - m_id{o.id()} -{} - - -void PQXX_COLD -pqxx::largeobject::to_file(dbtransaction &t, std::string_view file) const -{ - if (id() == oid_none) - throw usage_error{"No object selected."}; - if (lo_export(raw_connection(t), id(), std::data(file)) == -1) - { - int const err{errno}; - if (err == ENOMEM) - throw std::bad_alloc{}; - throw failure{internal::concat( - "Could not export large object ", m_id, " to file '", file, - "': ", reason(t.conn(), err))}; - } -} - - -void PQXX_COLD pqxx::largeobject::remove(dbtransaction &t) const -{ - if (id() == oid_none) - throw usage_error{"No object selected."}; - if (lo_unlink(raw_connection(t), id()) == -1) - { - int const err{errno}; - if (err == ENOMEM) - throw std::bad_alloc{}; - throw failure{internal::concat( - "Could not delete large object ", m_id, ": ", reason(t.conn(), err))}; - } -} - - -pqxx::internal::pq::PGconn *PQXX_COLD -pqxx::largeobject::raw_connection(dbtransaction const &t) -{ - return pqxx::internal::gate::connection_largeobject{t.conn()} - .raw_connection(); -} - - -std::string PQXX_COLD -pqxx::largeobject::reason(connection const &c, int err) const -{ - if (err == ENOMEM) - return "Out of memory"; - return pqxx::internal::gate::const_connection_largeobject{c}.error_message(); -} - - -PQXX_COLD -pqxx::largeobjectaccess::largeobjectaccess(dbtransaction &t, openmode mode) : - largeobject{t}, m_trans{t} -{ - open(mode); -} - - -PQXX_COLD pqxx::largeobjectaccess::largeobjectaccess( - dbtransaction &t, oid o, openmode mode) : - largeobject{o}, m_trans{t} -{ - open(mode); -} - - -PQXX_COLD pqxx::largeobjectaccess::largeobjectaccess( - dbtransaction &t, largeobject o, openmode mode) : - largeobject{o}, m_trans{t} -{ - open(mode); -} - - -PQXX_COLD pqxx::largeobjectaccess::largeobjectaccess( - dbtransaction &t, std::string_view file, openmode mode) : - largeobject{t, file}, m_trans{t} -{ - open(mode); -} - - -pqxx::largeobjectaccess::size_type PQXX_COLD -pqxx::largeobjectaccess::seek(size_type dest, seekdir dir) -{ - auto const res{cseek(dest, dir)}; - if (res == -1) - { - int const err{errno}; - if (err == ENOMEM) - throw std::bad_alloc{}; - if (id() == oid_none) - throw usage_error{"No object selected."}; - throw failure{ - internal::concat("Error seeking in large object: ", reason(err))}; - } - - return res; -} - - -pqxx::largeobjectaccess::pos_type PQXX_COLD -pqxx::largeobjectaccess::cseek(off_type dest, seekdir dir) noexcept -{ - return lo_lseek64(raw_connection(), m_fd, dest, std_dir_to_pq_dir(dir)); -} - - -pqxx::largeobjectaccess::pos_type PQXX_COLD -pqxx::largeobjectaccess::cwrite(char const buf[], std::size_t len) noexcept -{ - return std::max(lo_write(raw_connection(), m_fd, buf, len), -1); -} - - -pqxx::largeobjectaccess::pos_type PQXX_COLD -pqxx::largeobjectaccess::cread(char buf[], std::size_t len) noexcept -{ - return std::max(lo_read(raw_connection(), m_fd, buf, len), -1); -} - - -pqxx::largeobjectaccess::pos_type PQXX_COLD -pqxx::largeobjectaccess::ctell() const noexcept -{ - return lo_tell64(raw_connection(), m_fd); -} - - -void PQXX_COLD -pqxx::largeobjectaccess::write(char const buf[], std::size_t len) -{ - if (id() == oid_none) - throw usage_error{"No object selected."}; - if (auto const bytes{cwrite(buf, len)}; internal::cmp_less(bytes, len)) - { - int const err{errno}; - if (err == ENOMEM) - throw std::bad_alloc{}; - if (bytes < 0) - throw failure{internal::concat( - "Error writing to large object #", id(), ": ", reason(err))}; - if (bytes == 0) - throw failure{internal::concat( - "Could not write to large object #", id(), ": ", reason(err))}; - - throw failure{internal::concat( - "Wanted to write ", len, " bytes to large object #", id(), - "; could only write ", bytes, ".")}; - } -} - - -pqxx::largeobjectaccess::size_type PQXX_COLD -pqxx::largeobjectaccess::read(char buf[], std::size_t len) -{ - if (id() == oid_none) - throw usage_error{"No object selected."}; - auto const bytes{cread(buf, len)}; - if (bytes < 0) - { - int const err{errno}; - if (err == ENOMEM) - throw std::bad_alloc{}; - throw failure{internal::concat( - "Error reading from large object #", id(), ": ", reason(err))}; - } - return bytes; -} - - -void PQXX_COLD pqxx::largeobjectaccess::open(openmode mode) -{ - if (id() == oid_none) - throw usage_error{"No object selected."}; - m_fd = lo_open(raw_connection(), id(), std_mode_to_pq_mode(mode)); - if (m_fd < 0) - { - int const err{errno}; - if (err == ENOMEM) - throw std::bad_alloc{}; - throw failure{internal::concat( - "Could not open large object ", id(), ": ", reason(err))}; - } -} - - -void PQXX_COLD pqxx::largeobjectaccess::close() noexcept -{ - if (m_fd >= 0) - lo_close(raw_connection(), m_fd); -} - - -pqxx::largeobjectaccess::size_type PQXX_COLD -pqxx::largeobjectaccess::tell() const -{ - auto const res{ctell()}; - if (res == -1) - throw failure{reason(errno)}; - return res; -} - - -std::string PQXX_COLD pqxx::largeobjectaccess::reason(int err) const -{ - if (m_fd == -1) - return "No object opened."; - return largeobject::reason(m_trans.conn(), err); -} - - -void PQXX_COLD pqxx::largeobjectaccess::process_notice(zview s) noexcept -{ - m_trans.process_notice(s); -} - -#include "pqxx/internal/ignore-deprecated-post.hxx" diff --git a/ext/libpqxx-7.7.3/src/notification.cxx b/ext/libpqxx-7.7.3/src/notification.cxx deleted file mode 100644 index eb8d5e1a1..000000000 --- a/ext/libpqxx-7.7.3/src/notification.cxx +++ /dev/null @@ -1,35 +0,0 @@ -/** Implementation of the pqxx::notification_receiever class. - * - * pqxx::notification_receiver processes notifications. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/internal/gates/connection-notification_receiver.hxx" -#include "pqxx/notification.hxx" - -#include "pqxx/internal/header-post.hxx" - - -pqxx::notification_receiver::notification_receiver( - connection &c, std::string_view channel) : - m_conn{c}, m_channel{channel} -{ - pqxx::internal::gate::connection_notification_receiver{c}.add_receiver(this); -} - - -pqxx::notification_receiver::~notification_receiver() -{ - pqxx::internal::gate::connection_notification_receiver{this->conn()} - .remove_receiver(this); -} diff --git a/ext/libpqxx-7.7.3/src/params.cxx b/ext/libpqxx-7.7.3/src/params.cxx deleted file mode 100644 index bd3fc108c..000000000 --- a/ext/libpqxx-7.7.3/src/params.cxx +++ /dev/null @@ -1,122 +0,0 @@ -/* Implementations related to prepared and parameterised 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. - */ -#include "pqxx-source.hxx" - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/params.hxx" - -#include "pqxx/internal/header-post.hxx" - - -void pqxx::internal::c_params::reserve(std::size_t n) & -{ - values.reserve(n); - lengths.reserve(n); - formats.reserve(n); -} - - -void pqxx::params::reserve(std::size_t n) & -{ - m_params.reserve(n); -} - - -void pqxx::params::append() & -{ - m_params.emplace_back(nullptr); -} - - -void pqxx::params::append(zview value) & -{ - m_params.emplace_back(value); -} - - -void pqxx::params::append(std::string const &value) & -{ - m_params.emplace_back(value); -} - - -void pqxx::params::append(std::string &&value) & -{ - m_params.emplace_back(std::move(value)); -} - - -void pqxx::params::append(params const &value) & -{ - this->reserve(std::size(value.m_params) + std::size(this->m_params)); - for (auto const ¶m : value.m_params) m_params.emplace_back(param); -} - - -void pqxx::params::append(std::basic_string_view value) & -{ - m_params.emplace_back(value); -} - - -void pqxx::params::append(std::basic_string const &value) & -{ - m_params.emplace_back(value); -} - - -void pqxx::params::append(std::basic_string &&value) & -{ - m_params.emplace_back(std::move(value)); -} - - -void PQXX_COLD pqxx::params::append(binarystring const &value) & -{ - m_params.push_back(entry{value.bytes_view()}); -} - - -void pqxx::params::append(params &&value) & -{ - this->reserve(std::size(value.m_params) + std::size(this->m_params)); - for (auto const ¶m : value.m_params) - m_params.emplace_back(std::move(param)); - value.m_params.clear(); -} - - -pqxx::internal::c_params pqxx::params::make_c_params() const -{ - pqxx::internal::c_params p; - p.reserve(std::size(m_params)); - for (auto const ¶m : m_params) - std::visit( - [&p](auto const &value) { - using T = strip_t; - - if constexpr (std::is_same_v) - { - p.values.push_back(nullptr); - p.lengths.push_back(0); - } - else - { - p.values.push_back(reinterpret_cast(std::data(value))); - p.lengths.push_back( - check_cast(internal::ssize(value), s_overflow)); - } - - p.formats.push_back(param_format(value)); - }, - param); - - return p; -} diff --git a/ext/libpqxx-7.7.3/src/pipeline.cxx b/ext/libpqxx-7.7.3/src/pipeline.cxx deleted file mode 100644 index 854b1a70e..000000000 --- a/ext/libpqxx-7.7.3/src/pipeline.cxx +++ /dev/null @@ -1,448 +0,0 @@ -/** Implementation of the pqxx::pipeline class. - * - * Throughput-optimized query interface. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/dbtransaction.hxx" -#include "pqxx/internal/concat.hxx" -#include "pqxx/internal/gates/connection-pipeline.hxx" -#include "pqxx/internal/gates/result-creation.hxx" -#include "pqxx/internal/gates/result-pipeline.hxx" -#include "pqxx/pipeline.hxx" -#include "pqxx/separated_list.hxx" - -#include "pqxx/internal/header-post.hxx" - - -namespace -{ -std::string const theSeparator{"; "}; -std::string const theDummyValue{"1"}; -std::string const theDummyQuery{"SELECT " + theDummyValue + theSeparator}; -} // namespace - - -void pqxx::pipeline::init() -{ - m_encoding = internal::enc_group(m_trans.conn().encoding_id()); - m_issuedrange = make_pair(std::end(m_queries), std::end(m_queries)); - attach(); -} - - -pqxx::pipeline::~pipeline() noexcept -{ - try - { - cancel(); - } - catch (std::exception const &) - {} - detach(); -} - - -void pqxx::pipeline::attach() -{ - if (not registered()) - register_me(); -} - - -void pqxx::pipeline::detach() -{ - if (registered()) - unregister_me(); -} - - -pqxx::pipeline::query_id pqxx::pipeline::insert(std::string_view q) & -{ - attach(); - query_id const qid{generate_id()}; - auto const i{m_queries.insert(std::make_pair(qid, Query(q))).first}; - - if (m_issuedrange.second == std::end(m_queries)) - { - m_issuedrange.second = i; - if (m_issuedrange.first == std::end(m_queries)) - m_issuedrange.first = i; - } - m_num_waiting++; - - if (m_num_waiting > m_retain) - { - if (have_pending()) - receive_if_available(); - if (not have_pending()) - issue(); - } - - return qid; -} - - -void pqxx::pipeline::complete() -{ - if (have_pending()) - receive(m_issuedrange.second); - if (m_num_waiting and (m_error == qid_limit())) - { - issue(); - receive(std::end(m_queries)); - } - detach(); -} - - -void pqxx::pipeline::flush() -{ - if (not std::empty(m_queries)) - { - if (have_pending()) - receive(m_issuedrange.second); - m_issuedrange.first = m_issuedrange.second = std::end(m_queries); - m_num_waiting = 0; - m_dummy_pending = false; - m_queries.clear(); - } - detach(); -} - - -void PQXX_COLD pqxx::pipeline::cancel() -{ - while (have_pending()) - { - pqxx::internal::gate::connection_pipeline(m_trans.conn()).cancel_query(); - auto canceled_query{m_issuedrange.first}; - ++m_issuedrange.first; - m_queries.erase(canceled_query); - } -} - - -bool pqxx::pipeline::is_finished(pipeline::query_id q) const -{ - if (m_queries.find(q) == std::end(m_queries)) - throw std::logic_error{ - internal::concat("Requested status for unknown query '", q, "'.")}; - return (QueryMap::const_iterator(m_issuedrange.first) == - std::end(m_queries)) or - (q < m_issuedrange.first->first and q < m_error); -} - - -std::pair pqxx::pipeline::retrieve() -{ - if (std::empty(m_queries)) - throw std::logic_error{"Attempt to retrieve result from empty pipeline."}; - return retrieve(std::begin(m_queries)); -} - - -int pqxx::pipeline::retain(int retain_max) & -{ - if (retain_max < 0) - throw range_error{internal::concat( - "Attempt to make pipeline retain ", retain_max, " queries")}; - - int const oldvalue{m_retain}; - m_retain = retain_max; - - if (m_num_waiting >= m_retain) - resume(); - - return oldvalue; -} - - -void pqxx::pipeline::resume() & -{ - if (have_pending()) - receive_if_available(); - if (not have_pending() and m_num_waiting) - { - issue(); - receive_if_available(); - } -} - - -pqxx::pipeline::query_id pqxx::pipeline::generate_id() -{ - if (m_q_id == qid_limit()) - throw std::overflow_error{"Too many queries went through pipeline."}; - ++m_q_id; - return m_q_id; -} - - -void pqxx::pipeline::issue() -{ - // Retrieve that null result for the last query, if needed. - obtain_result(); - - // Don't issue anything if we've encountered an error. - if (m_error < qid_limit()) - return; - - // Start with oldest query (lowest id) not in previous issue range. - auto oldest{m_issuedrange.second}; - - // Construct cumulative query string for entire batch. - auto cum{separated_list( - theSeparator, oldest, std::end(m_queries), - [](QueryMap::const_iterator i) { return i->second.query; })}; - auto const num_issued{ - QueryMap::size_type(std::distance(oldest, std::end(m_queries)))}; - bool const prepend_dummy{num_issued > 1}; - if (prepend_dummy) - cum = theDummyQuery + cum; - - pqxx::internal::gate::connection_pipeline{m_trans.conn()}.start_exec( - cum.c_str()); - - // Since we managed to send out these queries, update state to reflect this. - m_dummy_pending = prepend_dummy; - m_issuedrange.first = oldest; - m_issuedrange.second = std::end(m_queries); - m_num_waiting -= check_cast(num_issued, "pipeline issue()"sv); -} - - -void PQXX_COLD pqxx::pipeline::internal_error(std::string const &err) -{ - set_error_at(0); - throw pqxx::internal_error{err}; -} - - -bool pqxx::pipeline::obtain_result(bool expect_none) -{ - pqxx::internal::gate::connection_pipeline gate{m_trans.conn()}; - auto const r{gate.get_result()}; - if (r == nullptr) - { - if (have_pending() and not expect_none) - { - PQXX_UNLIKELY - set_error_at(m_issuedrange.first->first); - m_issuedrange.second = m_issuedrange.first; - } - return false; - } - - result const res{pqxx::internal::gate::result_creation::create( - r, std::begin(m_queries)->second.query, m_encoding)}; - - if (not have_pending()) - { - PQXX_UNLIKELY - set_error_at(std::begin(m_queries)->first); - throw std::logic_error{ - "Got more results from pipeline than there were queries."}; - } - - // Must be the result for the oldest pending query. - if (not std::empty(m_issuedrange.first->second.res)) - PQXX_UNLIKELY - internal_error("Multiple results for one query."); - - m_issuedrange.first->second.res = res; - ++m_issuedrange.first; - - return true; -} - - -void pqxx::pipeline::obtain_dummy() -{ - // Allocate once, re-use across invocations. - static auto const text{ - std::make_shared("[DUMMY PIPELINE QUERY]")}; - - pqxx::internal::gate::connection_pipeline gate{m_trans.conn()}; - auto const r{gate.get_result()}; - m_dummy_pending = false; - - if (r == nullptr) - PQXX_UNLIKELY - internal_error("Pipeline got no result from backend when it expected one."); - - result R{pqxx::internal::gate::result_creation::create(r, text, m_encoding)}; - - bool OK{false}; - try - { - pqxx::internal::gate::result_creation{R}.check_status(); - OK = true; - } - catch (sql_error const &) - {} - if (OK) - { - PQXX_LIKELY - if (std::size(R) > 1) - PQXX_UNLIKELY - internal_error("Unexpected result for dummy query in pipeline."); - - if (R.at(0).at(0).as() != theDummyValue) - PQXX_UNLIKELY - internal_error("Dummy query in pipeline returned unexpected value."); - return; - } - - // TODO: Can we actually re-issue statements after a failure? - /* Execution of this batch failed. - * - * When we send multiple statements in one go, the backend treats them as a - * single transaction. So the entire batch was effectively rolled back. - * - * Since none of the queries in the batch were actually executed, we can - * afford to replay them one by one until we find the exact query that - * caused the error. This gives us not only a more specific error message - * to report, but also tells us which query to report it for. - */ - // First, give the whole batch the same syntax error message, in case all - // else is going to fail. - for (auto i{m_issuedrange.first}; i != m_issuedrange.second; ++i) - i->second.res = R; - - // Remember where the end of this batch was - auto const stop{m_issuedrange.second}; - - // Retrieve that null result for the last query, if needed - obtain_result(true); - - // Reset internal state to forget botched batch attempt - m_num_waiting += check_cast( - std::distance(m_issuedrange.first, stop), "pipeline obtain_dummy()"sv); - m_issuedrange.second = m_issuedrange.first; - - // Issue queries in failed batch one at a time. - unregister_me(); - try - { - do { - m_num_waiting--; - auto const query{*m_issuedrange.first->second.query}; - auto &holder{m_issuedrange.first->second}; - holder.res = m_trans.exec(query); - pqxx::internal::gate::result_creation{holder.res}.check_status(); - ++m_issuedrange.first; - } while (m_issuedrange.first != stop); - } - catch (std::exception const &) - { - auto const thud{m_issuedrange.first->first}; - ++m_issuedrange.first; - m_issuedrange.second = m_issuedrange.first; - auto q{m_issuedrange.first}; - set_error_at((q == std::end(m_queries)) ? thud + 1 : q->first); - } -} - - -std::pair -pqxx::pipeline::retrieve(pipeline::QueryMap::iterator q) -{ - if (q == std::end(m_queries)) - throw std::logic_error{"Attempt to retrieve result for unknown query."}; - - if (q->first >= m_error) - throw std::runtime_error{ - "Could not complete query in pipeline due to error in earlier query."}; - - // If query hasn't issued yet, do it now. - if ( - m_issuedrange.second != std::end(m_queries) and - (q->first >= m_issuedrange.second->first)) - { - if (have_pending()) - receive(m_issuedrange.second); - if (m_error == qid_limit()) - issue(); - } - - // If result not in yet, get it; else get at least whatever's convenient. - if (have_pending()) - { - if (q->first >= m_issuedrange.first->first) - { - auto suc{q}; - ++suc; - receive(suc); - } - else - { - receive_if_available(); - } - } - - if (q->first >= m_error) - throw std::runtime_error{ - "Could not complete query in pipeline due to error in earlier query."}; - - // Don't leave the backend idle if there are queries waiting to be issued. - if (m_num_waiting and not have_pending() and (m_error == qid_limit())) - issue(); - - result const R{q->second.res}; - auto const P{std::make_pair(q->first, R)}; - - m_queries.erase(q); - - pqxx::internal::gate::result_creation{R}.check_status(); - return P; -} - - -void pqxx::pipeline::get_further_available_results() -{ - pqxx::internal::gate::connection_pipeline gate{m_trans.conn()}; - while (not gate.is_busy() and obtain_result()) - if (not gate.consume_input()) - throw broken_connection{}; -} - - -void pqxx::pipeline::receive_if_available() -{ - pqxx::internal::gate::connection_pipeline gate{m_trans.conn()}; - if (not gate.consume_input()) - throw broken_connection{}; - if (gate.is_busy()) - return; - - if (m_dummy_pending) - obtain_dummy(); - if (have_pending()) - get_further_available_results(); -} - - -void pqxx::pipeline::receive(pipeline::QueryMap::const_iterator stop) -{ - if (m_dummy_pending) - obtain_dummy(); - - while (obtain_result() and - QueryMap::const_iterator{m_issuedrange.first} != stop) - ; - - // Also haul in any remaining "targets of opportunity". - if (QueryMap::const_iterator{m_issuedrange.first} == stop) - get_further_available_results(); -} diff --git a/ext/libpqxx-7.7.3/src/pqxx-source.hxx b/ext/libpqxx-7.7.3/src/pqxx-source.hxx deleted file mode 100644 index 1a8f5fb11..000000000 --- a/ext/libpqxx-7.7.3/src/pqxx-source.hxx +++ /dev/null @@ -1,30 +0,0 @@ -/* Compiler settings for compiling libpqxx itself. - * - * Include this header in every source file that goes into the libpqxx library - * binary, and nowhere else. - * - * To ensure this, include this file once, as the very first header, in each - * compilation unit for the library. - * - * 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. - */ - -// Workarounds & definitions needed to compile libpqxx into a library. -#include "pqxx/config-internal-compiler.h" - -#ifdef _WIN32 - -# ifdef PQXX_SHARED -// We're building libpqxx as a shared library. -# undef PQXX_LIBEXPORT -# define PQXX_LIBEXPORT __declspec(dllexport) -# define PQXX_PRIVATE __declspec() -# endif // PQXX_SHARED - -#endif // _WIN32 diff --git a/ext/libpqxx-7.7.3/src/result.cxx b/ext/libpqxx-7.7.3/src/result.cxx deleted file mode 100644 index 86a739004..000000000 --- a/ext/libpqxx-7.7.3/src/result.cxx +++ /dev/null @@ -1,536 +0,0 @@ -/** Implementation of the pqxx::result class and support classes. - * - * pqxx::result represents the set of result rows from a database query - * - * 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. - */ -#include "pqxx-source.hxx" - -#include -#include -#include - -extern "C" -{ -#include -} - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/except.hxx" -#include "pqxx/internal/concat.hxx" -#include "pqxx/internal/result_iterator.hxx" -#include "pqxx/result.hxx" -#include "pqxx/row.hxx" - -#include "pqxx/internal/header-post.hxx" - - -namespace pqxx -{ -PQXX_DECLARE_ENUM_CONVERSION(ExecStatusType); -} - -std::string const pqxx::result::s_empty_string; - - -/// C++ wrapper for libpq's PQclear. -void pqxx::internal::clear_result(pq::PGresult const *data) -{ - PQclear(const_cast(data)); -} - - -pqxx::result::result( - pqxx::internal::pq::PGresult *rhs, std::shared_ptr query, - internal::encoding_group enc) : - m_data{make_data_pointer(rhs)}, m_query{query}, m_encoding(enc) -{} - - -bool pqxx::result::operator==(result const &rhs) const noexcept -{ - if (&rhs == this) - PQXX_UNLIKELY return true; - auto const s{size()}; - if (std::size(rhs) != s) - return false; - for (size_type i{0}; i < s; ++i) - if ((*this)[i] != rhs[i]) - return false; - return true; -} - - -pqxx::result::const_reverse_iterator pqxx::result::rbegin() const -{ - return const_reverse_iterator{end()}; -} - - -pqxx::result::const_reverse_iterator pqxx::result::crbegin() const -{ - return rbegin(); -} - - -pqxx::result::const_reverse_iterator pqxx::result::rend() const -{ - return const_reverse_iterator{begin()}; -} - - -pqxx::result::const_reverse_iterator pqxx::result::crend() const -{ - return rend(); -} - - -pqxx::result::const_iterator pqxx::result::begin() const noexcept -{ - return {this, 0}; -} - - -pqxx::result::const_iterator pqxx::result::cbegin() const noexcept -{ - return begin(); -} - - -pqxx::result::size_type pqxx::result::size() const noexcept -{ - return (m_data.get() == nullptr) ? - 0 : - static_cast(PQntuples(m_data.get())); -} - - -bool pqxx::result::empty() const noexcept -{ - return (m_data.get() == nullptr) or (PQntuples(m_data.get()) == 0); -} - - -pqxx::result::reference pqxx::result::front() const noexcept -{ - return row{*this, 0, columns()}; -} - - -pqxx::result::reference pqxx::result::back() const noexcept -{ - return row{*this, size() - 1, columns()}; -} - - -void pqxx::result::swap(result &rhs) noexcept -{ - m_data.swap(rhs.m_data); - m_query.swap(rhs.m_query); -} - - -pqxx::row pqxx::result::operator[](result_size_type i) const noexcept -{ - return row{*this, i, columns()}; -} - - -#if defined(PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT) -pqxx::field pqxx::result::operator[]( - result_size_type row_num, row_size_type col_num) const noexcept -{ - return {*this, row_num, field_num}; -} -#endif - - -pqxx::row pqxx::result::at(pqxx::result::size_type i) const -{ - if (i >= size()) - throw range_error{"Row number out of range."}; - return operator[](i); -} - - -pqxx::field pqxx::result::at( - pqxx::result_size_type row_num, pqxx::row_size_type col_num) const -{ - if (row_num >= size()) - throw range_error{"Row number out of range."}; - if (col_num >= columns()) - throw range_error{"Column out of range."}; - return {*this, row_num, col_num}; -} - - -namespace -{ -/// C string comparison. -inline bool equal(char const lhs[], char const rhs[]) -{ - return strcmp(lhs, rhs) == 0; -} -} // namespace - -void PQXX_COLD pqxx::result::throw_sql_error( - std::string const &Err, std::string const &Query) const -{ - // Try to establish more precise error type, and throw corresponding - // type of exception. - char const *const code{PQresultErrorField(m_data.get(), PG_DIAG_SQLSTATE)}; - if (code == nullptr) - { - // No SQLSTATE at all. Can this even happen? - // Let's assume the connection is no longer usable. - throw broken_connection{Err}; - } - - switch (code[0]) - { - PQXX_UNLIKELY - case '\0': - // SQLSTATE is empty. We may have seen this happen in one - // circumstance: a client-side socket timeout (while using the - // tcp_user_timeout connection option). Unfortunately in that case the - // connection was just fine, so we had no real way of detecting the - // problem. (Trying to continue to use the connection does break - // though, so I feel justified in panicking.) - throw broken_connection{Err}; - - case '0': - switch (code[1]) - { - case 'A': throw feature_not_supported{Err, Query, code}; - case '8': throw broken_connection{Err}; - case 'L': - case 'P': throw insufficient_privilege{Err, Query, code}; - } - break; - case '2': - switch (code[1]) - { - case '2': throw data_exception{Err, Query, code}; - case '3': - if (equal(code, "23001")) - throw restrict_violation{Err, Query, code}; - if (equal(code, "23502")) - throw not_null_violation{Err, Query, code}; - if (equal(code, "23503")) - throw foreign_key_violation{Err, Query, code}; - if (equal(code, "23505")) - throw unique_violation{Err, Query, code}; - if (equal(code, "23514")) - throw check_violation{Err, Query, code}; - throw integrity_constraint_violation{Err, Query, code}; - case '4': throw invalid_cursor_state{Err, Query, code}; - case '6': throw invalid_sql_statement_name{Err, Query, code}; - } - break; - case '3': - switch (code[1]) - { - case '4': throw invalid_cursor_name{Err, Query, code}; - } - break; - case '4': - switch (code[1]) - { - case '0': - if (equal(code, "40000")) - throw transaction_rollback{Err, Query, code}; - if (equal(code, "40001")) - throw serialization_failure{Err, Query, code}; - if (equal(code, "40003")) - throw statement_completion_unknown{Err, Query, code}; - if (equal(code, "40P01")) - throw deadlock_detected{Err, Query, code}; - break; - case '2': - if (equal(code, "42501")) - throw insufficient_privilege{Err, Query}; - if (equal(code, "42601")) - throw syntax_error{Err, Query, code, errorposition()}; - if (equal(code, "42703")) - throw undefined_column{Err, Query, code}; - if (equal(code, "42883")) - throw undefined_function{Err, Query, code}; - if (equal(code, "42P01")) - throw undefined_table{Err, Query, code}; - } - break; - case '5': - switch (code[1]) - { - case '3': - if (equal(code, "53100")) - throw disk_full{Err, Query, code}; - if (equal(code, "53200")) - throw out_of_memory{Err, Query, code}; - if (equal(code, "53300")) - throw too_many_connections{Err}; - throw insufficient_resources{Err, Query, code}; - } - break; - - case 'P': - if (equal(code, "P0001")) - throw plpgsql_raise{Err, Query, code}; - if (equal(code, "P0002")) - throw plpgsql_no_data_found{Err, Query, code}; - if (equal(code, "P0003")) - throw plpgsql_too_many_rows{Err, Query, code}; - throw plpgsql_error{Err, Query, code}; - } - - // Unknown error code. - throw sql_error{Err, Query, code}; -} - -void pqxx::result::check_status(std::string_view desc) const -{ - if (auto err{status_error()}; not std::empty(err)) - { - PQXX_UNLIKELY - if (not std::empty(desc)) - err = pqxx::internal::concat("Failure during '", desc, "': ", err); - throw_sql_error(err, query()); - } -} - - -std::string pqxx::result::status_error() const -{ - if (m_data.get() == nullptr) - throw failure{"No result set given."}; - - std::string err; - - switch (PQresultStatus(m_data.get())) - { - case PGRES_EMPTY_QUERY: // The string sent to the backend was empty. - case PGRES_COMMAND_OK: // Successful completion, no result data. - case PGRES_TUPLES_OK: // The query successfully executed. - break; - - case PGRES_COPY_OUT: // Copy Out (from server) data transfer started. - case PGRES_COPY_IN: // Copy In (to server) data transfer started. - break; - - case PGRES_BAD_RESPONSE: // The server's response was not understood. - case PGRES_NONFATAL_ERROR: - case PGRES_FATAL_ERROR: err = PQresultErrorMessage(m_data.get()); break; - - default: - throw internal_error{internal::concat( - "pqxx::result: Unrecognized response code ", - PQresultStatus(m_data.get()))}; - } - return err; -} - - -char const *pqxx::result::cmd_status() const noexcept -{ - return PQcmdStatus(const_cast(m_data.get())); -} - - -std::string const &pqxx::result::query() const &noexcept -{ - return (m_query.get() == nullptr) ? s_empty_string : *m_query; -} - - -pqxx::oid pqxx::result::inserted_oid() const -{ - if (m_data.get() == nullptr) - throw usage_error{ - "Attempt to read oid of inserted row without an INSERT result"}; - return PQoidValue(const_cast(m_data.get())); -} - - -pqxx::result::size_type pqxx::result::affected_rows() const -{ - auto const rows_str{ - PQcmdTuples(const_cast(m_data.get()))}; - return (rows_str[0] == '\0') ? 0 : size_type(atoi(rows_str)); -} - - -char const *pqxx::result::get_value( - pqxx::result::size_type row, pqxx::row::size_type col) const -{ - return PQgetvalue(m_data.get(), row, col); -} - - -bool pqxx::result::get_is_null( - pqxx::result::size_type row, pqxx::row::size_type col) const -{ - return PQgetisnull(m_data.get(), row, col) != 0; -} - -pqxx::field::size_type pqxx::result::get_length( - pqxx::result::size_type row, pqxx::row::size_type col) const noexcept -{ - return static_cast( - PQgetlength(m_data.get(), row, col)); -} - - -pqxx::oid pqxx::result::column_type(row::size_type col_num) const -{ - oid const t{PQftype(m_data.get(), col_num)}; - if (t == oid_none) - throw argument_error{internal::concat( - "Attempt to retrieve type of nonexistent column ", col_num, - " of query result.")}; - return t; -} - - -pqxx::row::size_type pqxx::result::column_number(zview col_name) const -{ - auto const n{PQfnumber( - const_cast(m_data.get()), col_name.c_str())}; - if (n == -1) - throw argument_error{ - internal::concat("Unknown column name: '", col_name, "'.")}; - - return static_cast(n); -} - - -pqxx::oid pqxx::result::column_table(row::size_type col_num) const -{ - oid const t{PQftable(m_data.get(), col_num)}; - - /* If we get oid_none, it may be because the column is computed, or because - * we got an invalid row number. - */ - if (t == oid_none and col_num >= columns()) - throw argument_error{internal::concat( - "Attempt to retrieve table ID for column ", col_num, " out of ", - columns())}; - - return t; -} - - -pqxx::row::size_type pqxx::result::table_column(row::size_type col_num) const -{ - auto const n{row::size_type(PQftablecol(m_data.get(), col_num))}; - if (n != 0) - PQXX_LIKELY - return n - 1; - - // Failed. Now find out why, so we can throw a sensible exception. - auto const col_str{to_string(col_num)}; - if (col_num > columns()) - throw range_error{ - internal::concat("Invalid column index in table_column(): ", col_str)}; - - if (m_data.get() == nullptr) - throw usage_error{internal::concat( - "Can't query origin of column ", col_str, - ": result is not initialized.")}; - - throw usage_error{internal::concat( - "Can't query origin of column ", col_str, - ": not derived from table column.")}; -} - - -int pqxx::result::errorposition() const -{ - int pos{-1}; - if (m_data.get()) - { - auto const p{PQresultErrorField( - const_cast(m_data.get()), - PG_DIAG_STATEMENT_POSITION)}; - if (p) - pos = from_string(p); - } - return pos; -} - - -char const *pqxx::result::column_name(pqxx::row::size_type number) const & -{ - auto const n{PQfname(m_data.get(), number)}; - if (n == nullptr) - { - PQXX_UNLIKELY - if (m_data.get() == nullptr) - throw usage_error{"Queried column name on null result."}; - throw range_error{internal::concat( - "Invalid column number: ", number, " (maximum is ", (columns() - 1), - ").")}; - } - return n; -} - - -pqxx::row::size_type pqxx::result::columns() const noexcept -{ - auto ptr{const_cast(m_data.get())}; - return (ptr == nullptr) ? 0 : row::size_type(PQnfields(ptr)); -} - - -// const_result_iterator - -pqxx::const_result_iterator pqxx::const_result_iterator::operator++(int) -{ - const_result_iterator old{*this}; - m_index++; - return old; -} - - -pqxx::const_result_iterator pqxx::const_result_iterator::operator--(int) -{ - const_result_iterator old{*this}; - m_index--; - return old; -} - - -pqxx::result::const_iterator -pqxx::result::const_reverse_iterator::base() const noexcept -{ - iterator_type tmp{*this}; - return ++tmp; -} - - -pqxx::const_reverse_result_iterator -pqxx::const_reverse_result_iterator::operator++(int) -{ - const_reverse_result_iterator tmp{*this}; - iterator_type::operator--(); - return tmp; -} - - -pqxx::const_reverse_result_iterator -pqxx::const_reverse_result_iterator::operator--(int) -{ - const_reverse_result_iterator tmp{*this}; - iterator_type::operator++(); - return tmp; -} - - -template<> std::string pqxx::to_string(field const &value) -{ - return {value.c_str(), std::size(value)}; -} diff --git a/ext/libpqxx-7.7.3/src/robusttransaction.cxx b/ext/libpqxx-7.7.3/src/robusttransaction.cxx deleted file mode 100644 index 5bbfd64f8..000000000 --- a/ext/libpqxx-7.7.3/src/robusttransaction.cxx +++ /dev/null @@ -1,221 +0,0 @@ -/** Implementation of the pqxx::robusttransaction class. - * - * pqxx::robusttransaction is a slower but safer transaction class. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include -#include -#include -#include - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/connection.hxx" -#include "pqxx/internal/concat.hxx" -#include "pqxx/internal/wait.hxx" -#include "pqxx/nontransaction.hxx" -#include "pqxx/result.hxx" -#include "pqxx/robusttransaction.hxx" - -#include "pqxx/internal/header-post.hxx" - - -using namespace std::literals; - -namespace -{ -using pqxx::operator"" _zv; - -/// Statuses in which we may find our transaction. -/** There's also "in the future," but it manifests as an error, not as an - * actual status. - */ -enum tx_stat -{ - tx_unknown, - tx_committed, - tx_aborted, - tx_in_progress, -}; - - -constexpr auto committed{"committed"_zv}, aborted{"aborted"_zv}, - in_progress{"in progress"_zv}; - - -/// Parse a nonempty transaction status string. -constexpr tx_stat parse_status(std::string_view text) noexcept -{ - switch (text[0]) - { - case 'a': - if (text == aborted) - PQXX_LIKELY return tx_aborted; - break; - case 'c': - if (text == committed) - PQXX_LIKELY return tx_committed; - break; - case 'i': - if (text == in_progress) - PQXX_LIKELY return tx_in_progress; - break; - } - return tx_unknown; -} - - -tx_stat query_status(std::string const &xid, std::string const &conn_str) -{ - static std::string const name{"robusttxck"sv}; - auto const query{pqxx::internal::concat("SELECT txid_status(", xid, ")")}; - pqxx::connection c{conn_str}; - pqxx::nontransaction w{c, name}; - auto const status_row{w.exec1(query)}; - auto const status_field{status_row[0]}; - if (std::size(status_field) == 0) - throw pqxx::internal_error{"Transaction status string is empty."}; - auto const status{parse_status(status_field.as())}; - if (status == tx_unknown) - throw pqxx::internal_error{pqxx::internal::concat( - "Unknown transaction status string: ", status_field.view())}; - return status; -} -} // namespace - - -void pqxx::internal::basic_robusttransaction::init(zview begin_command) -{ - static auto const txid_q{ - std::make_shared("SELECT txid_current()"sv)}; - m_backendpid = conn().backendpid(); - direct_exec(begin_command); - direct_exec(txid_q)[0][0].to(m_xid); -} - - -pqxx::internal::basic_robusttransaction::basic_robusttransaction( - connection &c, zview begin_command, std::string_view tname) : - dbtransaction(c, tname), m_conn_string{c.connection_string()} -{ - init(begin_command); -} - - -pqxx::internal::basic_robusttransaction::basic_robusttransaction( - connection &c, zview begin_command) : - dbtransaction(c), m_conn_string{c.connection_string()} -{ - init(begin_command); -} - - -pqxx::internal::basic_robusttransaction::~basic_robusttransaction() = default; - - -void pqxx::internal::basic_robusttransaction::do_commit() -{ - static auto const check_constraints_q{ - std::make_shared("SET CONSTRAINTS ALL IMMEDIATE"sv)}, - commit_q{std::make_shared("COMMIT"sv)}; - // Check constraints before sending the COMMIT to the database, so as to - // minimise our in-doubt window. - try - { - direct_exec(check_constraints_q); - } - catch (std::exception const &) - { - do_abort(); - throw; - } - - // Here comes the in-doubt window. If we lose our connection here, we'll be - // left clueless as to what happened on the backend. It may have received - // the commit command and completed the transaction, and ended up with a - // success it could not report back to us. Or it may have noticed the broken - // connection and aborted the transaction. It may even still be executing - // the commit, only to fail later. - // - // All this uncertainty requires some special handling, and that s what makes - // robusttransaction what it is. - try - { - direct_exec(commit_q); - - // If we make it here, great. Normal, successful commit. - return; - } - catch (broken_connection const &) - { - // Oops, lost connection at the crucial moment. Fall through to in-doubt - // handling below. - } - catch (std::exception const &) - { - if (conn().is_open()) - { - // Commit failed, for some other reason. - do_abort(); - throw; - } - // Otherwise, fall through to in-doubt handling. - } - - // If we get here, we're in doubt. Figure out what happened. - - int const max_attempts{500}; - static_assert(max_attempts > 0); - - tx_stat stat; - for (int attempts{0}; attempts < max_attempts; - ++attempts, pqxx::internal::wait_for(300u)) - { - stat = tx_unknown; - try - { - stat = query_status(m_xid, m_conn_string); - } - catch (pqxx::broken_connection const &) - { - // Swallow the error. Pause and retry. - } - switch (stat) - { - case tx_unknown: - // We were unable to reconnect and query transaction status. - // Stay in it for another attempt. - return; - case tx_committed: - // Success! We're done. - return; - case tx_aborted: - // Aborted. We're done. - do_abort(); - return; - case tx_in_progress: - // The transaction is still running. Stick around until we know what - // transpires. - break; - } - } - - // Okay, this has taken too long. Give up, report in-doubt state. - throw in_doubt_error{internal::concat( - "Transaction ", name(), " (with transaction ID ", m_xid, - ") " - "lost connection while committing. It's impossible to tell whether " - "it committed, or aborted, or is still running. " - "Attempts to find out its outcome have failed. " - "The backend process on the server had process ID ", - m_backendpid, - ". " - "You may be able to check what happened to that process.")}; -} diff --git a/ext/libpqxx-7.7.3/src/row.cxx b/ext/libpqxx-7.7.3/src/row.cxx deleted file mode 100644 index f0974c839..000000000 --- a/ext/libpqxx-7.7.3/src/row.cxx +++ /dev/null @@ -1,250 +0,0 @@ -/** Implementation of the pqxx::result class and support classes. - * - * pqxx::result represents the set of result rows from a database query. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include -#include - -extern "C" -{ -#include -} - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/except.hxx" -#include "pqxx/result.hxx" -#include "pqxx/row.hxx" - -#include "pqxx/internal/header-post.hxx" - - -pqxx::row::row( - result const &r, result::size_type index, size_type cols) noexcept : - m_result{r}, m_index{index}, m_end{cols} -{} - - -pqxx::row::const_iterator pqxx::row::begin() const noexcept -{ - return {*this, m_begin}; -} - - -pqxx::row::const_iterator pqxx::row::cbegin() const noexcept -{ - return begin(); -} - - -pqxx::row::const_iterator pqxx::row::end() const noexcept -{ - return {*this, m_end}; -} - - -pqxx::row::const_iterator pqxx::row::cend() const noexcept -{ - return end(); -} - - -pqxx::row::reference pqxx::row::front() const noexcept -{ - return field{m_result, m_index, m_begin}; -} - - -pqxx::row::reference pqxx::row::back() const noexcept -{ - return field{m_result, m_index, m_end - 1}; -} - - -pqxx::row::const_reverse_iterator pqxx::row::rbegin() const -{ - return const_reverse_row_iterator{end()}; -} - - -pqxx::row::const_reverse_iterator pqxx::row::crbegin() const -{ - return rbegin(); -} - - -pqxx::row::const_reverse_iterator pqxx::row::rend() const -{ - return const_reverse_row_iterator{begin()}; -} - - -pqxx::row::const_reverse_iterator pqxx::row::crend() const -{ - return rend(); -} - - -bool pqxx::row::operator==(row const &rhs) const noexcept -{ - if (&rhs == this) - return true; - auto const s{size()}; - if (std::size(rhs) != s) - return false; - for (size_type i{0}; i < s; ++i) - if ((*this)[i] != rhs[i]) - return false; - return true; -} - - -pqxx::row::reference pqxx::row::operator[](size_type i) const noexcept -{ - return field{m_result, m_index, m_begin + i}; -} - - -pqxx::row::reference pqxx::row::operator[](zview col_name) const -{ - return at(col_name); -} - - -void pqxx::row::swap(row &rhs) noexcept -{ - auto const i{m_index}; - auto const b{m_begin}; - auto const e{m_end}; - m_result.swap(rhs.m_result); - m_index = rhs.m_index; - m_begin = rhs.m_begin; - m_end = rhs.m_end; - rhs.m_index = i; - rhs.m_begin = b; - rhs.m_end = e; -} - - -pqxx::field pqxx::row::at(zview col_name) const -{ - return {m_result, m_index, m_begin + column_number(col_name)}; -} - - -pqxx::field pqxx::row::at(pqxx::row::size_type i) const -{ - if (i >= size()) - throw range_error{"Invalid field number."}; - - return operator[](i); -} - - -pqxx::oid pqxx::row::column_type(size_type col_num) const -{ - return m_result.column_type(m_begin + col_num); -} - - -pqxx::oid pqxx::row::column_table(size_type col_num) const -{ - return m_result.column_table(m_begin + col_num); -} - - -pqxx::row::size_type pqxx::row::table_column(size_type col_num) const -{ - return m_result.table_column(m_begin + col_num); -} - - -pqxx::row::size_type pqxx::row::column_number(zview col_name) const -{ - auto const n{m_result.column_number(col_name)}; - if (n >= m_end) - throw argument_error{ - "Column '" + std::string{col_name} + "' falls outside slice."}; - if (n >= m_begin) - return n - m_begin; - - // This deals with a really nasty possibility: that the column name occurs - // twice - once before the beginning of the slice, and once inside the slice. - char const *const adapted_name{m_result.column_name(n)}; - for (auto i{m_begin}; i < m_end; ++i) - if (strcmp(adapted_name, m_result.column_name(i)) == 0) - return i - m_begin; - - // Didn't find any? Recurse just to produce the same error message. - return result{}.column_number(col_name); -} - - -pqxx::row PQXX_COLD pqxx::row::slice(size_type sbegin, size_type send) const -{ - if (sbegin > send or send > size()) - throw range_error{"Invalid field range."}; - -#include "pqxx/internal/ignore-deprecated-pre.hxx" - row res{*this}; -#include "pqxx/internal/ignore-deprecated-post.hxx" - res.m_begin = m_begin + sbegin; - res.m_end = m_begin + send; - return res; -} - - -bool PQXX_COLD pqxx::row::empty() const noexcept -{ - return m_begin == m_end; -} - - -pqxx::const_row_iterator pqxx::const_row_iterator::operator++(int) -{ - auto const old{*this}; - m_col++; - return old; -} - - -pqxx::const_row_iterator pqxx::const_row_iterator::operator--(int) -{ - auto const old{*this}; - m_col--; - return old; -} - - -pqxx::const_row_iterator -pqxx::const_reverse_row_iterator::base() const noexcept -{ - iterator_type tmp{*this}; - return ++tmp; -} - - -pqxx::const_reverse_row_iterator -pqxx::const_reverse_row_iterator::operator++(int) -{ - auto tmp{*this}; - operator++(); - return tmp; -} - - -pqxx::const_reverse_row_iterator -pqxx::const_reverse_row_iterator::operator--(int) -{ - auto tmp{*this}; - operator--(); - return tmp; -} diff --git a/ext/libpqxx-7.7.3/src/sql_cursor.cxx b/ext/libpqxx-7.7.3/src/sql_cursor.cxx deleted file mode 100644 index 1e5d6a790..000000000 --- a/ext/libpqxx-7.7.3/src/sql_cursor.cxx +++ /dev/null @@ -1,276 +0,0 @@ -/** Implementation of libpqxx STL-style cursor classes. - * - * These classes wrap SQL cursors in STL-like interfaces. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/cursor.hxx" -#include "pqxx/internal/encodings.hxx" -#include "pqxx/internal/gates/connection-sql_cursor.hxx" -#include "pqxx/internal/gates/transaction-sql_cursor.hxx" - -#include "pqxx/internal/header-post.hxx" - - -using namespace std::literals; - -namespace -{ -/// Is this character a "useless trailing character" in a query? -/** A character is "useless" at the end of a query if it is either whitespace - * or a semicolon. - */ -inline bool useless_trail(char c) -{ - return isspace(c) or c == ';'; -} - - -/// Find end of nonempty query, stripping off any trailing semicolon. -/** When executing a normal query, a trailing semicolon is meaningless but - * won't hurt. That's why we can't rule out that some code may include one. - * - * But for cursor queries, a trailing semicolon is a problem. The query gets - * embedded in a larger statement, which a semicolon would break into two. - * We'll have to remove it if present. - * - * A trailing semicolon may not actually be at the end. It could be masked by - * subsequent whitespace. If there's also a comment though, that's the - * caller's own lookout. We can't guard against every possible mistake, and - * text processing is actually remarkably sensitive to mistakes in a - * multi-encoding world. - * - * If there is a trailing semicolon, this function returns its offset. If - * there are more than one, it returns the offset of the first one. If there - * is no trailing semicolon, it returns the length of the query string. - * - * The query must be nonempty. - */ -std::string::size_type -find_query_end(std::string_view query, pqxx::internal::encoding_group enc) -{ - auto const text{std::data(query)}; - auto const size{std::size(query)}; - std::string::size_type end; - if (enc == pqxx::internal::encoding_group::MONOBYTE) - { - // This is an encoding where we can scan backwards from the end. - for (end = std::size(query); end > 0 and useless_trail(text[end - 1]); - --end) - ; - } - else - { - // Complex encoding. We only know how to iterate forwards, so start from - // the beginning. - end = 0; - - pqxx::internal::for_glyphs( - enc, - [text, &end](char const *gbegin, char const *gend) { - if (gend - gbegin > 1 or not useless_trail(*gbegin)) - end = std::string::size_type(gend - text); - }, - text, size); - } - - return end; -} -} // namespace - - -pqxx::internal::sql_cursor::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) : - cursor_base{t.conn(), cname}, - m_home{t.conn()}, - m_adopted{false}, - m_at_end{-1}, - m_pos{0} -{ - if (&t.conn() != &m_home) - throw internal_error{"Cursor in wrong connection"}; - - if (std::empty(query)) - throw usage_error{"Cursor has empty query."}; - auto const enc{enc_group(t.conn().encoding_id())}; - auto const qend{find_query_end(query, enc)}; - if (qend == 0) - throw usage_error{"Cursor has effectively empty query."}; - query.remove_suffix(std::size(query) - qend); - - std::string const cq{internal::concat( - "DECLARE "sv, t.quote_name(name()), " "sv, - ((ap == cursor_base::forward_only) ? "NO "sv : ""sv), "SCROLL CURSOR "sv, - (hold ? "WITH HOLD "sv : ""sv), "FOR "sv, query, " "sv, - ((up == cursor_base::update) ? "FOR UPDATE "sv : "FOR READ ONLY "sv))}; - - t.exec(cq); - - // Now that we're here in the starting position, keep a copy of an empty - // result. That may come in handy later, because we may not be able to - // construct an empty result with all the right metadata due to the weird - // meaning of "FETCH 0." - init_empty_result(t); - - m_ownership = op; -} - - -pqxx::internal::sql_cursor::sql_cursor( - transaction_base &t, std::string_view cname, - cursor_base::ownership_policy op) : - cursor_base{t.conn(), cname, false}, - m_home{t.conn()}, - m_empty_result{}, - m_adopted{true}, - m_at_end{0}, - m_pos{-1} -{ - m_adopted = true; - m_ownership = op; -} - - -void pqxx::internal::sql_cursor::close() noexcept -{ - if (m_ownership == cursor_base::owned) - { - try - { - gate::connection_sql_cursor{m_home}.exec( - internal::concat("CLOSE "sv, m_home.quote_name(name())).c_str()); - } - catch (std::exception const &) - {} - m_ownership = cursor_base::loose; - } -} - - -void pqxx::internal::sql_cursor::init_empty_result(transaction_base &t) -{ - if (pos() != 0) - throw internal_error{"init_empty_result() from bad pos()."}; - m_empty_result = - t.exec(internal::concat("FETCH 0 IN "sv, m_home.quote_name(name()))); -} - - -/// Compute actual displacement based on requested and reported displacements. -pqxx::internal::sql_cursor::difference_type pqxx::internal::sql_cursor::adjust( - difference_type hoped, difference_type actual) -{ - if (actual < 0) - throw internal_error{"Negative rows in cursor movement."}; - if (hoped == 0) - return 0; - int const direction{((hoped < 0) ? -1 : 1)}; - bool hit_end{false}; - if (actual != labs(hoped)) - { - if (actual > labs(hoped)) - throw internal_error{"Cursor displacement larger than requested."}; - - // If we see fewer rows than requested, then we've hit an end (on either - // side) of the result set. Wether we make an extra step to a one-past-end - // position or whether we're already there depends on where we were - // previously: if our last move was in the same direction and also fell - // short, we're already at a one-past-end row. - if (m_at_end != direction) - ++actual; - - // If we hit the beginning, make sure our position calculation ends up - // at zero (even if we didn't previously know where we were!), and if we - // hit the other end, register the fact that we now know where the end - // of the result set is. - if (direction > 0) - hit_end = true; - else if (m_pos == -1) - m_pos = actual; - else if (m_pos != actual) - throw internal_error{internal::concat( - "Moved back to beginning, but wrong position: hoped=", hoped, - ", actual=", actual, ", m_pos=", m_pos, ", direction=", direction, - ".")}; - - m_at_end = direction; - } - else - { - m_at_end = 0; - } - - if (m_pos >= 0) - m_pos += direction * actual; - if (hit_end) - { - if (m_endpos >= 0 and m_pos != m_endpos) - throw internal_error{"Inconsistent cursor end positions."}; - m_endpos = m_pos; - } - return direction * actual; -} - - -pqxx::result pqxx::internal::sql_cursor::fetch( - difference_type rows, difference_type &displacement) -{ - if (rows == 0) - { - displacement = 0; - return m_empty_result; - } - auto const query{pqxx::internal::concat( - "FETCH "sv, stridestring(rows), " IN "sv, m_home.quote_name(name()))}; - auto const r{gate::connection_sql_cursor{m_home}.exec(query.c_str())}; - displacement = adjust(rows, difference_type(std::size(r))); - return r; -} - - -pqxx::cursor_base::difference_type pqxx::internal::sql_cursor::move( - difference_type rows, difference_type &displacement) -{ - if (rows == 0) - { - displacement = 0; - return 0; - } - - auto const query{pqxx::internal::concat( - "MOVE "sv, stridestring(rows), " IN "sv, m_home.quote_name(name()))}; - auto const r{gate::connection_sql_cursor{m_home}.exec(query.c_str())}; - auto d{static_cast(r.affected_rows())}; - displacement = adjust(rows, d); - return d; -} - - -std::string pqxx::internal::sql_cursor::stridestring(difference_type n) -{ - /* Some special-casing for ALL and BACKWARD ALL here. We used to use numeric - * "infinities" for difference_type for this (the highest and lowest possible - * values for "long"), but for PostgreSQL 8.0 at least, the backend appears - * to expect a 32-bit number and fails to parse large 64-bit numbers. We - * could change the alias to match this behaviour, but that would break - * if/when Postgres is changed to accept 64-bit displacements. - */ - static std::string const All{"ALL"}, BackAll{"BACKWARD ALL"}; - if (n >= cursor_base::all()) - return All; - else if (n <= cursor_base::backward_all()) - return BackAll; - return to_string(n); -} diff --git a/ext/libpqxx-7.7.3/src/strconv.cxx b/ext/libpqxx-7.7.3/src/strconv.cxx deleted file mode 100644 index 2bd206b2a..000000000 --- a/ext/libpqxx-7.7.3/src/strconv.cxx +++ /dev/null @@ -1,785 +0,0 @@ -/** Implementation of string conversions. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if __has_include() -# include -#endif - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/except.hxx" -#include "pqxx/strconv.hxx" - -#include "pqxx/internal/header-post.hxx" - - -namespace -{ -#if !defined(PQXX_HAVE_CHARCONV_FLOAT) -/// Do we have fully functional thread_local support? -/** When building with libcxxrt on clang, you can't create thread_local objects - * of non-POD types. Any attempt will result in a link error. - */ -constexpr bool have_thread_local -{ -# if defined(PQXX_HAVE_THREAD_LOCAL) - true -# else - false -# endif -}; -#endif - - -/// String comparison between string_view. -constexpr inline bool equal(std::string_view lhs, std::string_view rhs) -{ - return lhs.compare(rhs) == 0; -} - - -/// The lowest possible value of integral type T. -template constexpr T bottom{std::numeric_limits::min()}; - -/// The highest possible value of integral type T. -template constexpr T top{std::numeric_limits::max()}; - -/// Write nonnegative integral value at end of buffer. Return start. -/** Assumes a sufficiently large buffer. - * - * Includes a single trailing null byte, right before @c *end. - */ -template constexpr inline char *nonneg_to_buf(char *end, T value) -{ - char *pos = end; - *--pos = '\0'; - do { - *--pos = pqxx::internal::number_to_digit(int(value % 10)); - value = T(value / 10); - } while (value > 0); - return pos; -} - - -/// Write negative version of value at end of buffer. Return start. -/** Like @c nonneg_to_buf, but prefixes a minus sign. - */ -template constexpr inline char *neg_to_buf(char *end, T value) -{ - char *pos = nonneg_to_buf(end, value); - *--pos = '-'; - return pos; -} - - -/// Write lowest possible negative value at end of buffer. -/** Like @c neg_to_buf, but for the special case of the bottom value. - */ -template constexpr inline char *bottom_to_buf(char *end) -{ - static_assert(std::is_signed_v); - - // This is the hard case. In two's-complement systems, which includes - // any modern-day system I can think of, a signed type's bottom value - // has no positive equivalent. Luckily the C++ standards committee can't - // think of any exceptions either, so it's the required representation as - // of C++20. We'll assume it right now, while still on C++17. - static_assert(-(bottom + 1) == top); - - // The unsigned version of T does have the unsigned version of bottom. - using unsigned_t = std::make_unsigned_t; - - // Careful though. If we tried to negate value in order to promote to - // unsigned_t, the value will overflow, which means behaviour is - // undefined. Promotion of a negative value to an unsigned type is - // well-defined, given a representation, so let's do that: - constexpr auto positive{static_cast(bottom)}; - - // As luck would have it, in two's complement, this gives us exactly the - // value we want. - static_assert(positive == top / 2 + 1); - - // So the only thing we need to do differently from the regular negative - // case is to skip that overflowing negation and promote to an unsigned type! - return neg_to_buf(end, positive); -} - - -#if defined(PQXX_HAVE_CHARCONV_INT) || defined(PQXX_HAVE_CHARCONV_FLOAT) -/// Call to_chars, report errors as exceptions, add zero, return pointer. -template -[[maybe_unused]] inline char * -wrap_to_chars(char *begin, char *end, T const &value) -{ - auto res{std::to_chars(begin, end - 1, value)}; - if (res.ec != std::errc()) - PQXX_UNLIKELY - switch (res.ec) - { - case std::errc::value_too_large: - throw pqxx::conversion_overrun{ - "Could not convert " + pqxx::type_name + - " to string: " - "buffer too small (" + - pqxx::to_string(end - begin) + " bytes)."}; - default: - throw pqxx::conversion_error{ - "Could not convert " + pqxx::type_name + " to string."}; - } - // No need to check for overrun here: we never even told to_chars about that - // last byte in the buffer, so it didn't get used up. - *res.ptr++ = '\0'; - return res.ptr; -} -#endif -} // namespace - - -namespace pqxx::internal -{ -template -zview integral_traits::to_buf(char *begin, char *end, T const &value) -{ - static_assert(std::is_integral_v); - auto const space{end - begin}, - need{static_cast(size_buffer(value))}; - if (space < need) - throw conversion_overrun{ - "Could not convert " + type_name + - " to string: " - "buffer too small. " + - pqxx::internal::state_buffer_overrun(space, need)}; - - char *pos; - if constexpr (std::is_unsigned_v) - pos = nonneg_to_buf(end, value); - else if (value >= 0) - pos = nonneg_to_buf(end, value); - else if (value > bottom) - pos = neg_to_buf(end, -value); - else - pos = bottom_to_buf(end); - - return {pos, end - pos - 1}; -} - - -template zview integral_traits::to_buf(char *, char *, short const &); -template zview integral_traits::to_buf( - char *, char *, unsigned short const &); -template zview integral_traits::to_buf(char *, char *, int const &); -template zview -integral_traits::to_buf(char *, char *, unsigned const &); -template zview integral_traits::to_buf(char *, char *, long const &); -template zview -integral_traits::to_buf(char *, char *, unsigned long const &); -template zview -integral_traits::to_buf(char *, char *, long long const &); -template zview integral_traits::to_buf( - char *, char *, unsigned long long const &); - - -template -char *integral_traits::into_buf(char *begin, char *end, T const &value) -{ -#if defined(PQXX_HAVE_CHARCONV_INT) - // This is exactly what to_chars is good at. Trust standard library - // implementers to optimise better than we can. - return wrap_to_chars(begin, end, value); -#else - return generic_into_buf(begin, end, value); -#endif -} - - -template char *integral_traits::into_buf(char *, char *, short const &); -template char *integral_traits::into_buf( - char *, char *, unsigned short const &); -template char *integral_traits::into_buf(char *, char *, int const &); -template char * -integral_traits::into_buf(char *, char *, unsigned const &); -template char *integral_traits::into_buf(char *, char *, long const &); -template char *integral_traits::into_buf( - char *, char *, unsigned long const &); -template char * -integral_traits::into_buf(char *, char *, long long const &); -template char *integral_traits::into_buf( - char *, char *, unsigned long long const &); -} // namespace pqxx::internal - - -namespace pqxx::internal -{ -std::string demangle_type_name(char const raw[]) -{ -#if defined(PQXX_HAVE_CXA_DEMANGLE) - // We've got __cxa_demangle. Use it to get a friendlier type name. - int status{0}; - - // We've seen this fail on FreeBSD 11.3 (see #361). Trying to throw a - // meaningful exception only made things worse. So in case of error, just - // fall back to the raw name. - // - // When __cxa_demangle fails, it's guaranteed to return null. - char *demangled{abi::__cxa_demangle(raw, nullptr, nullptr, &status)}; -#else - static constexpr char *demangled{nullptr}; -#endif - std::string const name{(demangled == nullptr) ? raw : demangled}; - - // Check for nullness to work around jemalloc bug (see #508). - if (demangled != nullptr) - std::free(demangled); - return name; -} - -void PQXX_COLD throw_null_conversion(std::string const &type) -{ - throw conversion_error{"Attempt to convert null to " + type + "."}; -} - - -std::string PQXX_COLD state_buffer_overrun(int have_bytes, int need_bytes) -{ - // We convert these in standard library terms, not for the localisation - // so much as to avoid "error cycles," if these values in turn should fail - // to get enough buffer space. - std::stringstream have, need; - have << have_bytes; - need << need_bytes; - return "Have " + have.str() + " bytes, need " + need.str() + "."; -} -} // namespace pqxx::internal - - -namespace -{ -#if defined(PQXX_HAVE_CHARCONV_INT) || defined(PQXX_HAVE_CHARCONV_FLOAT) -template -[[maybe_unused]] inline TYPE from_string_arithmetic(std::string_view in) -{ - char const *here; - auto const end{std::data(in) + std::size(in)}; - - // Skip whitespace. This is not the proper way to do it, but I see no way - // that any of the supported encodings could ever produce a valid character - // whose byte sequence would confuse this code. - for (here = std::data(in); here < end and (*here == ' ' or *here == '\t'); - ++here) - ; - - TYPE out{}; - auto const res{std::from_chars(here, end, out)}; - if (res.ec == std::errc() and res.ptr == end) - PQXX_LIKELY - return out; - - std::string msg; - if (res.ec == std::errc()) - { - msg = "Could not parse full string."; - } - else - { - switch (res.ec) - { - case std::errc::result_out_of_range: msg = "Value out of range."; break; - case std::errc::invalid_argument: msg = "Invalid argument."; break; - default: break; - } - } - - auto const base{ - "Could not convert '" + std::string(in) + - "' " - "to " + - pqxx::type_name}; - if (std::empty(msg)) - throw pqxx::conversion_error{base + "."}; - else - throw pqxx::conversion_error{base + ": " + msg}; -} -#endif -} // namespace - - -namespace -{ -#if !defined(PQXX_HAVE_CHARCONV_INT) -[[noreturn, maybe_unused]] void PQXX_COLD report_overflow() -{ - throw pqxx::conversion_error{ - "Could not convert string to integer: value out of range."}; -} - -template struct numeric_ten -{ - static inline constexpr T value = 10; -}; - -template struct numeric_high_threshold -{ - static inline constexpr T value = - (std::numeric_limits::max)() / numeric_ten::value; -}; - -template struct numeric_low_threshold -{ - static inline constexpr T value = - (std::numeric_limits::min)() / numeric_ten::value; -}; - -/// Return 10*n, or throw exception if it overflows. -template -[[maybe_unused]] constexpr inline T safe_multiply_by_ten(T n) -{ - using limits = std::numeric_limits; - - if (n > numeric_high_threshold::value) - PQXX_UNLIKELY - report_overflow(); - if constexpr (limits::is_signed) - { - if (numeric_low_threshold::value > n) - PQXX_UNLIKELY - report_overflow(); - } - return T(n * numeric_ten::value); -} - - -/// Add digit d to nonnegative n, or throw exception if it overflows. -template -[[maybe_unused]] constexpr inline T safe_add_digit(T n, T d) -{ - T const high_threshold{static_cast(std::numeric_limits::max() - d)}; - if (n > high_threshold) - PQXX_UNLIKELY - report_overflow(); - return static_cast(n + d); -} - - -/// Subtract digit d to nonpositive n, or throw exception if it overflows. -template -[[maybe_unused]] constexpr inline T safe_sub_digit(T n, T d) -{ - T const low_threshold{static_cast(std::numeric_limits::min() + d)}; - if (n < low_threshold) - PQXX_UNLIKELY - report_overflow(); - return static_cast(n - d); -} - - -/// For use in string parsing: add new numeric digit to intermediate value. -template -[[maybe_unused]] constexpr inline L absorb_digit_positive(L value, R digit) -{ - return safe_add_digit(safe_multiply_by_ten(value), L(digit)); -} - - -/// For use in string parsing: subtract digit from intermediate value. -template -[[maybe_unused]] constexpr inline L absorb_digit_negative(L value, R digit) -{ - return safe_sub_digit(safe_multiply_by_ten(value), L(digit)); -} - - -template -[[maybe_unused]] constexpr T from_string_integer(std::string_view text) -{ - if (std::size(text) == 0) - throw pqxx::conversion_error{ - "Attempt to convert empty string to " + pqxx::type_name + "."}; - - char const *const data{std::data(text)}; - std::size_t i{0}; - - // Skip whitespace. This is not the proper way to do it, but I see no way - // that any of the supported encodings could ever produce a valid character - // whose byte sequence would confuse this code. - // - // Why skip whitespace? Because that's how integral conversions are meant to - // work _for composite types._ I see no clean way to support leading - // whitespace there without putting the code in here. A shame about the - // overhead, modest as it is, for the normal case. - for (; i < std::size(text) and (data[i] == ' ' or data[i] == '\t'); ++i) - ; - if (i == std::size(text)) - throw pqxx::conversion_error{ - "Converting string to " + pqxx::type_name + - ", but it contains only whitespace."}; - - char const initial{data[i]}; - T result{0}; - - if (pqxx::internal::is_digit(initial)) - { - for (; pqxx::internal::is_digit(data[i]); ++i) - result = absorb_digit_positive( - result, pqxx::internal::digit_to_number(data[i])); - } - else if (initial == '-') - { - if constexpr (not std::is_signed_v) - throw pqxx::conversion_error{ - "Attempt to convert negative value to " + pqxx::type_name + "."}; - - ++i; - if (i >= std::size(text)) - throw pqxx::conversion_error{ - "Converting string to " + pqxx::type_name + - ", but it contains only a sign."}; - for (; i < std::size(text) and pqxx::internal::is_digit(data[i]); ++i) - result = absorb_digit_negative( - result, pqxx::internal::digit_to_number(data[i])); - } - else - { - throw pqxx::conversion_error{ - "Could not convert string to " + pqxx::type_name + - ": " - "'" + - std::string{text} + "'."}; - } - - if (i < std::size(text)) - throw pqxx::conversion_error{ - "Unexpected text after " + pqxx::type_name + - ": " - "'" + - std::string{text} + "'."}; - - return result; -} -#endif // !PQXX_HAVE_CHARCONV_INT -} // namespace - - -namespace -{ -[[maybe_unused]] constexpr bool -valid_infinity_string(std::string_view text) noexcept -{ - return equal("infinity", text) or equal("Infinity", text) or - equal("INFINITY", text) or equal("inf", text); -} -} // namespace - - -#if !defined(PQXX_HAVE_CHARCONV_FLOAT) -namespace -{ -/// Wrapper for std::stringstream with C locale. -/** We use this to work around missing std::to_chars for floating-point types. - * - * Initialising the stream (including locale and tweaked precision) seems to - * be expensive. So, create thread-local instances which we re-use. It's a - * lockless way of keeping global variables thread-safe, basically. - * - * The stream initialisation happens once per thread, in the constructor. - * And that's why we need to wrap this in a class. We can't just do it at the - * call site, or we'd still be doing it for every call. - */ -template class dumb_stringstream : public std::stringstream -{ -public: - // Do not initialise the base-class object using "stringstream{}" (with curly - // braces): that breaks on Visual C++. The classic "stringstream()" syntax - // (with parentheses) does work. - PQXX_COLD dumb_stringstream() - { - this->imbue(std::locale::classic()); - this->precision(std::numeric_limits::max_digits10); - } -}; - - -template -inline bool PQXX_COLD from_dumb_stringstream( - dumb_stringstream &s, F &result, std::string_view text) -{ - s.str(std::string{text}); - return static_cast(s >> result); -} - - -// These are hard, and some popular compilers still lack std::from_chars. -template -inline T PQXX_COLD from_string_awful_float(std::string_view text) -{ - if (std::empty(text)) - throw pqxx::conversion_error{ - "Trying to convert empty string to " + pqxx::type_name + "."}; - - bool ok{false}; - T result; - - switch (text[0]) - { - case 'N': - case 'n': - // Accept "NaN," "nan," etc. - ok = - (std::size(text) == 3 and (text[1] == 'A' or text[1] == 'a') and - (text[2] == 'N' or text[2] == 'n')); - result = std::numeric_limits::quiet_NaN(); - break; - - case 'I': - case 'i': - ok = valid_infinity_string(text); - result = std::numeric_limits::infinity(); - break; - - default: - if (text[0] == '-' and valid_infinity_string(text.substr(1))) - { - ok = true; - result = -std::numeric_limits::infinity(); - } - else - { - PQXX_LIKELY - if constexpr (have_thread_local) - { - thread_local dumb_stringstream S; - // Visual Studio 2017 seems to fail on repeated conversions if the - // clear() is done before the seekg(). Still don't know why! See #124 - // and #125. - S.seekg(0); - S.clear(); - ok = from_dumb_stringstream(S, result, text); - } - else - { - dumb_stringstream S; - ok = from_dumb_stringstream(S, result, text); - } - } - break; - } - - if (not ok) - throw pqxx::conversion_error{ - "Could not convert string to numeric value: '" + std::string{text} + - "'."}; - - return result; -} -} // namespace -#endif // !PQXX_HAVE_CHARCONV_FLOAT - - -namespace pqxx::internal -{ -/// Floating-point to_buf implemented in terms of to_string. -template -zview float_traits::to_buf(char *begin, char *end, T const &value) -{ -#if defined(PQXX_HAVE_CHARCONV_FLOAT) - { - // Definitely prefer to let the standard library handle this! - auto const ptr{wrap_to_chars(begin, end, value)}; - return zview{begin, std::size_t(ptr - begin - 1)}; - } -#else - { - // Implement it ourselves. Weird detail: since this workaround is based on - // std::stringstream, which produces a std::string, it's actually easier to - // build the to_buf() on top of the to_string() than the other way around. - if (std::isnan(value)) - return "nan"_zv; - if (std::isinf(value)) - return (value > 0) ? "infinity"_zv : "-infinity"_zv; - auto text{to_string_float(value)}; - auto have{end - begin}; - auto need{std::size(text) + 1}; - if (need > std::size_t(have)) - throw conversion_error{ - "Could not convert floating-point number to string: " - "buffer too small. " + - state_buffer_overrun(have, need)}; - text.copy(begin, need); - return zview{begin, std::size(text)}; - } -#endif -} - - -template zview float_traits::to_buf(char *, char *, float const &); -template zview float_traits::to_buf(char *, char *, double const &); -template zview -float_traits::to_buf(char *, char *, long double const &); - - -template -char *float_traits::into_buf(char *begin, char *end, T const &value) -{ -#if defined(PQXX_HAVE_CHARCONV_FLOAT) - return wrap_to_chars(begin, end, value); -#else - return generic_into_buf(begin, end, value); -#endif -} - - -template char *float_traits::into_buf(char *, char *, float const &); -template char *float_traits::into_buf(char *, char *, double const &); -template char * -float_traits::into_buf(char *, char *, long double const &); - - -#if !defined(PQXX_HAVE_CHARCONV_FLOAT) -template -inline std::string PQXX_COLD -to_dumb_stringstream(dumb_stringstream &s, F value) -{ - s.str(""); - s << value; - return s.str(); -} -#endif - - -/// Floating-point implementations for @c pqxx::to_string(). -template std::string to_string_float(T value) -{ -#if defined(PQXX_HAVE_CHARCONV_FLOAT) - { - static constexpr auto space{float_traits::size_buffer(value)}; - std::string buf; - buf.resize(space); - std::string_view const view{ - float_traits::to_buf(std::data(buf), std::data(buf) + space, value)}; - buf.resize(static_cast(std::end(view) - std::begin(view))); - return buf; - } -#else - { - // In this rare case, we can convert to std::string but not to a simple - // buffer. So, implement to_buf in terms of to_string instead of the other - // way around. - if constexpr (have_thread_local) - { - thread_local dumb_stringstream s; - return to_dumb_stringstream(s, value); - } - else - { - dumb_stringstream s; - return to_dumb_stringstream(s, value); - } - } -#endif -} -} // namespace pqxx::internal - - -namespace pqxx::internal -{ -template T integral_traits::from_string(std::string_view text) -{ -#if defined(PQXX_HAVE_CHARCONV_INT) - return from_string_arithmetic(text); -#else - return from_string_integer(text); -#endif -} - -template short integral_traits::from_string(std::string_view); -template unsigned short - integral_traits::from_string(std::string_view); -template int integral_traits::from_string(std::string_view); -template unsigned integral_traits::from_string(std::string_view); -template long integral_traits::from_string(std::string_view); -template unsigned long - integral_traits::from_string(std::string_view); -template long long integral_traits::from_string(std::string_view); -template unsigned long long - integral_traits::from_string(std::string_view); - - -template T float_traits::from_string(std::string_view text) -{ -#if defined(PQXX_HAVE_CHARCONV_FLOAT) - return from_string_arithmetic(text); -#else - return from_string_awful_float(text); -#endif -} - - -template float float_traits::from_string(std::string_view); -template double float_traits::from_string(std::string_view); -template long double float_traits::from_string(std::string_view); - - -template std::string to_string_float(float); -template std::string to_string_float(double); -template std::string to_string_float(long double); -} // namespace pqxx::internal - - -bool pqxx::string_traits::from_string(std::string_view text) -{ - std::optional result; - - switch (std::size(text)) - { - case 0: result = false; break; - - case 1: - switch (text[0]) - { - case 'f': - case 'F': - case '0': result = false; break; - - case 't': - case 'T': - case '1': result = true; break; - - default: break; - } - break; - - case 4: - if (equal(text, "true") or equal(text, "TRUE")) - result = true; - break; - - case 5: - if (equal(text, "false") or equal(text, "FALSE")) - result = false; - break; - - default: break; - } - - if (result) - return *result; - else - throw conversion_error{ - "Failed conversion to bool: '" + std::string{text} + "'."}; -} diff --git a/ext/libpqxx-7.7.3/src/stream_from.cxx b/ext/libpqxx-7.7.3/src/stream_from.cxx deleted file mode 100644 index f710300ea..000000000 --- a/ext/libpqxx-7.7.3/src/stream_from.cxx +++ /dev/null @@ -1,327 +0,0 @@ -/** Implementation of the pqxx::stream_from class. - * - * pqxx::stream_from enables optimized batch reads from a database table. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/internal/encodings.hxx" -#include "pqxx/internal/gates/connection-stream_from.hxx" -#include "pqxx/stream_from.hxx" -#include "pqxx/transaction_base.hxx" - -#include "pqxx/internal/header-post.hxx" - - -namespace -{ -pqxx::internal::glyph_scanner_func * -get_scanner(pqxx::transaction_base const &tx) -{ - auto const group{pqxx::internal::enc_group(tx.conn().encoding_id())}; - return pqxx::internal::get_glyph_scanner(group); -} - - -constexpr std::string_view class_name{"stream_from"}; -} // namespace - - -pqxx::stream_from::stream_from( - transaction_base &tx, from_query_t, std::string_view query) : - transaction_focus{tx, class_name}, m_glyph_scanner{get_scanner(tx)} -{ - tx.exec0(internal::concat("COPY ("sv, query, ") TO STDOUT"sv)); - register_me(); -} - - -pqxx::stream_from::stream_from( - transaction_base &tx, from_table_t, std::string_view table) : - transaction_focus{tx, class_name, table}, - m_glyph_scanner{get_scanner(tx)} -{ - tx.exec0(internal::concat("COPY "sv, tx.quote_name(table), " TO STDOUT"sv)); - register_me(); -} - - -pqxx::stream_from::stream_from( - transaction_base &tx, std::string_view table, std::string_view columns, - from_table_t) : - transaction_focus{tx, class_name, table}, - m_glyph_scanner{get_scanner(tx)} -{ - if (std::empty(columns)) - PQXX_UNLIKELY - tx.exec0(internal::concat("COPY "sv, table, " TO STDOUT"sv)); - else PQXX_LIKELY tx.exec0( - internal::concat("COPY "sv, table, "("sv, columns, ") TO STDOUT"sv)); - register_me(); -} - - -pqxx::stream_from::stream_from( - transaction_base &tx, std::string_view unquoted_table, - std::string_view columns, from_table_t, int) : - stream_from{ - tx, tx.conn().quote_table(unquoted_table), columns, from_table} -{} - - -pqxx::stream_from pqxx::stream_from::raw_table( - transaction_base &tx, std::string_view path, std::string_view columns) -{ - return {tx, path, columns, from_table}; -} - - -pqxx::stream_from pqxx::stream_from::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)); -} - - -pqxx::stream_from::~stream_from() noexcept -{ - try - { - close(); - } - catch (std::exception const &e) - { - reg_pending_error(e.what()); - } -} - - -pqxx::stream_from::raw_line pqxx::stream_from::get_raw_line() -{ - if (*this) - { - internal::gate::connection_stream_from gate{m_trans.conn()}; - try - { - raw_line line{gate.read_copy_line()}; - if (line.first.get() == nullptr) - close(); - return line; - } - catch (std::exception const &) - { - close(); - throw; - } - } - else - { - return {}; - } -} - - -void pqxx::stream_from::close() -{ - if (not m_finished) - { - PQXX_UNLIKELY - m_finished = true; - unregister_me(); - } -} - - -void pqxx::stream_from::complete() -{ - if (m_finished) - return; - try - { - // Flush any remaining lines - libpq will automatically close the stream - // when it hits the end. - bool done{false}; - while (not done) - { - auto [line, size] = get_raw_line(); - ignore_unused(size); - done = not line.get(); - } - } - catch (broken_connection const &) - { - close(); - throw; - } - catch (std::exception const &e) - { - reg_pending_error(e.what()); - } - close(); -} - - -void pqxx::stream_from::parse_line() -{ - if (m_finished) - PQXX_UNLIKELY - return; - auto const next_seq{m_glyph_scanner}; - - m_fields.clear(); - - auto const [line, line_size] = get_raw_line(); - if (line.get() == nullptr) - { - m_finished = true; - return; - } - - if (line_size >= (std::numeric_limits::max() / 2)) - throw range_error{"Stream produced a ridiculously long line."}; - - // Make room for unescaping the line. It's a pessimistic size. - // Unusually, we're storing terminating zeroes *inside* the string. - // This is the only place where we modify m_row. MAKE SURE THE BUFFER DOES - // NOT GET RESIZED while we're working, because we're working with views into - // its buffer. - m_row.resize(line_size + 1); - - char const *line_begin{line.get()}; - char const *line_end{line_begin + line_size}; - char const *read{line_begin}; - - // Output iterator for unescaped text. - char *write{m_row.data()}; - - // The pointer cannot be null at this point. But we initialise field_begin - // with this value, and carry it around the loop, and it can later become - // null. Static analysis in clang-tidy then likes to assume a case where - // field_begin is null, and deduces from this that "write" must have been - // null -- and so it marks "*write" as a null pointer dereference. - // - // This assertion tells clang-tidy just what it needs in order to deduce - // that *write never dereferences a null pointer. - assert(write != nullptr); - - // Beginning of current field in m_row, or nullptr for null fields. - char const *field_begin{write}; - - while (read < line_end) - { - auto const offset{static_cast(read - line_begin)}; - auto const glyph_end{line_begin + next_seq(line_begin, line_size, offset)}; - // XXX: find_char<'\t', '\\'>(). - if (glyph_end == read + 1) - { - // Single-byte character. - char c{*read++}; - switch (c) - { - case '\t': // Field separator. - // End the field. - if (field_begin == nullptr) - { - m_fields.emplace_back(); - } - else - { - // Would love to emplace_back() here, but gcc 9.1 warns about the - // constructor not throwing. It suggests adding "noexcept." Which - // we can hardly do, without std::string_view guaranteeing it. - m_fields.push_back(zview{field_begin, write - field_begin}); - *write++ = '\0'; - } - field_begin = write; - break; - - PQXX_UNLIKELY - case '\\': { - // Escape sequence. - if (read >= line_end) - throw failure{"Row ends in backslash"}; - - c = *read++; - switch (c) - { - case 'N': - // Null value. - if (write != field_begin) - throw failure{"Null sequence found in nonempty field"}; - field_begin = nullptr; - // (If there's any characters _after_ the null we'll just crash.) - break; - - case 'b': // Backspace. - PQXX_UNLIKELY - *write++ = '\b'; - break; - case 'f': // Form feed - PQXX_UNLIKELY - *write++ = '\f'; - break; - case 'n': // Line feed. - *write++ = '\n'; - break; - case 'r': // Carriage return. - *write++ = '\r'; - break; - case 't': // Horizontal tab. - *write++ = '\t'; - break; - case 'v': // Vertical tab. - *write++ = '\v'; - break; - - default: - PQXX_LIKELY - // Regular character ("self-escaped"). - *write++ = c; - break; - } - } - break; - - PQXX_LIKELY - default: *write++ = c; break; - } - } - else - { - // Multi-byte sequence. Never treated specially, so just append. - while (read < glyph_end) *write++ = *read++; - } - } - - // End the last field here. - if (field_begin == nullptr) - { - m_fields.emplace_back(); - } - else - { - m_fields.push_back(zview{field_begin, write - field_begin}); - *write++ = '\0'; - } - - // DO NOT shrink m_row to fit. We're carrying string_views pointing into - // the buffer. (Also, how useful would shrinking really be?) -} - - -std::vector const *pqxx::stream_from::read_row() & -{ - parse_line(); - return m_finished ? nullptr : &m_fields; -} diff --git a/ext/libpqxx-7.7.3/src/stream_to.cxx b/ext/libpqxx-7.7.3/src/stream_to.cxx deleted file mode 100644 index 1693ba377..000000000 --- a/ext/libpqxx-7.7.3/src/stream_to.cxx +++ /dev/null @@ -1,170 +0,0 @@ -/** Implementation of the pqxx::stream_to class. - * - * pqxx::stream_to enables optimized batch updates to a database table. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/internal/concat.hxx" -#include "pqxx/internal/gates/connection-stream_to.hxx" -#include "pqxx/stream_from.hxx" -#include "pqxx/stream_to.hxx" - -#include "pqxx/internal/header-post.hxx" - - -namespace -{ -using namespace std::literals; - -void begin_copy( - pqxx::transaction_base &tx, std::string_view table, std::string_view columns) -{ - tx.exec0( - std::empty(columns) ? - pqxx::internal::concat("COPY "sv, table, " FROM STDIN"sv) : - pqxx::internal::concat( - "COPY "sv, table, "("sv, columns, ") FROM STDIN"sv)); -} -} // namespace - - -pqxx::stream_to::~stream_to() noexcept -{ - try - { - complete(); - } - catch (std::exception const &e) - { - reg_pending_error(e.what()); - } -} - - -void pqxx::stream_to::write_raw_line(std::string_view text) -{ - internal::gate::connection_stream_to{m_trans.conn()}.write_copy_line(text); -} - - -void pqxx::stream_to::write_buffer() -{ - if (not std::empty(m_buffer)) - { - // In append_to_buffer() we write a tab after each field. We only want a - // tab _between_ fields. Remove that last one. - assert(m_buffer[std::size(m_buffer) - 1] == '\t'); - m_buffer.resize(std::size(m_buffer) - 1); - } - write_raw_line(m_buffer); - m_buffer.clear(); -} - - -pqxx::stream_to &pqxx::stream_to::operator<<(stream_from &tr) -{ - while (tr) - { - const auto [line, size] = tr.get_raw_line(); - if (line.get() == nullptr) - break; - write_raw_line(std::string_view{line.get(), size}); - } - return *this; -} - - -pqxx::stream_to::stream_to( - transaction_base &tx, std::string_view path, std::string_view columns) : - transaction_focus{tx, s_classname, path}, - m_scanner{get_glyph_scanner( - pqxx::internal::enc_group(tx.conn().encoding_id()))} -{ - begin_copy(tx, path, columns); - register_me(); -} - - -void pqxx::stream_to::complete() -{ - if (!m_finished) - { - m_finished = true; - unregister_me(); - internal::gate::connection_stream_to{m_trans.conn()}.end_copy_write(); - } -} - - -/// Return escape letter for c's backslash sequence, or 0 if not needed. -/** The API is a bit weird: you pass the width of the character, and its first - * byte. That's because we never need to escape a multibyte character anyway. - */ -constexpr char escape(std::size_t width, char c) -{ - if (width == 1u) - switch (c) - { - case '\b': return 'b'; - case '\f': return 'f'; - case '\n': return 'n'; - case '\r': return 'r'; - case '\t': return 't'; - case '\v': return 'v'; - case '\\': return '\\'; - } - - PQXX_LIKELY - return '\0'; -} - - -void pqxx::stream_to::escape_field_to_buffer(std::string_view data) -{ - if (not std::empty(data)) - { - // Mark the beginning of a stretch that we can copy into our buffer in one - // go. It feels like a waste to invoke generic multi-byte copies for every - // individual character in this loop, most of them actually probably only - // one byte long. - std::size_t begin_stretch{0}; - - std::size_t begin_char{0}, end; - // XXX: find_char<'\b', '\f', '\n', '\r', '\t', \v', '\\'>(). - for (end = m_scanner(std::data(data), std::size(data), begin_char); - begin_char < std::size(data); begin_char = end, - end = m_scanner(std::data(data), std::size(data), begin_char)) - { - // Escape sequence letter, if needed. - char const esc{escape(end - begin_char, data[begin_char])}; - if (esc != '\0') - { - // This character needs escaping. So, it ends any trivially copyable - // stretch that we may have been having. - - // Copy the stretch we've built up into our buffer. - m_buffer.append( - std::data(data) + begin_stretch, begin_char - begin_stretch); - - // Escape the current character. - m_buffer.push_back('\\'); - m_buffer.push_back(esc); - - // Start a new stretch, right after the current character. - begin_stretch = end; - } - } - // Copy the final stretch. - m_buffer.append( - std::data(data) + begin_stretch, begin_char - begin_stretch); - } - m_buffer.push_back('\t'); -} diff --git a/ext/libpqxx-7.7.3/src/subtransaction.cxx b/ext/libpqxx-7.7.3/src/subtransaction.cxx deleted file mode 100644 index 186ad13e8..000000000 --- a/ext/libpqxx-7.7.3/src/subtransaction.cxx +++ /dev/null @@ -1,68 +0,0 @@ -/** Implementation of the pqxx::subtransaction class. - * - * pqxx::transaction is a nested transaction, i.e. one within a transaction - * - * 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. - */ -#include "pqxx-source.hxx" - -#include -#include - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/connection.hxx" -#include "pqxx/internal/concat.hxx" -#include "pqxx/subtransaction.hxx" - -#include "pqxx/internal/header-post.hxx" - - -namespace -{ -using namespace std::literals; -constexpr std::string_view class_name{"subtransaction"sv}; -} // namespace - - -pqxx::subtransaction::subtransaction( - dbtransaction &t, std::string_view tname) : - transaction_focus{t, class_name, t.conn().adorn_name(tname)}, - // We can't initialise the rollback command here, because we don't yet - // have a full object to implement quoted_name(). - dbtransaction{t.conn(), tname, std::shared_ptr{}} -{ - set_rollback_cmd(std::make_shared( - internal::concat("ROLLBACK TO SAVEPOINT ", quoted_name()))); - direct_exec(std::make_shared( - internal::concat("SAVEPOINT ", quoted_name()))); -} - - -namespace -{ -using dbtransaction_ref = pqxx::dbtransaction &; -} - - -pqxx::subtransaction::subtransaction( - subtransaction &t, std::string_view tname) : - subtransaction(dbtransaction_ref(t), tname) -{} - - -pqxx::subtransaction::~subtransaction() noexcept -{ - close(); -} - - -void pqxx::subtransaction::do_commit() -{ - direct_exec(std::make_shared( - internal::concat("RELEASE SAVEPOINT ", quoted_name()))); -} diff --git a/ext/libpqxx-7.7.3/src/time.cxx b/ext/libpqxx-7.7.3/src/time.cxx deleted file mode 100644 index 6b3ffdb1c..000000000 --- a/ext/libpqxx-7.7.3/src/time.cxx +++ /dev/null @@ -1,226 +0,0 @@ -/** Implementation of date/time support. - */ -#include "pqxx-source.hxx" - -#include - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/time.hxx" - -#include "pqxx/internal/header-post.hxx" - -// std::chrono::year_month_day is C++20, so let's worry a bit less about C++17 -// compatibility in this file. -#if defined(PQXX_HAVE_YEAR_MONTH_DAY) -namespace -{ -using namespace std::literals; - - -/// Render the numeric part of a year value into a buffer. -/** Converts the year from "common era" (with a Year Zero) to "anno domini" - * (without a Year Zero). - * - * Doesn't render the sign. When you're rendering a date, you indicate a - * negative year by suffixing "BC" at the very end. - * - * Where @c string_traits::into_buf() returns a pointer to the position right - * after the terminating zero, this function returns a pointer to the character - * right after the last digit. (It may or may not write a terminating zero at - * that position itself.) - */ -inline char * -year_into_buf(char *begin, char *end, std::chrono::year const &value) -{ - int const y{value}; - if (y == int{(std::chrono::year::min)()}) - { - // This is an evil special case: C++ year -32767 translates to 32768 BC, - // which is a number we can't fit into a short. At the moment postgres - // doesn't handle years before 4713 BC, but who knows, right? - static_assert(int{(std::chrono::year::min)()} == -32767); - constexpr auto hardcoded{"32768"sv}; - PQXX_UNLIKELY - begin += hardcoded.copy(begin, std::size(hardcoded)); - } - else - { - // C++ std::chrono::year has a year zero. PostgreSQL does not. So, C++ - // year zero is 1 BC in the postgres calendar; C++ 1 BC is postgres 2 BC, - // and so on. - auto const absy{static_cast(std::abs(y) + int{y <= 0})}; - - // PostgreSQL requires year input to be at least 3 digits long, or it - // won't be able to deduce the date format correctly. However on output - // it always writes years as at least 4 digits, and we'll do the same. - // Dates and times are a dirty, dirty business. - if (absy < 1000) - { - PQXX_UNLIKELY - *begin++ = '0'; - if (absy < 100) - *begin++ = '0'; - if (absy < 10) - *begin++ = '0'; - } - begin = pqxx::string_traits::into_buf(begin, end, absy) - 1; - } - return begin; -} - - -/// Parse the numeric part of a year value. -inline int year_from_buf(std::string_view text) -{ - if (std::size(text) < 4) - throw pqxx::conversion_error{ - pqxx::internal::concat("Year field is too small: '", text, "'.")}; - // Parse as int, so we can accommodate 32768 BC which won't fit in a short - // as-is, but equates to 32767 BCE which will. - int const year{pqxx::string_traits::from_string(text)}; - if (year <= 0) - throw pqxx::conversion_error{ - pqxx::internal::concat("Bad year: '", text, "'.")}; - return year; -} - - -/// Render a valid 1-based month number into a buffer. -/* Where @c string_traits::into_buf() returns a pointer to the position right - * after the terminating zero, this function returns a pointer to the character - * right after the last digit. (It may or may not write a terminating zero at - * that position itself.) - */ -inline static char * -month_into_buf(char *begin, std::chrono::month const &value) -{ - unsigned const m{value}; - if (m >= 10) - *begin = '1'; - else - *begin = '0'; - ++begin; - *begin++ = pqxx::internal::number_to_digit(static_cast(m % 10)); - return begin; -} - - -/// Parse a 1-based month value. -inline std::chrono::month month_from_string(std::string_view text) -{ - if ( - not pqxx::internal::is_digit(text[0]) or - not pqxx::internal::is_digit(text[1])) - throw pqxx::conversion_error{ - pqxx::internal::concat("Invalid month: '", text, "'.")}; - return std::chrono::month{unsigned( - (10 * pqxx::internal::digit_to_number(text[0])) + - pqxx::internal::digit_to_number(text[1]))}; -} - - -/// Render a valid 1-based day-of-month value into a buffer. -inline char *day_into_buf(char *begin, std::chrono::day const &value) -{ - unsigned d{value}; - *begin++ = pqxx::internal::number_to_digit(static_cast(d / 10)); - *begin++ = pqxx::internal::number_to_digit(static_cast(d % 10)); - return begin; -} - - -/// Parse a 1-based day-of-month value. -inline std::chrono::day day_from_string(std::string_view text) -{ - if ( - not pqxx::internal::is_digit(text[0]) or - not pqxx::internal::is_digit(text[1])) - throw pqxx::conversion_error{ - pqxx::internal::concat("Bad day in date: '", text, "'.")}; - std::chrono::day const d{unsigned( - (10 * pqxx::internal::digit_to_number(text[0])) + - pqxx::internal::digit_to_number(text[1]))}; - if (not d.ok()) - throw pqxx::conversion_error{ - pqxx::internal::concat("Bad day in date: '", text, "'.")}; - return d; -} - - -/// Look for the dash separating year and month. -/** Assumes that @c text is nonempty. - */ -inline std::size_t find_year_month_separator(std::string_view text) noexcept -{ - // We're looking for a dash. PostgreSQL won't output a negative year, so - // no worries about a leading dash. We could start searching at offset 4, - // but starting at the beginning produces more helpful error messages for - // malformed years. - std::size_t here; - for (here = 0; here < std::size(text) and text[here] != '-'; ++here) - ; - return here; -} - - -/// Componse generic "invalid date" message for given (invalid) date text. -std::string make_parse_error(std::string_view text) -{ - return pqxx::internal::concat("Invalid date: '", text, "'."); -} -} // namespace - - -namespace pqxx -{ -char *string_traits::into_buf( - char *begin, char *end, std::chrono::year_month_day const &value) -{ - if (std::size_t(end - begin) < size_buffer(value)) - throw conversion_overrun{"Not enough room in buffer for date."}; - begin = year_into_buf(begin, end, value.year()); - *begin++ = '-'; - begin = month_into_buf(begin, value.month()); - *begin++ = '-'; - begin = day_into_buf(begin, value.day()); - if (int{value.year()} <= 0) - { - PQXX_UNLIKELY - begin += s_bc.copy(begin, std::size(s_bc)); - } - *begin++ = '\0'; - return begin; -} - - -std::chrono::year_month_day -string_traits::from_string(std::string_view text) -{ - // We can't just re-use the std::chrono::year conversions, because the "BC" - // suffix comes at the very end. - if (std::size(text) < 9) - throw conversion_error{make_parse_error(text)}; - bool const is_bc{text.ends_with(s_bc)}; - if (is_bc) - PQXX_UNLIKELY - text = text.substr(0, std::size(text) - std::size(s_bc)); - auto const ymsep{find_year_month_separator(text)}; - if ((std::size(text) - ymsep) != 6) - throw conversion_error{make_parse_error(text)}; - auto const base_year{ - year_from_buf(std::string_view{std::data(text), ymsep})}; - if (base_year == 0) - throw conversion_error{"Year zero conversion."}; - std::chrono::year const y{is_bc ? (-base_year + 1) : base_year}; - auto const m{month_from_string(text.substr(ymsep + 1, 2))}; - if (text[ymsep + 3] != '-') - throw conversion_error{make_parse_error(text)}; - auto const d{day_from_string(text.substr(ymsep + 4, 2))}; - std::chrono::year_month_day const date{y, m, d}; - if (not date.ok()) - throw conversion_error{make_parse_error(text)}; - return date; -} -} // namespace pqxx -#endif diff --git a/ext/libpqxx-7.7.3/src/transaction.cxx b/ext/libpqxx-7.7.3/src/transaction.cxx deleted file mode 100644 index 61ed29ef7..000000000 --- a/ext/libpqxx-7.7.3/src/transaction.cxx +++ /dev/null @@ -1,107 +0,0 @@ -/** Implementation of the pqxx::transaction class. - * - * pqxx::transaction represents a regular database transaction. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/connection.hxx" -#include "pqxx/result.hxx" -#include "pqxx/transaction.hxx" - -#include "pqxx/internal/header-post.hxx" - - -pqxx::internal::basic_transaction::basic_transaction( - connection &c, zview begin_command, std::string_view tname) : - dbtransaction(c, tname) -{ - register_transaction(); - direct_exec(begin_command); -} - - -pqxx::internal::basic_transaction::basic_transaction( - connection &c, zview begin_command, std::string &&tname) : - dbtransaction(c, std::move(tname)) -{ - register_transaction(); - direct_exec(begin_command); -} - - -pqxx::internal::basic_transaction::basic_transaction( - connection &c, zview begin_command) : - dbtransaction(c) -{ - register_transaction(); - direct_exec(begin_command); -} - - -// This should stop the compiler from generating the same vtables and -// destructor in multiple translation units. More importantly, if we don't do -// this, the sanitisers in g++ 7 and clang++ 6 complain about pointers to -// dbtransaction actually pointing to basic_transaction. Which is odd, in that -// any basic_transaction pointer should also be a dbtransaction pointer. But, -// apparently the vtable isn't the right one. -pqxx::internal::basic_transaction::~basic_transaction() noexcept = default; - - -void pqxx::internal::basic_transaction::do_commit() -{ - static auto const commit_q{std::make_shared("COMMIT"sv)}; - try - { - direct_exec(commit_q); - } - catch (statement_completion_unknown const &e) - { - // Outcome of "commit" is unknown. This is a disaster: we don't know the - // resulting state of the database. - process_notice(internal::concat(e.what(), "\n")); - - std::string msg{internal::concat( - "WARNING: Commit of transaction '", name(), - "' is unknown. " - "There is no way to tell whether the transaction succeeded " - "or was aborted except to check manually.\n")}; - process_notice(msg); - // Strip newline. It was only needed for process_notice(). - msg.pop_back(); - throw in_doubt_error{std::move(msg)}; - } - catch (std::exception const &e) - { - if (not conn().is_open()) - { - // We've lost the connection while committing. There is just no way of - // telling what happened on the other end. >8-O - process_notice(internal::concat(e.what(), "\n")); - - auto msg{internal::concat( - "WARNING: Connection lost while committing transaction '", name(), - "'. There is no way to tell whether the transaction succeeded " - "or was aborted except to check manually.\n")}; - process_notice(msg); - // Strip newline. It was only needed for process_notice(). - msg.pop_back(); - throw in_doubt_error{std::move(msg)}; - } - else - { - // Commit failed--probably due to a constraint violation or something - // similar. - throw; - } - } -} diff --git a/ext/libpqxx-7.7.3/src/transaction_base.cxx b/ext/libpqxx-7.7.3/src/transaction_base.cxx deleted file mode 100644 index c7d01ac08..000000000 --- a/ext/libpqxx-7.7.3/src/transaction_base.cxx +++ /dev/null @@ -1,539 +0,0 @@ -/** Common code and definitions for the transaction classes. - * - * pqxx::transaction_base defines the interface for any abstract class that - * represents a database transaction. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include -#include - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/connection.hxx" -#include "pqxx/internal/concat.hxx" -#include "pqxx/internal/encodings.hxx" -#include "pqxx/internal/gates/connection-transaction.hxx" -#include "pqxx/internal/gates/transaction-transaction_focus.hxx" -#include "pqxx/result.hxx" -#include "pqxx/transaction_base.hxx" -#include "pqxx/transaction_focus.hxx" - -#include "pqxx/internal/header-post.hxx" - - -using namespace std::literals; - -namespace -{ -/// Return a query pointer for the command "ROLLBACK". -/** Concentrates constructions so as to minimise the number of allocations. - * This way, the string gets allocated once and then all subsequent invocations - * copy shared_ptr instances to the same string. - */ -std::shared_ptr make_rollback_cmd() -{ - static auto const cmd{std::make_shared("ROLLBACK")}; - return cmd; -} -} // namespace - -pqxx::transaction_base::transaction_base(connection &c) : - m_conn{c}, m_rollback_cmd{make_rollback_cmd()} -{} - - -pqxx::transaction_base::transaction_base( - connection &c, std::string_view tname) : - m_conn{c}, m_name{tname}, m_rollback_cmd{make_rollback_cmd()} -{} - - -pqxx::transaction_base::~transaction_base() -{ - try - { - if (not std::empty(m_pending_error)) - PQXX_UNLIKELY - process_notice( - internal::concat("UNPROCESSED ERROR: ", m_pending_error, "\n")); - - if (m_registered) - { - m_conn.process_notice( - internal::concat(description(), " was never closed properly!\n")); - pqxx::internal::gate::connection_transaction{conn()} - .unregister_transaction(this); - } - } - catch (std::exception const &e) - { - try - { - process_notice(internal::concat(e.what(), "\n")); - } - catch (std::exception const &) - { - process_notice(e.what()); - } - } -} - - -void pqxx::transaction_base::register_transaction() -{ - pqxx::internal::gate::connection_transaction{conn()}.register_transaction( - this); - m_registered = true; -} - - -void pqxx::transaction_base::commit() -{ - check_pending_error(); - - // Check previous status code. Caller should only call this function if - // we're in "implicit" state, but multiple commits are silently accepted. - switch (m_status) - { - case status::active: // Just fine. This is what we expect. - break; - - case status::aborted: - throw usage_error{internal::concat( - "Attempt to commit previously aborted ", description())}; - - case status::committed: - // Transaction has been committed already. This is not exactly proper - // behaviour, but throwing an exception here would only give the impression - // that an abort is needed--which would only confuse things further at this - // stage. - // Therefore, multiple commits are accepted, though under protest. - m_conn.process_notice( - internal::concat(description(), " committed more than once.\n")); - return; - - case status::in_doubt: - // Transaction may or may not have been committed. The only thing we can - // really do is keep telling the caller that the transaction is in doubt. - throw in_doubt_error{internal::concat( - description(), " committed again while in an indeterminate state.")}; - - default: throw internal_error{"pqxx::transaction: invalid status code."}; - } - - // Tricky one. If stream is nested in transaction but inside the same scope, - // the commit() will come before the stream is closed. Which means the - // commit is premature. Punish this swiftly and without fail to discourage - // the habit from forming. - if (m_focus != nullptr) - throw failure{internal::concat( - "Attempt to commit ", description(), " with ", m_focus->description(), - " still open.")}; - - // Check that we're still connected (as far as we know--this is not an - // absolute thing!) before trying to commit. If the connection was broken - // already, the commit would fail anyway but this way at least we don't - // remain in-doubt as to whether the backend got the commit order at all. - if (not m_conn.is_open()) - throw broken_connection{ - "Broken connection to backend; cannot complete transaction."}; - - try - { - do_commit(); - m_status = status::committed; - } - catch (in_doubt_error const &) - { - m_status = status::in_doubt; - throw; - } - catch (std::exception const &) - { - m_status = status::aborted; - throw; - } - - close(); -} - - -void pqxx::transaction_base::do_abort() -{ - if (m_rollback_cmd) - direct_exec(m_rollback_cmd); -} - - -void pqxx::transaction_base::abort() -{ - // Check previous status code. Quietly accept multiple aborts to - // simplify emergency bailout code. - switch (m_status) - { - case status::active: - try - { - do_abort(); - } - catch (std::exception const &e) - { - m_conn.process_notice(internal::concat(e.what(), "\n")); - } - break; - - case status::aborted: return; - - case status::committed: - throw usage_error{internal::concat( - "Attempt to abort previously committed ", description())}; - - case status::in_doubt: - // Aborting an in-doubt transaction is probably a reasonably sane response - // to an insane situation. Log it, but do not fail. - m_conn.process_notice(internal::concat( - "Warning: ", description(), - " aborted after going into indeterminate state; " - "it may have been executed anyway.\n")); - return; - - default: throw internal_error{"Invalid transaction status."}; - } - - m_status = status::aborted; - close(); -} - - -std::string PQXX_COLD pqxx::transaction_base::quote_raw(zview bin) const -{ - return conn().quote(binary_cast(bin)); -} - - -namespace -{ -/// Guard command execution against clashes with pipelines and such. -/** A transaction can have only one focus at a time. Command execution is the - * most basic example of a transaction focus. - */ -class PQXX_PRIVATE command : pqxx::transaction_focus -{ -public: - command(pqxx::transaction_base &tx, std::string_view oname) : - transaction_focus{tx, "command"sv, oname} - { - register_me(); - } - - ~command() { unregister_me(); } -}; -} // namespace - -pqxx::result -pqxx::transaction_base::exec(std::string_view query, std::string_view desc) -{ - check_pending_error(); - - command cmd{*this, desc}; - - switch (m_status) - { - case status::active: break; - - case status::committed: - case status::aborted: - case status::in_doubt: { - std::string const n{ - std::empty(desc) ? "" : internal::concat("'", desc, "' ")}; - - throw usage_error{internal::concat( - "Could not execute command ", n, ": transaction is already closed.")}; - } - - default: throw internal_error{"pqxx::transaction: invalid status code."}; - } - - return direct_exec(query, desc); -} - - -pqxx::result pqxx::transaction_base::exec_n( - result::size_type rows, zview query, std::string_view desc) -{ -#include "pqxx/internal/ignore-deprecated-pre.hxx" - result const r{exec(query, desc)}; -#include "pqxx/internal/ignore-deprecated-post.hxx" - if (std::size(r) != rows) - { - std::string const N{ - std::empty(desc) ? "" : internal::concat("'", desc, "'")}; - throw unexpected_rows{internal::concat( - "Expected ", rows, " row(s) of data from query ", N, ", got ", - std::size(r), ".")}; - } - return r; -} - - -void pqxx::transaction_base::check_rowcount_prepared( - zview statement, result::size_type expected_rows, - result::size_type actual_rows) -{ - if (actual_rows != expected_rows) - throw unexpected_rows{internal::concat( - "Expected ", expected_rows, " row(s) of data from prepared statement '", - statement, "', got ", actual_rows, ".")}; -} - - -void pqxx::transaction_base::check_rowcount_params( - std::size_t expected_rows, std::size_t actual_rows) -{ - if (actual_rows != expected_rows) - throw unexpected_rows{internal::concat( - "Expected ", expected_rows, - " row(s) of data from parameterised query, got ", actual_rows, ".")}; -} - - -pqxx::result pqxx::transaction_base::internal_exec_prepared( - zview statement, internal::c_params const &args) -{ - command cmd{*this, statement}; - return pqxx::internal::gate::connection_transaction{conn()}.exec_prepared( - statement, args); -} - - -pqxx::result pqxx::transaction_base::internal_exec_params( - zview query, internal::c_params const &args) -{ - command cmd{*this, query}; - return pqxx::internal::gate::connection_transaction{conn()}.exec_params( - query, args); -} - - -void pqxx::transaction_base::set_variable( - std::string_view var, std::string_view value) -{ -#include "pqxx/internal/ignore-deprecated-pre.hxx" - conn().set_variable(var, value); -#include "pqxx/internal/ignore-deprecated-post.hxx" -} - - -std::string pqxx::transaction_base::get_variable(std::string_view var) -{ -#include "pqxx/internal/ignore-deprecated-pre.hxx" - return conn().get_variable(var); -#include "pqxx/internal/ignore-deprecated-post.hxx" -} - - -void pqxx::transaction_base::close() noexcept -{ - try - { - try - { - check_pending_error(); - } - catch (std::exception const &e) - { - m_conn.process_notice(e.what()); - } - - if (m_registered) - { - m_registered = false; - pqxx::internal::gate::connection_transaction{conn()} - .unregister_transaction(this); - } - - if (m_status != status::active) - return; - - if (m_focus != nullptr) - PQXX_UNLIKELY - m_conn.process_notice(internal::concat( - "Closing ", description(), " with ", m_focus->description(), - " still open.\n")); - - try - { - abort(); - } - catch (std::exception const &e) - { - m_conn.process_notice(e.what()); - } - } - catch (std::exception const &e) - { - try - { - m_conn.process_notice(e.what()); - } - catch (std::exception const &) - {} - } -} - - -namespace -{ -[[nodiscard]] std::string_view -get_classname(pqxx::transaction_focus const *focus) -{ - return (focus == nullptr) ? ""sv : focus->classname(); -} - - -[[nodiscard]] std::string_view -get_obj_name(pqxx::transaction_focus const *focus) -{ - return (focus == nullptr) ? ""sv : focus->name(); -} -} // namespace - - -void pqxx::transaction_base::register_focus(transaction_focus *new_focus) -{ - internal::check_unique_register( - m_focus, get_classname(m_focus), get_obj_name(m_focus), new_focus, - get_classname(new_focus), get_obj_name(new_focus)); - m_focus = new_focus; -} - - -void pqxx::transaction_base::unregister_focus( - transaction_focus *new_focus) noexcept -{ - try - { - pqxx::internal::check_unique_unregister( - m_focus, get_classname(m_focus), get_obj_name(m_focus), new_focus, - get_classname(new_focus), get_obj_name(new_focus)); - m_focus = nullptr; - } - catch (std::exception const &e) - { - m_conn.process_notice(internal::concat(e.what(), "\n")); - } -} - - -pqxx::result pqxx::transaction_base::direct_exec( - std::string_view cmd, std::string_view desc) -{ - check_pending_error(); - return pqxx::internal::gate::connection_transaction{conn()}.exec(cmd, desc); -} - - -pqxx::result pqxx::transaction_base::direct_exec( - std::shared_ptr cmd, std::string_view desc) -{ - check_pending_error(); - return pqxx::internal::gate::connection_transaction{conn()}.exec(cmd, desc); -} - - -void pqxx::transaction_base::register_pending_error(zview err) noexcept -{ - if (std::empty(m_pending_error) and not std::empty(err)) - { - try - { - m_pending_error = err; - } - catch (std::exception const &e) - { - try - { - PQXX_UNLIKELY - process_notice("UNABLE TO PROCESS ERROR\n"); - process_notice(e.what()); - process_notice("ERROR WAS:"); - process_notice(err); - } - catch (...) - {} - } - } -} - - -void pqxx::transaction_base::register_pending_error(std::string &&err) noexcept -{ - if (std::empty(m_pending_error) and not std::empty(err)) - { - try - { - m_pending_error = std::move(err); - } - catch (std::exception const &e) - { - try - { - PQXX_UNLIKELY - process_notice("UNABLE TO PROCESS ERROR\n"); - process_notice(e.what()); - process_notice("ERROR WAS:"); - process_notice(err); - } - catch (...) - {} - } - } -} - - -void pqxx::transaction_base::check_pending_error() -{ - if (not std::empty(m_pending_error)) - { - std::string err; - err.swap(m_pending_error); - throw failure{err}; - } -} - - -std::string pqxx::transaction_base::description() const -{ - return internal::describe_object("transaction", name()); -} - - -void pqxx::transaction_focus::register_me() -{ - pqxx::internal::gate::transaction_transaction_focus{m_trans}.register_focus( - this); - m_registered = true; -} - - -void pqxx::transaction_focus::unregister_me() noexcept -{ - pqxx::internal::gate::transaction_transaction_focus{m_trans} - .unregister_focus(this); - m_registered = false; -} - - -void pqxx::transaction_focus::reg_pending_error( - std::string const &err) noexcept -{ - pqxx::internal::gate::transaction_transaction_focus{m_trans} - .register_pending_error(err); -} diff --git a/ext/libpqxx-7.7.3/src/util.cxx b/ext/libpqxx-7.7.3/src/util.cxx deleted file mode 100644 index fe859bd2a..000000000 --- a/ext/libpqxx-7.7.3/src/util.cxx +++ /dev/null @@ -1,194 +0,0 @@ -/** Various utility functions. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include -#include -#include -#include -#include - -extern "C" -{ -#include -} - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/except.hxx" -#include "pqxx/internal/concat.hxx" -#include "pqxx/util.hxx" - -#include "pqxx/internal/header-post.hxx" - - -using namespace std::literals; - -pqxx::thread_safety_model PQXX_COLD pqxx::describe_thread_safety() -{ - thread_safety_model model; - model.safe_libpq = (PQisthreadsafe() != 0); - // Sadly I'm not aware of any way to avoid this just yet. - model.safe_kerberos = false; - - model.description = internal::concat( - (model.safe_libpq ? ""sv : - "Using a libpq build that is not thread-safe.\n"sv), - (model.safe_kerberos ? - ""sv : - "Kerberos is not thread-safe. If your application uses Kerberos, " - "protect all calls to Kerberos or libpqxx using a global lock.\n"sv)); - return model; -} - - -std::string pqxx::internal::describe_object( - std::string_view class_name, std::string_view obj_name) -{ - if (std::empty(obj_name)) - return std::string{class_name}; - else - return pqxx::internal::concat(class_name, " '", obj_name, "'"); -} - - -void pqxx::internal::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) -{ - if (new_guest == nullptr) - throw internal_error{"Null pointer registered."}; - - if (old_guest != nullptr) - throw usage_error{ - (old_guest == new_guest) ? - concat("Started twice: ", describe_object(old_class, old_name), ".") : - concat( - "Started new ", describe_object(new_class, new_name), " while ", - describe_object(new_class, new_name), " was still active.")}; -} - - -void pqxx::internal::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) -{ - if (new_guest != old_guest) - { - PQXX_UNLIKELY - if (new_guest == nullptr) - throw usage_error{concat( - "Expected to close ", describe_object(old_class, old_name), - ", but got null pointer instead.")}; - if (old_guest == nullptr) - throw usage_error{concat( - "Closed while not open: ", describe_object(new_class, new_name))}; - else - throw usage_error{concat( - "Closed ", describe_object(new_class, new_name), - "; expected to close ", describe_object(old_class, old_name))}; - } -} - - -namespace -{ -constexpr char hex_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - - -/// Translate a number (must be between 0 and 16 exclusive) to a hex digit. -constexpr char hex_digit(int c) noexcept -{ - return hex_digits[c]; -} - - -/// Translate a hex digit to a nibble. Return -1 if it's not a valid digit. -constexpr int nibble(int c) noexcept -{ - if (c >= '0' and c <= '9') - PQXX_LIKELY - return c - '0'; - else if (c >= 'a' and c <= 'f') return 10 + (c - 'a'); - else if (c >= 'A' and c <= 'F') return 10 + (c - 'A'); - else return -1; -} -} // namespace - - -void pqxx::internal::esc_bin( - std::basic_string_view binary_data, char buffer[]) noexcept -{ - auto here{buffer}; - *here++ = '\\'; - *here++ = 'x'; - - for (auto const byte : binary_data) - { - auto uc{static_cast(byte)}; - *here++ = hex_digit(uc >> 4); - *here++ = hex_digit(uc & 0x0f); - } - - // (No need to increment further. Facebook's "infer" complains if we do.) - *here = '\0'; -} - - -std::string -pqxx::internal::esc_bin(std::basic_string_view binary_data) -{ - auto const bytes{size_esc_bin(std::size(binary_data))}; - std::string buf; - buf.resize(bytes); - esc_bin(binary_data, buf.data()); - // Strip off the trailing zero. - buf.resize(bytes - 1); - return buf; -} - - -void pqxx::internal::unesc_bin( - std::string_view escaped_data, std::byte buffer[]) -{ - auto const in_size{std::size(escaped_data)}; - if (in_size < 2) - throw pqxx::failure{"Binary data appears truncated."}; - if ((in_size % 2) != 0) - throw pqxx::failure{"Invalid escaped binary length."}; - char const *in{escaped_data.data()}; - char const *const end{in + in_size}; - if (*in++ != '\\' or *in++ != 'x') - throw pqxx::failure( - "Escaped binary data did not start with '\\x'`. Is the server or libpq " - "too old?"); - auto out{buffer}; - while (in != end) - { - int hi{nibble(*in++)}; - if (hi < 0) - throw pqxx::failure{"Invalid hex-escaped data."}; - int lo{nibble(*in++)}; - if (lo < 0) - throw pqxx::failure{"Invalid hex-escaped data."}; - *out++ = static_cast((hi << 4) | lo); - } -} - - -std::basic_string -pqxx::internal::unesc_bin(std::string_view escaped_data) -{ - auto const bytes{size_unesc_bin(std::size(escaped_data))}; - std::basic_string buf; - buf.resize(bytes); - unesc_bin(escaped_data, buf.data()); - return buf; -} diff --git a/ext/libpqxx-7.7.3/src/version.cxx b/ext/libpqxx-7.7.3/src/version.cxx deleted file mode 100644 index e216ecd4f..000000000 --- a/ext/libpqxx-7.7.3/src/version.cxx +++ /dev/null @@ -1,27 +0,0 @@ -/** Version check. - * - * 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. - */ -#include "pqxx-source.hxx" - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/version.hxx" - -#include "pqxx/internal/header-post.hxx" - - -namespace pqxx::internal -{ -// One, single definition of this function. If a call fails to link, and -// (some) other calls do link, then the libpqxx binary was built against a -// different libpqxx version than the code which is being linked against it. -PQXX_LIBEXPORT int PQXX_VERSION_CHECK() noexcept -{ - return 0; -} -} // namespace pqxx::internal diff --git a/ext/libpqxx-7.7.3/src/wait.cxx b/ext/libpqxx-7.7.3/src/wait.cxx deleted file mode 100644 index 276d9659e..000000000 --- a/ext/libpqxx-7.7.3/src/wait.cxx +++ /dev/null @@ -1,136 +0,0 @@ -/** Functions that wait. - */ -#include "pqxx-source.hxx" - -// The header is still broken on MinGW. :-( -#if defined(PQXX_HAVE_SLEEP_FOR) -# include -#endif - -// For WSAPoll(): -#if __has_include() -# include -# define PQXX_HAVE_SELECT -#endif -#if __has_include() -# include -#endif -#if __has_include() -# include -#endif - -// For poll(): -#if __has_include() -# include -#endif - -// For select() on recent POSIX systems. -#if __has_include() -# include -# define PQXX_HAVE_SELECT -#endif - -// For select() on some older POSIX systems. -#if __has_include() -# include -# define PQXX_HAVE_SELECT -#endif -#if __has_include() -# include -#endif -#if __has_include() -# include -#endif - - -#include "pqxx/internal/header-pre.hxx" - -#include "pqxx/internal/wait.hxx" -#include "pqxx/util.hxx" - -#include "pqxx/internal/header-post.hxx" - - -namespace -{ -template T to_milli(unsigned seconds, unsigned microseconds) -{ - return pqxx::check_cast( - (seconds * 1000) + (microseconds / 1000), - "Wait timeout value out of bounds."); -} - - -#if defined(PQXX_HAVE_SELECT) -/// Set a bit on an fd_set. -[[maybe_unused]] void set_fdbit(fd_set &bits, int fd) -{ -# ifdef _MSC_VER -// Suppress pointless, unfixable warnings in Visual Studio. -# pragma warning(push) -# pragma warning(disable : 4389) // Signed/unsigned mismatch. -# pragma warning(disable : 4127) // Conditional expression is constant. -# endif - FD_SET(fd, &bits); -# ifdef _MSV_VER -// Restore prevalent warning settings. -# pragma warning(pop) -# endif -} -#endif -} // namespace - - -void pqxx::internal::wait_fd( - int fd, bool for_read, bool for_write, unsigned seconds, - unsigned microseconds) -{ -// WSAPoll is available in winsock2.h only for versions of Windows >= 0x0600 -#if defined(_WIN32) && (_WIN32_WINNT >= 0x0600) - short const events{static_cast( - (for_read ? POLLRDNORM : 0) | (for_write ? POLLWRNORM : 0))}; - WSAPOLLFD fdarray{SOCKET(fd), events, 0}; - WSAPoll(&fdarray, 1u, to_milli(seconds, microseconds)); - // TODO: Check for errors. -#elif defined(PQXX_HAVE_POLL) - auto const events{static_cast( - POLLERR | POLLHUP | POLLNVAL | (for_read ? POLLIN : 0) | - (for_write ? POLLOUT : 0))}; - pollfd pfd{fd, events, 0}; - poll(&pfd, 1, to_milli(seconds, microseconds)); - // TODO: Check for errors. -#else - // No poll()? Our last option is select(). - fd_set read_fds; - FD_ZERO(&read_fds); - if (for_read) - set_fdbit(read_fds, fd); - - fd_set write_fds; - FD_ZERO(&write_fds); - if (for_write) - set_fdbit(write_fds, fd); - - fd_set except_fds; - FD_ZERO(&except_fds); - set_fdbit(except_fds, fd); - - timeval tv = {seconds, microseconds}; - select(fd + 1, &read_fds, &write_fds, &except_fds, &tv); - // TODO: Check for errors. -#endif -} - - -void PQXX_COLD pqxx::internal::wait_for(unsigned int microseconds) -{ -#if defined(PQXX_HAVE_SLEEP_FOR) - std::this_thread::sleep_for(std::chrono::microseconds{microseconds}); -#else - // MinGW still does not have a functioning header. Work around this - // using select(). - // Not worth optimising for though -- they'll have to fix it at some point. - timeval tv{microseconds / 1'000'000u, microseconds % 1'000'000u}; - select(0, nullptr, nullptr, nullptr, &tv); -#endif -} diff --git a/ext/libpqxx-7.7.3/test/CMakeLists.txt b/ext/libpqxx-7.7.3/test/CMakeLists.txt deleted file mode 100644 index 331631145..000000000 --- a/ext/libpqxx-7.7.3/test/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -enable_testing() - -if(NOT PostgreSQL_FOUND) - find_package(PostgreSQL REQUIRED) -endif() - -file(GLOB TEST_SOURCES test*.cxx unit/test_*.cxx runner.cxx) - -add_executable(runner ${TEST_SOURCES}) -target_link_libraries(runner PUBLIC pqxx) -target_include_directories(runner PRIVATE ${PostgreSQL_INCLUDE_DIRS}) -add_test( - NAME runner - WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - COMMAND runner -) - -if(INSTALL_TEST) - install( - PROGRAMS runner - TYPE BIN - RENAME libpqxx-test-runner - ) -endif() diff --git a/ext/libpqxx-7.7.3/test/Makefile.am b/ext/libpqxx-7.7.3/test/Makefile.am deleted file mode 100644 index e3ce4be7b..000000000 --- a/ext/libpqxx-7.7.3/test/Makefile.am +++ /dev/null @@ -1,129 +0,0 @@ -# ############################################################################## -# 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 './test/Makefile.am.template'. -# ############################################################################## -# Makefile.am is generated automatically for automake whenever test programs are -# added to libpqxx. - -EXTRA_DIST = Makefile.am.template - -# Use the serial test runner, so tests don't get run in parallel. Otherwise, -# output from test failures will be hidden away in log files where we can't -# see them when running in a build slave. -AUTOMAKE_OPTIONS=serial-tests - - -AM_CPPFLAGS=-I$(top_builddir)/include -I$(top_srcdir)/include - -# Override automatically generated list of default includes. It contains only -# unnecessary entries, and incorrectly mentions include/pqxx directly. -DEFAULT_INCLUDES= - -noinst_HEADERS = test_helpers.hxx - -CLEANFILES=pqxxlo.txt -MAINTAINERCLEANFILES=Makefile.in - -#TESTS_ENVIRONMENT=PGDATABASE=libpqxx -# PGDATABASE, PGHOST, PGPORT, PGUSER - -runner_SOURCES = \ - test00.cxx \ - test01.cxx \ - test02.cxx \ - test04.cxx \ - test07.cxx \ - test10.cxx \ - test11.cxx \ - test13.cxx \ - test14.cxx \ - test16.cxx \ - test17.cxx \ - test18.cxx \ - test20.cxx \ - test21.cxx \ - test26.cxx \ - test29.cxx \ - test30.cxx \ - test32.cxx \ - test37.cxx \ - test39.cxx \ - test46.cxx \ - test56.cxx \ - test60.cxx \ - test61.cxx \ - test62.cxx \ - test69.cxx \ - test70.cxx \ - test71.cxx \ - test72.cxx \ - test74.cxx \ - test75.cxx \ - test76.cxx \ - test77.cxx \ - test78.cxx \ - test79.cxx \ - test82.cxx \ - test84.cxx \ - test87.cxx \ - test88.cxx \ - test89.cxx \ - test90.cxx \ - unit/test_array.cxx \ - unit/test_binarystring.cxx \ - unit/test_blob.cxx \ - unit/test_cancel_query.cxx \ - unit/test_column.cxx \ - unit/test_composite.cxx \ - unit/test_connection.cxx \ - unit/test_cursor.cxx \ - unit/test_encodings.cxx \ - unit/test_error_verbosity.cxx \ - unit/test_errorhandler.cxx \ - unit/test_escape.cxx \ - unit/test_exceptions.cxx \ - unit/test_field.cxx \ - unit/test_float.cxx \ - unit/test_largeobject.cxx \ - unit/test_nonblocking_connect.cxx \ - unit/test_notification.cxx \ - unit/test_pipeline.cxx \ - unit/test_prepared_statement.cxx \ - unit/test_range.cxx \ - unit/test_read_transaction.cxx \ - unit/test_result_iteration.cxx \ - unit/test_result_slicing.cxx \ - unit/test_row.cxx \ - unit/test_separated_list.cxx \ - unit/test_simultaneous_transactions.cxx \ - unit/test_sql_cursor.cxx \ - unit/test_stateless_cursor.cxx \ - unit/test_strconv.cxx \ - unit/test_stream_from.cxx \ - unit/test_stream_to.cxx \ - unit/test_string_conversion.cxx \ - unit/test_subtransaction.cxx \ - unit/test_test_helpers.cxx \ - unit/test_thread_safety_model.cxx \ - unit/test_time.cxx \ - unit/test_transaction.cxx \ - unit/test_transaction_base.cxx \ - unit/test_transaction_focus.cxx \ - unit/test_transactor.cxx \ - unit/test_type_name.cxx \ - unit/test_zview.cxx \ - runner.cxx - -runner_LDADD = $(top_builddir)/src/libpqxx.la ${POSTGRES_LIB} - -TESTS = runner -check_PROGRAMS = ${TESTS} diff --git a/ext/libpqxx-7.7.3/test/Makefile.am.template b/ext/libpqxx-7.7.3/test/Makefile.am.template deleted file mode 100644 index 2a21f6ef7..000000000 --- a/ext/libpqxx-7.7.3/test/Makefile.am.template +++ /dev/null @@ -1,38 +0,0 @@ -# Makefile.am is generated automatically for automake whenever test programs are -# added to libpqxx. - -EXTRA_DIST = Makefile.am.template - -# Use the serial test runner, so tests don't get run in parallel. Otherwise, -# output from test failures will be hidden away in log files where we can't -# see them when running in a build slave. -AUTOMAKE_OPTIONS=serial-tests - - -AM_CPPFLAGS=-I$(top_builddir)/include -I$(top_srcdir)/include - -# Override automatically generated list of default includes. It contains only -# unnecessary entries, and incorrectly mentions include/pqxx directly. -DEFAULT_INCLUDES= - -noinst_HEADERS = test_helpers.hxx - -CLEANFILES=pqxxlo.txt -MAINTAINERCLEANFILES=Makefile.in - -#TESTS_ENVIRONMENT=PGDATABASE=libpqxx -# PGDATABASE, PGHOST, PGPORT, PGUSER - -runner_SOURCES = \ -###MAKTEMPLATE:FOREACH test/test*.cxx - ###BASENAME###.cxx \ -###MAKTEMPLATE:ENDFOREACH -###MAKTEMPLATE:FOREACH test/unit/test_*.cxx - unit/###BASENAME###.cxx \ -###MAKTEMPLATE:ENDFOREACH - runner.cxx - -runner_LDADD = $(top_builddir)/src/libpqxx.la ${POSTGRES_LIB} - -TESTS = runner -check_PROGRAMS = ${TESTS} diff --git a/ext/libpqxx-7.7.3/test/Makefile.in b/ext/libpqxx-7.7.3/test/Makefile.in deleted file mode 100644 index 8ffcca06c..000000000 --- a/ext/libpqxx-7.7.3/test/Makefile.in +++ /dev/null @@ -1,1302 +0,0 @@ -# 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@ - -# ############################################################################## -# 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 './test/Makefile.am.template'. -# ############################################################################## -# Makefile.am is generated automatically for automake whenever test programs are -# added to libpqxx. - -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@ -TESTS = runner$(EXEEXT) -check_PROGRAMS = $(am__EXEEXT_1) -subdir = test -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 = $(top_builddir)/include/pqxx/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__EXEEXT_1 = runner$(EXEEXT) -am__dirstamp = $(am__leading_dot)dirstamp -am_runner_OBJECTS = test00.$(OBJEXT) test01.$(OBJEXT) test02.$(OBJEXT) \ - test04.$(OBJEXT) test07.$(OBJEXT) test10.$(OBJEXT) \ - test11.$(OBJEXT) test13.$(OBJEXT) test14.$(OBJEXT) \ - test16.$(OBJEXT) test17.$(OBJEXT) test18.$(OBJEXT) \ - test20.$(OBJEXT) test21.$(OBJEXT) test26.$(OBJEXT) \ - test29.$(OBJEXT) test30.$(OBJEXT) test32.$(OBJEXT) \ - test37.$(OBJEXT) test39.$(OBJEXT) test46.$(OBJEXT) \ - test56.$(OBJEXT) test60.$(OBJEXT) test61.$(OBJEXT) \ - test62.$(OBJEXT) test69.$(OBJEXT) test70.$(OBJEXT) \ - test71.$(OBJEXT) test72.$(OBJEXT) test74.$(OBJEXT) \ - test75.$(OBJEXT) test76.$(OBJEXT) test77.$(OBJEXT) \ - test78.$(OBJEXT) test79.$(OBJEXT) test82.$(OBJEXT) \ - test84.$(OBJEXT) test87.$(OBJEXT) test88.$(OBJEXT) \ - test89.$(OBJEXT) test90.$(OBJEXT) unit/test_array.$(OBJEXT) \ - unit/test_binarystring.$(OBJEXT) unit/test_blob.$(OBJEXT) \ - unit/test_cancel_query.$(OBJEXT) unit/test_column.$(OBJEXT) \ - unit/test_composite.$(OBJEXT) unit/test_connection.$(OBJEXT) \ - unit/test_cursor.$(OBJEXT) unit/test_encodings.$(OBJEXT) \ - unit/test_error_verbosity.$(OBJEXT) \ - unit/test_errorhandler.$(OBJEXT) unit/test_escape.$(OBJEXT) \ - unit/test_exceptions.$(OBJEXT) unit/test_field.$(OBJEXT) \ - unit/test_float.$(OBJEXT) unit/test_largeobject.$(OBJEXT) \ - unit/test_nonblocking_connect.$(OBJEXT) \ - unit/test_notification.$(OBJEXT) unit/test_pipeline.$(OBJEXT) \ - unit/test_prepared_statement.$(OBJEXT) \ - unit/test_range.$(OBJEXT) unit/test_read_transaction.$(OBJEXT) \ - unit/test_result_iteration.$(OBJEXT) \ - unit/test_result_slicing.$(OBJEXT) unit/test_row.$(OBJEXT) \ - unit/test_separated_list.$(OBJEXT) \ - unit/test_simultaneous_transactions.$(OBJEXT) \ - unit/test_sql_cursor.$(OBJEXT) \ - unit/test_stateless_cursor.$(OBJEXT) \ - unit/test_strconv.$(OBJEXT) unit/test_stream_from.$(OBJEXT) \ - unit/test_stream_to.$(OBJEXT) \ - unit/test_string_conversion.$(OBJEXT) \ - unit/test_subtransaction.$(OBJEXT) \ - unit/test_test_helpers.$(OBJEXT) \ - unit/test_thread_safety_model.$(OBJEXT) \ - unit/test_time.$(OBJEXT) unit/test_transaction.$(OBJEXT) \ - unit/test_transaction_base.$(OBJEXT) \ - unit/test_transaction_focus.$(OBJEXT) \ - unit/test_transactor.$(OBJEXT) unit/test_type_name.$(OBJEXT) \ - unit/test_zview.$(OBJEXT) runner.$(OBJEXT) -runner_OBJECTS = $(am_runner_OBJECTS) -runner_DEPENDENCIES = $(top_builddir)/src/libpqxx.la -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -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 = -depcomp = $(SHELL) $(top_srcdir)/config/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/runner.Po ./$(DEPDIR)/test00.Po \ - ./$(DEPDIR)/test01.Po ./$(DEPDIR)/test02.Po \ - ./$(DEPDIR)/test04.Po ./$(DEPDIR)/test07.Po \ - ./$(DEPDIR)/test10.Po ./$(DEPDIR)/test11.Po \ - ./$(DEPDIR)/test13.Po ./$(DEPDIR)/test14.Po \ - ./$(DEPDIR)/test16.Po ./$(DEPDIR)/test17.Po \ - ./$(DEPDIR)/test18.Po ./$(DEPDIR)/test20.Po \ - ./$(DEPDIR)/test21.Po ./$(DEPDIR)/test26.Po \ - ./$(DEPDIR)/test29.Po ./$(DEPDIR)/test30.Po \ - ./$(DEPDIR)/test32.Po ./$(DEPDIR)/test37.Po \ - ./$(DEPDIR)/test39.Po ./$(DEPDIR)/test46.Po \ - ./$(DEPDIR)/test56.Po ./$(DEPDIR)/test60.Po \ - ./$(DEPDIR)/test61.Po ./$(DEPDIR)/test62.Po \ - ./$(DEPDIR)/test69.Po ./$(DEPDIR)/test70.Po \ - ./$(DEPDIR)/test71.Po ./$(DEPDIR)/test72.Po \ - ./$(DEPDIR)/test74.Po ./$(DEPDIR)/test75.Po \ - ./$(DEPDIR)/test76.Po ./$(DEPDIR)/test77.Po \ - ./$(DEPDIR)/test78.Po ./$(DEPDIR)/test79.Po \ - ./$(DEPDIR)/test82.Po ./$(DEPDIR)/test84.Po \ - ./$(DEPDIR)/test87.Po ./$(DEPDIR)/test88.Po \ - ./$(DEPDIR)/test89.Po ./$(DEPDIR)/test90.Po \ - unit/$(DEPDIR)/test_array.Po \ - unit/$(DEPDIR)/test_binarystring.Po \ - unit/$(DEPDIR)/test_blob.Po \ - unit/$(DEPDIR)/test_cancel_query.Po \ - unit/$(DEPDIR)/test_column.Po unit/$(DEPDIR)/test_composite.Po \ - unit/$(DEPDIR)/test_connection.Po \ - unit/$(DEPDIR)/test_cursor.Po unit/$(DEPDIR)/test_encodings.Po \ - unit/$(DEPDIR)/test_error_verbosity.Po \ - unit/$(DEPDIR)/test_errorhandler.Po \ - unit/$(DEPDIR)/test_escape.Po \ - unit/$(DEPDIR)/test_exceptions.Po unit/$(DEPDIR)/test_field.Po \ - unit/$(DEPDIR)/test_float.Po \ - unit/$(DEPDIR)/test_largeobject.Po \ - unit/$(DEPDIR)/test_nonblocking_connect.Po \ - unit/$(DEPDIR)/test_notification.Po \ - unit/$(DEPDIR)/test_pipeline.Po \ - unit/$(DEPDIR)/test_prepared_statement.Po \ - unit/$(DEPDIR)/test_range.Po \ - unit/$(DEPDIR)/test_read_transaction.Po \ - unit/$(DEPDIR)/test_result_iteration.Po \ - unit/$(DEPDIR)/test_result_slicing.Po \ - unit/$(DEPDIR)/test_row.Po \ - unit/$(DEPDIR)/test_separated_list.Po \ - unit/$(DEPDIR)/test_simultaneous_transactions.Po \ - unit/$(DEPDIR)/test_sql_cursor.Po \ - unit/$(DEPDIR)/test_stateless_cursor.Po \ - unit/$(DEPDIR)/test_strconv.Po \ - unit/$(DEPDIR)/test_stream_from.Po \ - unit/$(DEPDIR)/test_stream_to.Po \ - unit/$(DEPDIR)/test_string_conversion.Po \ - unit/$(DEPDIR)/test_subtransaction.Po \ - unit/$(DEPDIR)/test_test_helpers.Po \ - unit/$(DEPDIR)/test_thread_safety_model.Po \ - unit/$(DEPDIR)/test_time.Po unit/$(DEPDIR)/test_transaction.Po \ - unit/$(DEPDIR)/test_transaction_base.Po \ - unit/$(DEPDIR)/test_transaction_focus.Po \ - unit/$(DEPDIR)/test_transactor.Po \ - unit/$(DEPDIR)/test_type_name.Po unit/$(DEPDIR)/test_zview.Po -am__mv = mv -f -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -AM_V_CXX = $(am__v_CXX_@AM_V@) -am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) -am__v_CXX_0 = @echo " CXX " $@; -am__v_CXX_1 = -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) -am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) -am__v_CXXLD_0 = @echo " CXXLD " $@; -am__v_CXXLD_1 = -SOURCES = $(runner_SOURCES) -DIST_SOURCES = $(runner_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -HEADERS = $(noinst_HEADERS) -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__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ - $(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@ -EXTRA_DIST = Makefile.am.template - -# Use the serial test runner, so tests don't get run in parallel. Otherwise, -# output from test failures will be hidden away in log files where we can't -# see them when running in a build slave. -AUTOMAKE_OPTIONS = serial-tests -AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include - -# Override automatically generated list of default includes. It contains only -# unnecessary entries, and incorrectly mentions include/pqxx directly. -DEFAULT_INCLUDES = -noinst_HEADERS = test_helpers.hxx -CLEANFILES = pqxxlo.txt -MAINTAINERCLEANFILES = Makefile.in - -#TESTS_ENVIRONMENT=PGDATABASE=libpqxx -# PGDATABASE, PGHOST, PGPORT, PGUSER -runner_SOURCES = \ - test00.cxx \ - test01.cxx \ - test02.cxx \ - test04.cxx \ - test07.cxx \ - test10.cxx \ - test11.cxx \ - test13.cxx \ - test14.cxx \ - test16.cxx \ - test17.cxx \ - test18.cxx \ - test20.cxx \ - test21.cxx \ - test26.cxx \ - test29.cxx \ - test30.cxx \ - test32.cxx \ - test37.cxx \ - test39.cxx \ - test46.cxx \ - test56.cxx \ - test60.cxx \ - test61.cxx \ - test62.cxx \ - test69.cxx \ - test70.cxx \ - test71.cxx \ - test72.cxx \ - test74.cxx \ - test75.cxx \ - test76.cxx \ - test77.cxx \ - test78.cxx \ - test79.cxx \ - test82.cxx \ - test84.cxx \ - test87.cxx \ - test88.cxx \ - test89.cxx \ - test90.cxx \ - unit/test_array.cxx \ - unit/test_binarystring.cxx \ - unit/test_blob.cxx \ - unit/test_cancel_query.cxx \ - unit/test_column.cxx \ - unit/test_composite.cxx \ - unit/test_connection.cxx \ - unit/test_cursor.cxx \ - unit/test_encodings.cxx \ - unit/test_error_verbosity.cxx \ - unit/test_errorhandler.cxx \ - unit/test_escape.cxx \ - unit/test_exceptions.cxx \ - unit/test_field.cxx \ - unit/test_float.cxx \ - unit/test_largeobject.cxx \ - unit/test_nonblocking_connect.cxx \ - unit/test_notification.cxx \ - unit/test_pipeline.cxx \ - unit/test_prepared_statement.cxx \ - unit/test_range.cxx \ - unit/test_read_transaction.cxx \ - unit/test_result_iteration.cxx \ - unit/test_result_slicing.cxx \ - unit/test_row.cxx \ - unit/test_separated_list.cxx \ - unit/test_simultaneous_transactions.cxx \ - unit/test_sql_cursor.cxx \ - unit/test_stateless_cursor.cxx \ - unit/test_strconv.cxx \ - unit/test_stream_from.cxx \ - unit/test_stream_to.cxx \ - unit/test_string_conversion.cxx \ - unit/test_subtransaction.cxx \ - unit/test_test_helpers.cxx \ - unit/test_thread_safety_model.cxx \ - unit/test_time.cxx \ - unit/test_transaction.cxx \ - unit/test_transaction_base.cxx \ - unit/test_transaction_focus.cxx \ - unit/test_transactor.cxx \ - unit/test_type_name.cxx \ - unit/test_zview.cxx \ - runner.cxx - -runner_LDADD = $(top_builddir)/src/libpqxx.la ${POSTGRES_LIB} -all: all-am - -.SUFFIXES: -.SUFFIXES: .cxx .lo .o .obj -$(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 test/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu test/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): - -clean-checkPROGRAMS: - @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list -unit/$(am__dirstamp): - @$(MKDIR_P) unit - @: > unit/$(am__dirstamp) -unit/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) unit/$(DEPDIR) - @: > unit/$(DEPDIR)/$(am__dirstamp) -unit/test_array.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_binarystring.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_blob.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_cancel_query.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_column.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_composite.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_connection.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_cursor.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_encodings.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_error_verbosity.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_errorhandler.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_escape.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_exceptions.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_field.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_float.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_largeobject.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_nonblocking_connect.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_notification.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_pipeline.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_prepared_statement.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_range.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_read_transaction.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_result_iteration.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_result_slicing.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_row.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_separated_list.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_simultaneous_transactions.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_sql_cursor.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_stateless_cursor.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_strconv.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_stream_from.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_stream_to.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_string_conversion.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_subtransaction.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_test_helpers.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_thread_safety_model.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_time.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_transaction.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_transaction_base.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_transaction_focus.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_transactor.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_type_name.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test_zview.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) - -runner$(EXEEXT): $(runner_OBJECTS) $(runner_DEPENDENCIES) $(EXTRA_runner_DEPENDENCIES) - @rm -f runner$(EXEEXT) - $(AM_V_CXXLD)$(CXXLINK) $(runner_OBJECTS) $(runner_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f unit/*.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/runner.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test00.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test01.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test02.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test04.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test07.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test10.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test11.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test13.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test14.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test16.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test17.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test18.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test20.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test21.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test26.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test29.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test30.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test32.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test37.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test39.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test46.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test56.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test60.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test61.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test62.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test69.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test70.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test71.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test72.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test74.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test75.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test76.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test77.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test78.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test79.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test82.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test84.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test87.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test88.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test89.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test90.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_array.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_binarystring.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_blob.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_cancel_query.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_column.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_composite.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_connection.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_cursor.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_encodings.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_error_verbosity.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_errorhandler.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_escape.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_exceptions.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_field.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_float.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_largeobject.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_nonblocking_connect.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_notification.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_pipeline.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_prepared_statement.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_range.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_read_transaction.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_result_iteration.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_result_slicing.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_row.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_separated_list.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_simultaneous_transactions.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_sql_cursor.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_stateless_cursor.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_strconv.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_stream_from.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_stream_to.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_string_conversion.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_subtransaction.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_test_helpers.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_thread_safety_model.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_time.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_transaction.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_transaction_base.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_transaction_focus.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_transactor.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_type_name.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_zview.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.cxx.o: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< - -.cxx.obj: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.cxx.lo: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; \ - srcdir=$(srcdir); export srcdir; \ - list=' $(TESTS) '; \ - $(am__tty_colors); \ - if test -n "$$list"; then \ - for tst in $$list; do \ - if test -f ./$$tst; then dir=./; \ - elif test -f $$tst; then dir=; \ - else dir="$(srcdir)/"; fi; \ - if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xpass=`expr $$xpass + 1`; \ - failed=`expr $$failed + 1`; \ - col=$$red; res=XPASS; \ - ;; \ - *) \ - col=$$grn; res=PASS; \ - ;; \ - esac; \ - elif test $$? -ne 77; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xfail=`expr $$xfail + 1`; \ - col=$$lgn; res=XFAIL; \ - ;; \ - *) \ - failed=`expr $$failed + 1`; \ - col=$$red; res=FAIL; \ - ;; \ - esac; \ - else \ - skip=`expr $$skip + 1`; \ - col=$$blu; res=SKIP; \ - fi; \ - echo "$${col}$$res$${std}: $$tst"; \ - done; \ - if test "$$all" -eq 1; then \ - tests="test"; \ - All=""; \ - else \ - tests="tests"; \ - All="All "; \ - fi; \ - if test "$$failed" -eq 0; then \ - if test "$$xfail" -eq 0; then \ - banner="$$All$$all $$tests passed"; \ - else \ - if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ - banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ - fi; \ - else \ - if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all $$tests failed"; \ - else \ - if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ - banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ - fi; \ - fi; \ - dashes="$$banner"; \ - skipped=""; \ - if test "$$skip" -ne 0; then \ - if test "$$skip" -eq 1; then \ - skipped="($$skip test was not run)"; \ - else \ - skipped="($$skip tests were not run)"; \ - fi; \ - test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$skipped"; \ - fi; \ - report=""; \ - if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ - report="Please report to $(PACKAGE_BUGREPORT)"; \ - test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$report"; \ - fi; \ - dashes=`echo "$$dashes" | sed s/./=/g`; \ - if test "$$failed" -eq 0; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - fi; \ - echo "$${col}$$dashes$${std}"; \ - echo "$${col}$$banner$${std}"; \ - test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ - test -z "$$report" || echo "$${col}$$report$${std}"; \ - echo "$${col}$$dashes$${std}"; \ - test "$$failed" -eq 0; \ - else :; fi -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am -all-am: Makefile $(HEADERS) -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: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -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) - -rm -f unit/$(DEPDIR)/$(am__dirstamp) - -rm -f unit/$(am__dirstamp) - -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-checkPROGRAMS clean-generic clean-libtool \ - mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/runner.Po - -rm -f ./$(DEPDIR)/test00.Po - -rm -f ./$(DEPDIR)/test01.Po - -rm -f ./$(DEPDIR)/test02.Po - -rm -f ./$(DEPDIR)/test04.Po - -rm -f ./$(DEPDIR)/test07.Po - -rm -f ./$(DEPDIR)/test10.Po - -rm -f ./$(DEPDIR)/test11.Po - -rm -f ./$(DEPDIR)/test13.Po - -rm -f ./$(DEPDIR)/test14.Po - -rm -f ./$(DEPDIR)/test16.Po - -rm -f ./$(DEPDIR)/test17.Po - -rm -f ./$(DEPDIR)/test18.Po - -rm -f ./$(DEPDIR)/test20.Po - -rm -f ./$(DEPDIR)/test21.Po - -rm -f ./$(DEPDIR)/test26.Po - -rm -f ./$(DEPDIR)/test29.Po - -rm -f ./$(DEPDIR)/test30.Po - -rm -f ./$(DEPDIR)/test32.Po - -rm -f ./$(DEPDIR)/test37.Po - -rm -f ./$(DEPDIR)/test39.Po - -rm -f ./$(DEPDIR)/test46.Po - -rm -f ./$(DEPDIR)/test56.Po - -rm -f ./$(DEPDIR)/test60.Po - -rm -f ./$(DEPDIR)/test61.Po - -rm -f ./$(DEPDIR)/test62.Po - -rm -f ./$(DEPDIR)/test69.Po - -rm -f ./$(DEPDIR)/test70.Po - -rm -f ./$(DEPDIR)/test71.Po - -rm -f ./$(DEPDIR)/test72.Po - -rm -f ./$(DEPDIR)/test74.Po - -rm -f ./$(DEPDIR)/test75.Po - -rm -f ./$(DEPDIR)/test76.Po - -rm -f ./$(DEPDIR)/test77.Po - -rm -f ./$(DEPDIR)/test78.Po - -rm -f ./$(DEPDIR)/test79.Po - -rm -f ./$(DEPDIR)/test82.Po - -rm -f ./$(DEPDIR)/test84.Po - -rm -f ./$(DEPDIR)/test87.Po - -rm -f ./$(DEPDIR)/test88.Po - -rm -f ./$(DEPDIR)/test89.Po - -rm -f ./$(DEPDIR)/test90.Po - -rm -f unit/$(DEPDIR)/test_array.Po - -rm -f unit/$(DEPDIR)/test_binarystring.Po - -rm -f unit/$(DEPDIR)/test_blob.Po - -rm -f unit/$(DEPDIR)/test_cancel_query.Po - -rm -f unit/$(DEPDIR)/test_column.Po - -rm -f unit/$(DEPDIR)/test_composite.Po - -rm -f unit/$(DEPDIR)/test_connection.Po - -rm -f unit/$(DEPDIR)/test_cursor.Po - -rm -f unit/$(DEPDIR)/test_encodings.Po - -rm -f unit/$(DEPDIR)/test_error_verbosity.Po - -rm -f unit/$(DEPDIR)/test_errorhandler.Po - -rm -f unit/$(DEPDIR)/test_escape.Po - -rm -f unit/$(DEPDIR)/test_exceptions.Po - -rm -f unit/$(DEPDIR)/test_field.Po - -rm -f unit/$(DEPDIR)/test_float.Po - -rm -f unit/$(DEPDIR)/test_largeobject.Po - -rm -f unit/$(DEPDIR)/test_nonblocking_connect.Po - -rm -f unit/$(DEPDIR)/test_notification.Po - -rm -f unit/$(DEPDIR)/test_pipeline.Po - -rm -f unit/$(DEPDIR)/test_prepared_statement.Po - -rm -f unit/$(DEPDIR)/test_range.Po - -rm -f unit/$(DEPDIR)/test_read_transaction.Po - -rm -f unit/$(DEPDIR)/test_result_iteration.Po - -rm -f unit/$(DEPDIR)/test_result_slicing.Po - -rm -f unit/$(DEPDIR)/test_row.Po - -rm -f unit/$(DEPDIR)/test_separated_list.Po - -rm -f unit/$(DEPDIR)/test_simultaneous_transactions.Po - -rm -f unit/$(DEPDIR)/test_sql_cursor.Po - -rm -f unit/$(DEPDIR)/test_stateless_cursor.Po - -rm -f unit/$(DEPDIR)/test_strconv.Po - -rm -f unit/$(DEPDIR)/test_stream_from.Po - -rm -f unit/$(DEPDIR)/test_stream_to.Po - -rm -f unit/$(DEPDIR)/test_string_conversion.Po - -rm -f unit/$(DEPDIR)/test_subtransaction.Po - -rm -f unit/$(DEPDIR)/test_test_helpers.Po - -rm -f unit/$(DEPDIR)/test_thread_safety_model.Po - -rm -f unit/$(DEPDIR)/test_time.Po - -rm -f unit/$(DEPDIR)/test_transaction.Po - -rm -f unit/$(DEPDIR)/test_transaction_base.Po - -rm -f unit/$(DEPDIR)/test_transaction_focus.Po - -rm -f unit/$(DEPDIR)/test_transactor.Po - -rm -f unit/$(DEPDIR)/test_type_name.Po - -rm -f unit/$(DEPDIR)/test_zview.Po - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/runner.Po - -rm -f ./$(DEPDIR)/test00.Po - -rm -f ./$(DEPDIR)/test01.Po - -rm -f ./$(DEPDIR)/test02.Po - -rm -f ./$(DEPDIR)/test04.Po - -rm -f ./$(DEPDIR)/test07.Po - -rm -f ./$(DEPDIR)/test10.Po - -rm -f ./$(DEPDIR)/test11.Po - -rm -f ./$(DEPDIR)/test13.Po - -rm -f ./$(DEPDIR)/test14.Po - -rm -f ./$(DEPDIR)/test16.Po - -rm -f ./$(DEPDIR)/test17.Po - -rm -f ./$(DEPDIR)/test18.Po - -rm -f ./$(DEPDIR)/test20.Po - -rm -f ./$(DEPDIR)/test21.Po - -rm -f ./$(DEPDIR)/test26.Po - -rm -f ./$(DEPDIR)/test29.Po - -rm -f ./$(DEPDIR)/test30.Po - -rm -f ./$(DEPDIR)/test32.Po - -rm -f ./$(DEPDIR)/test37.Po - -rm -f ./$(DEPDIR)/test39.Po - -rm -f ./$(DEPDIR)/test46.Po - -rm -f ./$(DEPDIR)/test56.Po - -rm -f ./$(DEPDIR)/test60.Po - -rm -f ./$(DEPDIR)/test61.Po - -rm -f ./$(DEPDIR)/test62.Po - -rm -f ./$(DEPDIR)/test69.Po - -rm -f ./$(DEPDIR)/test70.Po - -rm -f ./$(DEPDIR)/test71.Po - -rm -f ./$(DEPDIR)/test72.Po - -rm -f ./$(DEPDIR)/test74.Po - -rm -f ./$(DEPDIR)/test75.Po - -rm -f ./$(DEPDIR)/test76.Po - -rm -f ./$(DEPDIR)/test77.Po - -rm -f ./$(DEPDIR)/test78.Po - -rm -f ./$(DEPDIR)/test79.Po - -rm -f ./$(DEPDIR)/test82.Po - -rm -f ./$(DEPDIR)/test84.Po - -rm -f ./$(DEPDIR)/test87.Po - -rm -f ./$(DEPDIR)/test88.Po - -rm -f ./$(DEPDIR)/test89.Po - -rm -f ./$(DEPDIR)/test90.Po - -rm -f unit/$(DEPDIR)/test_array.Po - -rm -f unit/$(DEPDIR)/test_binarystring.Po - -rm -f unit/$(DEPDIR)/test_blob.Po - -rm -f unit/$(DEPDIR)/test_cancel_query.Po - -rm -f unit/$(DEPDIR)/test_column.Po - -rm -f unit/$(DEPDIR)/test_composite.Po - -rm -f unit/$(DEPDIR)/test_connection.Po - -rm -f unit/$(DEPDIR)/test_cursor.Po - -rm -f unit/$(DEPDIR)/test_encodings.Po - -rm -f unit/$(DEPDIR)/test_error_verbosity.Po - -rm -f unit/$(DEPDIR)/test_errorhandler.Po - -rm -f unit/$(DEPDIR)/test_escape.Po - -rm -f unit/$(DEPDIR)/test_exceptions.Po - -rm -f unit/$(DEPDIR)/test_field.Po - -rm -f unit/$(DEPDIR)/test_float.Po - -rm -f unit/$(DEPDIR)/test_largeobject.Po - -rm -f unit/$(DEPDIR)/test_nonblocking_connect.Po - -rm -f unit/$(DEPDIR)/test_notification.Po - -rm -f unit/$(DEPDIR)/test_pipeline.Po - -rm -f unit/$(DEPDIR)/test_prepared_statement.Po - -rm -f unit/$(DEPDIR)/test_range.Po - -rm -f unit/$(DEPDIR)/test_read_transaction.Po - -rm -f unit/$(DEPDIR)/test_result_iteration.Po - -rm -f unit/$(DEPDIR)/test_result_slicing.Po - -rm -f unit/$(DEPDIR)/test_row.Po - -rm -f unit/$(DEPDIR)/test_separated_list.Po - -rm -f unit/$(DEPDIR)/test_simultaneous_transactions.Po - -rm -f unit/$(DEPDIR)/test_sql_cursor.Po - -rm -f unit/$(DEPDIR)/test_stateless_cursor.Po - -rm -f unit/$(DEPDIR)/test_strconv.Po - -rm -f unit/$(DEPDIR)/test_stream_from.Po - -rm -f unit/$(DEPDIR)/test_stream_to.Po - -rm -f unit/$(DEPDIR)/test_string_conversion.Po - -rm -f unit/$(DEPDIR)/test_subtransaction.Po - -rm -f unit/$(DEPDIR)/test_test_helpers.Po - -rm -f unit/$(DEPDIR)/test_thread_safety_model.Po - -rm -f unit/$(DEPDIR)/test_time.Po - -rm -f unit/$(DEPDIR)/test_transaction.Po - -rm -f unit/$(DEPDIR)/test_transaction_base.Po - -rm -f unit/$(DEPDIR)/test_transaction_focus.Po - -rm -f unit/$(DEPDIR)/test_transactor.Po - -rm -f unit/$(DEPDIR)/test_type_name.Po - -rm -f unit/$(DEPDIR)/test_zview.Po - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: check-am install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ - check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ - cscopelist-am ctags ctags-am distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - - -# 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/test/runner.cxx b/ext/libpqxx-7.7.3/test/runner.cxx deleted file mode 100644 index 38c9849d8..000000000 --- a/ext/libpqxx-7.7.3/test/runner.cxx +++ /dev/null @@ -1,203 +0,0 @@ -/* libpqxx test runner. - */ -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "test_helpers.hxx" - -namespace -{ -inline std::string deref_field(pqxx::field const &f) -{ - return f.c_str(); -} -} // namespace - - -namespace pqxx::test -{ -test_failure::test_failure( - std::string const &ffile, int fline, std::string const &desc) : - std::logic_error(desc), m_file(ffile), m_line(fline) -{} - -test_failure::~test_failure() noexcept = default; - - -/// Drop table, if it exists. -inline void drop_table(transaction_base &t, std::string const &table) -{ - t.exec("DROP TABLE IF EXISTS " + table); -} - - -[[noreturn]] void -check_notreached(char const file[], int line, std::string desc) -{ - throw test_failure(file, line, desc); -} - - -void check( - char const file[], int line, bool condition, char const text[], - std::string const &desc) -{ - if (not condition) - throw test_failure( - file, line, desc + " (failed expression: " + text + ")"); -} - - -void expected_exception(std::string const &message) -{ - std::cout << "(Expected) " << message << std::endl; -} - - -std::string list_row(row Obj) -{ - return separated_list(", ", std::begin(Obj), std::end(Obj), deref_field); -} - - -std::string list_result(result Obj) -{ - if (std::empty(Obj)) - return ""; - return "{" + - separated_list( - "}\n{", std::begin(Obj), std::end(Obj), - [](row r) { return list_row(r); }) + - "}"; -} - - -std::string list_result_iterator(result::const_iterator Obj) -{ - return ""; -} - - -void create_pqxxevents(transaction_base &t) -{ - t.exec( - "CREATE TEMP TABLE pqxxevents(year integer, event varchar) " - "ON COMMIT PRESERVE ROWS"); - t.exec("INSERT INTO pqxxevents(year, event) VALUES (71, 'jtv')"); - t.exec("INSERT INTO pqxxevents(year, event) VALUES (38, 'time_t overflow')"); - t.exec( - "INSERT INTO pqxxevents(year, event) VALUES (1, '''911'' WTC attack')"); - t.exec("INSERT INTO pqxxevents(year, event) VALUES (81, 'C:\\>')"); - t.exec( - "INSERT INTO pqxxevents(year, event) VALUES (1978, 'bloody\t\tcold')"); - t.exec("INSERT INTO pqxxevents(year, event) VALUES (99, '')"); - t.exec("INSERT INTO pqxxevents(year, event) VALUES (2002, 'libpqxx')"); - t.exec( - "INSERT INTO pqxxevents(year, event) " - "VALUES (1989, 'Ode an die Freiheit')"); - t.exec( - "INSERT INTO pqxxevents(year, event) VALUES (2001, 'New millennium')"); - t.exec("INSERT INTO pqxxevents(year, event) VALUES (1974, '')"); - t.exec("INSERT INTO pqxxevents(year, event) VALUES (97, 'Asian crisis')"); - t.exec( - "INSERT INTO pqxxevents(year, event) VALUES (2001, 'A Space Odyssey')"); -} -} // namespace pqxx::test - - -namespace -{ -std::map *all_tests{nullptr}; -} // namespace - - -namespace pqxx::test -{ -void register_test(char const name[], pqxx::test::testfunc func) -{ - if (all_tests == nullptr) - { - all_tests = new std::map(); - } - else - { - assert(all_tests->find(name) == all_tests->end()); - } - (*all_tests)[name] = func; -} -} // namespace pqxx::test - - -int main(int argc, char const *argv[]) -{ - char const *const test_name{(argc > 1) ? argv[1] : nullptr}; - - int test_count = 0; - std::list failed; - for (auto const &i : *all_tests) - if (test_name == nullptr or std::string{test_name} == std::string{i.first}) - { - std::cout << std::endl << "Running: " << i.first << std::endl; - - bool success = false; - try - { - i.second(); - success = true; - } - catch (pqxx::test::test_failure const &e) - { - std::cerr << "Test failure in " + e.file() + " line " + - pqxx::to_string(e.line()) - << ": " << e.what() << std::endl; - } - catch (std::bad_alloc const &) - { - std::cerr << "Out of memory!" << std::endl; - } - catch (pqxx::feature_not_supported const &e) - { - std::cerr << "Not testing unsupported feature: " << e.what() - << std::endl; - success = true; - --test_count; - } - catch (pqxx::sql_error const &e) - { - std::cerr << "SQL error: " << e.what() << std::endl - << "Query was: " << e.query() << std::endl; - } - catch (std::exception const &e) - { - std::cerr << "Exception: " << e.what() << std::endl; - } - catch (...) - { - std::cerr << "Unknown exception" << std::endl; - } - - if (not success) - { - std::cerr << "FAILED: " << i.first << std::endl; - failed.emplace_back(i.first); - } - ++test_count; - } - - std::cout << "Ran " << test_count << " test(s).\n"; - - if (not std::empty(failed)) - { - std::cerr << "*** " << std::size(failed) << " test(s) failed: ***\n"; - for (auto const &i : failed) std::cerr << "\t" << i << '\n'; - } - - return int(std::size(failed)); -} diff --git a/ext/libpqxx-7.7.3/test/test00.cxx b/ext/libpqxx-7.7.3/test/test00.cxx deleted file mode 100644 index 698c9b81b..000000000 --- a/ext/libpqxx-7.7.3/test/test00.cxx +++ /dev/null @@ -1,114 +0,0 @@ -#include - -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Initial test program for libpqxx. Test functionality that doesn't require a -// running database. - -namespace -{ -template -inline void -strconv(std::string const &type, T const &Obj, std::string const &expected) -{ - std::string const Objstr{to_string(Obj)}; - - PQXX_CHECK_EQUAL(Objstr, expected, "String mismatch for " + type + "."); - T NewObj; - from_string(Objstr, NewObj); - PQXX_CHECK_EQUAL( - to_string(NewObj), expected, "String mismatch for recycled " + type + "."); -} - -// There's no from_string()... -inline void -strconv(std::string const &type, char const Obj[], std::string const &expected) -{ - std::string const Objstr(to_string(Obj)); - PQXX_CHECK_EQUAL(Objstr, expected, "String mismatch for " + type + "."); -} - -constexpr double not_a_number{std::numeric_limits::quiet_NaN()}; - -struct intderef -{ - template int operator()(ITER i) const noexcept - { - return int(*i); - } -}; - - -void test_000() -{ - PQXX_CHECK_EQUAL( - oid_none, 0u, - "InvalidIod is not zero as it used to be. This may conceivably " - "cause problems in libpqxx."); - - PQXX_CHECK( - cursor_base::prior() < 0 and cursor_base::backward_all() < 0, - "cursor_base::difference_type appears to be unsigned."); - - constexpr char weird[]{"foo\t\n\0bar"}; - std::string const weirdstr(weird, std::size(weird) - 1); - - // Test string conversions - strconv("char const[]", "", ""); - strconv("char const[]", "foo", "foo"); - strconv("int", 0, "0"); - strconv("int", 100, "100"); - strconv("int", -1, "-1"); - -#if defined(_MSC_VER) - long const long_min{LONG_MIN}, long_max{LONG_MAX}; -#else - long const long_min{std::numeric_limits::min()}, - long_max{std::numeric_limits::max()}; -#endif - - std::stringstream lminstr, lmaxstr, llminstr, llmaxstr, ullmaxstr; - lminstr.imbue(std::locale("C")); - lmaxstr.imbue(std::locale("C")); - llminstr.imbue(std::locale("C")); - llmaxstr.imbue(std::locale("C")); - ullmaxstr.imbue(std::locale("C")); - - lminstr << long_min; - lmaxstr << long_max; - - auto const ullong_max{std::numeric_limits::max()}; - auto const llong_max{std::numeric_limits::max()}, - llong_min{std::numeric_limits::min()}; - - llminstr << llong_min; - llmaxstr << llong_max; - ullmaxstr << ullong_max; - - strconv("long", 0, "0"); - strconv("long", long_min, lminstr.str()); - strconv("long", long_max, lmaxstr.str()); - strconv("double", not_a_number, "nan"); - strconv("string", std::string{}, ""); - strconv("string", weirdstr, weirdstr); - strconv("long long", 0LL, "0"); - strconv("long long", llong_min, llminstr.str()); - strconv("long long", llong_max, llmaxstr.str()); - strconv("unsigned long long", 0ULL, "0"); - strconv("unsigned long long", ullong_max, ullmaxstr.str()); - - std::stringstream ss; - strconv("empty stringstream", ss, ""); - ss << -3.1415; - strconv("stringstream", ss, ss.str()); -} - - -PQXX_REGISTER_TEST(test_000); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test01.cxx b/ext/libpqxx-7.7.3/test/test01.cxx deleted file mode 100644 index 84b7f3b78..000000000 --- a/ext/libpqxx-7.7.3/test/test01.cxx +++ /dev/null @@ -1,33 +0,0 @@ -#include - -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -namespace -{ -// Simple test program for libpqxx. Open connection to database, start -// a transaction, and perform a query inside it. -void test_001() -{ - connection conn; - - // Begin a transaction acting on our current connection. Give it a human- - // readable name so the library can include it in error messages. - work tx{conn, "test1"}; - - // Perform a query on the database, storing result rows in R. - result r(tx.exec("SELECT * FROM pg_tables")); - - // We're expecting to find some tables... - PQXX_CHECK(not std::empty(r), "No tables found."); - - tx.commit(); -} - - -PQXX_REGISTER_TEST(test_001); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test02.cxx b/ext/libpqxx-7.7.3/test/test02.cxx deleted file mode 100644 index f98e18d08..000000000 --- a/ext/libpqxx-7.7.3/test/test02.cxx +++ /dev/null @@ -1,76 +0,0 @@ -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Example/test program for libpqxx. Perform a query and enumerate its output -// using array indexing. - -namespace -{ -void bad_connect() -{ - connection conn{"totally#invalid@connect$string!?"}; -} - -void test_002() -{ - // Before we really connect, test the expected behaviour of the default - // connection type, where a failure to connect results in an immediate - // exception rather than a silent retry. - PQXX_CHECK_THROWS_EXCEPTION( - bad_connect(), "Invalid connection string did not cause exception."); - - // Set up connection to database - std::string ConnectString; - connection C{ConnectString}; - - // Start transaction within context of connection. - work T{C, "test2"}; - - // Perform query within transaction. - result R(T.exec("SELECT * FROM pg_tables")); - - // Let's keep the database waiting as briefly as possible: commit now, - // before we start processing results. We could do this later, or since - // we're not making any changes in the database that need to be committed, - // we could in this case even omit it altogether. - T.commit(); - - // Ah, this version of postgres will tell you which table a column in a - // result came from. Let's just test that functionality... - oid const rtable{R.column_table(0)}; - PQXX_CHECK_EQUAL( - rtable, R.column_table(pqxx::row::size_type(0)), - "Inconsistent answers from column_table()"); - - std::string const rcol{R.column_name(0)}; - oid const crtable{R.column_table(rcol)}; - PQXX_CHECK_EQUAL( - crtable, rtable, "Field looked up by name gives different origin."); - - // Now we've got all that settled, let's process our results. - for (auto const &f : R) - { - oid const ftable{f[0].table()}; - PQXX_CHECK_EQUAL(ftable, rtable, "field::table() is broken."); - - oid const ttable{f.column_table(0)}; - - PQXX_CHECK_EQUAL( - ttable, f.column_table(pqxx::row::size_type(0)), - "Inconsistent pqxx::row::column_table()."); - - PQXX_CHECK_EQUAL(ttable, rtable, "Inconsistent result::column_table()."); - - oid const cttable{f.column_table(rcol)}; - - PQXX_CHECK_EQUAL(cttable, rtable, "pqxx::row::column_table() is broken."); - } -} - - -PQXX_REGISTER_TEST(test_002); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test04.cxx b/ext/libpqxx-7.7.3/test/test04.cxx deleted file mode 100644 index 623446398..000000000 --- a/ext/libpqxx-7.7.3/test/test04.cxx +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include -#include - -#include - -#include - -#include - -#include -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - -// Example program for libpqxx. Send notification to self. - -namespace -{ -int Backend_PID{0}; - - -// Sample implementation of notification receiver. -class TestListener final : public notification_receiver -{ - bool m_done; - -public: - explicit TestListener(connection &conn) : - notification_receiver(conn, "listen"), m_done(false) - {} - - virtual void operator()(std::string const &, int be_pid) override - { - m_done = true; - PQXX_CHECK_EQUAL( - be_pid, Backend_PID, "Notification came from wrong backend process."); - } - - bool done() const { return m_done; } -}; - - -void test_004() -{ - connection conn; - - TestListener L{conn}; - // Trigger our notification receiver. - perform([&conn, &L] { - work tx(conn); - tx.exec0("NOTIFY " + conn.quote_name(L.channel())); - Backend_PID = conn.backendpid(); - tx.commit(); - }); - - int notifs{0}; - for (int i{0}; (i < 20) and not L.done(); ++i) - { - PQXX_CHECK_EQUAL(notifs, 0, "Got unexpected notifications."); - // Sleep for one second. I'm not proud of this, but how does one inject - // a change to the built-in clock in a static language? - pqxx::internal::wait_for(1'000'000u); - notifs = conn.get_notifs(); - } - - PQXX_CHECK_NOT_EQUAL(L.done(), false, "No notification received."); - PQXX_CHECK_EQUAL(notifs, 1, "Got too many notifications."); -} - - -PQXX_REGISTER_TEST(test_004); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test07.cxx b/ext/libpqxx-7.7.3/test/test07.cxx deleted file mode 100644 index 875ee8d50..000000000 --- a/ext/libpqxx-7.7.3/test/test07.cxx +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include - -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Example program for libpqxx. Modify the database, retaining transactional -// integrity using the transactor framework. -// -// This assumes the existence of a database table "pqxxevents" containing a -// 2-digit "year" field, which is extended to a 4-digit format by assuming all -// year numbers of 70 or higher are in the 20th century, and all others in the -// 21st, and that no years before 1970 are possible. - -namespace -{ -// Convert year to 4-digit format. -int To4Digits(int Y) -{ - int Result{Y}; - - PQXX_CHECK(Y >= 0, "Negative year: " + to_string(Y)); - if (Y < 70) - Result += 2000; - else if (Y < 100) - Result += 1900; - else if (Y < 1970) - PQXX_CHECK_NOTREACHED("Unexpected year: " + to_string(Y)); - - return Result; -} - - -void test_007() -{ - connection conn; - conn.set_client_encoding("SQL_ASCII"); - - { - work tx{conn}; - test::create_pqxxevents(tx); - tx.commit(); - } - - // Perform (an instantiation of) the UpdateYears transactor we've defined - // in the code above. This is where the work gets done. - std::map conversions; - perform([&conversions, &conn] { - work tx{conn}; - // First select all different years occurring in the table. - result R(tx.exec("SELECT year FROM pqxxevents")); - - // See if we get reasonable type identifier for this column. - oid const rctype{R.column_type(0)}; - PQXX_CHECK_EQUAL( - R.column_type(pqxx::row::size_type(0)), rctype, - "Inconsistent result::column_type()."); - - std::string const rct{to_string(rctype)}; - PQXX_CHECK(rctype > 0, "Got strange type ID for column: " + rct); - - std::string const rcol{R.column_name(0)}; - PQXX_CHECK(not std::empty(rcol), "Didn't get a name for column."); - - oid const rcctype{R.column_type(rcol)}; - PQXX_CHECK_EQUAL( - rcctype, rctype, "Column type is not what it is by name."); - - oid const rawrcctype{R.column_type(rcol)}; - PQXX_CHECK_EQUAL( - rawrcctype, rctype, "Column type by C-style name is different."); - - // Note all different years currently occurring in the table, writing - // them and their correct mappings to conversions. - for (auto const &r : R) - { - int Y{0}; - - // Read year, and if it is non-null, note its converted value - if (r[0] >> Y) - conversions[Y] = To4Digits(Y); - - // See if type identifiers are consistent - oid const tctype{r.column_type(0)}; - - PQXX_CHECK_EQUAL( - tctype, r.column_type(pqxx::row::size_type(0)), - "Inconsistent pqxx::row::column_type()"); - - PQXX_CHECK_EQUAL( - tctype, rctype, - "pqxx::row::column_type() is inconsistent with " - "result::column_type()."); - - oid const ctctype{r.column_type(rcol)}; - - PQXX_CHECK_EQUAL( - ctctype, rctype, "Column type lookup by column name is broken."); - - oid const rawctctype{r.column_type(rcol)}; - - PQXX_CHECK_EQUAL( - rawctctype, rctype, "Column type lookup by C-style name is broken."); - - oid const fctype{r[0].type()}; - PQXX_CHECK_EQUAL(fctype, rctype, "Field type lookup is broken."); - } - - // For each occurring year, write converted date back to whereever it may - // occur in the table. Since we're in a transaction, any changes made by - // others at the same time will not affect us. - for (auto const &c : conversions) - { - auto const query{ - "UPDATE pqxxevents " - "SET year=" + - to_string(c.second) + - " " - "WHERE year=" + - to_string(c.first)}; - R = tx.exec0(query); - } - }); -} - - -PQXX_REGISTER_TEST(test_007); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test10.cxx b/ext/libpqxx-7.7.3/test/test10.cxx deleted file mode 100644 index 4cb4aaba1..000000000 --- a/ext/libpqxx-7.7.3/test/test10.cxx +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include -#include - -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test program for libpqxx. Open connection to database, start a transaction, -// abort it, and verify that it "never happened." - -namespace -{ -// Let's take a boring year that is not going to be in the "pqxxevents" table -constexpr int BoringYear{1977}; - -std::string const Table("pqxxevents"); - - -// Count events, and boring events, in table -std::pair CountEvents(transaction_base &T) -{ - std::string const events_query{"SELECT count(*) FROM " + Table}; - std::string const boring_query{ - events_query + " WHERE year=" + to_string(BoringYear)}; - return std::make_pair( - T.query_value(events_query), T.query_value(boring_query)); -} - - -// Try adding a record, then aborting it, and check whether the abort was -// performed correctly. -void Test(connection &C, bool ExplicitAbort) -{ - std::pair EventCounts; - - // First run our doomed transaction. This will refuse to run if an event - // exists for our Boring Year. - { - // Begin a transaction acting on our current connection; we'll abort it - // later though. - work Doomed{C, "Doomed"}; - - // Verify that our Boring Year was not yet in the events table - EventCounts = CountEvents(Doomed); - - PQXX_CHECK_EQUAL( - EventCounts.second, 0, "Can't run, boring year is already in table."); - - // Now let's try to introduce a row for our Boring Year - Doomed.exec0( - "INSERT INTO " + Table + - "(year, event) " - "VALUES (" + - to_string(BoringYear) + ", 'yawn')"); - - auto const Recount{CountEvents(Doomed)}; - PQXX_CHECK_EQUAL( - Recount.second, 1, "Wrong # events for " + to_string(BoringYear)); - - PQXX_CHECK_EQUAL( - Recount.first, EventCounts.first + 1, "Number of events changed."); - - // Okay, we've added an entry but we don't really want to. Abort it - // explicitly if requested, or simply let the Transaction object "expire." - if (ExplicitAbort) - Doomed.abort(); - - // If now explicit abort requested, Doomed Transaction still ends here - } - - // Now check that we're back in the original state. Note that this may go - // wrong if somebody managed to change the table between our two - // transactions. - work Checkup(C, "Checkup"); - - auto const NewEvents{CountEvents(Checkup)}; - PQXX_CHECK_EQUAL( - NewEvents.first, EventCounts.first, - "Number of events changed. This may be due to a bug in libpqxx, " - "or the test table was modified by some other process."); - - PQXX_CHECK_EQUAL( - NewEvents.second, 0, - "Found unexpected events. This may be due to a bug in libpqxx, " - "or the test table was modified by some other process."); -} - - -void test_abort() -{ - connection conn; - nontransaction t{conn}; - test::create_pqxxevents(t); - connection &c(t.conn()); - t.commit(); - Test(c, true); - Test(c, false); -} - - -PQXX_REGISTER_TEST(test_abort); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test11.cxx b/ext/libpqxx-7.7.3/test/test11.cxx deleted file mode 100644 index 4b42a66d5..000000000 --- a/ext/libpqxx-7.7.3/test/test11.cxx +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include - -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test program for libpqxx. Query a table and report its metadata. -namespace -{ -void test_011() -{ - connection conn; - work tx{conn}; - std::string const Table{"pg_tables"}; - - result R(tx.exec("SELECT * FROM " + Table)); - - // Print column names - for (pqxx::row::size_type c{0}; c < R.columns(); ++c) - { - std::string N{R.column_name(c)}; - PQXX_CHECK_EQUAL(R.column_number(N), c, "Inconsistent column numbers."); - } - - // If there are rows in R, compare their metadata to R's. - if (not std::empty(R)) - { - PQXX_CHECK_EQUAL(R[0].rownumber(), 0, "Row 0 has wrong number."); - - if (std::size(R) >= 2) - PQXX_CHECK_EQUAL(R[1].rownumber(), 1, "Row 1 has wrong number."); - - // Test result::iterator::swap() - pqxx::result::const_iterator const T1(R[0]), T2(R[1]); - PQXX_CHECK_NOT_EQUAL(T1, T2, "Values are identical--can't test swap()."); - pqxx::result::const_iterator T1s(T1), T2s(T2); - PQXX_CHECK_EQUAL(T1s, T1, "Result iterator copy-construction is wrong."); - PQXX_CHECK_EQUAL( - T2s, T2, "Result iterator copy-construction is inconsistently wrong."); - T1s.swap(T2s); - PQXX_CHECK_NOT_EQUAL(T1s, T1, "Result iterator swap doesn't work."); - PQXX_CHECK_NOT_EQUAL( - T2s, T2, "Result iterator swap inconsistently wrong."); - PQXX_CHECK_EQUAL(T2s, T1, "Result iterator swap is asymmetric."); - PQXX_CHECK_EQUAL( - T1s, T2, "Result iterator swap is inconsistently asymmetric."); - - for (pqxx::row::size_type c{0}; c < std::size(R[0]); ++c) - { - std::string N{R.column_name(c)}; - - PQXX_CHECK_EQUAL( - std::string{R[0].at(c).c_str()}, R[0].at(N).c_str(), - "Field by name != field by number."); - - PQXX_CHECK_EQUAL( - std::string{R[0][c].c_str()}, R[0][N].c_str(), - "at() is inconsistent with operator[]."); - - PQXX_CHECK_EQUAL(R[0][c].name(), N, "Field names are inconsistent."); - - PQXX_CHECK_EQUAL( - std::size(R[0][c]), strlen(R[0][c].c_str()), - "Field size is not what we expected."); - } - } -} - - -PQXX_REGISTER_TEST(test_011); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test13.cxx b/ext/libpqxx-7.7.3/test/test13.cxx deleted file mode 100644 index b3577a5d3..000000000 --- a/ext/libpqxx-7.7.3/test/test13.cxx +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test program for libpqxx. Verify abort behaviour of transactor. -// -// The program will attempt to add an entry to a table called "pqxxevents", -// with a key column called "year"--and then abort the change. -// -// Note for the superstitious: the numbering for this test program is pure -// coincidence. -namespace -{ -// Let's take a boring year that is not going to be in the "pqxxevents" table -constexpr unsigned int BoringYear = 1977; - - -// Count events and specifically events occurring in Boring Year, leaving the -// former count in the result pair's first member, and the latter in second. -std::pair count_events(connection &conn, std::string const &table) -{ - work tx{conn}; - std::string const count_query{"SELECT count(*) FROM " + table}; - return std::make_pair( - tx.query_value(count_query), - tx.query_value(count_query + " WHERE year=" + to_string(BoringYear))); -} - - -struct deliberate_error : std::exception -{}; - - -void failed_insert(connection &C, std::string const &table) -{ - work tx(C); - result R = tx.exec0( - "INSERT INTO " + table + " VALUES (" + to_string(BoringYear) + - ", " - "'yawn')"); - - PQXX_CHECK_EQUAL(R.affected_rows(), 1, "Bad affected_rows()."); - throw deliberate_error(); -} - - -void test_013() -{ - connection conn; - { - work tx{conn}; - test::create_pqxxevents(tx); - tx.commit(); - } - - std::string const Table{"pqxxevents"}; - - auto const Before{ - perform([&conn, &Table] { return count_events(conn, Table); })}; - PQXX_CHECK_EQUAL( - Before.second, 0, - "Already have event for " + to_string(BoringYear) + "--can't test."); - - quiet_errorhandler d(conn); - PQXX_CHECK_THROWS( - perform([&conn, &Table] { failed_insert(conn, Table); }), deliberate_error, - "Failing transactor failed to throw correct exception."); - - auto const After{ - perform([&conn, &Table] { return count_events(conn, Table); })}; - - PQXX_CHECK_EQUAL( - After.first, Before.first, "abort() didn't reset event count."); - - PQXX_CHECK_EQUAL( - After.second, Before.second, - "abort() didn't reset event count for " + to_string(BoringYear)); -} - - -PQXX_REGISTER_TEST(test_013); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test14.cxx b/ext/libpqxx-7.7.3/test/test14.cxx deleted file mode 100644 index c82f2323c..000000000 --- a/ext/libpqxx-7.7.3/test/test14.cxx +++ /dev/null @@ -1,36 +0,0 @@ -#include - -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test nontransaction. - -namespace -{ -void test_014() -{ - connection conn; - - // Begin a "non-transaction" acting on our current connection. This is - // really all the transactional integrity we need since we're only - // performing one query which does not modify the database. - nontransaction tx{conn, "test14"}; - - // The transaction class family also has process_notice() functions. - // These simply pass the notice through to their connection, but this may - // be more convenient in some cases. All process_notice() functions accept - // C++ strings as well as C strings. - tx.process_notice(std::string{"Started nontransaction\n"}); - - // "Commit" the non-transaction. This doesn't really do anything since - // nontransaction doesn't start a backend transaction. - tx.commit(); -} - - -PQXX_REGISTER_TEST(test_014); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test16.cxx b/ext/libpqxx-7.7.3/test/test16.cxx deleted file mode 100644 index 211bbba6a..000000000 --- a/ext/libpqxx-7.7.3/test/test16.cxx +++ /dev/null @@ -1,46 +0,0 @@ -#include - -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test robusttransaction. -namespace -{ -void test_016() -{ - connection conn; - robusttransaction<> tx{conn}; - result R{tx.exec("SELECT * FROM pg_tables")}; - - result::const_iterator c; - for (c = std::begin(R); c != std::end(R); ++c) - ; - - // See if back() and row comparison work properly - PQXX_CHECK( - std::size(R) >= 2, "Not enough rows in pg_tables to test, sorry!"); - - --c; - - PQXX_CHECK_EQUAL( - c->size(), std::size(R.back()), - "Size mismatch between row iterator and back()."); - - std::string const nullstr; - for (pqxx::row::size_type i{0}; i < c->size(); ++i) - PQXX_CHECK_EQUAL( - c[i].as(nullstr), R.back()[i].as(nullstr), "Value mismatch in back()."); - PQXX_CHECK(*c == R.back(), "Row equality is broken."); - PQXX_CHECK(not(*c != R.back()), "Row inequality is broken."); - - tx.commit(); -} - - -PQXX_REGISTER_TEST(test_016); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test17.cxx b/ext/libpqxx-7.7.3/test/test17.cxx deleted file mode 100644 index 7c99a35cc..000000000 --- a/ext/libpqxx-7.7.3/test/test17.cxx +++ /dev/null @@ -1,29 +0,0 @@ -#include - -#include -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Simple test program for libpqxx. Open connection to database, start -// a dummy transaction to gain nontransactional access, and perform a query. -namespace -{ -void test_017() -{ - connection conn; - perform([&conn] { - nontransaction tx{conn}; - auto const r{tx.exec("SELECT * FROM generate_series(1, 4)")}; - PQXX_CHECK_EQUAL(std::size(r), 4, "Weird query result."); - tx.commit(); - }); -} - - -PQXX_REGISTER_TEST(test_017); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test18.cxx b/ext/libpqxx-7.7.3/test/test18.cxx deleted file mode 100644 index 9718d2daa..000000000 --- a/ext/libpqxx-7.7.3/test/test18.cxx +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test program for libpqxx. Verify abort behaviour of RobustTransaction. -// -// The program will attempt to add an entry to a table called "pqxxevents", -// with a key column called "year"--and then abort the change. -namespace -{ -// Let's take a boring year that is not going to be in the "pqxxevents" table -constexpr long BoringYear{1977}; - - -// Count events and specifically events occurring in Boring Year, leaving the -// former count in the result pair's first member, and the latter in second. -std::pair count_events(connection &conn, std::string const &table) -{ - nontransaction tx{conn}; - std::string const count_query{"SELECT count(*) FROM " + table}; - return std::make_pair( - tx.query_value(count_query), - tx.query_value(count_query + " WHERE year=" + to_string(BoringYear))); -} - - -struct deliberate_error : std::exception -{}; - - -void test_018() -{ - connection conn; - { - work tx{conn}; - test::create_pqxxevents(tx); - tx.commit(); - } - - std::string const Table{"pqxxevents"}; - - auto const Before{ - perform([&conn, &Table] { return count_events(conn, Table); })}; - PQXX_CHECK_EQUAL( - Before.second, 0, - "Already have event for " + to_string(BoringYear) + ", cannot run."); - - { - quiet_errorhandler d{conn}; - PQXX_CHECK_THROWS( - perform([&conn, Table] { - robusttransaction tx{conn}; - tx.exec0( - "INSERT INTO " + Table + " VALUES (" + to_string(BoringYear) + - ", '" + tx.esc("yawn") + "')"); - - throw deliberate_error(); - }), - deliberate_error, - "Not getting expected exception from failing transactor."); - } - - auto const After{ - perform([&conn, &Table] { return count_events(conn, Table); })}; - - PQXX_CHECK_EQUAL(After.first, Before.first, "Event count changed."); - PQXX_CHECK_EQUAL( - After.second, Before.second, - "Event count for " + to_string(BoringYear) + " changed."); -} - - -PQXX_REGISTER_TEST(test_018); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test20.cxx b/ext/libpqxx-7.7.3/test/test20.cxx deleted file mode 100644 index 1ddd4b09a..000000000 --- a/ext/libpqxx-7.7.3/test/test20.cxx +++ /dev/null @@ -1,95 +0,0 @@ -#include - -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test: nontransaction changes are not rolled back on abort. -namespace -{ -constexpr unsigned long BoringYear{1977}; - - -void test_020() -{ - connection conn; - nontransaction t1{conn}; - test::create_pqxxevents(t1); - - std::string const Table{"pqxxevents"}; - - // Verify our start condition before beginning: there must not be a 1977 - // record already. - result R(t1.exec(("SELECT * FROM " + Table + - " " - "WHERE year=" + - to_string(BoringYear)) - .c_str())); - PQXX_CHECK_EQUAL( - std::size(R), 0, - "Already have a row for " + to_string(BoringYear) + ", cannot test."); - - // (Not needed, but verify that clear() works on empty containers) - R.clear(); - PQXX_CHECK(std::empty(R), "result::clear() is broken."); - - // OK. Having laid that worry to rest, add a record for 1977. - t1.exec0( - "INSERT INTO " + Table + - " VALUES" - "(" + - to_string(BoringYear) + - "," - "'Yawn'" - ")"); - - // Abort T1. Since T1 is a nontransaction, which provides only the - // transaction class interface without providing any form of transactional - // integrity, this is not going to undo our work. - t1.abort(); - - // Verify that our record was added, despite the Abort() - nontransaction t2{conn, "t2"}; - R = t2.exec(("SELECT * FROM " + Table + - " " - "WHERE year=" + - to_string(BoringYear)) - .c_str()); - - PQXX_CHECK_EQUAL( - std::size(R), 1, - "Found wrong number of rows for " + to_string(BoringYear) + "."); - - PQXX_CHECK(R.capacity() >= std::size(R), "Result's capacity is too small."); - - R.clear(); - PQXX_CHECK(std::empty(R), "result::clear() doesn't work."); - - // Now remove our record again - t2.exec0( - "DELETE FROM " + Table + - " " - "WHERE year=" + - to_string(BoringYear)); - - t2.commit(); - - // And again, verify results - nontransaction t3{conn, "t3"}; - - R = t3.exec(("SELECT * FROM " + Table + - " " - "WHERE year=" + - to_string(BoringYear)) - .c_str()); - - PQXX_CHECK_EQUAL(std::size(R), 0, "Record still found after removal."); -} - - -PQXX_REGISTER_TEST(test_020); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test21.cxx b/ext/libpqxx-7.7.3/test/test21.cxx deleted file mode 100644 index 1090050d9..000000000 --- a/ext/libpqxx-7.7.3/test/test21.cxx +++ /dev/null @@ -1,70 +0,0 @@ -#include - -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Simple test program for libpqxx. Open a connection to database, start a -// transaction, and perform a query inside it. -namespace -{ -void test_021() -{ - connection conn; - - std::string const HostName{ - ((conn.hostname() == nullptr) ? "" : conn.hostname())}; - conn.process_notice( - std::string{} + "database=" + conn.dbname() + - ", " - "username=" + - conn.username() + - ", " - "hostname=" + - HostName + - ", " - "port=" + - to_string(conn.port()) + - ", " - "backendpid=" + - to_string(conn.backendpid()) + "\n"); - - work tx{conn, "test_021"}; - - // By now our connection should really have been created - conn.process_notice("Printing details on actual connection\n"); - conn.process_notice( - std::string{} + "database=" + conn.dbname() + - ", " - "username=" + - conn.username() + - ", " - "hostname=" + - HostName + - ", " - "port=" + - to_string(conn.port()) + - ", " - "backendpid=" + - to_string(conn.backendpid()) + "\n"); - - std::string P; - from_string(conn.port(), P); - PQXX_CHECK_EQUAL( - P, to_string(conn.port()), "Port string conversion is broken."); - PQXX_CHECK_EQUAL(to_string(P), P, "Port string conversion is broken."); - - result R(tx.exec("SELECT * FROM pg_tables")); - - tx.process_notice(pqxx::internal::concat( - to_string(std::size(R)), " result row in transaction ", tx.name(), "\n")); - tx.commit(); -} - - -PQXX_REGISTER_TEST(test_021); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test26.cxx b/ext/libpqxx-7.7.3/test/test26.cxx deleted file mode 100644 index 69b04d839..000000000 --- a/ext/libpqxx-7.7.3/test/test26.cxx +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include - -#include -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Example program for libpqxx. Modify the database, retaining transactional -// integrity using the transactor framework. -namespace -{ -// Convert year to 4-digit format. -int To4Digits(int Y) -{ - int Result{Y}; - - PQXX_CHECK(Y >= 0, "Negative year: " + to_string(Y)); - - if (Y < 70) - Result += 2000; - else if (Y < 100) - Result += 1900; - else - PQXX_CHECK(Y >= 1970, "Unexpected year: " + to_string(Y)); - return Result; -} - - -// Transaction definition for year-field update. Returns conversions done. -std::map update_years(connection &C) -{ - std::map conversions; - work tx{C}; - - // Note all different years currently occurring in the table, writing them - // and their correct mappings to m_conversions - for (auto const &[y] : - tx.stream>("SELECT year FROM pqxxevents")) - { - // Read year, and if it is non-null, note its converted value - if (bool(y)) - conversions[y.value()] = To4Digits(y.value()); - } - - // For each occurring year, write converted date back to whereever it may - // occur in the table. Since we're in a transaction, any changes made by - // others at the same time will not affect us. - for (auto const &c : conversions) - tx.exec0( - "UPDATE pqxxevents " - "SET year=" + - to_string(c.second) + - " " - "WHERE year=" + - to_string(c.first)); - - tx.commit(); - - return conversions; -} - - -void test_026() -{ - connection conn; - { - nontransaction tx{conn}; - test::create_pqxxevents(tx); - tx.commit(); - } - - // Perform (an instantiation of) the UpdateYears transactor we've defined - // in the code above. This is where the work gets done. - auto const conversions{perform([&conn] { return update_years(conn); })}; - - PQXX_CHECK(not std::empty(conversions), "No conversions done!"); -} - - -PQXX_REGISTER_TEST(test_026); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test29.cxx b/ext/libpqxx-7.7.3/test/test29.cxx deleted file mode 100644 index 4547523f1..000000000 --- a/ext/libpqxx-7.7.3/test/test29.cxx +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#include - -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test program for libpqxx. Open connection to database, start a transaction, -// abort it, and verify that it "never happened." -// -// The program will attempt to add an entry to a table called "pqxxevents", -// with a key column called "year"--and then abort the change. -namespace -{ -// Let's take a boring year that is not going to be in the "pqxxevents" table -constexpr int BoringYear{1977}; - -std::string const Table{"pqxxevents"}; - - -// Count events, and boring events, in table -std::pair CountEvents(transaction_base &tx) -{ - std::string const events_query{"SELECT count(*) FROM " + Table}; - std::string const boring_query{ - events_query + " WHERE year=" + to_string(BoringYear)}; - - return std::make_pair( - tx.query_value(events_query), tx.query_value(boring_query)); -} - - -// Try adding a record, then aborting it, and check whether the abort was -// performed correctly. -void Test(connection &conn, bool ExplicitAbort) -{ - std::vector BoringRow{to_string(BoringYear), "yawn"}; - - std::pair EventCounts; - - // First run our doomed transaction. This will refuse to run if an event - // exists for our Boring Year. - { - // Begin a transaction acting on our current connection; we'll abort it - // later though. - work Doomed(conn, "Doomed"); - - // Verify that our Boring Year was not yet in the events table - EventCounts = CountEvents(Doomed); - - PQXX_CHECK_EQUAL( - EventCounts.second, 0, - "Can't run; " + to_string(BoringYear) + " is already in the table."); - - // Now let's try to introduce a row for our Boring Year - Doomed.exec0( - "INSERT INTO " + Table + - "(year, event) " - "VALUES (" + - to_string(BoringYear) + ", 'yawn')"); - - auto Recount{CountEvents(Doomed)}; - PQXX_CHECK_EQUAL(Recount.second, 1, "Unexpected number of events."); - PQXX_CHECK_EQUAL( - Recount.first, EventCounts.first + 1, "Number of events changed."); - - // Okay, we've added an entry but we don't really want to. Abort it - // explicitly if requested, or simply let the Transaction object "expire." - if (ExplicitAbort) - Doomed.abort(); - - // If now explicit abort requested, Doomed Transaction still ends here - } - - // Now check that we're back in the original state. Note that this may go - // wrong if somebody managed to change the table between our two - // transactions. - work Checkup(conn, "Checkup"); - - auto NewEvents{CountEvents(Checkup)}; - PQXX_CHECK_EQUAL( - NewEvents.first, EventCounts.first, "Wrong number of events."); - - PQXX_CHECK_EQUAL(NewEvents.second, 0, "Found unexpected events."); -} - - -void test_029() -{ - connection conn; - { - nontransaction tx{conn}; - test::create_pqxxevents(tx); - } - - // Test abort semantics, both with explicit and implicit abort - Test(conn, true); - Test(conn, false); -} - - -PQXX_REGISTER_TEST(test_029); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test30.cxx b/ext/libpqxx-7.7.3/test/test30.cxx deleted file mode 100644 index fb6a05da0..000000000 --- a/ext/libpqxx-7.7.3/test/test30.cxx +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include - -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test program for libpqxx. Query a table and report its metadata. -namespace -{ -void test_030() -{ - std::string const Table{"pg_tables"}; - - connection conn; - work tx{conn, "test30"}; - - result R(tx.exec(("SELECT * FROM " + Table).c_str())); - PQXX_CHECK(not std::empty(R), "Table " + Table + " is empty, cannot test."); - - // Print column names - for (pqxx::row::size_type c{0}; c < R.columns(); ++c) - { - std::string N{R.column_name(c)}; - - PQXX_CHECK_EQUAL( - R[0].column_number(N), R.column_number(N), - "row::column_number() is inconsistent with result::column_number()."); - - PQXX_CHECK_EQUAL(R[0].column_number(N), c, "Inconsistent column numbers."); - } - - // If there are rows in R, compare their metadata to R's. - if (std::empty(R)) - { - std::cout << "(Table is empty.)\n"; - return; - } - - PQXX_CHECK_EQUAL(R[0].rownumber(), 0, "Row 0 reports wrong number."); - - if (std::size(R) < 2) - std::cout << "(Only one row in table.)\n"; - else - PQXX_CHECK_EQUAL(R[1].rownumber(), 1, "Row 1 reports wrong number."); - - for (pqxx::row::size_type c{0}; c < std::size(R[0]); ++c) - { - std::string N{R.column_name(c)}; - - PQXX_CHECK_EQUAL( - std::string{R[0].at(c).c_str()}, R[0].at(N).c_str(), - "Different field values by name and by number."); - - PQXX_CHECK_EQUAL( - std::string{R[0][c].c_str()}, R[0][N].c_str(), - "at() is inconsistent with operator[]."); - - PQXX_CHECK_EQUAL(R[0][c].name(), N, "Inconsistent field names."); - - PQXX_CHECK_EQUAL( - std::size(R[0][c]), std::strlen(R[0][c].c_str()), - "Inconsistent field lengths."); - } -} - - -PQXX_REGISTER_TEST(test_030); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test32.cxx b/ext/libpqxx-7.7.3/test/test32.cxx deleted file mode 100644 index 90f0db68c..000000000 --- a/ext/libpqxx-7.7.3/test/test32.cxx +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test program for libpqxx. Verify abort behaviour of transactor. -// -// The program will attempt to add an entry to a table called "pqxxevents", -// with a key column called "year"--and then abort the change. -// -// Note for the superstitious: the numbering for this test program is pure -// coincidence. - -namespace -{ -// Let's take a boring year that is not going to be in the "pqxxevents" table -constexpr int BoringYear{1977}; - -std::pair count_events(connection &conn, std::string const &table) -{ - std::string const count_query{"SELECT count(*) FROM " + table}; - work tx{conn}; - return std::make_pair( - tx.query_value(count_query), - tx.query_value(count_query + " WHERE year=" + to_string(BoringYear))); -} - - -struct deliberate_error : std::exception -{}; - - -void test_032() -{ - connection conn; - { - nontransaction tx{conn}; - test::create_pqxxevents(tx); - } - - std::string const Table{"pqxxevents"}; - - std::pair const Before{ - perform([&conn, &Table] { return count_events(conn, Table); })}; - PQXX_CHECK_EQUAL( - Before.second, 0, - "Already have event for " + to_string(BoringYear) + ", cannot test."); - - { - quiet_errorhandler d(conn); - PQXX_CHECK_THROWS( - perform([&conn, &Table] { - work{conn}.exec0( - "INSERT INTO " + Table + " VALUES (" + to_string(BoringYear) + - ", " - "'yawn')"); - throw deliberate_error(); - }), - deliberate_error, - "Did not get expected exception from failing transactor."); - } - - std::pair const After{ - perform([&conn, &Table] { return count_events(conn, Table); })}; - - PQXX_CHECK_EQUAL(After.first, Before.first, "Event count changed."); - PQXX_CHECK_EQUAL( - After.second, Before.second, - "Event count for " + to_string(BoringYear) + " changed."); -} - - -PQXX_REGISTER_TEST(test_032); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test37.cxx b/ext/libpqxx-7.7.3/test/test37.cxx deleted file mode 100644 index fe231d39b..000000000 --- a/ext/libpqxx-7.7.3/test/test37.cxx +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test program for libpqxx. Verify abort behaviour of RobustTransaction. -// -// The program will attempt to add an entry to a table called "pqxxevents", -// with a key column called "year"--and then abort the change. -namespace -{ -// Let's take a boring year that is not going to be in the "pqxxevents" table -constexpr int BoringYear{1977}; - -// Count events and specifically events occurring in Boring Year, leaving the -// former count in the result pair's first member, and the latter in second. -std::pair count_events(connection &conn, std::string const &table) -{ - std::string const count_query{"SELECT count(*) FROM " + table}; - nontransaction tx{conn}; - return std::make_pair( - tx.query_value(count_query), - tx.query_value(count_query + " WHERE year=" + to_string(BoringYear))); -} - - -struct deliberate_error : std::exception -{}; - - -void test_037() -{ - connection conn; - { - nontransaction tx{conn}; - test::create_pqxxevents(tx); - } - - std::string const Table{"pqxxevents"}; - - auto const Before{ - perform([&conn, &Table] { return count_events(conn, Table); })}; - PQXX_CHECK_EQUAL( - Before.second, 0, - "Already have event for " + to_string(BoringYear) + ", cannot test."); - - { - quiet_errorhandler d(conn); - PQXX_CHECK_THROWS( - perform([&conn, &Table] { - robusttransaction<> tx{conn}; - tx.exec0( - "INSERT INTO " + Table + " VALUES (" + to_string(BoringYear) + - ", " - "'yawn')"); - - throw deliberate_error(); - }), - deliberate_error, - "Did not get expected exception from failing transactor."); - } - - auto const After{ - perform([&conn, &Table] { return count_events(conn, Table); })}; - - PQXX_CHECK_EQUAL(After.first, Before.first, "Number of events changed."); - PQXX_CHECK_EQUAL( - After.second, Before.second, - "Number of events for " + to_string(BoringYear) + " changed."); -} - - -PQXX_REGISTER_TEST(test_037); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test39.cxx b/ext/libpqxx-7.7.3/test/test39.cxx deleted file mode 100644 index d26855811..000000000 --- a/ext/libpqxx-7.7.3/test/test39.cxx +++ /dev/null @@ -1,89 +0,0 @@ -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test: nontransaction changes are committed immediately. -namespace -{ -int BoringYear{1977}; - - -void test_039() -{ - connection conn; - nontransaction tx1{conn}; - test::create_pqxxevents(tx1); - std::string const Table{"pqxxevents"}; - - // Verify our start condition before beginning: there must not be a 1977 - // record already. - result R(tx1.exec( - "SELECT * FROM " + Table + - " " - "WHERE year=" + - to_string(BoringYear))); - - PQXX_CHECK_EQUAL( - std::size(R), 0, - "Already have a row for " + to_string(BoringYear) + ", cannot test."); - - // (Not needed, but verify that clear() works on empty containers) - R.clear(); - PQXX_CHECK(std::empty(R), "Result is non-empty after clear()."); - - // OK. Having laid that worry to rest, add a record for 1977. - tx1.exec0( - "INSERT INTO " + Table + - " VALUES" - "(" + - to_string(BoringYear) + - "," - "'Yawn'" - ")"); - - // Abort tx1. Since tx1 is a nontransaction, which provides only the - // transaction class interface without providing any form of transactional - // integrity, this is not going to undo our work. - tx1.abort(); - - // Verify that our record was added, despite the Abort() - nontransaction tx2(conn, "tx2"); - R = tx2.exec( - "SELECT * FROM " + Table + - " " - "WHERE year=" + - to_string(BoringYear)); - PQXX_CHECK_EQUAL(std::size(R), 1, "Unexpected result size."); - - PQXX_CHECK(R.capacity() >= std::size(R), "Result's capacity is too small."); - - R.clear(); - PQXX_CHECK(std::empty(R), "result::clear() is broken."); - - // Now remove our record again - tx2.exec0( - "DELETE FROM " + Table + - " " - "WHERE year=" + - to_string(BoringYear)); - - tx2.commit(); - - // And again, verify results - nontransaction tx3(conn, "tx3"); - - R = tx3.exec( - "SELECT * FROM " + Table + - " " - "WHERE year=" + - to_string(BoringYear)); - - PQXX_CHECK_EQUAL(std::size(R), 0, "Record is not gone as expected."); -} - - -PQXX_REGISTER_TEST(test_039); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test46.cxx b/ext/libpqxx-7.7.3/test/test46.cxx deleted file mode 100644 index 0fa88915a..000000000 --- a/ext/libpqxx-7.7.3/test/test46.cxx +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include - -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Streams test program for libpqxx. Insert a result field into various -// types of streams. -namespace -{ -void test_046() -{ - connection conn; - work tx{conn}; - - row R{tx.exec1("SELECT count(*) FROM pg_tables")}; - - // Read the value into a stringstream. - std::stringstream I; - I << R[0]; - - // Now convert the stringstream into a numeric type - long L{}, L2{}; - I >> L; - - R[0].to(L2); - PQXX_CHECK_EQUAL(L, L2, "Inconsistency between conversion methods."); - - float F{}, F2{}; - std::stringstream I2; - I2 << R[0]; - I2 >> F; - R[0].to(F2); - PQXX_CHECK_BOUNDS(F2, F - 0.01, F + 0.01, "Bad floating-point result."); - - auto F3{from_string(R[0].c_str())}; - PQXX_CHECK_BOUNDS(F3, F - 0.01, F + 0.01, "Bad float from from_string."); - - auto D{from_string(R[0].c_str())}; - PQXX_CHECK_BOUNDS(D, F - 0.01, F + 0.01, "Bad double from from_string."); - - auto LD{from_string(R[0].c_str())}; - PQXX_CHECK_BOUNDS( - LD, F - 0.01, F + 0.01, "Bad long double from from_string."); - - auto S{from_string(R[0].c_str())}, - S2{from_string(std::string{R[0].c_str()})}, - S3{from_string(R[0])}; - - PQXX_CHECK_EQUAL( - S2, S, - "from_string(char const[], std::string &) " - "is inconsistent with " - "from_string(std::string const &, std::string &)."); - - PQXX_CHECK_EQUAL( - S3, S2, - "from_string(result::field const &, std::string &) " - "is inconsistent with " - "from_string(std::string const &, std::string &)."); - - PQXX_CHECK(tx.query_value("SELECT 1=1"), "1=1 doesn't yield 'true.'"); - - PQXX_CHECK(not tx.query_value("SELECT 2+2=5"), "2+2=5 yields 'true.'"); -} - - -PQXX_REGISTER_TEST(test_046); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test56.cxx b/ext/libpqxx-7.7.3/test/test56.cxx deleted file mode 100644 index 3aef757bb..000000000 --- a/ext/libpqxx-7.7.3/test/test56.cxx +++ /dev/null @@ -1,24 +0,0 @@ -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Simple test program for libpqxx. Issue invalid query and handle error. -namespace -{ -void test_056() -{ - connection conn; - work tx{conn}; - quiet_errorhandler d(conn); - - PQXX_CHECK_THROWS( - tx.exec("DELIBERATELY INVALID TEST QUERY..."), sql_error, - "SQL syntax error did not raise expected exception."); -} - - -PQXX_REGISTER_TEST(test_056); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test60.cxx b/ext/libpqxx-7.7.3/test/test60.cxx deleted file mode 100644 index a29ce9ff7..000000000 --- a/ext/libpqxx-7.7.3/test/test60.cxx +++ /dev/null @@ -1,85 +0,0 @@ -#include - -#include -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Example program for libpqxx. Test session variable functionality. -namespace -{ -std::string GetDatestyle(connection &conn) -{ - return conn.get_var("DATESTYLE"); -} - - -std::string SetDatestyle(connection &conn, std::string style) -{ - conn.set_session_var("DATESTYLE", style); - std::string const fullname{GetDatestyle(conn)}; - PQXX_CHECK( - not std::empty(fullname), - "Setting datestyle to " + style + " makes it an empty string."); - - return fullname; -} - - -void CheckDatestyle(connection &conn, std::string expected) -{ - PQXX_CHECK_EQUAL(GetDatestyle(conn), expected, "Got wrong datestyle."); -} - - -void RedoDatestyle( - connection &conn, std::string const &style, std::string const &expected) -{ - PQXX_CHECK_EQUAL( - SetDatestyle(conn, style), expected, "Set wrong datestyle."); -} - - -void ActivationTest( - connection &conn, std::string const &style, std::string const &expected) -{ - RedoDatestyle(conn, style, expected); - CheckDatestyle(conn, expected); -} - - -void test_060() -{ - connection conn; - - PQXX_CHECK(not std::empty(GetDatestyle(conn)), "Initial datestyle not set."); - - std::string const ISOname{SetDatestyle(conn, "ISO")}; - std::string const SQLname{SetDatestyle(conn, "SQL")}; - - PQXX_CHECK_NOT_EQUAL(ISOname, SQLname, "Same datestyle in SQL and ISO."); - - RedoDatestyle(conn, "SQL", SQLname); - - ActivationTest(conn, "ISO", ISOname); - ActivationTest(conn, "SQL", SQLname); - - PQXX_CHECK_THROWS( - conn.set_session_var("bonjour_name", std::optional{}), - pqxx::variable_set_to_null, - "Setting a variable to null did not report the error correctly."); - - // Prove that setting an unknown variable causes an error, as expected - quiet_errorhandler d{conn}; - PQXX_CHECK_THROWS( - conn.set_session_var("NONEXISTENT_VARIABLE_I_HOPE", 1), sql_error, - "Setting unknown variable failed to fail."); -} - - -PQXX_REGISTER_TEST(test_060); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test61.cxx b/ext/libpqxx-7.7.3/test/test61.cxx deleted file mode 100644 index a9c871bdb..000000000 --- a/ext/libpqxx-7.7.3/test/test61.cxx +++ /dev/null @@ -1,61 +0,0 @@ -#include - -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Example program for libpqxx. Test local variable functionality. -namespace -{ -std::string GetDatestyle(transaction_base &T) -{ - return T.conn().get_var("DATESTYLE"); -} - - -std::string SetDatestyle(transaction_base &T, std::string style) -{ - T.conn().set_session_var("DATESTYLE", style); - std::string const fullname{GetDatestyle(T)}; - PQXX_CHECK( - not std::empty(fullname), - "Setting datestyle to " + style + " makes it an empty string."); - - return fullname; -} - - -void RedoDatestyle( - transaction_base &T, std::string const &style, std::string const &expected) -{ - PQXX_CHECK_EQUAL(SetDatestyle(T, style), expected, "Set wrong datestyle."); -} - - -void test_061() -{ - connection conn; - work tx{conn}; - - PQXX_CHECK(not std::empty(GetDatestyle(tx)), "Initial datestyle not set."); - - std::string const ISOname{SetDatestyle(tx, "ISO")}; - std::string const SQLname{SetDatestyle(tx, "SQL")}; - - PQXX_CHECK_NOT_EQUAL(ISOname, SQLname, "Same datestyle in SQL and ISO."); - - RedoDatestyle(tx, "SQL", SQLname); - - // Prove that setting an unknown variable causes an error, as expected - quiet_errorhandler d(tx.conn()); - PQXX_CHECK_THROWS( - conn.set_session_var("NONEXISTENT_VARIABLE_I_HOPE", 1), sql_error, - "Setting unknown variable failed to fail."); -} - - -PQXX_REGISTER_TEST(test_061); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test62.cxx b/ext/libpqxx-7.7.3/test/test62.cxx deleted file mode 100644 index d23e49e5a..000000000 --- a/ext/libpqxx-7.7.3/test/test62.cxx +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include - -#include - -#include "test_helpers.hxx" - - -using namespace pqxx; - - -// Example program for libpqxx. Test binary string functionality. -namespace -{ -void test_062() -{ - connection conn; - work tx{conn}; - - std::string const TestStr{ - "Nasty\n\030Test\n\t String with \200\277 weird bytes " - "\r\0 and Trailer\\\\\0"}; - - tx.exec0("CREATE TEMP TABLE pqxxbin (binfield bytea)"); - - std::string const Esc{tx.esc_raw(std::basic_string{ - reinterpret_cast(std::data(TestStr)), - std::size(TestStr)})}; - - tx.exec0("INSERT INTO pqxxbin VALUES ('" + Esc + "')"); - - result R{tx.exec("SELECT * from pqxxbin")}; - tx.exec0("DELETE FROM pqxxbin"); - - auto const B{R.at(0).at(0).as>()}; - - PQXX_CHECK(not std::empty(B), "Binary string became empty in conversion."); - - PQXX_CHECK_EQUAL( - std::size(B), std::size(TestStr), "Binary string was mangled."); - - std::basic_string::const_iterator c; - std::basic_string::size_type i; - for (i = 0, c = std::begin(B); i < std::size(B); ++i, ++c) - { - PQXX_CHECK(c != std::end(B), "Premature end to binary string."); - - char const x{TestStr.at(i)}, y{char(B.at(i))}, z{char(std::data(B)[i])}; - - PQXX_CHECK_EQUAL( - std::string(&x, 1), std::string(&y, 1), "Binary string byte changed."); - - PQXX_CHECK_EQUAL( - std::string(&y, 1), std::string(&z, 1), - "Inconsistent byte at offset " + to_string(i) + "."); - } -} - - -PQXX_REGISTER_TEST(test_062); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test69.cxx b/ext/libpqxx-7.7.3/test/test69.cxx deleted file mode 100644 index d15ff1489..000000000 --- a/ext/libpqxx-7.7.3/test/test69.cxx +++ /dev/null @@ -1,55 +0,0 @@ -#include - -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test program for libpqxx. Issue a query repeatedly through a pipeline, and -// compare results. -namespace -{ -void TestPipeline(pipeline &P, int numqueries) -{ - std::string const Q{"SELECT 99"}; - - for (int i{numqueries}; i > 0; --i) P.insert(Q); - - PQXX_CHECK( - (numqueries == 0) or not std::empty(P), "pipeline::empty() is broken."); - - int res{0}; - for (int i{numqueries}; i > 0; --i) - { - PQXX_CHECK( - not std::empty(P), "Got wrong number of queries from pipeline."); - - auto R{P.retrieve()}; - - if (res != 0) - PQXX_CHECK_EQUAL( - R.second[0][0].as(), res, - "Got unexpected result out of pipeline."); - - res = R.second[0][0].as(); - } - - PQXX_CHECK(std::empty(P), "Pipeline not empty after retrieval."); -} - - -void test_069() -{ - connection conn; - work tx{conn}; - pipeline P(tx); - PQXX_CHECK(std::empty(P), "Pipeline is not empty initially."); - for (int i{0}; i < 5; ++i) TestPipeline(P, i); -} - - -PQXX_REGISTER_TEST(test_069); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/test70.cxx b/ext/libpqxx-7.7.3/test/test70.cxx deleted file mode 100644 index 0f72089f1..000000000 --- a/ext/libpqxx-7.7.3/test/test70.cxx +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -namespace -{ -void TestPipeline(pipeline &P, int numqueries) -{ - std::string const Q{"SELECT * FROM generate_series(1, 10)"}; - result const Empty; - PQXX_CHECK(std::empty(Empty), "Default-constructed result is not empty."); - PQXX_CHECK( - std::empty(Empty.query()), "Default-constructed result has query"); - - P.retain(); - for (int i{numqueries}; i > 0; --i) P.insert(Q); - P.resume(); - - PQXX_CHECK( - (numqueries == 0) || not std::empty(P), "pipeline::empty() is broken."); - - int res{0}; - result Prev; - PQXX_CHECK_EQUAL(Prev, Empty, "Default-constructed results are not equal."); - - for (int i{numqueries}; i > 0; --i) - { - PQXX_CHECK(not std::empty(P), "Got no results from pipeline."); - - auto R{P.retrieve()}; - - PQXX_CHECK_NOT_EQUAL(R.second, Empty, "Got empty result."); - if (Prev != Empty) - PQXX_CHECK_EQUAL(R.second, Prev, "Results to same query are different."); - - Prev = R.second; - PQXX_CHECK_EQUAL(Prev, R.second, "Assignment breaks result equality."); - PQXX_CHECK_EQUAL(R.second.query(), Q, "Result is for unexpected query."); - - if (res != 0) - PQXX_CHECK_EQUAL(Prev[0][0].as(), res, "Bad result from pipeline."); - - res = Prev[0][0].as(); - } - - PQXX_CHECK(std::empty(P), "Pipeline was not empty after retrieval."); -} - - -// Test program for libpqxx. Issue a query repeatedly through a pipeline, and -// compare results. Use retain() and resume() for performance. -void test_070() -{ - connection conn; - work tx{conn}; - pipeline P(tx); - - PQXX_CHECK(std::empty(P), "Pipeline is not empty initially."); - - // Try to confuse the pipeline by feeding it a query and flushing - P.retain(); - std::string const Q{"SELECT * FROM pg_tables"}; - P.insert(Q); - P.flush(); - - PQXX_CHECK(std::empty(P), "Pipeline was not empty after flush()."); - - // See if complete() breaks retain() as it should - P.retain(); - P.insert(Q); - PQXX_CHECK(not std::empty(P), "Pipeline was empty after insert()."); - P.complete(); - PQXX_CHECK(not std::empty(P), "complete() emptied pipeline."); - - PQXX_CHECK_EQUAL( - P.retrieve().second.query(), Q, "Result is for wrong query."); - - PQXX_CHECK(std::empty(P), "Pipeline not empty after retrieve()."); - - // See if retrieve() breaks retain() when it needs to - P.retain(); - P.insert(Q); - PQXX_CHECK_EQUAL( - P.retrieve().second.query(), Q, "Got result for wrong query."); - - // See if regular retain()/resume() works - for (int i{0}; i < 5; ++i) TestPipeline(P, i); - - // See if retrieve() fails on an empty pipeline, as it should - quiet_errorhandler d(conn); - PQXX_CHECK_THROWS_EXCEPTION( - P.retrieve(), "Empty pipeline allows retrieve()."); -} -} // namespace - - -PQXX_REGISTER_TEST(test_070); diff --git a/ext/libpqxx-7.7.3/test/test71.cxx b/ext/libpqxx-7.7.3/test/test71.cxx deleted file mode 100644 index e669d9ad5..000000000 --- a/ext/libpqxx-7.7.3/test/test71.cxx +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include - -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test program for libpqxx. Issue queries through a pipeline, and retrieve -// results both in-order and out-of-order. -namespace -{ -using Exp = std::map; - -template void checkresult(pipeline &P, PAIR c) -{ - result const r{P.retrieve(c.first)}; - int const val{r.at(0).at(0).as(int(0))}; - PQXX_CHECK_EQUAL(val, c.second, "Wrong result from pipeline."); -} - - -void test_071() -{ - connection conn; - work tx{conn}; - pipeline P(tx); - - // Keep expected result for every query we issue - Exp values; - - // Insert queries returning various numbers. - for (int i{1}; i < 10; ++i) values[P.insert("SELECT " + to_string(i))] = i; - - // Retrieve results in query_id order, and compare to expected values - for (auto &c : values) checkresult(P, c); - - PQXX_CHECK(std::empty(P), "Pipeline was not empty retrieving all results."); - - values.clear(); - - // Insert more queries returning various numbers - P.retain(20); - for (int i{100}; i > 90; --i) values[P.insert("SELECT " + to_string(i))] = i; - - P.resume(); - - // Retrieve results in reverse order - for (auto c{std::rbegin(values)}; c != std::rend(values); ++c) - checkresult(P, *c); - - values.clear(); - P.retain(10); - for (int i{1010}; i > 1000; --i) - values[P.insert("SELECT " + to_string(i))] = i; - for (auto &c : values) - { - if (P.is_finished(c.first)) - std::cout << "Query #" << c.first << " completed despite retain()" - << std::endl; - } - - // See that all results are retrieved by complete() - P.complete(); - for (auto &c : values) - PQXX_CHECK(P.is_finished(c.first), "Query not finished after complete()."); -} -} // namespace - - -PQXX_REGISTER_TEST(test_071); diff --git a/ext/libpqxx-7.7.3/test/test72.cxx b/ext/libpqxx-7.7.3/test/test72.cxx deleted file mode 100644 index 716081ed7..000000000 --- a/ext/libpqxx-7.7.3/test/test72.cxx +++ /dev/null @@ -1,53 +0,0 @@ -#include - -#include -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test program for libpqxx. Test error handling for pipeline. -namespace -{ -void test_072() -{ - connection conn; - work tx{conn}; - pipeline P{tx}; - - // Ensure all queries are issued at once to make the test more interesting - P.retain(); - - // The middle query should fail; the surrounding two should succeed - auto const id_1{P.insert("SELECT 1")}; - auto const id_f{P.insert("SELECT * FROM pg_nonexist")}; - auto const id_2{P.insert("SELECT 2")}; - - // See that we can process the queries without stumbling over the error - P.complete(); - - // We should be able to get the first result, which preceeds the error - auto const res_1{P.retrieve(id_1).at(0).at(0).as()}; - PQXX_CHECK_EQUAL(res_1, 1, "Got wrong result from pipeline."); - - // We should *not* get a result for the query behind the error - { - quiet_errorhandler d{conn}; - PQXX_CHECK_THROWS( - P.retrieve(id_2).at(0).at(0).as(), std::runtime_error, - "Pipeline wrongly resumed after SQL error."); - } - - // Now see that we get an exception when we touch the failed result - { - quiet_errorhandler d{conn}; - PQXX_CHECK_THROWS( - P.retrieve(id_f), sql_error, "Pipeline failed to register SQL error."); - } -} -} // namespace - - -PQXX_REGISTER_TEST(test_072); diff --git a/ext/libpqxx-7.7.3/test/test74.cxx b/ext/libpqxx-7.7.3/test/test74.cxx deleted file mode 100644 index ff1abd993..000000000 --- a/ext/libpqxx-7.7.3/test/test74.cxx +++ /dev/null @@ -1,72 +0,0 @@ -#include - -#include - -#include "test_helpers.hxx" - -using namespace pqxx; - - -// Test program for libpqxx. Test fieldstream. -namespace -{ -void test_074() -{ - connection conn; - work tx{conn}; - - result R{tx.exec("SELECT * FROM pg_tables")}; - std::string const sval{R.at(0).at(1).c_str()}; - std::string sval2; - fieldstream fs1(R.front()[1]); - fs1 >> sval2; - PQXX_CHECK_EQUAL(sval2, sval, "fieldstream returned wrong value."); - - R = tx.exec("SELECT count(*) FROM pg_tables"); - int ival; - fieldstream fs2(R.at(0).at(0)); - fs2 >> ival; - PQXX_CHECK_EQUAL( - ival, R.front().front().as(), "fieldstream::front() is broken."); - - double dval; - (fieldstream(R.at(0).at(0))) >> dval; - PQXX_CHECK_BOUNDS( - dval, R[0][0].as() - 0.1, R[0][0].as() + 0.1, - "Got wrong double from fieldstream."); - - auto const roughpi{static_cast(3.1415926435)}; - R = tx.exec("SELECT " + to_string(roughpi)); - float pival; - (fieldstream(R.at(0).at(0))) >> pival; - PQXX_CHECK_BOUNDS( - pival, roughpi - 0.001, roughpi + 0.001, - "Pi approximation came back wrong from fieldstream."); - - PQXX_CHECK_EQUAL( - to_string(R[0][0]), R[0][0].c_str(), - "to_string(result::field) is inconsistent with c_str()."); - - float float_pi; - from_string(to_string(roughpi), float_pi); - PQXX_CHECK_BOUNDS( - float_pi, roughpi - 0.00001, roughpi + 0.00001, - "Float changed in conversion."); - - double double_pi; - pqxx::from_string(pqxx::to_string(static_cast(roughpi)), double_pi); - PQXX_CHECK_BOUNDS( - double_pi, roughpi - 0.00001, roughpi + 0.00001, - "Double changed in conversion."); - - long double const ld{roughpi}; - long double long_double_pi; - from_string(to_string(ld), long_double_pi); - PQXX_CHECK_BOUNDS( - long_double_pi, roughpi - 0.00001, roughpi + 0.00001, - "long double changed in conversion."); -} -} // namespace - - -PQXX_REGISTER_TEST(test_074); diff --git a/ext/libpqxx-7.7.3/test/test75.cxx b/ext/libpqxx-7.7.3/test/test75.cxx deleted file mode 100644 index 07f00141e..000000000 --- a/ext/libpqxx-7.7.3/test/test75.cxx +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include - -#include - -#include "test_helpers.hxx" - - -// Test program for libpqxx. Compare const_reverse_iterator iteration of a -// result to a regular, const_iterator iteration. -namespace -{ -void test_075() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - - pqxx::test::create_pqxxevents(tx); - auto const R(tx.exec("SELECT year FROM pqxxevents")); - PQXX_CHECK(not std::empty(R), "No events found, cannot test."); - - PQXX_CHECK_EQUAL(R[0], R.at(0), "Inconsistent result indexing."); - PQXX_CHECK(not(R[0] != R.at(0)), "result::row::operator!=() is broken."); - - PQXX_CHECK_EQUAL(R[0][0], R[0].at(0), "Inconsistent row indexing."); - PQXX_CHECK( - not(R[0][0] != R[0].at(0)), "result::field::operator!=() is broken."); - - std::vector contents; - for (auto const &i : R) contents.push_back(i.at(0).as()); - - PQXX_CHECK_EQUAL( - std::size(contents), std::vector::size_type(std::size(R)), - "Number of values does not match result size."); - - for (pqxx::result::size_type i{0}; i < std::size(R); ++i) - PQXX_CHECK_EQUAL( - contents[static_cast(i)], R.at(i).at(0).c_str(), - "Inconsistent iteration."); - - // Thorough test for result::const_reverse_iterator - pqxx::result::const_reverse_iterator ri1(std::rbegin(R)), ri2(ri1), - ri3(std::end(R)); - ri2 = std::rbegin(R); - - PQXX_CHECK(ri2 == ri1, "reverse_iterator copy constructor is broken."); - PQXX_CHECK(ri3 == ri2, "result::end() does not generate rbegin()."); - PQXX_CHECK_EQUAL( - ri2 - ri3, 0, - "const_reverse_iterator is at nonzero distance from its own copy."); - - PQXX_CHECK(ri2 == ri3 + 0, "reverse_iterator+0 gives strange result."); - PQXX_CHECK(ri2 == ri3 - 0, "reverse_iterator-0 gives strange result."); - PQXX_CHECK(not(ri3 < ri2), "operator<() breaks on equal reverse_iterators."); - PQXX_CHECK(ri2 <= ri3, "operator<=() breaks on equal reverse_iterators."); - - PQXX_CHECK(ri3++ == ri2, "reverse_iterator post-increment is broken."); - - PQXX_CHECK_EQUAL(ri3 - ri2, 1, "Wrong nonzero reverse_iterator distance."); - PQXX_CHECK(ri3 > ri2, "reverse_iterator operator>() is broken."); - PQXX_CHECK(ri3 >= ri2, "reverse_iterator operator>=() is broken."); - PQXX_CHECK(ri2 < ri3, "reverse_iterator operator<() is broken."); - PQXX_CHECK(ri2 <= ri3, "reverse_iterator operator<=() is broken."); - PQXX_CHECK(ri3 == ri2 + 1, "Adding int to reverse_iterator is broken."); - PQXX_CHECK( - ri2 == ri3 - 1, "Subtracting int from reverse_iterator is broken."); - - PQXX_CHECK(ri3 == ++ri2, "reverse_iterator pre-increment is broken."); - PQXX_CHECK(ri3 >= ri2, "operator>=() breaks on equal reverse_iterators."); - PQXX_CHECK(ri3 >= ri2, "operator<=() breaks on equal reverse_iterators."); - - PQXX_CHECK( - *ri3.base() == R.back(), "reverse_iterator does not arrive at back()."); - - PQXX_CHECK( - ri1->at(0) == (*ri1).at(0), - "reverse_iterator operator->() is inconsistent with operator*()."); - - PQXX_CHECK(ri2-- == ri3, "reverse_iterator post-decrement is broken."); - PQXX_CHECK(ri2 == --ri3, "reverse_iterator pre-decrement is broken."); - PQXX_CHECK(ri2 == std::rbegin(R), "reverse_iterator decrement is broken."); - - ri2 += 1; - ri3 -= -1; - - PQXX_CHECK( - ri2 != std::rbegin(R), "Adding to reverse_iterator does not work."); - PQXX_CHECK( - ri3 == ri2, "reverse_iterator operator-=() breaks on negative distances."); - - ri2 -= 1; - PQXX_CHECK( - ri2 == std::rbegin(R), - "reverse_iterator operator+=() and operator-=() do not cancel out."); - - // Now verify that reverse iterator also sees the same results... - auto l{std::rbegin(contents)}; - for (auto i{std::rbegin(R)}; i != std::rend(R); ++i, ++l) - PQXX_CHECK_EQUAL(*l, i->at(0).c_str(), "Inconsistent reverse iteration."); - - PQXX_CHECK(l == std::rend(contents), "Reverse iteration ended too soon."); - - PQXX_CHECK(not std::empty(R), "No events found in table, cannot test."); -} -} // namespace - - -PQXX_REGISTER_TEST(test_075); diff --git a/ext/libpqxx-7.7.3/test/test76.cxx b/ext/libpqxx-7.7.3/test/test76.cxx deleted file mode 100644 index 122c0445c..000000000 --- a/ext/libpqxx-7.7.3/test/test76.cxx +++ /dev/null @@ -1,52 +0,0 @@ -#include - -#include "test_helpers.hxx" - -// Simple test program for libpqxx. Test string conversion routines. -namespace -{ -void test_076() -{ - pqxx::connection conn; - pqxx::nontransaction tx{conn}; - - auto RFalse{tx.exec1("SELECT 1=0")}, RTrue{tx.exec1("SELECT 1=1")}; - auto False{pqxx::from_string(RFalse[0])}, - True{pqxx::from_string(RTrue[0])}; - PQXX_CHECK(not False, "False bool converted to true."); - PQXX_CHECK(True, "True bool converted to false."); - - RFalse = tx.exec1("SELECT " + pqxx::to_string(False)); - RTrue = tx.exec1("SELECT " + pqxx::to_string(True)); - False = pqxx::from_string(RFalse[0]); - True = pqxx::from_string(RTrue[0]); - PQXX_CHECK(not False, "False bool converted to true."); - PQXX_CHECK(True, "True bool converted to false."); - - short const svals[]{-1, 1, 999, -32767, -32768, 32767, 0}; - for (int i{0}; svals[i] != 0; ++i) - { - auto s{pqxx::from_string(pqxx::to_string(svals[i]))}; - PQXX_CHECK_EQUAL(s, svals[i], "short/string conversion not bijective."); - s = pqxx::from_string( - tx.exec1("SELECT " + pqxx::to_string(svals[i]))[0].c_str()); - PQXX_CHECK_EQUAL(s, svals[i], "Roundtrip through backend changed short."); - } - - unsigned short const uvals[]{1, 999, 32767, 32768, 65535, 0}; - for (int i{0}; uvals[i] != 0; ++i) - { - auto u{pqxx::from_string(pqxx::to_string(uvals[i]))}; - PQXX_CHECK_EQUAL( - u, uvals[i], "unsigned short/string conversion not bijective."); - - u = pqxx::from_string( - tx.exec1("SELECT " + pqxx::to_string(uvals[i]))[0].c_str()); - PQXX_CHECK_EQUAL( - u, uvals[i], "Roundtrip through backend changed unsigned short."); - } -} -} // namespace - - -PQXX_REGISTER_TEST(test_076); diff --git a/ext/libpqxx-7.7.3/test/test77.cxx b/ext/libpqxx-7.7.3/test/test77.cxx deleted file mode 100644 index 88e83c26d..000000000 --- a/ext/libpqxx-7.7.3/test/test77.cxx +++ /dev/null @@ -1,28 +0,0 @@ -#include - -#include "test_helpers.hxx" - - -// Test program for libpqxx. Test result::swap() -namespace -{ -void test_077() -{ - pqxx::connection conn; - pqxx::nontransaction tx{conn}; - - auto RFalse{tx.exec("SELECT 1=0")}, RTrue{tx.exec("SELECT 1=1")}; - auto f{pqxx::from_string(RFalse[0][0])}; - auto t{pqxx::from_string(RTrue[0][0])}; - PQXX_CHECK( - not f and t, "Booleans converted incorrectly; can't trust this test."); - - RFalse.swap(RTrue); - f = pqxx::from_string(RFalse[0][0]); - t = pqxx::from_string(RTrue[0][0]); - PQXX_CHECK(f and not t, "result::swap() is broken."); -} -} // namespace - - -PQXX_REGISTER_TEST(test_077); diff --git a/ext/libpqxx-7.7.3/test/test78.cxx b/ext/libpqxx-7.7.3/test/test78.cxx deleted file mode 100644 index f970cc926..000000000 --- a/ext/libpqxx-7.7.3/test/test78.cxx +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include - -#include -#include -#include - -#include "test_helpers.hxx" - - -// Example program for libpqxx. Send notification to self, using a -// notification name with unusal characters, and without polling. -namespace -{ -// Sample implementation of notification receiver. -class TestListener : public pqxx::notification_receiver -{ - bool m_done; - -public: - explicit TestListener(pqxx::connection &conn, std::string const &Name) : - pqxx::notification_receiver(conn, Name), m_done(false) - {} - - void operator()(std::string const &, int be_pid) override - { - m_done = true; - PQXX_CHECK_EQUAL( - be_pid, conn().backendpid(), - "Got notification from wrong backend process."); - - std::cout << "Received notification: " << channel() << " pid=" << be_pid - << std::endl; - } - - bool done() const { return m_done; } -}; - - -void test_078() -{ - pqxx::connection conn; - - std::string const NotifName{"my listener"}; - TestListener L{conn, NotifName}; - - pqxx::perform([&conn, &L] { - pqxx::work tx{conn}; - tx.exec0("NOTIFY " + tx.quote_name(L.channel())); - tx.commit(); - }); - - int notifs{0}; - for (int i{0}; (i < 20) and not L.done(); ++i) - { - PQXX_CHECK_EQUAL(notifs, 0, "Got unexpected notifications."); - std::cout << "."; - notifs = conn.await_notification(); - } - std::cout << std::endl; - - PQXX_CHECK(L.done(), "No notification received."); - PQXX_CHECK_EQUAL(notifs, 1, "Got unexpected number of notifications."); -} -} // namespace - - -PQXX_REGISTER_TEST(test_078); diff --git a/ext/libpqxx-7.7.3/test/test79.cxx b/ext/libpqxx-7.7.3/test/test79.cxx deleted file mode 100644 index 761e5f3c3..000000000 --- a/ext/libpqxx-7.7.3/test/test79.cxx +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include - -#include -#include -#include - -#include "test_helpers.hxx" - - -// Example program for libpqxx. Test waiting for notification with timeout. -namespace -{ -// Sample implementation of notification receiver. -class TestListener final : public pqxx::notification_receiver -{ - bool m_done; - -public: - explicit TestListener(pqxx::connection &conn, std::string const &Name) : - pqxx::notification_receiver(conn, Name), m_done(false) - {} - - void operator()(std::string const &, int be_pid) override - { - m_done = true; - PQXX_CHECK_EQUAL( - be_pid, conn().backendpid(), "Notification came from wrong backend."); - - std::cout << "Received notification: " << channel() << " pid=" << be_pid - << std::endl; - } - - bool done() const { return m_done; } -}; - - -void test_079() -{ - pqxx::connection conn; - - std::string const NotifName{"mylistener"}; - TestListener L(conn, NotifName); - - // First see if the timeout really works: we're not expecting any notifs - int notifs{conn.await_notification(0, 1)}; - PQXX_CHECK_EQUAL(notifs, 0, "Got unexpected notification."); - - pqxx::perform([&conn, &L] { - pqxx::work tx{conn}; - tx.exec0("NOTIFY " + L.channel()); - tx.commit(); - }); - - for (int i{0}; (i < 20) and not L.done(); ++i) - { - PQXX_CHECK_EQUAL(notifs, 0, "Got notifications, but no handler called."); - std::cout << "."; - notifs = conn.await_notification(1, 0); - } - std::cout << std::endl; - - PQXX_CHECK(L.done(), "No notifications received."); - PQXX_CHECK_EQUAL(notifs, 1, "Got unexpected notifications."); -} -} // namespace - - -PQXX_REGISTER_TEST(test_079); diff --git a/ext/libpqxx-7.7.3/test/test82.cxx b/ext/libpqxx-7.7.3/test/test82.cxx deleted file mode 100644 index e7b2769c7..000000000 --- a/ext/libpqxx-7.7.3/test/test82.cxx +++ /dev/null @@ -1,154 +0,0 @@ -#include - -#include - -#include "test_helpers.hxx" - - -// Test program for libpqxx. Read and print table using row iterators. -namespace -{ -void test_082() -{ - pqxx::connection conn; - pqxx::nontransaction tx{conn}; - - pqxx::test::create_pqxxevents(tx); - std::string const Table{"pqxxevents"}; - pqxx::result R{tx.exec("SELECT * FROM " + Table)}; - - PQXX_CHECK(not std::empty(R), "Got empty result."); - - std::string const nullstr("[null]"); - - for (auto const &r : R) - { - pqxx::row::const_iterator f2(r[0]); - for (auto const &f : r) - { - PQXX_CHECK_EQUAL( - (*f2).as(nullstr), f.as(nullstr), "Inconsistent iteration result."); - ++f2; - } - - PQXX_CHECK( - std::begin(r) + pqxx::row::difference_type(std::size(r)) == std::end(r), - "Row end() appears to be in the wrong place."); - PQXX_CHECK( - pqxx::row::difference_type(std::size(r)) + std::begin(r) == std::end(r), - "Row iterator addition is not commutative."); - PQXX_CHECK_EQUAL( - std::begin(r)->num(), 0, "Wrong column number at begin()."); - - pqxx::row::const_iterator f3(r[std::size(r)]); - - PQXX_CHECK(f3 == std::end(r), "Did not get end() at end of row."); - - PQXX_CHECK( - f3 > std::begin(r), "Row end() appears to precede its begin()."); - - PQXX_CHECK( - f3 >= std::end(r) and std::begin(r) < f3, - "Row iterator operator<() is broken."); - - PQXX_CHECK(f3 > std::begin(r), "Row end() not greater than begin()."); - - pqxx::row::const_iterator f4{r, std::size(r)}; - PQXX_CHECK(f4 == f3, "Row iterator constructor with offset is broken."); - - --f3; - f4 -= 1; - - PQXX_CHECK(f3 < std::end(r), "Last field in row is not before end()."); - PQXX_CHECK(f3 >= std::begin(r), "Last field in row precedes begin()."); - PQXX_CHECK( - f3 == std::end(r) - 1, "Back from end() doese not yield end()-1."); - PQXX_CHECK_EQUAL( - std::end(r) - f3, 1, "Wrong distance from last row to end()."); - - PQXX_CHECK(f4 == f3, "Row iterator operator-=() is broken."); - f4 += 1; - PQXX_CHECK(f4 == std::end(r), "Row iterator operator+=() is broken."); - - for (auto fr = std::rbegin(r); fr != std::rend(r); ++fr, --f3) - PQXX_CHECK_EQUAL( - *fr, *f3, - "Reverse traversal is not consistent with forward traversal."); - } - - // Thorough test for row::const_reverse_iterator - pqxx::row::const_reverse_iterator ri1(std::rbegin(R.front())), ri2(ri1), - ri3(std::end(R.front())); - ri2 = std::rbegin(R.front()); - - PQXX_CHECK( - ri1 == ri2, "Copy-constructed reverse_iterator is not equal to original."); - - PQXX_CHECK(ri2 == ri3, "result::end() does not generate rbegin()."); - PQXX_CHECK_EQUAL( - ri2 - ri3, 0, - "Distance between identical const_reverse_iterators was nonzero."); - - PQXX_CHECK( - pqxx::row::const_reverse_iterator(ri1.base()) == ri1, - "Back-conversion of reverse_iterator base() fails."); - - PQXX_CHECK(ri2 == ri3 + 0, "reverse_iterator+0 gives strange result."); - PQXX_CHECK(ri2 == ri3 - 0, "reverse_iterator-0 gives strange result."); - - PQXX_CHECK( - not(ri3 < ri2), - "reverse_iterator operator<() breaks on identical iterators."); - PQXX_CHECK( - ri2 <= ri3, - "reverse_iterator operator<=() breaks on identical iterators."); - PQXX_CHECK(ri3++ == ri2, "reverse_iterator post-increment is broken."); - - PQXX_CHECK_EQUAL(ri3 - ri2, 1, "Wrong reverse_iterator distance."); - PQXX_CHECK(ri3 > ri2, "reverse_iterator operator>() is broken."); - PQXX_CHECK(ri3 >= ri2, "reverse_iterator operator>=() is broken."); - PQXX_CHECK(ri2 < ri3, "reverse_iterator operator<() is broken."); - PQXX_CHECK(ri2 <= ri3, "reverse_iterator operator<=() is broken."); - PQXX_CHECK(ri3 == ri2 + 1, "Adding number to reverse_iterator goes wrong."); - PQXX_CHECK(ri2 == ri3 - 1, "Subtracting from reverse_iterator goes wrong."); - - PQXX_CHECK( - ri3 == ++ri2, "reverse_iterator pre-incremen returns wrong result."); - - PQXX_CHECK( - ri3 >= ri2, "reverse_iterator operator>=() breaks on equal iterators."); - PQXX_CHECK( - ri3 >= ri2, "reverse_iterator operator<=() breaks on equal iterators."); - PQXX_CHECK( - *ri3.base() == R.front().back(), - "reverse_iterator does not arrive at back()."); - PQXX_CHECK( - ri1->c_str()[0] == (*ri1).c_str()[0], - "reverse_iterator operator->() is inconsistent with operator*()."); - PQXX_CHECK( - ri2-- == ri3, "reverse_iterator post-decrement returns wrong result."); - PQXX_CHECK( - ri2 == --ri3, "reverse_iterator pre-increment returns wrong result."); - PQXX_CHECK( - ri2 == std::rbegin(R.front()), - "Moving iterator back and forth doesn't get it back to origin."); - - ri2 += 1; - ri3 -= -1; - - PQXX_CHECK( - ri2 != std::rbegin(R.front()), "Adding to reverse_iterator doesn't work."); - PQXX_CHECK( - ri2 != std::rbegin(R.front()), "Adding to reverse_iterator doesn't work."); - PQXX_CHECK( - ri3 == ri2, "reverse_iterator operator-=() breaks on negative numbers."); - - ri2 -= 1; - PQXX_CHECK( - ri2 == std::rbegin(R.front()), - "reverse_iterator operator+=() and operator-=() do not cancel out"); -} -} // namespace - - -PQXX_REGISTER_TEST(test_082); diff --git a/ext/libpqxx-7.7.3/test/test84.cxx b/ext/libpqxx-7.7.3/test/test84.cxx deleted file mode 100644 index d35dc521b..000000000 --- a/ext/libpqxx-7.7.3/test/test84.cxx +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include "test_helpers.hxx" - - -// "Adopted SQL Cursor" test program for libpqxx. Create SQL cursor, wrap it -// in a cursor stream, then use it to fetch data and check for consistent -// results. Compare results against an icursor_iterator so that is tested as -// well. -namespace -{ -void test_084() -{ - pqxx::connection conn; - pqxx::transaction tx{conn}; - - std::string const Table{"pg_tables"}, Key{"tablename"}; - - // Count rows. - pqxx::result R(tx.exec("SELECT count(*) FROM " + Table)); - - PQXX_CHECK( - R.at(0).at(0).as() > 20, - "Not enough rows in " + Table + ", cannot test."); - - // Create an SQL cursor and, for good measure, muddle up its state a bit. - std::string const CurName{"MYCUR"}, - Query{"SELECT * FROM " + Table + " ORDER BY " + Key}; - constexpr int InitialSkip{2}, GetRows{3}; - - tx.exec0("DECLARE " + tx.quote_name(CurName) + " CURSOR FOR " + Query); - tx.exec0( - "MOVE " + pqxx::to_string(InitialSkip * GetRows) + - " " - "IN " + - tx.quote_name(CurName)); - - // Wrap cursor in cursor stream. Apply some trickery to get its name inside - // a result field for this purpose. This isn't easy because it's not - // supposed to be easy; normally we'd only construct streams around existing - // SQL cursors if they were being returned by functions. - pqxx::icursorstream C{ - tx, tx.exec("SELECT '" + tx.esc(CurName) + "'")[0][0], GetRows}; - - // Create parallel cursor to check results - pqxx::icursorstream C2{tx, Query, "CHECKCUR", GetRows}; - pqxx::icursor_iterator i2{C2}; - - // Remember, our adopted cursor is at position (InitialSkip*GetRows) - pqxx::icursor_iterator i3(i2); - - PQXX_CHECK( - (i3 == i2) and not(i3 != i2), - "Equality on copy-constructed icursor_iterator is broken."); - PQXX_CHECK( - not(i3 > i2) and not(i3 < i2) and (i3 <= i2) and (i3 >= i2), - "Comparison on identical icursor_iterators is broken."); - - i3 += InitialSkip; - - PQXX_CHECK(not(i3 <= i2), "icursor_iterator operator<=() is broken."); - - pqxx::icursor_iterator iend, i4; - PQXX_CHECK(i3 != iend, "Early end to icursor_iterator iteration."); - i4 = iend; - PQXX_CHECK(i4 == iend, "Assigning empty icursor_iterator fails."); - - // Now start testing our new Cursor. - C >> R; - i2 = i3; - pqxx::result R2(*i2++); - - PQXX_CHECK_EQUAL( - std::size(R), static_cast(GetRows), - "Got unexpected number of rows."); - - PQXX_CHECK_EQUAL(R, R2, "Unexpected result at [1]"); - - C.get(R); - R2 = *i2; - PQXX_CHECK_EQUAL(R, R2, "Unexpected result at [2]"); - i2 += 1; - - C.ignore(GetRows); - C.get(R); - R2 = *++i2; - - PQXX_CHECK_EQUAL(R, R2, "Unexpected result at [3]"); - - ++i2; - R2 = *i2++; - for (int i{1}; C.get(R) and i2 != iend; R2 = *i2++, ++i) - PQXX_CHECK_EQUAL( - R, R2, "Unexpected result in iteration at " + pqxx::to_string(i)); - - PQXX_CHECK(i2 == iend, "Adopted cursor terminated early."); - PQXX_CHECK(not(C >> R), "icursor_iterator terminated early."); -} -} // namespace - - -PQXX_REGISTER_TEST(test_084); diff --git a/ext/libpqxx-7.7.3/test/test87.cxx b/ext/libpqxx-7.7.3/test/test87.cxx deleted file mode 100644 index 3a9a58b16..000000000 --- a/ext/libpqxx-7.7.3/test/test87.cxx +++ /dev/null @@ -1,83 +0,0 @@ -#include "pqxx/config-public-compiler.h" -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include -#include -#include - -#include "test_helpers.hxx" - - -// Test program for libpqxx. Send notification to self, and wait on the -// socket's connection for it to come in. In a simple situation you'd use -// connection::await_notification() for this, but that won't let you wait for -// multiple sockets. -namespace -{ -// Sample implementation of notification receiver. -class TestListener final : public pqxx::notification_receiver -{ - bool m_done; - -public: - explicit TestListener(pqxx::connection &conn, std::string Name) : - pqxx::notification_receiver(conn, Name), m_done(false) - {} - - void operator()(std::string const &, int be_pid) override - { - m_done = true; - PQXX_CHECK_EQUAL( - be_pid, conn().backendpid(), - "Notification came from wrong backend process."); - - std::cout << "Received notification: " << channel() << " pid=" << be_pid - << std::endl; - } - - bool done() const { return m_done; } -}; - - -void test_087() -{ - pqxx::connection conn; - - std::string const NotifName{"my notification"}; - TestListener L{conn, NotifName}; - - pqxx::perform([&conn, &L] { - pqxx::work tx{conn}; - tx.exec0("NOTIFY " + tx.quote_name(L.channel())); - tx.commit(); - }); - - int notifs{0}; - for (int i{0}; (i < 20) and not L.done(); ++i) - { - PQXX_CHECK_EQUAL(notifs, 0, "Got unexpected notifications."); - - std::cout << "."; - - pqxx::internal::wait_fd(conn.sock(), true, false); - notifs = conn.get_notifs(); - } - std::cout << std::endl; - - PQXX_CHECK(L.done(), "No notification received."); - PQXX_CHECK_EQUAL(notifs, 1, "Got unexpected number of notifications."); -} -} // namespace - - -PQXX_REGISTER_TEST(test_087); diff --git a/ext/libpqxx-7.7.3/test/test88.cxx b/ext/libpqxx-7.7.3/test/test88.cxx deleted file mode 100644 index d5deaea75..000000000 --- a/ext/libpqxx-7.7.3/test/test88.cxx +++ /dev/null @@ -1,91 +0,0 @@ -#include - -#include -#include - -#include "test_helpers.hxx" - - -// Test program for libpqxx. Attempt to perform nested transactions. -namespace -{ -void test_088() -{ - pqxx::connection conn; - - pqxx::work tx0{conn}; - pqxx::test::create_pqxxevents(tx0); - - // Trivial test: create subtransactions, and commit/abort - std::cout << tx0.exec1("SELECT 'tx0 starts'")[0].c_str() << std::endl; - - pqxx::subtransaction T0a(static_cast(tx0), "T0a"); - T0a.commit(); - - pqxx::subtransaction T0b(static_cast(tx0), "T0b"); - T0b.abort(); - std::cout << tx0.exec1("SELECT 'tx0 ends'")[0].c_str() << std::endl; - tx0.commit(); - - // Basic functionality: perform query in subtransaction; abort, continue - pqxx::work tx1{conn, "tx1"}; - std::cout << tx1.exec1("SELECT 'tx1 starts'")[0].c_str() << std::endl; - pqxx::subtransaction tx1a{tx1, "tx1a"}; - std::cout << tx1a.exec1("SELECT ' a'")[0].c_str() << std::endl; - tx1a.commit(); - pqxx::subtransaction tx1b{tx1, "tx1b"}; - std::cout << tx1b.exec1("SELECT ' b'")[0].c_str() << std::endl; - tx1b.abort(); - pqxx::subtransaction tx1c{tx1, "tx1c"}; - std::cout << tx1c.exec1("SELECT ' c'")[0].c_str() << std::endl; - tx1c.commit(); - std::cout << tx1.exec1("SELECT 'tx1 ends'")[0].c_str() << std::endl; - tx1.commit(); - - // Commit/rollback functionality - pqxx::work tx2{conn, "tx2"}; - std::string const Table{"test088"}; - tx2.exec0("CREATE TEMP TABLE " + Table + "(no INTEGER, text VARCHAR)"); - - tx2.exec0("INSERT INTO " + Table + " VALUES(1,'tx2')"); - - pqxx::subtransaction tx2a{tx2, "tx2a"}; - tx2a.exec0("INSERT INTO " + Table + " VALUES(2,'tx2a')"); - tx2a.commit(); - pqxx::subtransaction tx2b{tx2, "tx2b"}; - tx2b.exec0("INSERT INTO " + Table + " VALUES(3,'tx2b')"); - tx2b.abort(); - pqxx::subtransaction tx2c{tx2, "tx2c"}; - tx2c.exec0("INSERT INTO " + Table + " VALUES(4,'tx2c')"); - tx2c.commit(); - auto const R{tx2.exec("SELECT * FROM " + Table + " ORDER BY no")}; - for (auto const &i : R) - std::cout << '\t' << i[0].c_str() << '\t' << i[1].c_str() << std::endl; - - PQXX_CHECK_EQUAL(std::size(R), 3, "Wrong number of results."); - - int expected[3]{1, 2, 4}; - for (pqxx::result::size_type n{0}; n < std::size(R); ++n) - PQXX_CHECK_EQUAL( - R[n][0].as(), expected[n], "Hit unexpected row number."); - - tx2.abort(); - - // Auto-abort should only roll back the subtransaction. - pqxx::work tx3{conn, "tx3"}; - pqxx::subtransaction tx3a(tx3, "tx3a"); - PQXX_CHECK_THROWS( - tx3a.exec("SELECT * FROM nonexistent_table WHERE nonattribute=0"), - pqxx::sql_error, "Bogus query did not fail."); - - // Subtransaction can only be aborted now, because there was an error. - tx3a.abort(); - // We're back in our top-level transaction. This did not abort. - tx3.exec1("SELECT count(*) FROM pqxxevents"); - // Make sure we can commit exactly one more level of transaction. - tx3.commit(); -} -} // namespace - - -PQXX_REGISTER_TEST(test_088); diff --git a/ext/libpqxx-7.7.3/test/test89.cxx b/ext/libpqxx-7.7.3/test/test89.cxx deleted file mode 100644 index 2b96dfcd2..000000000 --- a/ext/libpqxx-7.7.3/test/test89.cxx +++ /dev/null @@ -1,44 +0,0 @@ -#include - -#include -#include - -#include "test_helpers.hxx" - -// Test program for libpqxx. Attempt to perform nested queries on various -// types of connections. -namespace -{ -void test_089() -{ - pqxx::connection C; - - // Trivial test: create subtransactions, and commit/abort - pqxx::work T0(C, "T0"); - T0.exec1("SELECT 'T0 starts'"); - pqxx::subtransaction T0a(T0, "T0a"); - T0a.commit(); - pqxx::subtransaction T0b(T0, "T0b"); - T0b.abort(); - T0.exec1("SELECT 'T0 ends'"); - T0.commit(); - - // Basic functionality: perform query in subtransaction; abort, continue - pqxx::work T1(C, "T1"); - T1.exec1("SELECT 'T1 starts'"); - pqxx::subtransaction T1a(T1, "T1a"); - T1a.exec1("SELECT ' a'"); - T1a.commit(); - pqxx::subtransaction T1b(T1, "T1b"); - T1b.exec1("SELECT ' b'"); - T1b.abort(); - pqxx::subtransaction T1c(T1, "T1c"); - T1c.exec1("SELECT ' c'"); - T1c.commit(); - T1.exec1("SELECT 'T1 ends'"); - T1.commit(); -} -} // namespace - - -PQXX_REGISTER_TEST(test_089); diff --git a/ext/libpqxx-7.7.3/test/test90.cxx b/ext/libpqxx-7.7.3/test/test90.cxx deleted file mode 100644 index d7d97f9f3..000000000 --- a/ext/libpqxx-7.7.3/test/test90.cxx +++ /dev/null @@ -1,23 +0,0 @@ -#include - -#include "test_helpers.hxx" - -// Test program for libpqxx. Test adorn_name. - -namespace -{ -void test_090() -{ - pqxx::connection conn; - - // Test connection's adorn_name() function for uniqueness - std::string const nametest{"basename"}; - - PQXX_CHECK_NOT_EQUAL( - conn.adorn_name(nametest), conn.adorn_name(nametest), - "\"Unique\" names are not unique."); -} -} // namespace - - -PQXX_REGISTER_TEST(test_090); diff --git a/ext/libpqxx-7.7.3/test/test_helpers.hxx b/ext/libpqxx-7.7.3/test/test_helpers.hxx deleted file mode 100644 index 6db3ab971..000000000 --- a/ext/libpqxx-7.7.3/test/test_helpers.hxx +++ /dev/null @@ -1,305 +0,0 @@ -#include -#include - -#include -#include - -namespace pqxx -{ -namespace test -{ -class test_failure : public std::logic_error -{ - std::string const m_file; - int m_line; - -public: - test_failure(std::string const &ffile, int fline, std::string const &desc); - - ~test_failure() noexcept override; - - std::string const &file() const noexcept { return m_file; } - int line() const noexcept { return m_line; } -}; - - -/// Drop a table, if it exists. -void drop_table(transaction_base &, std::string const &table); - - -using testfunc = void (*)(); - - -void register_test(char const name[], testfunc func); - - -/// Register a test while not inside a function. -struct registrar -{ - registrar(char const name[], testfunc func) - { - pqxx::test::register_test(name, func); - } -}; - - -// Register a test function, so the runner will run it. -#define PQXX_REGISTER_TEST(func) \ - pqxx::test::registrar tst_##func { #func, func } - - -// Unconditional test failure. -#define PQXX_CHECK_NOTREACHED(desc) \ - pqxx::test::check_notreached(__FILE__, __LINE__, (desc)) -[[noreturn]] void -check_notreached(char const file[], int line, std::string desc); - -// Verify that a condition is met, similar to assert() -#define PQXX_CHECK(condition, desc) \ - pqxx::test::check(__FILE__, __LINE__, (condition), #condition, (desc)) -void check( - char const file[], int line, bool condition, char const text[], - std::string const &desc); - -// Verify that variable has the expected value. -#define PQXX_CHECK_EQUAL(actual, expected, desc) \ - pqxx::test::check_equal( \ - __FILE__, __LINE__, (actual), #actual, (expected), #expected, (desc)) -template -inline void check_equal( - char const file[], int line, ACTUAL actual, char const actual_text[], - EXPECTED expected, char const expected_text[], std::string const &desc) -{ - if (expected == actual) - return; - std::string const fulldesc = desc + " (" + actual_text + " <> " + - expected_text + - ": " - "actual=" + - to_string(actual) + - ", " - "expected=" + - to_string(expected) + ")"; - throw test_failure(file, line, fulldesc); -} - -// Verify that two values are not equal. -#define PQXX_CHECK_NOT_EQUAL(value1, value2, desc) \ - pqxx::test::check_not_equal( \ - __FILE__, __LINE__, (value1), #value1, (value2), #value2, (desc)) -template -inline void check_not_equal( - char const file[], int line, VALUE1 value1, char const text1[], - VALUE2 value2, char const text2[], std::string const &desc) -{ - if (value1 != value2) - return; - std::string const fulldesc = desc + " (" + text1 + " == " + text2 + - ": " - "both are " + - to_string(value2) + ")"; - throw test_failure(file, line, fulldesc); -} - - -// Verify that value1 is less than value2. -#define PQXX_CHECK_LESS(value1, value2, desc) \ - pqxx::test::check_less( \ - __FILE__, __LINE__, (value1), #value1, (value2), #value2, (desc)) -// Verify that value1 is greater than value2. -#define PQXX_CHECK_GREATER(value2, value1, desc) \ - pqxx::test::check_less( \ - __FILE__, __LINE__, (value1), #value1, (value2), #value2, (desc)) -template -inline void check_less( - char const file[], int line, VALUE1 value1, char const text1[], - VALUE2 value2, char const text2[], std::string const &desc) -{ - if (value1 < value2) - return; - std::string const fulldesc = desc + " (" + text1 + " >= " + text2 + - ": " - "\"lower\"=" + - to_string(value1) + - ", " - "\"upper\"=" + - to_string(value2) + ")"; - throw test_failure(file, line, fulldesc); -} - - -// Verify that value1 is less than or equal to value2. -#define PQXX_CHECK_LESS_EQUAL(value1, value2, desc) \ - pqxx::test::check_less_equal( \ - __FILE__, __LINE__, (value1), #value1, (value2), #value2, (desc)) -// Verify that value1 is greater than or equal to value2. -#define PQXX_CHECK_GREATER_EQUAL(value2, value1, desc) \ - pqxx::test::check_less_equal( \ - __FILE__, __LINE__, (value1), #value1, (value2), #value2, (desc)) -template -inline void check_less_equal( - char const file[], int line, VALUE1 value1, char const text1[], - VALUE2 value2, char const text2[], std::string const &desc) -{ - if (value1 <= value2) - return; - std::string const fulldesc = desc + " (" + text1 + " > " + text2 + - ": " - "\"lower\"=" + - to_string(value1) + - ", " - "\"upper\"=" + - to_string(value2) + ")"; - throw test_failure(file, line, fulldesc); -} - - -struct failure_to_fail -{}; - - -namespace internal -{ -/// Syntactic placeholder: require (and accept) semicolon after block. -inline void end_of_statement() {} -} // namespace internal - - -// Verify that "action" does not throw an exception. -#define PQXX_CHECK_SUCCEEDS(action, desc) \ - { \ - try \ - { \ - action; \ - } \ - catch (std::exception const &e) \ - { \ - PQXX_CHECK_NOTREACHED( \ - std::string{desc} + " - \"" + \ - #action "\" threw exception: " + e.what()); \ - } \ - catch (...) \ - { \ - PQXX_CHECK_NOTREACHED( \ - std::string{desc} + " - \"" + #action "\" threw a non-exception!"); \ - } \ - } \ - pqxx::test::internal::end_of_statement() - -// Verify that "action" throws an exception, of any std::exception-based type. -#define PQXX_CHECK_THROWS_EXCEPTION(action, desc) \ - { \ - try \ - { \ - action; \ - throw pqxx::test::failure_to_fail(); \ - } \ - catch (pqxx::test::failure_to_fail const &) \ - { \ - PQXX_CHECK_NOTREACHED( \ - std::string{desc} + " (\"" #action "\" did not throw)"); \ - } \ - catch (std::exception const &) \ - {} \ - catch (...) \ - { \ - PQXX_CHECK_NOTREACHED( \ - std::string{desc} + " (\"" #action "\" threw non-exception type)"); \ - } \ - } \ - pqxx::test::internal::end_of_statement() - -// Verify that "action" throws "exception_type" (which is not std::exception). -#define PQXX_CHECK_THROWS(action, exception_type, desc) \ - { \ - try \ - { \ - action; \ - throw pqxx::test::failure_to_fail(); \ - } \ - catch (pqxx::test::failure_to_fail const &) \ - { \ - PQXX_CHECK_NOTREACHED( \ - std::string{desc} + " (\"" #action \ - "\" did not throw " #exception_type ")"); \ - } \ - catch (exception_type const &) \ - {} \ - catch (std::exception const &e) \ - { \ - PQXX_CHECK_NOTREACHED( \ - std::string{desc} + \ - " (\"" #action \ - "\" " \ - "threw exception other than " #exception_type ": " + \ - e.what() + ")"); \ - } \ - catch (...) \ - { \ - PQXX_CHECK_NOTREACHED( \ - std::string{desc} + " (\"" #action "\" threw non-exception type)"); \ - } \ - } \ - pqxx::test::internal::end_of_statement() - -#define PQXX_CHECK_BOUNDS(value, lower, upper, desc) \ - pqxx::test::check_bounds( \ - __FILE__, __LINE__, (value), #value, (lower), #lower, (upper), #upper, \ - (desc)) -template -inline void check_bounds( - char const file[], int line, VALUE value, char const text[], LOWER lower, - char const lower_text[], UPPER upper, char const upper_text[], - std::string const &desc) -{ - std::string const range_check = std::string{lower_text} + " < " + upper_text, - lower_check = - std::string{"!("} + text + " < " + lower_text + ")", - upper_check = std::string{text} + " < " + upper_text; - - pqxx::test::check( - file, line, lower < upper, range_check.c_str(), - desc + " (acceptable range is empty; value was " + text + ")"); - pqxx::test::check( - file, line, not(value < lower), lower_check.c_str(), - desc + " (" + text + " is below lower bound " + lower_text + ")"); - pqxx::test::check( - file, line, value < upper, upper_check.c_str(), - desc + " (" + text + " is not below upper bound " + upper_text + ")"); -} - - -// Report expected exception -void expected_exception(std::string const &); - - -// Represent result row as string. -std::string list_row(row); -// Represent result as string. -std::string list_result(result); -// Represent result iterator as string. -std::string list_result_iterator(result::const_iterator); - - -// @deprecated Set up test data for legacy tests. -void create_pqxxevents(transaction_base &); -} // namespace test - - -template<> inline std::string to_string(row const &value) -{ - return pqxx::test::list_row(value); -} - - -template<> inline std::string to_string(result const &value) -{ - return pqxx::test::list_result(value); -} - - -template<> inline std::string to_string(result::const_iterator const &value) -{ - return pqxx::test::list_result_iterator(value); -} -} // namespace pqxx diff --git a/ext/libpqxx-7.7.3/test/test_types.hxx b/ext/libpqxx-7.7.3/test/test_types.hxx deleted file mode 100644 index 38c045370..000000000 --- a/ext/libpqxx-7.7.3/test/test_types.hxx +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Custom types for testing & libpqxx support those types - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace pqxx -{ -template<> struct nullness : no_null -{}; - - -constexpr static auto hex_digit{"0123456789abcdef"}; - - -template<> struct string_traits -{ - static std::size_t size_buffer(std::byte const &) { return 3; } - - static zview to_buf(char *begin, char *end, std::byte const &value) - { - if (pqxx::internal::cmp_less(end - begin, size_buffer(value))) - throw pqxx::conversion_overrun{ - "Not enough buffer to convert std::byte."}; - auto uc{static_cast(value)}; - begin[0] = hex_digit[uc >> 4]; - begin[1] = hex_digit[uc & 0x0f]; - return zview{begin, 2u}; - } - - static char *into_buf(char *begin, char *end, std::byte const &value) - { - auto view{to_buf(begin, end, value)}; - return begin + std::size(view); - } -}; -} // namespace pqxx - - -class ipv4 -{ -public: - ipv4() : m_as_int{0u} {} - ipv4(ipv4 const &) = default; - ipv4(ipv4 &&) = default; - explicit ipv4(uint32_t i) : m_as_int{i} {} - ipv4( - unsigned char b1, unsigned char b2, unsigned char b3, unsigned char b4) : - ipv4() - { - set_byte(0, b1); - set_byte(1, b2); - set_byte(2, b3); - set_byte(3, b4); - } - - bool operator==(ipv4 const &o) const { return m_as_int == o.m_as_int; } - ipv4 &operator=(ipv4 const &) = default; - - /// Index bytes, from 0 to 3, in network (i.e. Big-Endian) byte order. - unsigned int operator[](int byte) const - { - if (byte < 0 or byte > 3) - throw pqxx::usage_error("Byte out of range."); - auto const shift = compute_shift(byte); - return static_cast((m_as_int >> shift) & 0xff); - } - - /// Set individual byte, in network byte order. - void set_byte(int byte, uint32_t value) - { - auto const shift = compute_shift(byte); - auto const blanked = (m_as_int & ~uint32_t(0xff << shift)); - m_as_int = (blanked | ((value & 0xff) << shift)); - } - -private: - static unsigned compute_shift(int byte) - { - if (byte < 0 or byte > 3) - throw pqxx::usage_error("Byte out of range."); - return static_cast((3 - byte) * 8); - } - - uint32_t m_as_int; -}; - - -using bytea = std::vector; - - -namespace pqxx -{ -template<> struct nullness : no_null -{}; - - -template<> struct string_traits -{ - static ipv4 from_string(std::string_view text) - { - ipv4 ts; - if (std::data(text) == nullptr) - internal::throw_null_conversion(type_name); - std::regex ipv4_regex{R"--((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}))--"}; - std::smatch match; - // Need non-temporary for `std::regex_match()` - std::string sstr{text}; - if (not std::regex_match(sstr, match, ipv4_regex) or std::size(match) != 5) - throw std::runtime_error{"Invalid ipv4 format: " + std::string{text}}; - try - { - for (std::size_t i{0}; i < 4; ++i) - ts.set_byte(int(i), uint32_t(std::stoi(match[i + 1]))); - } - catch (std::invalid_argument const &) - { - throw std::runtime_error{"Invalid ipv4 format: " + std::string{text}}; - } - catch (std::out_of_range const &) - { - throw std::runtime_error{"Invalid ipv4 format: " + std::string{text}}; - } - return ts; - } - - static char *into_buf(char *begin, char *end, ipv4 const &value) - { - if (pqxx::internal::cmp_less(end - begin, size_buffer(value))) - throw conversion_error{"Buffer too small for ipv4."}; - char *here = begin; - for (int i = 0; i < 4; ++i) - { - here = string_traits::into_buf(here, end, value[i]); - *(here - 1) = '.'; - } - *(here - 1) = '\0'; - return here; - } - - static zview to_buf(char *begin, char *end, ipv4 const &value) - { - return zview{ - begin, - static_cast(into_buf(begin, end, value) - begin - 1)}; - } - - static constexpr std::size_t size_buffer(ipv4 const &) noexcept - { - return 20; - } -}; - - -namespace -{ -inline char nibble_to_hex(unsigned nibble) -{ - if (nibble < 10) - return char('0' + nibble); - else if (nibble < 16) - return char('a' + (nibble - 10)); - else - throw std::runtime_error{"Invalid digit going into bytea."}; -} - - -inline unsigned hex_to_digit(char hex) -{ - auto x = static_cast(hex); - if (x >= '0' and x <= '9') - return x - '0'; - else if (x >= 'a' and x <= 'f') - return 10 + x - 'a'; - else if (x >= 'A' and x <= 'F') - return 10 + x - 'A'; - else - throw std::runtime_error{"Invalid hex in bytea."}; -} -} // namespace - - -template<> struct nullness : no_null -{}; - - -template<> struct string_traits -{ - static bytea from_string(std::string_view text) - { - if ((std::size(text) & 1) != 0) - throw std::runtime_error{"Odd hex size."}; - bytea value; - value.reserve((std::size(text) - 2) / 2); - for (std::size_t i = 2; i < std::size(text); i += 2) - { - auto hi = hex_to_digit(text[i]), lo = hex_to_digit(text[i + 1]); - value.push_back(static_cast((hi << 4) | lo)); - } - return value; - } - - static zview to_buf(char *begin, char *end, bytea const &value) - { - auto const need = size_buffer(value); - auto const have = end - begin; - if (std::size_t(have) < need) - throw pqxx::conversion_overrun{"Not enough space in buffer for bytea."}; - char *pos = begin; - *pos++ = '\\'; - *pos++ = 'x'; - for (unsigned char const u : value) - { - *pos++ = nibble_to_hex(unsigned(u) >> 4); - *pos++ = nibble_to_hex(unsigned(u) & 0x0f); - } - *pos++ = '\0'; - return {begin, pos - begin - 1}; - } - - static char *into_buf(char *begin, char *end, bytea const &value) - { - return begin + std::size(to_buf(begin, end, value)) + 1; - } - - static std::size_t size_buffer(bytea const &value) - { - return 2 + 2 * std::size(value) + 1; - } -}; -} // namespace pqxx diff --git a/ext/libpqxx-7.7.3/test/unit/CMakeLists.txt b/ext/libpqxx-7.7.3/test/unit/CMakeLists.txt deleted file mode 100644 index f938a4181..000000000 --- a/ext/libpqxx-7.7.3/test/unit/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -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() - -file(GLOB UNIT_TEST_SOURCES *.cxx) - -add_executable(unit_runner ${UNIT_TEST_SOURCES}) -target_link_libraries(unit_runner PUBLIC pqxx) -target_include_directories(unit_runner PRIVATE ${PostgreSQL_INCLUDE_DIRS}) -add_test( - NAME unit_runner - WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - COMMAND unit_runner -) diff --git a/ext/libpqxx-7.7.3/test/unit/test_array.cxx b/ext/libpqxx-7.7.3/test/unit/test_array.cxx deleted file mode 100644 index 229ac5145..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_array.cxx +++ /dev/null @@ -1,548 +0,0 @@ -#include - -#include "../test_helpers.hxx" - -// Test program for libpqxx array parsing. - -namespace pqxx -{ -template<> -struct nullness : no_null -{}; - - -inline std::string to_string(pqxx::array_parser::juncture const &j) -{ - using junc = pqxx::array_parser::juncture; - switch (j) - { - case junc::row_start: return "row_start"; - case junc::row_end: return "row_end"; - case junc::null_value: return "null_value"; - case junc::string_value: return "string_value"; - case junc::done: return "done"; - default: return "UNKNOWN JUNCTURE: " + to_string(static_cast(j)); - } -} -} // namespace pqxx - - -namespace -{ -void test_empty_arrays() -{ - std::pair output; - - // Parsing a null pointer just immediately returns "done". - output = pqxx::array_parser(std::string_view()).get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::done, - "get_next on null array did not return done."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - // Parsing an empty array string immediately returns "done". - output = pqxx::array_parser("").get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::done, - "get_next on an empty array string did not return done."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - // Parsing an empty array returns "row_start", "row_end", "done". - pqxx::array_parser empty_parser("{}"); - output = empty_parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Empty array did not start with row_start."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = empty_parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_end, - "Empty array did not end with row_end."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = empty_parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::done, - "Empty array did not conclude with done."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); -} - - -void test_null_value() -{ - std::pair output; - pqxx::array_parser containing_null("{NULL}"); - - output = containing_null.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Array containing null did not start with row_start."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = containing_null.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::null_value, - "Array containing null did not return null_value."); - PQXX_CHECK_EQUAL(output.second, "", "Null value was not empty."); - - output = containing_null.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_end, - "Array containing null did not end with row_end."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = containing_null.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::done, - "Array containing null did not conclude with done."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); -} - - -void test_single_quoted_string() -{ - std::pair output; - pqxx::array_parser parser("{'item'}"); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Array did not start with row_start."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::string_value, - "Array did not return string_value."); - PQXX_CHECK_EQUAL(output.second, "item", "Unexpected string value."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_end, - "Array did not end with row_end."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::done, - "Array did not conclude with done."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); -} - - -void test_single_quoted_escaping() -{ - std::pair output; - pqxx::array_parser parser("{'don''t\\\\ care'}"); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Array did not start with row_start."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::string_value, - "Array did not return string_value."); - PQXX_CHECK_EQUAL(output.second, "don't\\ care", "Unexpected string value."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_end, - "Array did not end with row_end."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::done, - "Array did not conclude with done."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); -} - - -void test_double_quoted_string() -{ - std::pair output; - pqxx::array_parser parser("{\"item\"}"); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Array did not start with row_start."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::string_value, - "Array did not return string_value."); - PQXX_CHECK_EQUAL(output.second, "item", "Unexpected string value."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_end, - "Array did not end with row_end."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::done, - "Array did not conclude with done."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); -} - - -void test_double_quoted_escaping() -{ - std::pair output; - pqxx::array_parser parser(R"--({"don''t\\ care"})--"); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Array did not start with row_start."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::string_value, - "Array did not return string_value."); - PQXX_CHECK_EQUAL(output.second, "don''t\\ care", "Unexpected string value."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_end, - "Array did not end with row_end."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::done, - "Array did not conclude with done."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); -} - - -// A pair of double quotes in a double-quoted string is an escaped quote. -void test_double_double_quoted_string() -{ - std::pair output; - pqxx::array_parser parser{R"--({"3"" steel"})--"}; - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Array did not start with row_start."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::string_value, - "Array did not return string_value."); - - PQXX_CHECK_EQUAL(output.second, "3\" steel", "Unexpected string value."); -} - - -void test_unquoted_string() -{ - std::pair output; - pqxx::array_parser parser("{item}"); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Array did not start with row_start."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::string_value, - "Array did not return string_value."); - PQXX_CHECK_EQUAL(output.second, "item", "Unexpected string value."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_end, - "Array did not end with row_end."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::done, - "Array did not conclude with done."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); -} - - -void test_multiple_values() -{ - std::pair output; - pqxx::array_parser parser("{1,2}"); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Array did not start with row_start."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::string_value, - "Array did not return string_value."); - PQXX_CHECK_EQUAL(output.second, "1", "Unexpected string value."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::string_value, - "Array did not return string_value."); - PQXX_CHECK_EQUAL(output.second, "2", "Unexpected string value."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_end, - "Array did not end with row_end."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::done, - "Array did not conclude with done."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); -} - - -void test_nested_array() -{ - std::pair output; - pqxx::array_parser parser("{{item}}"); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Array did not start with row_start."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Nested array did not start 2nd dimension with row_start."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::string_value, - "Array did not return string_value."); - PQXX_CHECK_EQUAL(output.second, "item", "Unexpected string value."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_end, - "Nested array did not end 2nd dimension with row_end."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_end, - "Array did not end with row_end."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::done, - "Array did not conclude with done."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); -} - - -void test_nested_array_with_multiple_entries() -{ - std::pair output; - pqxx::array_parser parser("{{1,2},{3,4}}"); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Array did not start with row_start."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Nested array did not start 2nd dimension with row_start."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::string_value, - "Array did not return string_value."); - PQXX_CHECK_EQUAL(output.second, "1", "Unexpected string value."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::string_value, - "Array did not return string_value."); - PQXX_CHECK_EQUAL(output.second, "2", "Unexpected string value."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_end, - "Nested array did not end 2nd dimension with row_end."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_start, - "Nested array did not descend to 2nd dimension with row_start."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::string_value, - "Array did not return string_value."); - PQXX_CHECK_EQUAL(output.second, "3", "Unexpected string value."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::string_value, - "Array did not return string_value."); - PQXX_CHECK_EQUAL(output.second, "4", "Unexpected string value."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_end, - "Nested array did not leave 2nd dimension with row_end."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::row_end, - "Array did not end with row_end."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); - - output = parser.get_next(); - PQXX_CHECK_EQUAL( - output.first, pqxx::array_parser::juncture::done, - "Array did not conclude with done."); - PQXX_CHECK_EQUAL(output.second, "", "Unexpected nonempty output."); -} - - -void test_array_parse() -{ - test_empty_arrays(); - test_null_value(); - test_single_quoted_string(); - test_single_quoted_escaping(); - test_double_quoted_string(); - test_double_quoted_escaping(); - test_double_double_quoted_string(); - test_unquoted_string(); - test_multiple_values(); - test_nested_array(); - test_nested_array_with_multiple_entries(); -} - - -void test_generate_empty_array() -{ - PQXX_CHECK_EQUAL( - pqxx::to_string(std::vector{}), "{}", - "Basic array output is not as expected."); - PQXX_CHECK_EQUAL( - pqxx::to_string(std::vector{}), "{}", - "String array comes out different."); -} - - -void test_generate_null_value() -{ - PQXX_CHECK_EQUAL( - pqxx::to_string(std::vector{nullptr}), "{NULL}", - "Null array value did not come out as expected."); -} - - -void test_generate_single_item() -{ - PQXX_CHECK_EQUAL( - pqxx::to_string(std::vector{42}), "{42}", - "Numeric conversion came out wrong."); - - PQXX_CHECK_EQUAL( - pqxx::to_string(std::vector{"foo"}), "{\"foo\"}", - "String array conversion came out wrong."); -} - - -void test_generate_multiple_items() -{ - PQXX_CHECK_EQUAL( - pqxx::to_string(std::vector{5, 4, 3, 2}), "{5,4,3,2}", - "Array with multiple values is not correct."); - PQXX_CHECK_EQUAL( - pqxx::to_string(std::vector{"foo", "bar"}), - "{\"foo\",\"bar\"}", "Array with multiple strings came out wrong."); -} - - -void test_generate_nested_array() -{ - PQXX_CHECK_EQUAL( - pqxx::to_string(std::vector>{{1, 2}, {3, 4}}), - "{{1,2},{3,4}}", "Nested arrays don't work right."); -} - - -void test_generate_escaped_strings() -{ - PQXX_CHECK_EQUAL( - pqxx::to_string(std::vector{"a\\b"}), "{\"a\\\\b\"}", - "Backslashes are not escaped properly."); - PQXX_CHECK_EQUAL( - pqxx::to_string(std::vector{"x\"y\""}), "{\"x\\\"y\\\"\"}", - "Double quotes are not escaped properly."); -} - - -void test_array_generate() -{ - test_generate_empty_array(); - test_generate_null_value(); - test_generate_single_item(); - test_generate_multiple_items(); - test_generate_nested_array(); - test_generate_escaped_strings(); -} - - -void test_array_roundtrip() -{ - pqxx::connection c; - pqxx::work w{c}; - - std::vector const in{0, 1, 2, 3, 5}; - auto const r1{w.exec1("SELECT " + c.quote(in) + "::integer[]")}; - pqxx::array_parser parser{r1[0].view()}; - auto item{parser.get_next()}; - PQXX_CHECK_EQUAL( - item.first, pqxx::array_parser::juncture::row_start, - "Array did not start with row_start."); - - std::vector out; - for (item = parser.get_next(); - item.first == pqxx::array_parser::juncture::string_value; - item = parser.get_next()) - { - out.push_back(pqxx::from_string(item.second)); - } - - PQXX_CHECK_EQUAL( - item.first, pqxx::array_parser::juncture::row_end, - "Array values did not end in row_end."); - PQXX_CHECK_EQUAL( - std::size(out), std::size(in), "Array came back with different length."); - - for (std::size_t i{0}; i < std::size(in); ++i) - PQXX_CHECK_EQUAL(out[i], in[i], "Array element has changed."); - - item = parser.get_next(); - PQXX_CHECK_EQUAL( - item.first, pqxx::array_parser::juncture::done, - "Array did not end in done."); -} - - -PQXX_REGISTER_TEST(test_array_parse); -PQXX_REGISTER_TEST(test_array_generate); -PQXX_REGISTER_TEST(test_array_roundtrip); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_binarystring.cxx b/ext/libpqxx-7.7.3/test/unit/test_binarystring.cxx deleted file mode 100644 index e6097d039..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_binarystring.cxx +++ /dev/null @@ -1,211 +0,0 @@ -#include -#include -#include - -#include "../test_helpers.hxx" -#include "../test_types.hxx" - - -namespace -{ -pqxx::binarystring -make_binarystring(pqxx::transaction_base &T, std::string content) -{ -#include "pqxx/internal/ignore-deprecated-pre.hxx" - return pqxx::binarystring(T.exec1("SELECT " + T.quote_raw(content))[0]); -#include "pqxx/internal/ignore-deprecated-post.hxx" -} - - -void test_binarystring() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - auto b{make_binarystring(tx, "")}; - PQXX_CHECK(std::empty(b), "Empty binarystring is not empty."); - PQXX_CHECK_EQUAL(b.str(), "", "Empty binarystring doesn't work."); - PQXX_CHECK_EQUAL(std::size(b), 0u, "Empty binarystring has nonzero size."); - PQXX_CHECK_EQUAL(b.length(), 0u, "Length/size mismatch."); - PQXX_CHECK(std::begin(b) == std::end(b), "Empty binarystring iterates."); - PQXX_CHECK( - std::cbegin(b) == std::begin(b), "Wrong cbegin for empty binarystring."); - PQXX_CHECK( - std::rbegin(b) == std::rend(b), "Empty binarystring reverse-iterates."); - PQXX_CHECK( - std::crbegin(b) == std::rbegin(b), - "Wrong crbegin for empty binarystring."); - PQXX_CHECK_THROWS( - b.at(0), std::out_of_range, "Empty binarystring accepts at()."); - - b = make_binarystring(tx, "z"); - PQXX_CHECK_EQUAL(b.str(), "z", "Basic nonempty binarystring is broken."); - PQXX_CHECK(not std::empty(b), "Nonempty binarystring is empty."); - PQXX_CHECK_EQUAL(std::size(b), 1u, "Bad binarystring size."); - PQXX_CHECK_EQUAL(b.length(), 1u, "Length/size mismatch."); - PQXX_CHECK( - std::begin(b) != std::end(b), "Nonempty binarystring does not iterate."); - PQXX_CHECK( - std::rbegin(b) != std::rend(b), - "Nonempty binarystring does not reverse-iterate."); - PQXX_CHECK(std::begin(b) + 1 == std::end(b), "Bad iteration."); - PQXX_CHECK(std::rbegin(b) + 1 == std::rend(b), "Bad reverse iteration."); - PQXX_CHECK(std::cbegin(b) == std::begin(b), "Wrong cbegin."); - PQXX_CHECK(std::cend(b) == std::end(b), "Wrong cend."); - PQXX_CHECK(std::crbegin(b) == std::rbegin(b), "Wrong crbegin."); - PQXX_CHECK(std::crend(b) == std::rend(b), "Wrong crend."); - PQXX_CHECK(b.front() == 'z', "Unexpected front()."); - PQXX_CHECK(b.back() == 'z', "Unexpected back()."); - PQXX_CHECK(b.at(0) == 'z', "Unexpected data at index 0."); - PQXX_CHECK_THROWS( - b.at(1), std::out_of_range, "Failed to catch range error."); - - std::string const simple{"ab"}; - b = make_binarystring(tx, simple); - PQXX_CHECK_EQUAL( - b.str(), simple, "Binary (un)escaping went wrong somewhere."); - PQXX_CHECK_EQUAL( - std::size(b), std::size(simple), "Escaping confuses length."); - - std::string const simple_escaped{ - tx.esc_raw(std::basic_string_view{ - reinterpret_cast(std::data(simple)), - std::size(simple)})}; - for (auto c : simple_escaped) - { - auto const uc{static_cast(c)}; - PQXX_CHECK(uc <= 127, "Non-ASCII byte in escaped string."); - } - -#include "pqxx/internal/ignore-deprecated-pre.hxx" - PQXX_CHECK_EQUAL( - tx.quote_raw( - reinterpret_cast(simple.c_str()), - std::size(simple)), - tx.quote(b), "quote_raw is broken"); - PQXX_CHECK_EQUAL( - tx.quote(b), tx.quote_raw(simple), "Binary quoting is broken."); - PQXX_CHECK_EQUAL( - pqxx::binarystring(tx.exec1("SELECT " + tx.quote(b))[0]).str(), simple, - "Binary string is not idempotent."); -#include "pqxx/internal/ignore-deprecated-post.hxx" - - std::string const bytes("\x01\x23\x23\xa1\x2b\x0c\xff"); - b = make_binarystring(tx, bytes); - PQXX_CHECK_EQUAL(b.str(), bytes, "Binary data breaks (un)escaping."); - - std::string const nully("a\0b", 3); - b = make_binarystring(tx, nully); - PQXX_CHECK_EQUAL(b.str(), nully, "Nul byte broke binary (un)escaping."); - PQXX_CHECK_EQUAL(std::size(b), 3u, "Nul byte broke binarystring size."); - - b = make_binarystring(tx, "foo"); - PQXX_CHECK_EQUAL(std::string(b.get(), 3), "foo", "get() appears broken."); - - auto b1{make_binarystring(tx, "1")}, b2{make_binarystring(tx, "2")}; - PQXX_CHECK_NOT_EQUAL(b1.get(), b2.get(), "Madness rules."); - PQXX_CHECK_NOT_EQUAL(b1.str(), b2.str(), "Logic has no more meaning."); - b1.swap(b2); - PQXX_CHECK_NOT_EQUAL(b1.str(), b2.str(), "swap() equalized binarystrings."); - PQXX_CHECK_NOT_EQUAL(b1.str(), "1", "swap() did not happen."); - PQXX_CHECK_EQUAL(b1.str(), "2", "swap() is broken."); - PQXX_CHECK_EQUAL(b2.str(), "1", "swap() went insane."); - - b = make_binarystring(tx, "bar"); - b.swap(b); - PQXX_CHECK_EQUAL(b.str(), "bar", "Self-swap confuses binarystring."); - - b = make_binarystring(tx, "\\x"); - PQXX_CHECK_EQUAL(b.str(), "\\x", "Hex-escape header confused (un)escaping."); -} - - -void test_binarystring_conversion() -{ - constexpr char bytes[]{"f\to\0o\n\0"}; - std::string_view const data{bytes, std::size(bytes) - 1}; -#include "pqxx/internal/ignore-deprecated-pre.hxx" - pqxx::binarystring bin{data}; -#include "pqxx/internal/ignore-deprecated-post.hxx" - auto const escaped{pqxx::to_string(bin)}; - PQXX_CHECK_EQUAL( - escaped, std::string_view{"\\x66096f006f0a00"}, "Unexpected hex escape."); - auto const restored{pqxx::from_string(escaped)}; - PQXX_CHECK_EQUAL( - std::size(restored), std::size(data), "Unescaping produced wrong length."); -} - - -void test_binarystring_stream() -{ - constexpr char bytes[]{"a\tb\0c"}; - std::string_view const data{bytes, std::size(bytes) - 1}; -#include "pqxx/internal/ignore-deprecated-pre.hxx" - pqxx::binarystring bin{data}; -#include "pqxx/internal/ignore-deprecated-post.hxx" - - pqxx::connection conn; - pqxx::transaction tx{conn}; - tx.exec0("CREATE TEMP TABLE pqxxbinstream(id integer, bin bytea)"); - - auto to{pqxx::stream_to::table(tx, {"pqxxbinstream"})}; - to.write_values(0, bin); - to.complete(); - - auto ptr{reinterpret_cast(std::data(data))}; - auto expect{ - tx.quote(std::basic_string_view{ptr, std::size(data)})}; - PQXX_CHECK( - tx.query_value("SELECT bin = " + expect + " FROM pqxxbinstream"), - "binarystring did not stream_to properly."); - PQXX_CHECK_EQUAL( - tx.query_value("SELECT octet_length(bin) FROM pqxxbinstream"), - std::size(data), "Did the terminating zero break the bytea?"); -} - - -void test_binarystring_array_stream() -{ - pqxx::connection conn; - pqxx::transaction tx{conn}; - tx.exec0("CREATE TEMP TABLE pqxxbinstream(id integer, vec bytea[])"); - - constexpr char bytes1[]{"a\tb\0c"}, bytes2[]{"1\0.2"}; - std::string_view const data1{bytes1}, data2{bytes2}; -#include "pqxx/internal/ignore-deprecated-pre.hxx" - pqxx::binarystring bin1{data1}, bin2{data2}; - std::vector const vec{bin1, bin2}; -#include "pqxx/internal/ignore-deprecated-post.hxx" - - auto to{pqxx::stream_to::table(tx, {"pqxxbinstream"})}; - to.write_values(0, vec); - to.complete(); - - PQXX_CHECK_EQUAL( - tx.query_value( - "SELECT array_length(vec, 1) FROM pqxxbinstream"), - std::size(vec), "Array came out with wrong length."); - - auto ptr1{reinterpret_cast(std::data(data1))}, - ptr2{reinterpret_cast(std::data(data2))}; - auto expect1{ - tx.quote(std::basic_string_view{ptr1, std::size(data1)})}, - expect2{ - tx.quote(std::basic_string_view{ptr2, std::size(data2)})}; - PQXX_CHECK( - tx.query_value("SELECT vec[1] = " + expect1 + " FROM pqxxbinstream"), - "Bytea in array came out wrong."); - PQXX_CHECK( - tx.query_value("SELECT vec[2] = " + expect2 + " FROM pqxxbinstream"), - "First bytea in array worked, but second did not."); - PQXX_CHECK_EQUAL( - tx.query_value( - "SELECT octet_length(vec[1]) FROM pqxxbinstream"), - std::size(data1), "Bytea length broke inside array."); -} - - -PQXX_REGISTER_TEST(test_binarystring); -PQXX_REGISTER_TEST(test_binarystring_conversion); -PQXX_REGISTER_TEST(test_binarystring_stream); -PQXX_REGISTER_TEST(test_binarystring_array_stream); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_blob.cxx b/ext/libpqxx-7.7.3/test/unit/test_blob.cxx deleted file mode 100644 index 709c1f489..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_blob.cxx +++ /dev/null @@ -1,644 +0,0 @@ -#include - -#include -#include - -#include "../test_helpers.hxx" -#include "../test_types.hxx" - - -namespace -{ -void test_blob_is_useless_by_default() -{ - pqxx::blob b{}; - std::basic_string buf; - PQXX_CHECK_THROWS( - b.read(buf, 1), pqxx::usage_error, - "Read on default-constructed blob did not throw failure."); - PQXX_CHECK_THROWS( - b.write(buf), pqxx::usage_error, - "Write on default-constructed blob did not throw failure."); -} - - -void test_blob_create_makes_empty_blob() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::oid id{pqxx::blob::create(tx)}; - auto b{pqxx::blob::open_r(tx, id)}; - b.seek_end(0); - PQXX_CHECK_EQUAL(b.tell(), 0, "New blob is not empty."); -} - - -void test_blob_create_with_oid_requires_oid_be_free() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - auto id{pqxx::blob::create(tx)}; - - PQXX_CHECK_THROWS( - pqxx::ignore_unused(pqxx::blob::create(tx, id)), pqxx::failure, - "Not getting expected error when oid not free."); -} - - -void test_blob_create_with_oid_obeys_oid() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - auto id{pqxx::blob::create(tx)}; - pqxx::blob::remove(tx, id); - - auto actual_id{pqxx::blob::create(tx, id)}; - PQXX_CHECK_EQUAL(actual_id, id, "Create with oid returned different oid."); -} - - -void test_blobs_are_transactional() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::oid id{pqxx::blob::create(tx)}; - tx.abort(); - pqxx::work tx2{conn}; - PQXX_CHECK_THROWS( - pqxx::ignore_unused(pqxx::blob::open_r(tx2, id)), pqxx::failure, - "Blob from aborted transaction still exists."); -} - - -void test_blob_remove_removes_blob() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::oid id{pqxx::blob::create(tx)}; - pqxx::blob::remove(tx, id); - PQXX_CHECK_THROWS( - pqxx::ignore_unused(pqxx::blob::open_r(tx, id)), pqxx::failure, - "Attempt to open blob after removing should have failed."); -} - - -void test_blob_remove_is_not_idempotent() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::oid id{pqxx::blob::create(tx)}; - pqxx::blob::remove(tx, id); - PQXX_CHECK_THROWS( - pqxx::blob::remove(tx, id), pqxx::failure, - "Redundant remove() did not throw failure."); -} - - -void test_blob_checks_open_mode() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::oid id{pqxx::blob::create(tx)}; - pqxx::blob b_r{pqxx::blob::open_r(tx, id)}; - pqxx::blob b_w{pqxx::blob::open_w(tx, id)}; - pqxx::blob b_rw{pqxx::blob::open_rw(tx, id)}; - - std::basic_string buf{std::byte{3}, std::byte{2}, std::byte{1}}; - - // These are all allowed: - b_w.write(buf); - b_r.read(buf, 3); - b_rw.seek_end(0); - b_rw.write(buf); - b_rw.seek_abs(0); - b_rw.read(buf, 6); - - // These are not: - PQXX_CHECK_THROWS( - b_r.write(buf), pqxx::failure, "Read-only blob did not stop write."); - PQXX_CHECK_THROWS( - b_w.read(buf, 10), pqxx::failure, "Write-only blob did not stop read."); -} - - -void test_blob_supports_move() -{ - std::basic_string buf; - buf.push_back(std::byte{'x'}); - - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::oid id{pqxx::blob::create(tx)}; - pqxx::blob b1{pqxx::blob::open_rw(tx, id)}; - b1.write(buf); - - pqxx::blob b2{std::move(b1)}; - b2.seek_abs(0); - b2.read(buf, 1u); - - PQXX_CHECK_THROWS( - b1.read(buf, 1u), pqxx::usage_error, - "Blob still works after move construction."); - - b1 = std::move(b2); - b1.read(buf, 1u); - - PQXX_CHECK_THROWS( - b2.read(buf, 1u), pqxx::usage_error, - "Blob still works after move assignment."); -} - - -void test_blob_read_reads_data() -{ - std::basic_string const data{ - std::byte{'a'}, std::byte{'b'}, std::byte{'c'}}; - - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::oid id{pqxx::blob::from_buf(tx, data)}; - - std::basic_string buf; - auto b{pqxx::blob::open_rw(tx, id)}; - PQXX_CHECK_EQUAL( - b.read(buf, 2), 2u, "Full read() returned an unexpected value."); - PQXX_CHECK_EQUAL( - buf, (std::basic_string{std::byte{'a'}, std::byte{'b'}}), - "Read back the wrong data."); - PQXX_CHECK_EQUAL( - b.read(buf, 2), 1u, "Partial read() returned an unexpected value."); - PQXX_CHECK_EQUAL( - buf, (std::basic_string{std::byte{'c'}}), - "Continued read produced wrong data."); - PQXX_CHECK_EQUAL( - b.read(buf, 2), 0u, "read at end returned an unexpected value."); - PQXX_CHECK_EQUAL( - buf, (std::basic_string{}), "Read past end produced data."); -} - - -void test_blob_read_span() -{ -#if defined(PQXX_HAVE_SPAN) - std::basic_string const data{std::byte{'u'}, std::byte{'v'}, - std::byte{'w'}, std::byte{'x'}, - std::byte{'y'}, std::byte{'z'}}; - - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::oid id{pqxx::blob::from_buf(tx, data)}; - - auto b{pqxx::blob::open_r(tx, id)}; - std::basic_string string_buf; - string_buf.resize(2); - - std::span output; - - output = b.read(std::span{}); - PQXX_CHECK_EQUAL( - std::size(output), 0u, "Empty read produced nonempty buffer."); - output = b.read(string_buf); - PQXX_CHECK_EQUAL( - std::size(output), 2u, "Got unexpected buf size from blob::read()."); - PQXX_CHECK_EQUAL( - output[0], std::byte{'u'}, "Unexpected byte from blob::read()."); - PQXX_CHECK_EQUAL( - output[1], std::byte{'v'}, "Unexpected byte from blob::read()."); - - string_buf.resize(100); - output = b.read(std::span{string_buf.data(), 1}); - PQXX_CHECK_EQUAL( - std::size(output), 1u, - "Did blob::read() follow string size instead of span size?"); - PQXX_CHECK_EQUAL( - output[0], std::byte{'w'}, "Unexpected byte from blob::read()."); - - std::vector vec_buf; - vec_buf.resize(2); - auto output2{b.read(vec_buf)}; - PQXX_CHECK_EQUAL( - std::size(output2), 2u, "Got unexpected buf size from blob::read()."); - PQXX_CHECK_EQUAL( - output2[0], std::byte{'x'}, "Unexpected byte from blob::read()."); - PQXX_CHECK_EQUAL( - output2[1], std::byte{'y'}, "Unexpected byte from blob::read()."); - - vec_buf.resize(100); - output2 = b.read(vec_buf); - PQXX_CHECK_EQUAL(std::size(output2), 1u, "Weird things happened at EOF."); - PQXX_CHECK_EQUAL(output2[0], std::byte{'z'}, "Bad data at EOF."); -#endif // PQXX_HAVE_SPAN -} - - -void test_blob_reads_vector() -{ - char const content[]{"abcd"}; - pqxx::connection conn; - pqxx::work tx{conn}; - auto id{pqxx::blob::from_buf( - tx, std::basic_string_view{ - reinterpret_cast(content), std::size(content)})}; - std::vector buf; - buf.resize(10); - auto out{pqxx::blob::open_r(tx, id).read(buf)}; - PQXX_CHECK_EQUAL( - std::size(out), std::size(content), - "Got wrong length back when reading as vector."); - PQXX_CHECK_EQUAL( - out[0], std::byte{'a'}, "Got bad data when reading as vector."); -} - - -void test_blob_write_appends_at_insertion_point() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - auto id{pqxx::blob::create(tx)}; - - auto b{pqxx::blob::open_rw(tx, id)}; - b.write(std::basic_string{std::byte{'z'}}); - b.write(std::basic_string{std::byte{'a'}}); - - std::basic_string buf; - b.read(buf, 5); - PQXX_CHECK_EQUAL( - buf, (std::basic_string{}), "Found data at the end."); - b.seek_abs(0); - b.read(buf, 5); - PQXX_CHECK_EQUAL( - buf, (std::basic_string{std::byte{'z'}, std::byte{'a'}}), - "Consecutive writes did not append correctly."); - - b.write(std::basic_string{std::byte{'x'}}); - // Blob now contains "zax". That's not we wanted... Rewind and rewrite. - b.seek_abs(1); - b.write(std::basic_string{std::byte{'y'}}); - b.seek_abs(0); - b.read(buf, 5); - PQXX_CHECK_EQUAL( - buf, - (std::basic_string{ - std::byte{'z'}, std::byte{'y'}, std::byte{'x'}}), - "Rewriting in the middle did not work right."); -} - - -void test_blob_writes_span() -{ -#if defined(PQXX_HAVE_SPAN) - pqxx::connection conn; - pqxx::work tx{conn}; - constexpr char content[]{"gfbltk"}; - std::basic_string data{ - reinterpret_cast(content), std::size(content)}; - - auto id{pqxx::blob::create(tx)}; - auto b{pqxx::blob::open_rw(tx, id)}; - b.write(std::span{data.data() + 1, 3u}); - b.seek_abs(0); - - std::vector buf; - buf.resize(4); - auto out{b.read(std::span{buf.data(), 4u})}; - PQXX_CHECK_EQUAL( - std::size(out), 3u, "Did not get expected number of bytes back."); - PQXX_CHECK_EQUAL(out[0], std::byte{'f'}, "Data did not come back right."); - PQXX_CHECK_EQUAL(out[2], std::byte{'l'}, "Data started right, ended wrong!"); -#endif // PQXX_HAVE_SPAN -} - - -void test_blob_resize_shortens_to_desired_length() -{ - std::basic_string const data{ - std::byte{'w'}, std::byte{'o'}, std::byte{'r'}, std::byte{'k'}}; - - pqxx::connection conn; - pqxx::work tx{conn}; - auto id{pqxx::blob::from_buf(tx, data)}; - - pqxx::blob::open_w(tx, id).resize(2); - std::basic_string buf; - pqxx::blob::to_buf(tx, id, buf, 10); - PQXX_CHECK_EQUAL( - buf, (std::basic_string{std::byte{'w'}, std::byte{'o'}}), - "Truncate did not shorten correctly."); -} - - -void test_blob_resize_extends_to_desired_length() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - auto id{ - pqxx::blob::from_buf(tx, std::basic_string{std::byte{100}})}; - pqxx::blob::open_w(tx, id).resize(3); - std::basic_string buf; - pqxx::blob::to_buf(tx, id, buf, 10); - PQXX_CHECK_EQUAL( - buf, - (std::basic_string{std::byte{100}, std::byte{0}, std::byte{0}}), - "Resize did not zero-extend correctly."); -} - - -void test_blob_tell_tracks_position() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - auto id{pqxx::blob::create(tx)}; - auto b{pqxx::blob::open_rw(tx, id)}; - - PQXX_CHECK_EQUAL( - b.tell(), 0, "Empty blob started out in non-zero position."); - b.write(std::basic_string{std::byte{'e'}, std::byte{'f'}}); - PQXX_CHECK_EQUAL( - b.tell(), 2, "Empty blob started out in non-zero position."); - b.seek_abs(1); - PQXX_CHECK_EQUAL(b.tell(), 1, "tell() did not track seek."); -} - - -void test_blob_seek_sets_positions() -{ - std::basic_string data{ - std::byte{0}, std::byte{1}, std::byte{2}, std::byte{3}, std::byte{4}, - std::byte{5}, std::byte{6}, std::byte{7}, std::byte{8}, std::byte{9}}; - pqxx::connection conn; - pqxx::work tx{conn}; - auto id{pqxx::blob::from_buf(tx, data)}; - auto b{pqxx::blob::open_r(tx, id)}; - - std::basic_string buf; - b.seek_rel(3); - b.read(buf, 1u); - PQXX_CHECK_EQUAL( - buf[0], std::byte{3}, - "seek_rel() from beginning did not take us to the right position."); - - b.seek_abs(2); - b.read(buf, 1u); - PQXX_CHECK_EQUAL( - buf[0], std::byte{2}, "seek_abs() did not take us to the right position."); - - b.seek_end(-2); - b.read(buf, 1u); - PQXX_CHECK_EQUAL( - buf[0], std::byte{8}, "seek_end() did not take us to the right position."); -} - - -void test_blob_from_buf_interoperates_with_to_buf() -{ - std::basic_string const data{std::byte{'h'}, std::byte{'i'}}; - std::basic_string buf; - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::blob::to_buf(tx, pqxx::blob::from_buf(tx, data), buf, 10); - PQXX_CHECK_EQUAL(buf, data, "from_buf()/to_buf() roundtrip did not work."); -} - - -void test_blob_append_from_buf_appends() -{ - std::basic_string const data{std::byte{'h'}, std::byte{'o'}}; - pqxx::connection conn; - pqxx::work tx{conn}; - auto id{pqxx::blob::create(tx)}; - pqxx::blob::append_from_buf(tx, data, id); - pqxx::blob::append_from_buf(tx, data, id); - std::basic_string buf; - pqxx::blob::to_buf(tx, id, buf, 10); - PQXX_CHECK_EQUAL(buf, data + data, "append_from_buf() wrote wrong data?"); -} - - -namespace -{ -/// Wrap `std::fopen`. -/** This is just here to stop Visual Studio from advertising its own - * alternative. - */ -std::unique_ptr> -my_fopen(char const *path, char const *mode) -{ -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4996) -#endif - return {std::fopen(path, mode), std::fclose}; -#if defined(_MSC_VER) -# pragma warning(pop) -#endif -} - - -void read_file( - char const path[], std::size_t len, std::basic_string &buf) -{ - buf.resize(len); - auto f{my_fopen(path, "rb")}; - auto bytes{ - std::fread(reinterpret_cast(buf.data()), 1, len, f.get())}; - if (bytes == 0) - throw std::runtime_error{"Error reading test file."}; - buf.resize(bytes); -} - - -void write_file(char const path[], std::basic_string_view data) -{ - try - { - auto f{my_fopen(path, "wb")}; - if ( - std::fwrite( - reinterpret_cast(data.data()), 1, std::size(data), - f.get()) < std::size(data)) - std::runtime_error{"File write failed."}; - } - catch (const std::exception &) - { - std::remove(path); - throw; - } -} - - -/// Temporary file. -class TempFile -{ -public: - /// Create (and later clean up) a file at path containing data. - TempFile(char const path[], std::basic_string_view data) : - m_path(path) - { - write_file(path, data); - } - - ~TempFile() { std::remove(m_path.c_str()); } - -private: - std::string m_path; -}; -} // namespace - - -void test_blob_from_file_creates_blob_from_file_contents() -{ - char const temp_file[] = "blob-test-from_file.tmp"; - std::basic_string const data{std::byte{'4'}, std::byte{'2'}}; - - pqxx::connection conn; - pqxx::work tx{conn}; - std::basic_string buf; - - pqxx::oid id; - { - TempFile f{temp_file, data}; - id = pqxx::blob::from_file(tx, temp_file); - } - pqxx::blob::to_buf(tx, id, buf, 10); - PQXX_CHECK_EQUAL(buf, data, "Wrong data from blob::from_file()."); -} - - -void test_blob_from_file_with_oid_writes_blob() -{ - std::basic_string const data{std::byte{'6'}, std::byte{'9'}}; - char const temp_file[] = "blob-test-from_file-oid.tmp"; - std::basic_string buf; - - pqxx::connection conn; - pqxx::work tx{conn}; - - // Guarantee (more or less) that id is not in use. - auto id{pqxx::blob::create(tx)}; - pqxx::blob::remove(tx, id); - - { - TempFile f{temp_file, data}; - pqxx::blob::from_file(tx, temp_file, id); - } - pqxx::blob::to_buf(tx, id, buf, 10); - PQXX_CHECK_EQUAL(buf, data, "Wrong data from blob::from_file()."); -} - - -void test_blob_append_to_buf_appends() -{ - std::basic_string const data{ - std::byte{'b'}, std::byte{'l'}, std::byte{'u'}, std::byte{'b'}}; - - pqxx::connection conn; - pqxx::work tx{conn}; - auto id{pqxx::blob::from_buf(tx, data)}; - - std::basic_string buf; - PQXX_CHECK_EQUAL( - pqxx::blob::append_to_buf(tx, id, 0u, buf, 1u), 1u, - "append_to_buf() returned unexpected value."); - PQXX_CHECK_EQUAL(std::size(buf), 1u, "Appended the wrong number of bytes."); - PQXX_CHECK_EQUAL( - pqxx::blob::append_to_buf(tx, id, 1u, buf, 5u), 3u, - "append_to_buf() returned unexpected value."); - PQXX_CHECK_EQUAL(std::size(buf), 4u, "Appended the wrong number of bytes."); - - PQXX_CHECK_EQUAL( - buf, data, "Reading using append_to_buf gave us wrong data."); -} - - -void test_blob_to_file_writes_file() -{ - std::basic_string const data{ - std::byte{'C'}, std::byte{'+'}, std::byte{'+'}}; - - char const temp_file[] = "blob-test-to_file.tmp"; - pqxx::connection conn; - pqxx::work tx{conn}; - auto id{pqxx::blob::from_buf(tx, data)}; - std::basic_string buf; - - try - { - pqxx::blob::to_file(tx, id, temp_file); - read_file(temp_file, 10u, buf); - std::remove(temp_file); - } - catch (std::exception const &) - { - std::remove(temp_file); - throw; - } - PQXX_CHECK_EQUAL(buf, data, "Got wrong data from to_file()."); -} - - -void test_blob_close_leaves_blob_unusable() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - auto id{ - pqxx::blob::from_buf(tx, std::basic_string{std::byte{1}})}; - auto b{pqxx::blob::open_rw(tx, id)}; - b.close(); - std::basic_string buf; - PQXX_CHECK_THROWS( - b.read(buf, 1), pqxx::usage_error, - "Reading from closed blob did not fail right."); -} - - -void test_blob_accepts_std_filesystem_path() -{ -#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) - // A bug in gcc 8's ~std::filesystem::path() causes a run-time crash. -# if !defined(__GNUC__) || (__GNUC__ > 8) - - char const temp_file[] = "blob-test-filesystem-path.tmp"; - std::basic_string const data{std::byte{'4'}, std::byte{'2'}}; - - pqxx::connection conn; - pqxx::work tx{conn}; - std::basic_string buf; - - TempFile f{temp_file, data}; - std::filesystem::path const path{temp_file}; - auto id{pqxx::blob::from_file(tx, path)}; - pqxx::blob::to_buf(tx, id, buf, 10); - PQXX_CHECK_EQUAL(buf, data, "Wrong data from blob::from_file()."); - -# endif -#endif -} - - -PQXX_REGISTER_TEST(test_blob_is_useless_by_default); -PQXX_REGISTER_TEST(test_blob_create_makes_empty_blob); -PQXX_REGISTER_TEST(test_blob_create_with_oid_requires_oid_be_free); -PQXX_REGISTER_TEST(test_blob_create_with_oid_obeys_oid); -PQXX_REGISTER_TEST(test_blobs_are_transactional); -PQXX_REGISTER_TEST(test_blob_remove_removes_blob); -PQXX_REGISTER_TEST(test_blob_remove_is_not_idempotent); -PQXX_REGISTER_TEST(test_blob_checks_open_mode); -PQXX_REGISTER_TEST(test_blob_supports_move); -PQXX_REGISTER_TEST(test_blob_read_reads_data); -PQXX_REGISTER_TEST(test_blob_reads_vector); -PQXX_REGISTER_TEST(test_blob_read_span); -PQXX_REGISTER_TEST(test_blob_write_appends_at_insertion_point); -PQXX_REGISTER_TEST(test_blob_writes_span); -PQXX_REGISTER_TEST(test_blob_resize_shortens_to_desired_length); -PQXX_REGISTER_TEST(test_blob_resize_extends_to_desired_length); -PQXX_REGISTER_TEST(test_blob_tell_tracks_position); -PQXX_REGISTER_TEST(test_blob_seek_sets_positions); -PQXX_REGISTER_TEST(test_blob_from_buf_interoperates_with_to_buf); -PQXX_REGISTER_TEST(test_blob_append_from_buf_appends); -PQXX_REGISTER_TEST(test_blob_from_file_creates_blob_from_file_contents); -PQXX_REGISTER_TEST(test_blob_from_file_with_oid_writes_blob); -PQXX_REGISTER_TEST(test_blob_append_to_buf_appends); -PQXX_REGISTER_TEST(test_blob_to_file_writes_file); -PQXX_REGISTER_TEST(test_blob_close_leaves_blob_unusable); -PQXX_REGISTER_TEST(test_blob_accepts_std_filesystem_path); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_cancel_query.cxx b/ext/libpqxx-7.7.3/test/unit/test_cancel_query.cxx deleted file mode 100644 index 5329d195f..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_cancel_query.cxx +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_cancel_query() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - // Calling cancel_query() while none is in progress has no effect. - conn.cancel_query(); - - // Nothing much is guaranteed about cancel_query, except that it doesn't make - // the process die in flames. - pqxx::pipeline p{tx, "test_cancel_query"}; - p.retain(0); - p.insert("SELECT pg_sleep(1)"); - conn.cancel_query(); -} - - -PQXX_REGISTER_TEST(test_cancel_query); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_column.cxx b/ext/libpqxx-7.7.3/test/unit/test_column.cxx deleted file mode 100644 index 9c50faff4..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_column.cxx +++ /dev/null @@ -1,61 +0,0 @@ -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_table_column() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - - tx.exec0("CREATE TEMP TABLE pqxxfoo (x varchar, y integer, z integer)"); - tx.exec0("INSERT INTO pqxxfoo VALUES ('xx', 1, 2)"); - auto R{tx.exec("SELECT z,y,x FROM pqxxfoo")}; - auto X{tx.exec("SELECT x,y,z,99 FROM pqxxfoo")}; - - pqxx::row::size_type x{R.table_column(2)}, y{R.table_column(1)}, - z{R.table_column(static_cast(0))}; - - PQXX_CHECK_EQUAL(x, 0, "Wrong column number."); - PQXX_CHECK_EQUAL(y, 1, "Wrong column number."); - PQXX_CHECK_EQUAL(z, 2, "Wrong column number."); - - x = R.table_column("x"); - y = R.table_column("y"); - z = R.table_column("z"); - - PQXX_CHECK_EQUAL(x, 0, "Wrong number for named column."); - PQXX_CHECK_EQUAL(y, 1, "Wrong number for named column."); - PQXX_CHECK_EQUAL(z, 2, "Wrong number for named column."); - - pqxx::row::size_type xx{X[0].table_column(static_cast(0))}, - yx{X[0].table_column(pqxx::row::size_type(1))}, zx{X[0].table_column("z")}; - - PQXX_CHECK_EQUAL(xx, 0, "Bad result from table_column(int)."); - PQXX_CHECK_EQUAL(yx, 1, "Bad result from table_column(size_type)."); - PQXX_CHECK_EQUAL(zx, 2, "Bad result from table_column(string)."); - - for (pqxx::row::size_type i{0}; i < std::size(R[0]); ++i) - PQXX_CHECK_EQUAL( - R[0][i].table_column(), R.table_column(i), - "Bad result from column_table()."); - - int col; - PQXX_CHECK_THROWS_EXCEPTION( - col = R.table_column(3), "table_column() with invalid index didn't fail."); - pqxx::ignore_unused(col); - - PQXX_CHECK_THROWS_EXCEPTION( - col = R.table_column("nonexistent"), - "table_column() with invalid column name didn't fail."); - pqxx::ignore_unused(col); - - PQXX_CHECK_THROWS_EXCEPTION( - col = X.table_column(3), "table_column() on non-table didn't fail."); - pqxx::ignore_unused(col); -} -} // namespace - - -PQXX_REGISTER_TEST(test_table_column); diff --git a/ext/libpqxx-7.7.3/test/unit/test_composite.cxx b/ext/libpqxx-7.7.3/test/unit/test_composite.cxx deleted file mode 100644 index dcd65360c..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_composite.cxx +++ /dev/null @@ -1,98 +0,0 @@ -#include "../test_helpers.hxx" - -#include "pqxx/composite" -#include "pqxx/transaction" - -namespace -{ -void test_composite() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - tx.exec0("CREATE TYPE pqxxfoo AS (a integer, b text)"); - auto const r{tx.exec1("SELECT '(5,hello)'::pqxxfoo")}; - - int a; - std::string b; - pqxx::parse_composite(r[0].view(), a, b); - - PQXX_CHECK_EQUAL(a, 5, "Integer composite field came back wrong."); - PQXX_CHECK_EQUAL(b, "hello", "String composite field came back wrong."); -} - - -void test_composite_escapes() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::row r; - tx.exec0("CREATE TYPE pqxxsingle AS (x text)"); - std::string s; - - r = tx.exec1(R"--(SELECT '("a""b")'::pqxxsingle)--"); - pqxx::parse_composite(r[0].view(), s); - PQXX_CHECK_EQUAL( - s, "a\"b", "Double-double-quotes escaping did not parse correctly."); - - r = tx.exec1(R"--(SELECT '("a\"b")'::pqxxsingle)--"); - pqxx::parse_composite(r[0].view(), s); - PQXX_CHECK_EQUAL(s, "a\"b", "Backslash escaping did not parse correctly."); -} - - -void test_composite_handles_nulls() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::row r; - - tx.exec0("CREATE TYPE pqxxnull AS (a integer)"); - int nonnull; - r = tx.exec1("SELECT '()'::pqxxnull"); - PQXX_CHECK_THROWS( - pqxx::parse_composite(r[0].view(), nonnull), pqxx::conversion_error, - "No conversion error when reading a null into a nulless variable."); - std::optional nullable{5}; - pqxx::parse_composite(r[0].view(), nullable); - PQXX_CHECK( - not nullable.has_value(), "Null integer came out as having a value."); - - tx.exec0("CREATE TYPE pqxxnulls AS (a integer, b integer)"); - std::optional a{2}, b{4}; - r = tx.exec1("SELECT '(,)'::pqxxnulls"); - pqxx::parse_composite(r[0].view(), a, b); - PQXX_CHECK(not a.has_value(), "Null first integer stored as value."); - PQXX_CHECK(not b.has_value(), "Null second integer stored as value."); -} - - -void test_composite_renders_to_string() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - char buf[1000]; - - pqxx::composite_into_buf( - std::begin(buf), std::end(buf), 355, "foo", "b\na\\r"); - PQXX_CHECK_EQUAL( - std::string{buf}, "(355,\"foo\",\"b\na\\\\r\")", - "Composite was not rendered as expected."); - - tx.exec0("CREATE TYPE pqxxcomp AS (a integer, b text, c text)"); - auto const r{tx.exec1("SELECT '" + std::string{buf} + "'::pqxxcomp")}; - - int a; - std::string b, c; - bool const nonnull{r[0].composite_to(a, b, c)}; - PQXX_CHECK(nonnull, "Mistaken nullness."); - PQXX_CHECK_EQUAL(a, 355, "Int came back wrong."); - PQXX_CHECK_EQUAL(b, "foo", "Simple string came back wrong."); - PQXX_CHECK_EQUAL(c, "b\na\\r", "Escaping went wrong."); -} - - -PQXX_REGISTER_TEST(test_composite); -PQXX_REGISTER_TEST(test_composite_escapes); -PQXX_REGISTER_TEST(test_composite_handles_nulls); -PQXX_REGISTER_TEST(test_composite_renders_to_string); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_connection.cxx b/ext/libpqxx-7.7.3/test/unit/test_connection.cxx deleted file mode 100644 index bbb780854..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_connection.cxx +++ /dev/null @@ -1,212 +0,0 @@ -#include - -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_connection_string_constructor() -{ - pqxx::connection c1{""}; - pqxx::connection c2{std::string{}}; -} - - -void test_move_constructor() -{ - pqxx::connection c1; - PQXX_CHECK(c1.is_open(), "New connection is not open."); - - pqxx::connection c2{std::move(c1)}; - - PQXX_CHECK(not c1.is_open(), "Moving did not close original connection."); - PQXX_CHECK(c2.is_open(), "Moved constructor is not open."); - - pqxx::work tx{c2}; - PQXX_CHECK_EQUAL(tx.query_value("SELECT 5"), 5, "Weird result!"); - - PQXX_CHECK_THROWS( - pqxx::connection c3{std::move(c2)}, pqxx::usage_error, - "Moving a connection with a transaction open should be an error."); -} - - -void test_move_assign() -{ - pqxx::connection c1; - pqxx::connection c2; - - c2.close(); - - c2 = std::move(c1); - - PQXX_CHECK(not c1.is_open(), "Connection still open after being moved out."); - PQXX_CHECK(c2.is_open(), "Moved constructor is not open."); - - { - pqxx::work tx1{c2}; - PQXX_CHECK_EQUAL(tx1.query_value("SELECT 8"), 8, "What!?"); - - pqxx::connection c3; - PQXX_CHECK_THROWS( - c3 = std::move(c2), pqxx::usage_error, - "Moving a connection with a transaction open should be an error."); - - PQXX_CHECK_THROWS( - c2 = std::move(c3), pqxx::usage_error, - "Moving a connection onto one with a transaction open should be " - "an error."); - } - - // After failed move attempts, the connection is still usable. - pqxx::work tx2{c2}; - PQXX_CHECK_EQUAL(tx2.query_value("SELECT 6"), 6, "Huh!?"); -} - - -void test_encrypt_password() -{ - pqxx::connection c; - auto pw{c.encrypt_password("user", "password")}; - PQXX_CHECK(not std::empty(pw), "Encrypted password was empty."); - PQXX_CHECK_EQUAL( - std::strlen(pw.c_str()), std::size(pw), - "Encrypted password contains a null byte."); -} - - -void test_connection_string() -{ - pqxx::connection c; - std::string const connstr{c.connection_string()}; - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4996) -#endif - if (std::getenv("PGUSER") == nullptr) -#if defined(_MSC_VER) -# pragma warning(pop) -#endif - { - PQXX_CHECK( - connstr.find("user=" + std::string{c.username()}) != std::string::npos, - "Connection string did not specify user name: " + connstr); - } - else - { - PQXX_CHECK( - connstr.find("user=" + std::string{c.username()}) == std::string::npos, - "Connection string specified user name, even when using default: " + - connstr); - } -} - - -#if defined(PQXX_HAVE_CONCEPTS) -template std::size_t length(STR const &str) -{ - return std::size(str); -} - - -std::size_t length(char const str[]) -{ - return std::strlen(str); -} -#endif // PQXX_HAVE_CONCEPTS - - -template void test_params_type() -{ -#if defined(PQXX_HAVE_CONCEPTS) - using item_t = std::remove_reference_t< - decltype(*std::declval>())>; - using key_t = decltype(std::get<0>(std::declval())); - using value_t = decltype(std::get<1>(std::declval())); - - // Set some parameters that are relatively safe to change arbitrarily. - MAP const params{{ - {key_t{"application_name"}, value_t{"pqxx-test"}}, - {key_t{"connect_timeout"}, value_t{"96"}}, - {key_t{"keepalives_idle"}, value_t{"771"}}, - }}; - - // Can we create a connection from these parameters? - pqxx::connection c{params}; - - // Check that the parameters came through in the connection string. - // We don't know the exact format, but the parameters have to be in there. - auto const min_size{std::accumulate( - std::cbegin(params), std::cend(params), std::size(params) - 1, - [](auto count, auto item) { - return count + length(std::get<0>(item)) + 1 + length(std::get<1>(item)); - })}; - - auto const connstr{c.connection_string()}; - PQXX_CHECK_GREATER_EQUAL( - std::size(connstr), min_size, - "Connection string can't possibly contain the options we gave."); - for (auto const &[key, value] : params) - { - PQXX_CHECK_NOT_EQUAL( - connstr.find(key), std::string::npos, - "Could not find param name '" + std::string{key} + - "' in connection string: " + connstr); - PQXX_CHECK_NOT_EQUAL( - connstr.find(value), std::string::npos, - "Could not find value for '" + std::string{value} + - "' in connection string: " + connstr); - } -#endif // PQXX_HAVE_CONCEPTS -} - - -void test_connection_params() -{ - // Connecting in this way supports a wide variety of formats for the - // parameters. - test_params_type>(); - test_params_type>(); - test_params_type>(); - test_params_type>(); - test_params_type>(); - test_params_type>>(); - test_params_type>>(); - test_params_type>>(); - test_params_type>>(); -} - - -void test_raw_connection() -{ - pqxx::connection conn1; - PQXX_CHECK(conn1.is_open(), "Fresh connection is not open!"); - pqxx::work tx1{conn1}; - PQXX_CHECK_EQUAL( - tx1.query_value("SELECT 8"), 8, "Something weird happened."); - pqxx::internal::pq::PGconn *raw{std::move(conn1).release_raw_connection()}; - PQXX_CHECK(raw != nullptr, "Raw connection is null."); - PQXX_CHECK( - not conn1.is_open(), - "Releasing raw connection did not close pqxx::connection."); - - pqxx::connection conn2{pqxx::connection::seize_raw_connection(raw)}; - PQXX_CHECK( - conn2.is_open(), "Can't produce open connection from raw connection."); - pqxx::work tx2{conn2}; - PQXX_CHECK_EQUAL( - tx2.query_value("SELECT 9"), 9, - "Raw connection did not produce a working new connection."); -} - - -PQXX_REGISTER_TEST(test_connection_string_constructor); -PQXX_REGISTER_TEST(test_move_constructor); -PQXX_REGISTER_TEST(test_move_assign); -PQXX_REGISTER_TEST(test_encrypt_password); -PQXX_REGISTER_TEST(test_connection_string); -PQXX_REGISTER_TEST(test_connection_params); -PQXX_REGISTER_TEST(test_raw_connection); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_cursor.cxx b/ext/libpqxx-7.7.3/test/unit/test_cursor.cxx deleted file mode 100644 index 8761f6946..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_cursor.cxx +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_stateless_cursor_provides_random_access(pqxx::connection &conn) -{ - pqxx::work tx{conn}; - pqxx::stateless_cursor< - pqxx::cursor_base::read_only, pqxx::cursor_base::owned> - c{tx, "SELECT * FROM generate_series(0, 3)", "count", false}; - - auto r{c.retrieve(1, 2)}; - PQXX_CHECK_EQUAL(std::size(r), 1, "Wrong number of rows from retrieve()."); - PQXX_CHECK_EQUAL(r[0][0].as(), 1, "Cursor retrieved wrong data."); - - r = c.retrieve(3, 10); - PQXX_CHECK_EQUAL(std::size(r), 1, "Expected 1 row retrieving past end."); - PQXX_CHECK_EQUAL(r[0][0].as(), 3, "Wrong data retrieved at end."); - - r = c.retrieve(0, 1); - PQXX_CHECK_EQUAL(std::size(r), 1, "Wrong number of rows back at beginning."); - PQXX_CHECK_EQUAL(r[0][0].as(), 0, "Wrong data back at beginning."); -} - - -void test_stateless_cursor_ignores_trailing_semicolon(pqxx::connection &conn) -{ - pqxx::work tx{conn}; - pqxx::stateless_cursor< - pqxx::cursor_base::read_only, pqxx::cursor_base::owned> - c{tx, "SELECT * FROM generate_series(0, 3) ;; ; \n \t ", "count", false}; - - auto r{c.retrieve(1, 2)}; - PQXX_CHECK_EQUAL(std::size(r), 1, "Trailing semicolon confused retrieve()."); -} - - -void test_cursor() -{ - pqxx::connection conn; - test_stateless_cursor_provides_random_access(conn); - test_stateless_cursor_ignores_trailing_semicolon(conn); -} - - -PQXX_REGISTER_TEST(test_cursor); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_encodings.cxx b/ext/libpqxx-7.7.3/test/unit/test_encodings.cxx deleted file mode 100644 index 4374671c6..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_encodings.cxx +++ /dev/null @@ -1,114 +0,0 @@ -#include "../test_helpers.hxx" - -#include "pqxx/internal/encodings.hxx" - - -namespace -{ -void test_scan_ascii() -{ - auto const scan{pqxx::internal::get_glyph_scanner( - pqxx::internal::encoding_group::MONOBYTE)}; - std::string const text{"hello"}; - - PQXX_CHECK_EQUAL( - scan(text.c_str(), std::size(text), 0), 1ul, - "Monobyte scanner acting up."); - PQXX_CHECK_EQUAL( - scan(text.c_str(), std::size(text), 1), 2ul, - "Monobyte scanner is inconsistent."); -} - - -void test_scan_utf8() -{ - auto const scan{ - pqxx::internal::get_glyph_scanner(pqxx::internal::encoding_group::UTF8)}; - - // Thai: "Khrab". - std::string const text{"\xe0\xb8\x95\xe0\xb8\xa3\xe0\xb8\xb1\xe0\xb8\x9a"}; - PQXX_CHECK_EQUAL( - scan(text.c_str(), std::size(text), 0), 3ul, - "UTF-8 scanner mis-scanned Thai khor khwai."); - PQXX_CHECK_EQUAL( - scan(text.c_str(), std::size(text), 3), 6ul, - "UTF-8 scanner mis-scanned Thai ror reua."); -} - - -void test_for_glyphs_empty() -{ - bool iterated{false}; - pqxx::internal::for_glyphs( - pqxx::internal::encoding_group::MONOBYTE, - [&iterated](char const *, char const *) { iterated = true; }, "", 0); - PQXX_CHECK(!iterated, "Empty string went through an iteration."); -} - - -void test_for_glyphs_ascii() -{ - std::string const text{"hi"}; - std::vector points; - - pqxx::internal::for_glyphs( - pqxx::internal::encoding_group::UTF8, - [&points](char const *gbegin, char const *gend) { - points.push_back(gend - gbegin); - }, - text.c_str(), std::size(text)); - - PQXX_CHECK_EQUAL(std::size(points), 2u, "Wrong number of ASCII iterations."); - PQXX_CHECK_EQUAL(points[0], 1u, "ASCII iteration started off wrong."); - PQXX_CHECK_EQUAL(points[1], 1u, "ASCII iteration was inconsistent."); -} - - -void test_for_glyphs_utf8() -{ - // Greek: alpha omega. - std::string const text{"\xce\x91\xce\xa9"}; - std::vector points; - - pqxx::internal::for_glyphs( - pqxx::internal::encoding_group::UTF8, - [&points](char const *gbegin, char const *gend) { - points.push_back(gend - gbegin); - }, - text.c_str(), std::size(text)); - - PQXX_CHECK_EQUAL(std::size(points), 2u, "Wrong number of UTF-8 iterations."); - PQXX_CHECK_EQUAL(points[0], 2u, "UTF-8 iteration started off wrong."); - PQXX_CHECK_EQUAL(points[1], 2u, "ASCII iteration was inconsistent."); - - // Greek lambda, ASCII plus sign, Old Persian Gu. - std::string const mix{"\xce\xbb+\xf0\x90\x8e\xa6"}; - points.clear(); - - pqxx::internal::for_glyphs( - pqxx::internal::encoding_group::UTF8, - [&points](char const *gbegin, char const *gend) { - points.push_back(gend - gbegin); - }, - mix.c_str(), std::size(mix)); - - PQXX_CHECK_EQUAL(std::size(points), 3u, "Mixed UTF-8 iteration is broken."); - PQXX_CHECK_EQUAL(points[0], 2u, "Mixed UTF-8 iteration started off wrong."); - PQXX_CHECK_EQUAL(points[1], 1u, "Mixed UTF-8 iteration got ASCII wrong."); - PQXX_CHECK_EQUAL( - points[2], 4u, "Mixed UTF-8 iteration got long char wrong."); -} - - -void test_encodings() -{ - test_scan_ascii(); - test_scan_utf8(); - test_for_glyphs_empty(); - test_for_glyphs_ascii(); - test_for_glyphs_utf8(); -} - - -PQXX_REGISTER_TEST(test_encodings); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_error_verbosity.cxx b/ext/libpqxx-7.7.3/test/unit/test_error_verbosity.cxx deleted file mode 100644 index 67dc88763..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_error_verbosity.cxx +++ /dev/null @@ -1,37 +0,0 @@ -#include - -#include "../test_helpers.hxx" - -extern "C" -{ -#include -} - -namespace -{ -void test_error_verbosity() -{ - PQXX_CHECK_EQUAL( - static_cast(pqxx::error_verbosity::terse), - static_cast(PQERRORS_TERSE), - "error_verbosity enum should match PGVerbosity."); - PQXX_CHECK_EQUAL( - static_cast(pqxx::error_verbosity::normal), - static_cast(PQERRORS_DEFAULT), - "error_verbosity enum should match PGVerbosity."); - PQXX_CHECK_EQUAL( - static_cast(pqxx::error_verbosity::verbose), - static_cast(PQERRORS_VERBOSE), - "error_verbosity enum should match PGVerbosity."); - - pqxx::connection conn; - pqxx::work tx{conn}; - conn.set_verbosity(pqxx::error_verbosity::terse); - tx.exec1("SELECT 1"); - conn.set_verbosity(pqxx::error_verbosity::verbose); - tx.exec1("SELECT 2"); -} - - -PQXX_REGISTER_TEST(test_error_verbosity); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_errorhandler.cxx b/ext/libpqxx-7.7.3/test/unit/test_errorhandler.cxx deleted file mode 100644 index c2cd4a797..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_errorhandler.cxx +++ /dev/null @@ -1,223 +0,0 @@ -#include - -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -class TestErrorHandler final : public pqxx::errorhandler -{ -public: - TestErrorHandler( - pqxx::connection &c, std::vector &activated_handlers, - bool retval = true) : - pqxx::errorhandler(c), - return_value(retval), - message(), - handler_list(activated_handlers) - {} - - bool operator()(char const msg[]) noexcept override - { - message = std::string{msg}; - handler_list.push_back(this); - return return_value; - } - - bool return_value; - std::string message; - std::vector &handler_list; -}; -} // namespace - - -namespace pqxx -{ -template<> struct nullness -{ - // clang warns about these being unused. And clang 6 won't accept a - // [[maybe_unused]] attribute on them either! - - // static inline constexpr bool has_null{true}; - // static inline constexpr bool always_null{false}; - - static constexpr bool is_null(TestErrorHandler *e) noexcept - { - return e == nullptr; - } - static constexpr TestErrorHandler *null() noexcept { return nullptr; } -}; - - -template<> struct string_traits -{ - static constexpr std::size_t size_buffer(TestErrorHandler *const &) noexcept - { - return 100; - } - - static char *into_buf(char *begin, char *end, TestErrorHandler *const &value) - { - std::string text{"TestErrorHandler at " + pqxx::to_string(value)}; - if (pqxx::internal::cmp_greater_equal(std::size(text), end - begin)) - throw conversion_overrun{"Not enough buffer for TestErrorHandler."}; - std::memcpy(begin, text.c_str(), std::size(text) + 1); - return begin + std::size(text) + 1; - } -}; -} // namespace pqxx - - -namespace -{ -void test_process_notice_calls_errorhandler(pqxx::connection &c) -{ - std::vector dummy; - TestErrorHandler handler(c, dummy); - c.process_notice("Error!\n"); - PQXX_CHECK_EQUAL(handler.message, "Error!\n", "Error not handled."); -} - - -void test_error_handlers_get_called_newest_to_oldest(pqxx::connection &c) -{ - std::vector handlers; - TestErrorHandler h1(c, handlers); - TestErrorHandler h2(c, handlers); - TestErrorHandler h3(c, handlers); - c.process_notice("Warning.\n"); - PQXX_CHECK_EQUAL(h3.message, "Warning.\n", "Message not handled."); - PQXX_CHECK_EQUAL(h2.message, "Warning.\n", "Broken handling chain."); - PQXX_CHECK_EQUAL(h1.message, "Warning.\n", "Insane handling chain."); - PQXX_CHECK_EQUAL(std::size(handlers), 3u, "Wrong number of handler calls."); - PQXX_CHECK_EQUAL(&h3, handlers[0], "Unexpected handling order."); - PQXX_CHECK_EQUAL(&h2, handlers[1], "Insane handling order."); - PQXX_CHECK_EQUAL(&h1, handlers[2], "Impossible handling order."); -} - -void test_returning_false_stops_error_handling(pqxx::connection &c) -{ - std::vector handlers; - TestErrorHandler starved(c, handlers); - TestErrorHandler blocker(c, handlers, false); - c.process_notice("Error output.\n"); - PQXX_CHECK_EQUAL(std::size(handlers), 1u, "Handling chain was not stopped."); - PQXX_CHECK_EQUAL(handlers[0], &blocker, "Wrong handler got message."); - PQXX_CHECK_EQUAL(blocker.message, "Error output.\n", "Didn't get message."); - PQXX_CHECK_EQUAL(starved.message, "", "Message received; it shouldn't be."); -} - -void test_destroyed_error_handlers_are_not_called(pqxx::connection &c) -{ - std::vector handlers; - { - TestErrorHandler doomed(c, handlers); - } - c.process_notice("Unheard output."); - PQXX_CHECK( - std::empty(handlers), "Message was received on dead errorhandler."); -} - -void test_destroying_connection_unregisters_handlers() -{ - TestErrorHandler *survivor; - std::vector handlers; - { - pqxx::connection c; - survivor = new TestErrorHandler(c, handlers); - } - // Make some pointless use of survivor just to prove that this doesn't crash. - (*survivor)("Hi"); - PQXX_CHECK_EQUAL( - std::size(handlers), 1u, "Ghost of dead ex-connection haunts handler."); - delete survivor; -} - - -class MinimalErrorHandler final : public pqxx::errorhandler -{ -public: - explicit MinimalErrorHandler(pqxx::connection &c) : pqxx::errorhandler(c) {} - bool operator()(char const[]) noexcept override { return true; } -}; - - -void test_get_errorhandlers(pqxx::connection &c) -{ - std::unique_ptr eh3; - auto const handlers_before{c.get_errorhandlers()}; - std::size_t const base_handlers{std::size(handlers_before)}; - - { - MinimalErrorHandler eh1(c); - auto const handlers_with_eh1{c.get_errorhandlers()}; - PQXX_CHECK_EQUAL( - std::size(handlers_with_eh1), base_handlers + 1, - "Registering a handler didn't create exactly one handler."); - PQXX_CHECK_EQUAL( - std::size_t(*std::rbegin(handlers_with_eh1)), std::size_t(&eh1), - "Wrong handler or wrong order."); - - { - MinimalErrorHandler eh2(c); - auto const handlers_with_eh2{c.get_errorhandlers()}; - PQXX_CHECK_EQUAL( - std::size(handlers_with_eh2), base_handlers + 2, - "Adding second handler didn't work."); - PQXX_CHECK_EQUAL( - std::size_t(*(std::rbegin(handlers_with_eh2) + 1)), std::size_t(&eh1), - "Second handler upset order."); - PQXX_CHECK_EQUAL( - std::size_t(*std::rbegin(handlers_with_eh2)), std::size_t(&eh2), - "Second handler isn't right."); - } - auto const handlers_without_eh2{c.get_errorhandlers()}; - PQXX_CHECK_EQUAL( - std::size(handlers_without_eh2), base_handlers + 1, - "Handler destruction produced wrong-sized handlers list."); - PQXX_CHECK_EQUAL( - std::size_t(*std::rbegin(handlers_without_eh2)), std::size_t(&eh1), - "Destroyed wrong handler."); - - eh3 = std::make_unique(c); - auto const handlers_with_eh3{c.get_errorhandlers()}; - PQXX_CHECK_EQUAL( - std::size(handlers_with_eh3), base_handlers + 2, - "Remove-and-add breaks."); - PQXX_CHECK_EQUAL( - std::size_t(*std::rbegin(handlers_with_eh3)), std::size_t(eh3.get()), - "Added wrong third handler."); - } - auto const handlers_without_eh1{c.get_errorhandlers()}; - PQXX_CHECK_EQUAL( - std::size(handlers_without_eh1), base_handlers + 1, - "Destroying oldest handler didn't work as expected."); - PQXX_CHECK_EQUAL( - std::size_t(*std::rbegin(handlers_without_eh1)), std::size_t(eh3.get()), - "Destroyed wrong handler."); - - eh3.reset(); - - auto const handlers_without_all{c.get_errorhandlers()}; - PQXX_CHECK_EQUAL( - std::size(handlers_without_all), base_handlers, - "Destroying all custom handlers didn't work as expected."); -} - - -void test_errorhandler() -{ - pqxx::connection conn; - test_process_notice_calls_errorhandler(conn); - test_error_handlers_get_called_newest_to_oldest(conn); - test_returning_false_stops_error_handling(conn); - test_destroyed_error_handlers_are_not_called(conn); - test_destroying_connection_unregisters_handlers(); - test_get_errorhandlers(conn); -} - - -PQXX_REGISTER_TEST(test_errorhandler); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_escape.cxx b/ext/libpqxx-7.7.3/test/unit/test_escape.cxx deleted file mode 100644 index baff4d62c..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_escape.cxx +++ /dev/null @@ -1,228 +0,0 @@ -#include - -#include - -#include "../test_helpers.hxx" - -namespace -{ -using namespace std::literals; - - -void compare_esc( - pqxx::connection &c, pqxx::transaction_base &t, char const text[]) -{ - std::size_t const len{std::size(std::string{text})}; - PQXX_CHECK_EQUAL( - c.esc(std::string_view{text, len}), t.esc(std::string_view{text, len}), - "Connection & transaction escape differently."); - - PQXX_CHECK_EQUAL( - t.esc(std::string_view{text, len}), t.esc(text), - "Length argument to esc() changes result."); - - PQXX_CHECK_EQUAL( - t.esc(std::string{text}), t.esc(text), - "esc(std::string()) differs from esc(char const[])."); - - PQXX_CHECK_EQUAL( - text, - t.query_value( - "SELECT '" + t.esc(std::string_view{text, len}) + "'"), - "esc() is not idempotent."); - - PQXX_CHECK_EQUAL( - t.esc(std::string_view{text, len}), t.esc(text), - "Oversized buffer affects esc()."); -} - - -void test_esc(pqxx::connection &c, pqxx::transaction_base &t) -{ - PQXX_CHECK_EQUAL( - t.esc(std::string_view{"", 0}), "", - "Empty string doesn't escape properly."); - PQXX_CHECK_EQUAL( - t.esc(std::string_view{"'", 1}), "''", - "Single quote escaped incorrectly."); - PQXX_CHECK_EQUAL( - t.esc(std::string_view{"hello"}), "hello", "Trivial escape went wrong."); - char const *const escstrings[]{"x", " ", "", nullptr}; - for (std::size_t i{0}; escstrings[i] != nullptr; ++i) - compare_esc(c, t, escstrings[i]); -} - - -void test_quote(pqxx::connection &c, pqxx::transaction_base &t) -{ - PQXX_CHECK_EQUAL(t.quote("x"), "'x'", "Basic quote() fails."); - PQXX_CHECK_EQUAL( - t.quote(1), "'1'", "quote() not dealing with int properly."); - PQXX_CHECK_EQUAL(t.quote(0), "'0'", "Quoting zero is a problem."); - char const *const null_ptr{nullptr}; - PQXX_CHECK_EQUAL(t.quote(null_ptr), "NULL", "Not quoting NULL correctly."); - PQXX_CHECK_EQUAL( - t.quote(std::string{"'"}), "''''", "Escaping quotes goes wrong."); - - PQXX_CHECK_EQUAL( - t.quote("x"), c.quote("x"), - "Connection and transaction quote differently."); - - char const *test_strings[]{"", "x", "\\", "\\\\", "'", - "''", "\\'", "\t", "\n", nullptr}; - - for (std::size_t i{0}; test_strings[i] != nullptr; ++i) - { - auto r{t.query_value("SELECT " + t.quote(test_strings[i]))}; - PQXX_CHECK_EQUAL( - r, test_strings[i], "Selecting quoted string does not come back equal."); - } -} - - -void test_quote_name(pqxx::transaction_base &t) -{ - PQXX_CHECK_EQUAL( - "\"A b\"", t.quote_name("A b"), "Escaped identifier is not as expected."); - PQXX_CHECK_EQUAL( - std::string{"A b"}, - t.exec("SELECT 1 AS " + t.quote_name("A b")).column_name(0), - "Escaped identifier does not work in SQL."); -} - - -void test_esc_raw_unesc_raw(pqxx::transaction_base &t) -{ - constexpr char binary[]{"1\0023\\4x5"}; - std::basic_string const data( - reinterpret_cast(binary), std::size(binary)); - std::string const escaped{t.esc_raw( - std::basic_string_view{std::data(data), std::size(binary)})}; - - for (auto const i : escaped) - { - PQXX_CHECK_GREATER( - static_cast(static_cast(i)), 7u, - "Non-ASCII character in escaped data: " + escaped); - PQXX_CHECK_LESS( - static_cast(static_cast(i)), 127u, - "Non-ASCII character in escaped data: " + escaped); - } - - for (auto const i : escaped) - PQXX_CHECK( - isprint(i), "Unprintable character in escaped data: " + escaped); - - PQXX_CHECK_EQUAL( - escaped, "\\x3102335c34783500", "Binary data escaped wrong."); - PQXX_CHECK_EQUAL( - std::size(t.unesc_bin(escaped)), std::size(data), - "Wrong size after unescaping."); - auto unescaped{t.unesc_bin(escaped)}; - PQXX_CHECK_EQUAL( - std::size(unescaped), std::size(data), - "Unescaping did not restore original size."); - for (std::size_t i{0}; i < std::size(unescaped); ++i) - PQXX_CHECK_EQUAL( - int(unescaped[i]), int(data[i]), - "Unescaping binary data did not restore byte #" + pqxx::to_string(i) + - "."); -} - - -void test_esc_like(pqxx::transaction_base &tx) -{ - PQXX_CHECK_EQUAL(tx.esc_like(""), "", "esc_like breaks on empty string."); - PQXX_CHECK_EQUAL(tx.esc_like("abc"), "abc", "esc_like is broken."); - PQXX_CHECK_EQUAL(tx.esc_like("_"), "\\_", "esc_like fails on underscore."); - PQXX_CHECK_EQUAL(tx.esc_like("%"), "\\%", "esc_like fails on %."); - PQXX_CHECK_EQUAL( - tx.esc_like("a%b_c"), "a\\%b\\_c", "esc_like breaks on mix."); - PQXX_CHECK_EQUAL( - tx.esc_like("_", '+'), "+_", "esc_like ignores escape character."); -} - - -void test_escaping() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - test_esc(conn, tx); - test_quote(conn, tx); - test_quote_name(tx); - test_esc_raw_unesc_raw(tx); - test_esc_like(tx); -} - - -void test_esc_escapes_into_buffer() -{ -#if defined(PQXX_HAVE_CONCEPTS) - pqxx::connection conn; - pqxx::work tx{conn}; - - std::string buffer; - buffer.resize(20); - - auto const text{"Ain't"sv}; - auto escaped_text{tx.esc(text, buffer)}; - PQXX_CHECK_EQUAL(escaped_text, "Ain''t", "Escaping into buffer went wrong."); - - std::basic_string const data{std::byte{0x22}, std::byte{0x43}}; - auto escaped_data(tx.esc(data, buffer)); - PQXX_CHECK_EQUAL(escaped_data, "\\x2243", "Binary data escaped wrong."); -#endif -} - - -void test_esc_accepts_various_types() -{ -#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) - pqxx::connection conn; - pqxx::work tx{conn}; - - std::string buffer; - buffer.resize(20); - - std::string const text{"it's"}; - auto escaped_text{tx.esc(text, buffer)}; - PQXX_CHECK_EQUAL(escaped_text, "it''s", "Escaping into buffer went wrong."); - - std::vector const data{std::byte{0x23}, std::byte{0x44}}; - auto escaped_data(tx.esc(data, buffer)); - PQXX_CHECK_EQUAL(escaped_data, "\\x2344", "Binary data escaped wrong."); -#endif -} - - -void test_binary_esc_checks_buffer_length() -{ -#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) - pqxx::connection conn; - pqxx::work tx{conn}; - - std::string buf; - std::basic_string bin{ - std::byte{'b'}, std::byte{'o'}, std::byte{'o'}}; - - buf.resize(2 * std::size(bin) + 3); - pqxx::ignore_unused(tx.esc(bin, buf)); - PQXX_CHECK_EQUAL(int{buf[0]}, int{'\\'}, "Unexpected binary escape format."); - PQXX_CHECK_NOT_EQUAL( - int(buf[std::size(buf) - 2]), int('\0'), "Escaped binary ends too soon."); - PQXX_CHECK_EQUAL( - int(buf[std::size(buf) - 1]), int('\0'), "Terminating zero is missing."); - - buf.resize(2 * std::size(bin) + 2); - PQXX_CHECK_THROWS( - pqxx::ignore_unused(tx.esc(bin, buf)), pqxx::range_error, - "Didn't get expected exception from escape overrun."); -#endif -} - - -PQXX_REGISTER_TEST(test_escaping); -PQXX_REGISTER_TEST(test_esc_escapes_into_buffer); -PQXX_REGISTER_TEST(test_esc_accepts_various_types); -PQXX_REGISTER_TEST(test_binary_esc_checks_buffer_length); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_exceptions.cxx b/ext/libpqxx-7.7.3/test/unit/test_exceptions.cxx deleted file mode 100644 index 4b84b7fba..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_exceptions.cxx +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - - -namespace -{ -void test_exceptions() -{ - std::string const broken_query{"SELECT HORRIBLE ERROR"}, - err{"Error message"}; - - try - { - throw pqxx::sql_error{err, broken_query}; - } - catch (std::exception const &e) - { - PQXX_CHECK_EQUAL(e.what(), err, "Exception contains wrong message."); - auto downcast{dynamic_cast(&e)}; - PQXX_CHECK( - downcast != nullptr, "exception-to-sql_error downcast is broken."); - PQXX_CHECK_EQUAL( - downcast->query(), broken_query, - "Getting query from pqxx exception is broken."); - } - - pqxx::connection conn; - pqxx::work tx{conn}; - try - { - tx.exec("INVALID QUERY HERE"); - } - catch (pqxx::syntax_error const &e) - { - // SQL syntax error has sqlstate error 42601. - PQXX_CHECK_EQUAL( - e.sqlstate(), "42601", "Unexpected sqlstate on syntax error."); - } -} - - -PQXX_REGISTER_TEST(test_exceptions); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_field.cxx b/ext/libpqxx-7.7.3/test/unit/test_field.cxx deleted file mode 100644 index 013ea1a82..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_field.cxx +++ /dev/null @@ -1,57 +0,0 @@ -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_field() -{ - pqxx::connection c; - pqxx::work tx{c}; - auto const r1{tx.exec1("SELECT 9")}; - auto const &f1{r1[0]}; - - PQXX_CHECK_EQUAL(f1.as(), "9", "as() is broken."); - PQXX_CHECK_EQUAL( - f1.as("z"), "9", "as(string) is broken."); - - PQXX_CHECK_EQUAL(f1.as(), 9, "as() is broken."); - PQXX_CHECK_EQUAL(f1.as(10), 9, "as(int) is broken."); - - std::string s; - PQXX_CHECK(f1.to(s), "to(string) failed."); - PQXX_CHECK_EQUAL(s, "9", "to(string) is broken."); - s = "x"; - PQXX_CHECK(f1.to(s, std::string{"7"}), "to(string, string) failed."); - PQXX_CHECK_EQUAL(s, "9", "to(string, string) is broken."); - - int i{}; - PQXX_CHECK(f1.to(i), "to(int) failed."); - PQXX_CHECK_EQUAL(i, 9, "to(int) is broken."); - i = 8; - PQXX_CHECK(f1.to(i, 12), "to(int, int) failed."); - PQXX_CHECK_EQUAL(i, 9, "to(int, int) is broken."); - - auto const r2{tx.exec1("SELECT NULL")}; - auto const f2{r2[0]}; - i = 100; - PQXX_CHECK_THROWS( - f2.as(), pqxx::conversion_error, "Null conversion failed to throw."); - PQXX_CHECK_EQUAL(i, 100, "Null conversion touched its output."); - - PQXX_CHECK_EQUAL(f2.as(66), 66, "as default is broken."); - - PQXX_CHECK(!(f2.to(i)), "to(int) failed to report a null."); - PQXX_CHECK(!(f2.to(i, 54)), "to(int, int) failed to report a null."); - PQXX_CHECK_EQUAL(i, 54, "to(int, int) failed to default."); - - auto const r3{tx.exec("SELECT generate_series(1, 5)")}; - PQXX_CHECK_EQUAL(r3.at(3, 0).as(), 4, "Two-argument at() went wrong."); -#if defined(PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT) - PQXX_CHECK_EQUAL((r3[3, 0].as()), 4, "Two-argument [] went wrong."); -#endif -} - - -PQXX_REGISTER_TEST(test_field); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_float.cxx b/ext/libpqxx-7.7.3/test/unit/test_float.cxx deleted file mode 100644 index a0463e4d0..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_float.cxx +++ /dev/null @@ -1,175 +0,0 @@ -#include - -#include - -#include "../test_helpers.hxx" - -namespace -{ -/// Test conversions for some floating-point type. -template void infinity_test() -{ - T inf{std::numeric_limits::infinity()}; - std::string inf_string; - T back_conversion; - - inf_string = pqxx::to_string(inf); - pqxx::from_string(inf_string, back_conversion); - PQXX_CHECK_LESS( - T(999999999), back_conversion, - "Infinity doesn't convert back to something huge."); - - inf_string = pqxx::to_string(-inf); - pqxx::from_string(inf_string, back_conversion); - PQXX_CHECK_LESS( - back_conversion, -T(999999999), "Negative infinity is broken"); -} - -void test_infinities() -{ - infinity_test(); - infinity_test(); - infinity_test(); -} - - -/// Reproduce bug #262: repeated float conversions break without charconv. -template void bug_262() -{ - pqxx::connection conn; - conn.prepare("stmt", "select cast($1 as float)"); - pqxx::work tr{conn}; - - // We must use the same float type both for passing the value to the - // statement and for retrieving result of the statement execution. This is - // due to an internal stringstream being instantiated as a a parameterized - // thread-local singleton. So, there are separate stream, - // stream, stream, but every such instance is a - // singleton. We should use only one of them for this test. - - pqxx::row row; - - // Nothing bad here, select a float value. - // The stream is clear, so just fill it with the value and extract str(). - row = tr.exec1("SELECT 1.0"); - - // This works properly, but as we parse the value from the stream, the - // seeking cursor moves towards the EOF. When the inevitable EOF happens - // 'eof' flag is set in the stream and 'good' flag is unset. - row[0].as(); - - // The second try. Select a float value again. The stream is not clean, so - // we need to put an empty string into its buffer {stream.str("");}. This - // resets the seeking cursor to 0. Then we will put the value using - // operator<<(). - // ... - // ... - // OOPS. stream.str("") does not reset 'eof' flag and 'good' flag! We are - // trying to read from EOF! This is no good. - // Throws on unpatched pqxx v6.4.5 - row = tr.exec1("SELECT 2.0"); - - // We won't get here without patch. The following statements are just for - // demonstration of how are intended to work. If we - // simply just reset the stream flags properly, this would work fine. - // The most obvious patch is just explicitly stream.seekg(0). - row[0].as(); - row = tr.exec1("SELECT 3.0"); - row[0].as(); -} - - -/// Test for bug #262. -void test_bug_262() -{ - bug_262(); - bug_262(); - bug_262(); -} - - -/// Test conversion of malformed floating-point values. -void test_bad_float() -{ - float x [[maybe_unused]]; - PQXX_CHECK_THROWS( - x = pqxx::from_string(""), pqxx::conversion_error, - "Conversion of empty string to float was not caught."); - - PQXX_CHECK_THROWS( - x = pqxx::from_string("Infancy"), pqxx::conversion_error, - "Misleading infinity was not caught."); - PQXX_CHECK_THROWS( - x = pqxx::from_string("-Infighting"), pqxx::conversion_error, - "Misleading negative infinity was not caught."); - - PQXX_CHECK_THROWS( - x = pqxx::from_string("Nanny"), pqxx::conversion_error, - "Conversion of misleading NaN was not caught."); -} - - -template void test_float_length(T value) -{ - auto const text{pqxx::to_string(value)}; - PQXX_CHECK_GREATER_EQUAL( - pqxx::size_buffer(value), std::size(text) + 1, - "Not enough buffer space for " + text + "."); -} - - -/// Test conversion of long float values to strings. -void test_long_float() -{ - test_float_length(0.1f); - test_float_length(0.1); - - test_float_length(std::numeric_limits::denorm_min()); - test_float_length(-std::numeric_limits::denorm_min()); - test_float_length(std::numeric_limits::min()); - test_float_length(-std::numeric_limits::min()); - test_float_length(std::numeric_limits::max()); - test_float_length(-std::numeric_limits::max()); - test_float_length(-std::nextafter(1.0f, 2.0f)); - - test_float_length(std::numeric_limits::denorm_min()); - test_float_length(-std::numeric_limits::denorm_min()); - test_float_length(std::numeric_limits::min()); - test_float_length(-std::numeric_limits::min()); - test_float_length(std::numeric_limits::max()); - test_float_length(-std::numeric_limits::max()); - test_float_length(-std::nextafter(1.0, 2.0)); - - test_float_length(std::numeric_limits::denorm_min()); - test_float_length(-std::numeric_limits::denorm_min()); - test_float_length(std::numeric_limits::min()); - test_float_length(-std::numeric_limits::min()); - test_float_length(std::numeric_limits::max()); - test_float_length(-std::numeric_limits::max()); - test_float_length(-std::nextafter(1.0L, 2.0L)); - - // Ahem. I'm not proud of this. We really can't assume much about the - // floating-point types, but I'd really like to try a few things to see that - // buffer sizes are in the right ballpark. So, if "double" is at least 64 - // bits, check for some examples of long conversions. - if constexpr (sizeof(double) >= 8) - { - auto constexpr awkward{-2.2250738585072014e-308}; - auto const text{pqxx::to_string(awkward)}; - PQXX_CHECK_LESS_EQUAL( - std::size(text), 25u, text + " converted to too long a string."); - } - if constexpr (sizeof(double) <= 8) - { - auto const text{pqxx::to_string(0.99)}; - PQXX_CHECK_LESS_EQUAL( - pqxx::size_buffer(0.99), 25u, text + " converted to too long a string."); - } -} - - -PQXX_REGISTER_TEST(test_infinities); -PQXX_REGISTER_TEST(test_bug_262); -PQXX_REGISTER_TEST(test_bad_float); -PQXX_REGISTER_TEST(test_long_float); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_largeobject.cxx b/ext/libpqxx-7.7.3/test/unit/test_largeobject.cxx deleted file mode 100644 index 8184fa2f8..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_largeobject.cxx +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include - -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_stream_large_object() -{ - pqxx::connection conn; - - // Construct a really nasty string. (Don't just construct a std::string from - // a char[] constant, because it'll terminate at the embedded zero.) - // - // The crucial thing is the "ff" byte at the beginning. It tests for - // possible conflation between "eof" (-1) and a char which just happens to - // have the same bit pattern as an 8-bit value of -1. This conflation can be - // a problem when it occurs at buffer boundaries. - constexpr char bytes[]{"\xff\0end"}; - std::string const contents{bytes, std::size(bytes)}; - - pqxx::work tx{conn}; -#include "pqxx/internal/ignore-deprecated-pre.hxx" - pqxx::largeobject new_obj{tx}; - - pqxx::olostream write{tx, new_obj}; - write << contents; - write.flush(); - - pqxx::largeobjectaccess check{tx, new_obj, std::ios::in | std::ios::binary}; - std::array buf; - std::size_t const len{ - static_cast(check.read(std::data(buf), std::size(buf)))}; - PQXX_CHECK_EQUAL(len, std::size(contents), "olostream truncated data."); - std::string const check_str{std::data(buf), len}; - PQXX_CHECK_EQUAL(check_str, contents, "olostream mangled data."); - - pqxx::ilostream read{tx, new_obj}; - std::string read_back; - std::string chunk; - while (read >> chunk) read_back += chunk; - - new_obj.remove(tx); - - PQXX_CHECK_EQUAL(read_back, contents, "Got wrong data from ilostream."); - PQXX_CHECK_EQUAL( - std::size(read_back), std::size(contents), "ilostream truncated data."); - PQXX_CHECK_EQUAL( - std::size(read_back), std::size(bytes), "ilostream truncated data."); -#include "pqxx/internal/ignore-deprecated-post.hxx" -} - - -PQXX_REGISTER_TEST(test_stream_large_object); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_nonblocking_connect.cxx b/ext/libpqxx-7.7.3/test/unit/test_nonblocking_connect.cxx deleted file mode 100644 index d1a32ac64..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_nonblocking_connect.cxx +++ /dev/null @@ -1,27 +0,0 @@ -#include - -#include - -#include "../test_helpers.hxx" - - -namespace -{ -void test_nonblocking_connect() -{ - pqxx::connecting nbc; - while (not nbc.done()) - { - pqxx::internal::wait_fd( - nbc.sock(), nbc.wait_to_read(), nbc.wait_to_write()); - nbc.process(); - } - - pqxx::connection conn{std::move(nbc).produce()}; - pqxx::work tx{conn}; - PQXX_CHECK_EQUAL(tx.query_value("SELECT 10"), 10, "Bad value!?"); -} - - -PQXX_REGISTER_TEST(test_nonblocking_connect); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_notification.cxx b/ext/libpqxx-7.7.3/test/unit/test_notification.cxx deleted file mode 100644 index 6487169b4..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_notification.cxx +++ /dev/null @@ -1,86 +0,0 @@ -#include - -#include - -#include - -#include - -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -class TestReceiver final : public pqxx::notification_receiver -{ -public: - std::string payload; - int backend_pid; - - TestReceiver(pqxx::connection &c, std::string const &channel_name) : - pqxx::notification_receiver(c, channel_name), - payload(), - backend_pid(0) - {} - - virtual void - operator()(std::string const &payload_string, int backend) override - { - this->payload = payload_string; - this->backend_pid = backend; - } -}; - - -void test_receive( - pqxx::transaction_base &t, std::string const &channel, - char const payload[] = nullptr) -{ - pqxx::connection &conn(t.conn()); - - std::string SQL{"NOTIFY \"" + channel + "\""}; - if (payload != nullptr) - SQL += ", " + t.quote(payload); - - TestReceiver receiver{t.conn(), channel}; - - // Clear out any previously pending notifications that might otherwise - // confuse the test. - conn.get_notifs(); - - // Notify, and receive. - t.exec(SQL); - t.commit(); - - int notifs{0}; - for (int i{0}; (i < 10) and (notifs == 0); - ++i, pqxx::internal::wait_for(1'000'000u)) - notifs = conn.get_notifs(); - - PQXX_CHECK_EQUAL(notifs, 1, "Got wrong number of notifications."); - PQXX_CHECK_EQUAL(receiver.backend_pid, conn.backendpid(), "Bad pid."); - if (payload == nullptr) - PQXX_CHECK(std::empty(receiver.payload), "Unexpected payload."); - else - PQXX_CHECK_EQUAL(receiver.payload, payload, "Bad payload."); -} - - -void test_notification() -{ - pqxx::connection conn; - TestReceiver receiver(conn, "mychannel"); - PQXX_CHECK_EQUAL(receiver.channel(), "mychannel", "Bad channel."); - - pqxx::work tx{conn}; - test_receive(tx, "channel1"); - - pqxx::nontransaction u(conn); - test_receive(u, "channel2", "payload"); -} - - -PQXX_REGISTER_TEST(test_notification); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_pipeline.cxx b/ext/libpqxx-7.7.3/test/unit/test_pipeline.cxx deleted file mode 100644 index 63b97662b..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_pipeline.cxx +++ /dev/null @@ -1,64 +0,0 @@ -#include - -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_pipeline() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - - // A pipeline grabs transaction focus, blocking regular queries and such. - pqxx::pipeline pipe(tx, "test_pipeline_detach"); - PQXX_CHECK_THROWS( - tx.exec("SELECT 1"), std::logic_error, - "Pipeline does not block regular queries"); - - // Flushing a pipeline relinquishes transaction focus. - pipe.flush(); - auto r{tx.exec("SELECT 2")}; - PQXX_CHECK_EQUAL( - std::size(r), 1, "Wrong query result after flushing pipeline."); - PQXX_CHECK_EQUAL( - r[0][0].as(), 2, "Query returns wrong data after flushing pipeline."); - - // Inserting a query makes the pipeline grab transaction focus back. - auto q{pipe.insert("SELECT 2")}; - PQXX_CHECK_THROWS( - tx.exec("SELECT 3"), std::logic_error, - "Pipeline does not block regular queries"); - - // Invoking complete() also detaches the pipeline from the transaction. - pipe.complete(); - r = tx.exec("SELECT 4"); - PQXX_CHECK_EQUAL(std::size(r), 1, "Wrong query result after complete()."); - PQXX_CHECK_EQUAL( - r[0][0].as(), 4, "Query returns wrong data after complete()."); - - // The complete() also received any pending query results from the backend. - r = pipe.retrieve(q); - PQXX_CHECK_EQUAL(std::size(r), 1, "Wrong result from pipeline."); - PQXX_CHECK_EQUAL(r[0][0].as(), 2, "Pipeline returned wrong data."); - - // We can cancel while the pipe is empty, and things will still work. - pipe.cancel(); - - // Issue a query and cancel it. Measure time to see that we don't really - // wait. - using clock = std::chrono::steady_clock; - auto const start{clock::now()}; - pipe.retain(0); - pipe.insert("pg_sleep(10)"); - pipe.cancel(); - auto const finish{clock::now()}; - auto const seconds{ - std::chrono::duration_cast(finish - start).count()}; - PQXX_CHECK_LESS(seconds, 5, "Canceling a sleep took suspiciously long."); -} -} // namespace - -PQXX_REGISTER_TEST(test_pipeline); diff --git a/ext/libpqxx-7.7.3/test/unit/test_prepared_statement.cxx b/ext/libpqxx-7.7.3/test/unit/test_prepared_statement.cxx deleted file mode 100644 index c9eb4ee84..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_prepared_statement.cxx +++ /dev/null @@ -1,334 +0,0 @@ -#include -#include -#include -#include - -#include - -#include "../test_helpers.hxx" - -// Test program for libpqxx. Define and use prepared statements. - -#define COMPARE_RESULTS(name, lhs, rhs) \ - PQXX_CHECK_EQUAL( \ - rhs, lhs, \ - "Executing " name " as prepared statement yields different results."); - -namespace -{ -using namespace std::literals; - - -template std::string stringize(pqxx::transaction_base &t, T i) -{ - return stringize(t, pqxx::to_string(i)); -} - - -// Substitute variables in raw query. This is not likely to be very robust, -// but it should do for just this test. The main shortcomings are escaping, -// and not knowing when to quote the variables. -// Note we do the replacement backwards (meaning forward_only iterators won't -// do!) to avoid substituting e.g. "$12" as "$1" first. -template -std::string -subst(pqxx::transaction_base &t, std::string q, ITER patbegin, ITER patend) -{ - ptrdiff_t i{distance(patbegin, patend)}; - for (ITER arg{patend}; i > 0; --i) - { - --arg; - std::string const marker{"$" + pqxx::to_string(i)}, - var{stringize(t, *arg)}; - std::string::size_type const msz{std::size(marker)}; - while (q.find(marker) != std::string::npos) - q.replace(q.find(marker), msz, var); - } - return q; -} - - -template -std::string -subst(pqxx::transaction_base &t, std::string const &q, CNTNR const &patterns) -{ - return subst(t, q, std::begin(patterns), std::end(patterns)); -} - - -void test_registration_and_invocation() -{ - constexpr auto count_to_5{"SELECT * FROM generate_series(1, 5)"}; - - pqxx::connection c; - pqxx::work tx1{c}; - - // Prepare a simple statement. - tx1.conn().prepare("CountToFive", count_to_5); - - // The statement returns exactly what you'd expect. - COMPARE_RESULTS( - "CountToFive", tx1.exec_prepared("CountToFive"), tx1.exec(count_to_5)); - - // Re-preparing it is an error. - PQXX_CHECK_THROWS( - tx1.conn().prepare("CountToFive", count_to_5), pqxx::sql_error, - "Did not report re-definition of prepared statement."); - - tx1.abort(); - pqxx::work tx2{c}; - - // Executing a nonexistent prepared statement is also an error. - PQXX_CHECK_THROWS( - tx2.exec_prepared("NonexistentStatement"), pqxx::sql_error, - "Did not report invocation of nonexistent prepared statement."); -} - - -void test_basic_args() -{ - pqxx::connection c; - c.prepare("EchoNum", "SELECT $1::int"); - pqxx::work tx{c}; - auto r{tx.exec_prepared("EchoNum", 7)}; - PQXX_CHECK_EQUAL( - std::size(r), 1, "Did not get 1 row from prepared statement."); - PQXX_CHECK_EQUAL(std::size(r.front()), 1, "Did not get exactly one column."); - PQXX_CHECK_EQUAL(r[0][0].as(), 7, "Got wrong result."); - - auto rw{tx.exec_prepared1("EchoNum", 8)}; - PQXX_CHECK_EQUAL( - std::size(rw), 1, "Did not get 1 column from exec_prepared1."); - PQXX_CHECK_EQUAL(rw[0].as(), 8, "Got wrong result."); -} - - -void test_multiple_params() -{ - pqxx::connection c; - c.prepare("CountSeries", "SELECT * FROM generate_series($1::int, $2::int)"); - pqxx::work tx{c}; - auto r{tx.exec_prepared_n(4, "CountSeries", 7, 10)}; - PQXX_CHECK_EQUAL( - std::size(r), 4, "Wrong number of rows, but no error raised."); - PQXX_CHECK_EQUAL(r.front().front().as(), 7, "Wrong $1."); - PQXX_CHECK_EQUAL(r.back().front().as(), 10, "Wrong $2."); - - c.prepare("Reversed", "SELECT * FROM generate_series($2::int, $1::int)"); - r = tx.exec_prepared_n(3, "Reversed", 8, 6); - PQXX_CHECK_EQUAL( - r.front().front().as(), 6, "Did parameters get reordered?"); - PQXX_CHECK_EQUAL( - r.back().front().as(), 8, "$2 did not come through properly."); -} - - -void test_nulls() -{ - pqxx::connection c; - pqxx::work tx{c}; - c.prepare("EchoStr", "SELECT $1::varchar"); - auto rw{tx.exec_prepared1("EchoStr", nullptr)}; - PQXX_CHECK(rw.front().is_null(), "nullptr did not translate to null."); - - char const *n{nullptr}; - rw = tx.exec_prepared1("EchoStr", n); - PQXX_CHECK(rw.front().is_null(), "Null pointer did not translate to null."); -} - - -void test_strings() -{ - pqxx::connection c; - pqxx::work tx{c}; - c.prepare("EchoStr", "SELECT $1::varchar"); - auto rw{tx.exec_prepared1("EchoStr", "foo")}; - PQXX_CHECK_EQUAL( - rw.front().as(), "foo", "Wrong string result."); - - char const nasty_string[]{R"--('\"\)--"}; - rw = tx.exec_prepared1("EchoStr", nasty_string); - PQXX_CHECK_EQUAL( - rw.front().as(), std::string(nasty_string), - "Prepared statement did not quote/escape correctly."); - - rw = tx.exec_prepared1("EchoStr", std::string{nasty_string}); - PQXX_CHECK_EQUAL( - rw.front().as(), std::string(nasty_string), - "Quoting/escaping went wrong in std::string."); - - char nonconst[]{"non-const C string"}; - rw = tx.exec_prepared1("EchoStr", nonconst); - PQXX_CHECK_EQUAL( - rw.front().as(), std::string(nonconst), - "Non-const C string passed incorrectly."); -} - - -void test_binary() -{ - pqxx::connection c; - pqxx::work tx{c}; - c.prepare("EchoBin", "SELECT $1::bytea"); - constexpr char raw_bytes[]{"Binary\0bytes'\"with\tweird\xff bytes"}; - std::string const input{raw_bytes, std::size(raw_bytes)}; - -#include "pqxx/internal/ignore-deprecated-pre.hxx" - { - pqxx::binarystring const bin{input}; - auto rw{tx.exec_prepared1("EchoBin", bin)}; - PQXX_CHECK_EQUAL( - pqxx::binarystring(rw[0]).str(), input, - "Binary string came out damaged."); - } -#include "pqxx/internal/ignore-deprecated-post.hxx" - - { - std::basic_string bytes{ - reinterpret_cast(raw_bytes), std::size(raw_bytes)}; - auto bp{tx.exec_prepared1("EchoBin", bytes)}; - auto bval{bp[0].as>()}; - PQXX_CHECK_EQUAL( - (std::string_view{ - reinterpret_cast(bval.c_str()), std::size(bval)}), - input, "Binary string parameter went wrong."); - } - - // Now try it with a complex type that ultimately uses the conversions of - // std::basic_string, but complex enough that the call may - // convert the data to a text string on the libpqxx side. Which would be - // okay, except of course it's likely to be slower. - - { - auto ptr{std::make_shared>( - reinterpret_cast(raw_bytes), std::size(raw_bytes))}; - auto rp{tx.exec_prepared1("EchoBin", ptr)}; - auto pval{rp[0].as>()}; - PQXX_CHECK_EQUAL( - (std::string_view{ - reinterpret_cast(pval.c_str()), std::size(pval)}), - input, "Binary string as shared_ptr-to-optional went wrong."); - } - - { - auto opt{std::optional>{ - std::in_place, reinterpret_cast(raw_bytes), - std::size(raw_bytes)}}; - auto op{tx.exec_prepared1("EchoBin", opt)}; - auto oval{op[0].as>()}; - PQXX_CHECK_EQUAL( - (std::string_view{ - reinterpret_cast(oval.c_str()), std::size(oval)}), - input, "Binary string as shared_ptr-to-optional went wrong."); - } - -#if defined(PQXX_HAVE_CONCEPTS) - // By the way, it doesn't have to be a std::basic_string. Any contiguous - // range will do. - { - std::vector data{std::byte{'x'}, std::byte{'v'}}; - auto op{tx.exec_prepared1("EchoBin", data)}; - auto oval{op[0].as>()}; - PQXX_CHECK_EQUAL( - std::size(oval), 2u, "Binary data came back as wrong length."); - PQXX_CHECK_EQUAL(static_cast(oval[0]), int('x'), "Wrong data."); - PQXX_CHECK_EQUAL(static_cast(oval[1]), int('v'), "Wrong data."); - } -#endif -} - - -void test_params() -{ - pqxx::connection c; - pqxx::work tx{c}; - c.prepare("Concat2Numbers", "SELECT 10 * $1 + $2"); - std::vector values{3, 9}; - pqxx::params params; - params.reserve(std::size(values)); - params.append_multi(values); - - auto const rw39{tx.exec_prepared1("Concat2Numbers", params)}; - PQXX_CHECK_EQUAL( - rw39.front().as(), 39, - "Dynamic prepared-statement parameters went wrong."); - - c.prepare("Concat4Numbers", "SELECT 1000*$1 + 100*$2 + 10*$3 + $4"); - auto const rw1396{tx.exec_prepared1("Concat4Numbers", 1, params, 6)}; - PQXX_CHECK_EQUAL( - rw1396.front().as(), 1396, - "Dynamic params did not interleave with static ones properly."); -} - - -void test_optional() -{ - pqxx::connection c; - pqxx::work tx{c}; - c.prepare("EchoNum", "SELECT $1::int"); - pqxx::row rw{ - tx.exec_prepared1("EchoNum", std::optional{std::in_place, 10})}; - PQXX_CHECK_EQUAL( - rw.front().as(), 10, - "optional (with value) did not return the right value."); - - rw = tx.exec_prepared1("EchoNum", std::optional{}); - PQXX_CHECK( - rw.front().is_null(), "optional without value did not come out as null."); -} - - -void test_prepared_statements() -{ - test_registration_and_invocation(); - test_basic_args(); - test_multiple_params(); - test_nulls(); - test_strings(); - test_binary(); - test_params(); - - test_optional(); -} - - -void test_placeholders_generates_names() -{ - using pqxx::operator""_zv; - pqxx::placeholders name; - PQXX_CHECK_EQUAL(name.view(), "$1"_zv, "Bad placeholders initial zview."); - PQXX_CHECK_EQUAL(name.view(), "$1"sv, "Bad placeholders string_view."); - PQXX_CHECK_EQUAL(name.get(), "$1", "Bad placeholders::get()."); - - name.next(); - PQXX_CHECK_EQUAL(name.view(), "$2"_zv, "Incorrect placeholders::next()."); - - name.next(); - PQXX_CHECK_EQUAL(name.view(), "$3"_zv, "Incorrect placeholders::next()."); - name.next(); - PQXX_CHECK_EQUAL(name.view(), "$4"_zv, "Incorrect placeholders::next()."); - name.next(); - PQXX_CHECK_EQUAL(name.view(), "$5"_zv, "Incorrect placeholders::next()."); - name.next(); - PQXX_CHECK_EQUAL(name.view(), "$6"_zv, "Incorrect placeholders::next()."); - name.next(); - PQXX_CHECK_EQUAL(name.view(), "$7"_zv, "Incorrect placeholders::next()."); - name.next(); - PQXX_CHECK_EQUAL(name.view(), "$8"_zv, "Incorrect placeholders::next()."); - name.next(); - PQXX_CHECK_EQUAL(name.view(), "$9"_zv, "Incorrect placeholders::next()."); - name.next(); - PQXX_CHECK_EQUAL(name.view(), "$10"_zv, "Incorrect placeholders carry."); - name.next(); - PQXX_CHECK_EQUAL(name.view(), "$11"_zv, "Incorrect placeholders 11."); - - while (name.count() < 999) name.next(); - PQXX_CHECK_EQUAL(name.view(), "$999"_zv, "Incorrect placeholders 999."); - name.next(); - PQXX_CHECK_EQUAL(name.view(), "$1000"_zv, "Incorrect large placeholder."); -} - - -PQXX_REGISTER_TEST(test_prepared_statements); -PQXX_REGISTER_TEST(test_placeholders_generates_names); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_range.cxx b/ext/libpqxx-7.7.3/test/unit/test_range.cxx deleted file mode 100644 index b40d9b043..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_range.cxx +++ /dev/null @@ -1,555 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - - -namespace -{ -void test_range_construct() -{ - using optint = std::optional; - using oibound = pqxx::inclusive_bound>; - using oxbound = pqxx::inclusive_bound>; - PQXX_CHECK_THROWS( - (pqxx::range{oibound{optint{}}, oibound{optint{}}}), - pqxx::argument_error, "Inclusive bound accepted a null."); - PQXX_CHECK_THROWS( - (pqxx::range{oxbound{optint{}}, oxbound{optint{}}}), - pqxx::argument_error, "Exclusive bound accepted a null."); - - using ibound = pqxx::inclusive_bound; - PQXX_CHECK_THROWS( - (pqxx::range{ibound{1}, ibound{0}}), pqxx::range_error, - "Range constructor accepted backwards range."); - - PQXX_CHECK_THROWS( - (pqxx::range{ - pqxx::inclusive_bound{-1000.0}, - pqxx::inclusive_bound{-std::numeric_limits::infinity()}}), - pqxx::range_error, - "Was able to construct range with infinity bound at the wrong end."); -} - - -void test_range_equality() -{ - using range = pqxx::range; - using ibound = pqxx::inclusive_bound; - using xbound = pqxx::exclusive_bound; - using ubound = pqxx::no_bound; - - PQXX_CHECK_EQUAL( - range{}, range{}, "Default-constructed range is not consistent."); - PQXX_CHECK_EQUAL( - (range{xbound{0}, xbound{0}}), (range{xbound{5}, xbound{5}}), - "Empty ranges at different values are not equal."); - - PQXX_CHECK_EQUAL( - (range{ubound{}, ubound{}}), (range{ubound{}, ubound{}}), - "Universal range is inconsistent."); - PQXX_CHECK_EQUAL( - (range{ibound{5}, ibound{8}}), (range{ibound{5}, ibound{8}}), - "Inclusive range is inconsistent."); - PQXX_CHECK_EQUAL( - (range{xbound{5}, xbound{8}}), (range{xbound{5}, xbound{8}}), - "Exclusive range is inconsistent."); - PQXX_CHECK_EQUAL( - (range{xbound{5}, ibound{8}}), (range{xbound{5}, ibound{8}}), - "Left-exclusive interval is not equal to itself."); - PQXX_CHECK_EQUAL( - (range{ibound{5}, xbound{8}}), (range{ibound{5}, xbound{8}}), - "Right-exclusive interval is not equal to itself."); - PQXX_CHECK_EQUAL( - (range{ubound{}, ibound{8}}), (range{ubound{}, ibound{8}}), - "Unlimited lower bound does not compare equal to same."); - PQXX_CHECK_EQUAL( - (range{ibound{8}, ubound{}}), (range{ibound{8}, ubound{}}), - "Unlimited upper bound does not compare equal to same."); - - PQXX_CHECK_NOT_EQUAL( - (range{ibound{5}, ibound{8}}), (range{xbound{5}, ibound{8}}), - "Equality does not detect inclusive vs. exclusive lower bound."); - PQXX_CHECK_NOT_EQUAL( - (range{ibound{5}, ibound{8}}), (range{ubound{}, ibound{8}}), - "Equality does not detect inclusive vs. unlimited lower bound."); - PQXX_CHECK_NOT_EQUAL( - (range{xbound{5}, ibound{8}}), (range{ubound{}, ibound{8}}), - "Equality does not detect exclusive vs. unlimited lower bound."); - PQXX_CHECK_NOT_EQUAL( - (range{ibound{5}, ibound{8}}), (range{ibound{5}, xbound{8}}), - "Equality does not detect inclusive vs. exclusive upper bound."); - PQXX_CHECK_NOT_EQUAL( - (range{ibound{5}, ibound{8}}), (range{ibound{5}, ubound{}}), - "Equality does not detect inclusive vs. unlimited upper bound."); - PQXX_CHECK_NOT_EQUAL( - (range{ibound{5}, xbound{8}}), (range{ibound{5}, ubound{}}), - "Equality does not detect exclusive vs. unlimited upper bound."); - - PQXX_CHECK_NOT_EQUAL( - (range{ibound{5}, ibound{8}}), (range{ibound{4}, ibound{8}}), - "Equality does not compare lower inclusive bound value."); - PQXX_CHECK_NOT_EQUAL( - (range{xbound{5}, ibound{8}}), (range{xbound{4}, ibound{8}}), - "Equality does not compare lower exclusive bound value."); - PQXX_CHECK_NOT_EQUAL( - (range{xbound{5}, ibound{8}}), (range{xbound{5}, ibound{7}}), - "Equality does not compare upper inclusive bound value."); - PQXX_CHECK_NOT_EQUAL( - (range{xbound{5}, xbound{8}}), (range{xbound{5}, xbound{7}}), - "Equality does not compare lower exclusive bound value."); -} - - -void test_range_empty() -{ - using range = pqxx::range; - using ibound = pqxx::inclusive_bound; - using xbound = pqxx::exclusive_bound; - using ubound = pqxx::no_bound; - PQXX_CHECK((range{}.empty()), "Default-constructed range is not empty."); - PQXX_CHECK( - (range{ibound{10}, xbound{10}}).empty(), - "Right-exclusive zero-length interval is not empty."); - PQXX_CHECK( - (range{xbound{10}, ibound{10}}).empty(), - "Left-exclusive zero-length interval is not empty."); - PQXX_CHECK( - (range{xbound{10}, xbound{10}}).empty(), - "Exclusive zero-length interval is not empty."); - - PQXX_CHECK( - not(range{ibound{10}, ibound{10}}).empty(), - "Inclusive zero-length interval is empty."); - PQXX_CHECK( - not(range{xbound{10}, ibound{11}}.empty()), - "Interval is incorrectly empty."); - PQXX_CHECK( - not(range{ubound{}, ubound{}}.empty()), - "Double-unlimited interval is empty."); - PQXX_CHECK( - not(range{ubound{}, xbound{0}}.empty()), - "Left-unlimited interval is empty."); - PQXX_CHECK( - not(range{xbound{0}, ubound{}}.empty()), - "Right-unlimited interval is empty."); -} - - -void test_range_contains() -{ - using range = pqxx::range; - using ibound = pqxx::inclusive_bound; - using xbound = pqxx::exclusive_bound; - using ubound = pqxx::no_bound; - - PQXX_CHECK(not(range{}.contains(-1)), "Empty range contains a value."); - PQXX_CHECK(not(range{}.contains(0)), "Empty range contains a value."); - PQXX_CHECK(not(range{}.contains(1)), "Empty range contains a value."); - - PQXX_CHECK( - not(range{ibound{5}, ibound{8}}.contains(4)), - "Inclusive range contains value outside its left bound."); - PQXX_CHECK( - (range{ibound{5}, ibound{8}}.contains(5)), - "Inclusive range does not contain value on its left bound."); - PQXX_CHECK( - (range{ibound{5}, ibound{8}}.contains(6)), - "Inclusive range does not contain value inside it."); - PQXX_CHECK( - (range{ibound{5}, ibound{8}}.contains(8)), - "Inclusive range does not contain value on its right bound."); - PQXX_CHECK( - not(range{ibound{5}, ibound{8}}.contains(9)), - "Inclusive range contains value outside its right bound."); - - PQXX_CHECK( - not(range{ibound{5}, xbound{8}}.contains(4)), - "Left-inclusive range contains value outside its left bound."); - PQXX_CHECK( - (range{ibound{5}, xbound{8}}.contains(5)), - "Left-inclusive range does not contain value on its left bound."); - PQXX_CHECK( - (range{ibound{5}, xbound{8}}.contains(6)), - "Left-inclusive range does not contain value inside it."); - PQXX_CHECK( - not(range{ibound{5}, xbound{8}}.contains(8)), - "Left-inclusive range contains value on its right bound."); - PQXX_CHECK( - not(range{ibound{5}, xbound{8}}.contains(9)), - "Left-inclusive range contains value outside its right bound."); - - PQXX_CHECK( - not(range{xbound{5}, ibound{8}}.contains(4)), - "Right-inclusive range contains value outside its left bound."); - PQXX_CHECK( - not(range{xbound{5}, ibound{8}}.contains(5)), - "Right-inclusive range does contains value on its left bound."); - PQXX_CHECK( - (range{xbound{5}, ibound{8}}.contains(6)), - "Right-inclusive range does not contain value inside it."); - PQXX_CHECK( - (range{xbound{5}, ibound{8}}.contains(8)), - "Right-inclusive range does not contain value on its right bound."); - PQXX_CHECK( - not(range{xbound{5}, ibound{8}}.contains(9)), - "Right-inclusive range contains value outside its right bound."); - - PQXX_CHECK( - not(range{xbound{5}, xbound{8}}.contains(4)), - "Exclusive range contains value outside its left bound."); - PQXX_CHECK( - not(range{xbound{5}, xbound{8}}.contains(5)), - "Exclusive range contains value on its left bound."); - PQXX_CHECK( - (range{xbound{5}, xbound{8}}.contains(6)), - "Exclusive range does not contain value inside it."); - PQXX_CHECK( - not(range{xbound{5}, xbound{8}}.contains(8)), - "Exclusive range does contains value on its right bound."); - PQXX_CHECK( - not(range{xbound{5}, xbound{8}}.contains(9)), - "Exclusive range contains value outside its right bound."); - - PQXX_CHECK( - (range{ubound{}, ibound{8}}.contains(7)), - "Right-inclusive range does not contain value inside it."); - PQXX_CHECK( - (range{ubound{}, ibound{8}}.contains(8)), - "Right-inclusive range does not contain value on its right bound."); - PQXX_CHECK( - not(range{ubound{}, ibound{8}}.contains(9)), - "Right-inclusive range contains value outside its right bound."); - - PQXX_CHECK( - (range{ubound{}, xbound{8}}.contains(7)), - "Right-exclusive range does not contain value inside it."); - PQXX_CHECK( - not(range{ubound{}, xbound{8}}.contains(8)), - "Right-exclusive range contains value on its right bound."); - PQXX_CHECK( - not(range{ubound{}, xbound{8}}.contains(9)), - "Right-exclusive range contains value outside its right bound."); - - PQXX_CHECK( - not(range{ibound{5}, ubound{}}.contains(4)), - "Left-inclusive range contains value outside its left bound."); - PQXX_CHECK( - (range{ibound{5}, ubound{}}.contains(5)), - "Left-inclusive range does not contain value on its left bound."); - PQXX_CHECK( - (range{ibound{5}, ubound{}}.contains(6)), - "Left-inclusive range does not contain value inside it."); - - PQXX_CHECK( - not(range{xbound{5}, ubound{}}.contains(4)), - "Left-exclusive range contains value outside its left bound."); - PQXX_CHECK( - not(range{xbound{5}, ubound{}}.contains(5)), - "Left-exclusive range contains value on its left bound."); - PQXX_CHECK( - (range{xbound{5}, ubound{}}.contains(6)), - "Left-exclusive range does not contain value inside it."); - - PQXX_CHECK( - (range{ubound{}, ubound{}}.contains(-1)), "Value not in universal range."); - PQXX_CHECK( - (range{ubound{}, ubound{}}.contains(0)), "Value not in universal range."); - PQXX_CHECK( - (range{ubound{}, ubound{}}.contains(1)), "Value not in universal range."); -} - - -void test_float_range_contains() -{ - using range = pqxx::range; - using ibound = pqxx::inclusive_bound; - using xbound = pqxx::exclusive_bound; - using ubound = pqxx::no_bound; - using limits = std::numeric_limits; - constexpr auto inf{limits::infinity()}; - - PQXX_CHECK( - not(range{ibound{4.0}, ibound{8.0}}.contains(3.9)), - "Float inclusive range contains value beyond its lower bound."); - PQXX_CHECK( - (range{ibound{4.0}, ibound{8.0}}.contains(4.0)), - "Float inclusive range does not contain its lower bound value."); - PQXX_CHECK( - (range{ibound{4.0}, ibound{8.0}}.contains(5.0)), - "Float inclusive range does not contain value inside it."); - - PQXX_CHECK( - (range{ibound{0}, ibound{inf}}).contains(9999.0), - "Range to infinity did not include large number."); - PQXX_CHECK( - not(range{ibound{0}, ibound{inf}}.contains(-0.1)), - "Range to infinity includes number outside it."); - PQXX_CHECK( - (range{ibound{0}, xbound{inf}}.contains(9999.0)), - "Range to exclusive infinity did not include large number."); - PQXX_CHECK( - (range{ibound{0}, ibound{inf}}).contains(inf), - "Range to inclusive infinity does not include infinity."); - PQXX_CHECK( - not(range{ibound{0}, xbound{inf}}.contains(inf)), - "Range to exclusive infinity includes infinity."); - PQXX_CHECK( - (range{ibound{0}, ubound{}}).contains(inf), - "Right-unlimited range does not include infinity."); - - PQXX_CHECK( - (range{ibound{-inf}, ibound{0}}).contains(-9999.0), - "Range from infinity did not include large negative number."); - PQXX_CHECK( - not(range{ibound{-inf}, ibound{0}}.contains(0.1)), - "Range from infinity includes number outside it."); - PQXX_CHECK( - (range{xbound{-inf}, ibound{0}}).contains(-9999.0), - "Range from exclusive infinity did not include large negative number."); - PQXX_CHECK( - (range{ibound{-inf}, ibound{0}}).contains(-inf), - "Range from inclusive infinity does not include negative infinity."); - PQXX_CHECK( - not(range{xbound{-inf}, ibound{0}}).contains(-inf), - "Range to infinity exclusive includes negative infinity."); - PQXX_CHECK( - (range{ubound{}, ibound{0}}).contains(-inf), - "Left-unlimited range does not include negative infinity."); -} - - -void test_range_subset() -{ - using range = pqxx::range; - using traits = pqxx::string_traits; - - std::string_view subsets[][2]{ - {"empty", "empty"}, {"(,)", "empty"}, {"(0,1)", "empty"}, - {"(,)", "[-10,10]"}, {"(,)", "(-10,10)"}, {"(,)", "(,)"}, - {"(,10)", "(,10)"}, {"(,10)", "(,9)"}, {"(,10]", "(,10)"}, - {"(,10]", "(,10]"}, {"(1,)", "(10,)"}, {"(1,)", "(9,)"}, - {"[1,)", "(10,)"}, {"[1,)", "[10,)"}, {"[0,5]", "[1,4]"}, - {"(0,5)", "[1,4]"}, - }; - for (auto const [super, sub] : subsets) - PQXX_CHECK( - traits::from_string(super).contains(traits::from_string(sub)), - pqxx::internal::concat( - "Range '", super, "' did not contain '", sub, "'.")); - - std::string_view non_subsets[][2]{ - {"empty", "[0,0]"}, {"empty", "(,)"}, {"[-10,10]", "(,)"}, - {"(-10,10)", "(,)"}, {"(,9)", "(,10)"}, {"(,10)", "(,10]"}, - {"[1,4]", "[0,4]"}, {"[1,4]", "[1,5]"}, {"(0,10)", "[0,10]"}, - {"(0,10)", "(0,10]"}, {"(0,10)", "[0,10)"}, - }; - for (auto const [super, sub] : non_subsets) - PQXX_CHECK( - not traits::from_string(super).contains(traits::from_string(sub)), - pqxx::internal::concat("Range '", super, "' contained '", sub, "'.")); -} - - -void test_range_to_string() -{ - using range = pqxx::range; - using ibound = pqxx::inclusive_bound; - using xbound = pqxx::exclusive_bound; - using ubound = pqxx::no_bound; - - PQXX_CHECK_EQUAL( - pqxx::to_string(range{}), "empty", "Empty range came out wrong."); - - PQXX_CHECK_EQUAL( - pqxx::to_string(range{ibound{5}, ibound{8}}), "[5,8]", - "Inclusive range came out wrong."); - PQXX_CHECK_EQUAL( - pqxx::to_string(range{xbound{5}, ibound{8}}), "(5,8]", - "Left-exclusive range came out wrong."); - PQXX_CHECK_EQUAL( - pqxx::to_string(range{ibound{5}, xbound{8}}), "[5,8)", - "Right-exclusive range came out wrong."); - PQXX_CHECK_EQUAL( - pqxx::to_string(range{xbound{5}, xbound{8}}), "(5,8)", - "Exclusive range came out wrong."); - - // Unlimited boundaries can use brackets or parentheses. Doesn't matter. - // We cheat and use some white-box knowledge of our implementation here. - PQXX_CHECK_EQUAL( - pqxx::to_string(range{ubound{}, ubound{}}), "(,)", - "Universal range came out unexpected."); - PQXX_CHECK_EQUAL( - pqxx::to_string(range{ubound{}, ibound{8}}), "(,8]", - "Left-unlimited range came out unexpected."); - PQXX_CHECK_EQUAL( - pqxx::to_string(range{ubound{}, xbound{8}}), "(,8)", - "Left-unlimited range came out unexpected."); - PQXX_CHECK_EQUAL( - pqxx::to_string(range{ibound{5}, ubound{}}), "[5,)", - "Right-unlimited range came out unexpected."); - PQXX_CHECK_EQUAL( - pqxx::to_string(range{xbound{5}, ubound{}}), "(5,)", - "Right-unlimited range came out unexpected."); -} - - -void test_parse_range() -{ - using range = pqxx::range; - using ubound = pqxx::no_bound; - using traits = pqxx::string_traits; - - constexpr std::string_view empties[]{"empty", "EMPTY", "eMpTy"}; - for (auto empty : empties) - PQXX_CHECK( - traits::from_string(empty).empty(), - pqxx::internal::concat( - "This was supposed to produce an empty range: '", empty, "'")); - - constexpr std::string_view universals[]{"(,)", "[,)", "(,]", "[,]"}; - for (auto univ : universals) - PQXX_CHECK_EQUAL( - traits::from_string(univ), (range{ubound{}, ubound{}}), - pqxx::internal::concat( - "This was supposed to produce a universal range: '", univ, "'")); - - PQXX_CHECK( - traits::from_string("(0,10]").lower_bound().is_exclusive(), - "Exclusive lower bound did not parse right."); - PQXX_CHECK( - traits::from_string("[0,10]").lower_bound().is_inclusive(), - "Inclusive lower bound did not parse right."); - PQXX_CHECK( - traits::from_string("(0,10)").upper_bound().is_exclusive(), - "Exclusive upper bound did not parse right."); - PQXX_CHECK( - traits::from_string("[0,10]").upper_bound().is_inclusive(), - "Inclusive upper bound did not parse right."); - - PQXX_CHECK_EQUAL( - *traits::from_string("(\"0\",\"10\")").lower_bound().value(), 0, - "Quoted range boundary did not parse right."); - PQXX_CHECK_EQUAL( - *traits::from_string("(\"0\",\"10\")").upper_bound().value(), 10, - "Quoted upper boundary did not parse right."); - - auto floats{ - pqxx::string_traits>::from_string("(0,1.0)")}; - PQXX_CHECK_GREATER( - *floats.lower_bound().value(), -0.001, - "Float lower bound is out of range."); - PQXX_CHECK_LESS( - *floats.lower_bound().value(), 0.001, - "Float lower bound is out of range."); - PQXX_CHECK_GREATER( - *floats.upper_bound().value(), 0.999, - "Float upper bound is out of range."); - PQXX_CHECK_LESS( - *floats.upper_bound().value(), 1.001, - "Float upper bound is out of range."); -} - - -void test_parse_bad_range() -{ - using range = pqxx::range; - using conv_err = pqxx::conversion_error; - using traits = pqxx::string_traits; - constexpr std::string_view bad_ranges[]{ - "", "x", "e", "empt", "emptyy", "()", - "[]", "(empty)", "(empty, 0)", "(0, empty)", ",", "(,", - ",)", "(1,2,3)", "(4,5x)", "(null, 0)", "[0, 1.0]", "[1.0, 0]", - }; - - for (auto bad : bad_ranges) - PQXX_CHECK_THROWS( - pqxx::ignore_unused(traits::from_string(bad)), conv_err, - pqxx::internal::concat( - "This range wasn't supposed to parse: '", bad, "'")); -} - - -/// Parse ranges lhs and rhs, return their intersection as a string. -template -std::string intersect(std::string_view lhs, std::string_view rhs) -{ - using traits = pqxx::string_traits>; - return pqxx::to_string(traits::from_string(lhs) & traits::from_string(rhs)); -} - - -void test_range_intersection() -{ - // Intersections and their expected results, in text form. - // Each row contains two ranges, and their intersection. - std::string_view intersections[][3]{ - {"empty", "empty", "empty"}, - {"(,)", "empty", "empty"}, - {"[,]", "empty", "empty"}, - {"empty", "[0,10]", "empty"}, - {"(,)", "(,)", "(,)"}, - {"(,)", "(5,8)", "(5,8)"}, - {"(,)", "[5,8)", "[5,8)"}, - {"(,)", "(5,8]", "(5,8]"}, - {"(,)", "[5,8]", "[5,8]"}, - {"(-1000,10)", "(0,1000)", "(0,10)"}, - {"[-1000,10)", "(0,1000)", "(0,10)"}, - {"(-1000,10]", "(0,1000)", "(0,10]"}, - {"[-1000,10]", "(0,1000)", "(0,10]"}, - {"[0,100]", "[0,100]", "[0,100]"}, - {"[0,100]", "[0,100)", "[0,100)"}, - {"[0,100]", "(0,100]", "(0,100]"}, - {"[0,100]", "(0,100)", "(0,100)"}, - {"[0,10]", "[11,20]", "empty"}, - {"[0,10]", "(11,20]", "empty"}, - {"[0,10]", "[11,20)", "empty"}, - {"[0,10]", "(11,20)", "empty"}, - {"[0,10]", "[10,11]", "[10,10]"}, - {"[0,10)", "[10,11]", "empty"}, - {"[0,10]", "(10,11]", "empty"}, - {"[0,10)", "(10,11]", "empty"}, - }; - for (auto [left, right, expected] : intersections) - { - PQXX_CHECK_EQUAL( - intersect(left, right), expected, - pqxx::internal::concat( - "Intersection of '", left, "' and '", right, - " produced unexpected result.")); - PQXX_CHECK_EQUAL( - intersect(right, left), expected, - pqxx::internal::concat( - "Intersection of '", left, "' and '", right, " was asymmetric.")); - } -} - - -void test_range_conversion() -{ - std::string_view const ranges[]{ - "empty", "(,)", "(,10)", "(0,)", "[0,10]", "[0,10)", "(0,10]", "(0,10)", - }; - - for (auto r : ranges) - { - auto const shortr{pqxx::from_string>(r)}; - pqxx::range intr{shortr}; - PQXX_CHECK_EQUAL( - pqxx::to_string(intr), r, "Converted range looks different."); - } -} - - -PQXX_REGISTER_TEST(test_range_construct); -PQXX_REGISTER_TEST(test_range_equality); -PQXX_REGISTER_TEST(test_range_empty); -PQXX_REGISTER_TEST(test_range_contains); -PQXX_REGISTER_TEST(test_float_range_contains); -PQXX_REGISTER_TEST(test_range_subset); -PQXX_REGISTER_TEST(test_range_to_string); -PQXX_REGISTER_TEST(test_parse_range); -PQXX_REGISTER_TEST(test_parse_bad_range); -PQXX_REGISTER_TEST(test_range_intersection); -PQXX_REGISTER_TEST(test_range_conversion); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_read_transaction.cxx b/ext/libpqxx-7.7.3/test/unit/test_read_transaction.cxx deleted file mode 100644 index 402f2a06f..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_read_transaction.cxx +++ /dev/null @@ -1,22 +0,0 @@ -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_read_transaction() -{ - pqxx::connection conn; - pqxx::read_transaction tx{conn}; - PQXX_CHECK_EQUAL( - tx.exec("SELECT 1")[0][0].as(), 1, - "Bad result from read transaction."); - - PQXX_CHECK_THROWS( - tx.exec("CREATE TABLE should_not_exist(x integer)"), pqxx::sql_error, - "Read-only transaction allows database to be modified."); -} - - -PQXX_REGISTER_TEST(test_read_transaction); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_result_iteration.cxx b/ext/libpqxx-7.7.3/test/unit/test_result_iteration.cxx deleted file mode 100644 index 3d26e3c3e..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_result_iteration.cxx +++ /dev/null @@ -1,137 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_result_iteration() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::result r{tx.exec("SELECT generate_series(1, 3)")}; - - PQXX_CHECK(std::end(r) != std::begin(r), "Broken begin/end."); - PQXX_CHECK(std::rend(r) != std::rbegin(r), "Broken rbegin/rend."); - - PQXX_CHECK(std::cbegin(r) == std::begin(r), "Wrong cbegin."); - PQXX_CHECK(std::cend(r) == std::end(r), "Wrong cend."); - PQXX_CHECK(std::crbegin(r) == std::rbegin(r), "Wrong crbegin."); - PQXX_CHECK(std::crend(r) == std::rend(r), "Wrong crend."); - - PQXX_CHECK_EQUAL(r.front().front().as(), 1, "Unexpected front()."); - PQXX_CHECK_EQUAL(r.back().front().as(), 3, "Unexpected back()."); -} - - -void test_result_iter() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::result r{tx.exec("SELECT generate_series(1, 3)")}; - - int total{0}; - for (auto const &[i] : r.iter()) total += i; - PQXX_CHECK_EQUAL(total, 6, "iter() loop did not get the right values."); -} - - -void test_result_iterator_swap() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::result r{tx.exec("SELECT generate_series(1, 3)")}; - - auto head{std::begin(r)}, next{head + 1}; - head.swap(next); - PQXX_CHECK_EQUAL(head[0].as(), 2, "Result iterator swap is wrong."); - PQXX_CHECK_EQUAL(next[0].as(), 1, "Result iterator swap is crazy."); - - auto tail{std::rbegin(r)}, prev{tail + 1}; - tail.swap(prev); - PQXX_CHECK_EQUAL(tail[0].as(), 2, "Reverse iterator swap is wrong."); - PQXX_CHECK_EQUAL(prev[0].as(), 3, "Reverse iterator swap is crazy."); -} - - -void test_result_iterator_assignment() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::result r{tx.exec("SELECT generate_series(1, 3)")}; - - pqxx::result::const_iterator fwd; - pqxx::result::const_reverse_iterator rev; - - fwd = std::begin(r); - PQXX_CHECK_EQUAL( - fwd[0].as(), std::begin(r)[0].as(), - "Result iterator assignment is wrong."); - - rev = std::rbegin(r); - PQXX_CHECK_EQUAL( - rev[0].as(), std::rbegin(r)[0].as(), - "Reverse iterator assignment is wrong."); -} - - -void check_employee(std::string name, int salary) -{ - PQXX_CHECK(name == "x" or name == "y" or name == "z", "Unknown name."); - PQXX_CHECK( - salary == 1000 or salary == 1200 or salary == 1500, "Unknown salary."); -} - - -void test_result_for_each() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - tx.exec0("CREATE TEMP TABLE employee(name varchar, salary int)"); - auto fill{pqxx::stream_to::table(tx, {"employee"}, {"name", "salary"})}; - fill.write_values("x", 1000); - fill.write_values("y", 1200); - fill.write_values("z", 1500); - fill.complete(); - - auto const res{tx.exec("SELECT name, salary FROM employee ORDER BY name")}; - - // Use for_each with a function. - res.for_each(check_employee); - - // Use for_each with a simple lambda. - res.for_each( - [](std::string name, int salary) { check_employee(name, salary); }); - - // Use for_each with a lambda closure. - std::string names{}; - int total{0}; - - res.for_each([&names, &total](std::string name, int salary) { - names.append(name); - total += salary; - }); - PQXX_CHECK_EQUAL( - names, "xyz", "result::for_each did not accumulate names correctly."); - PQXX_CHECK_EQUAL(total, 1000 + 1200 + 1500, "Salaries added up wrong."); - - // In addition to regular conversions, you can receive arguments as - // string_view, or as references. - names.clear(); - total = 0; - res.for_each([&names, &total](std::string_view &&name, int const &salary) { - names.append(name); - total += salary; - }); - PQXX_CHECK_EQUAL( - names, "xyz", "result::for_each did not accumulate names correctly."); - PQXX_CHECK_EQUAL(total, 1000 + 1200 + 1500, "Salaries added up wrong."); -} - - -PQXX_REGISTER_TEST(test_result_iteration); -PQXX_REGISTER_TEST(test_result_iter); -PQXX_REGISTER_TEST(test_result_iterator_swap); -PQXX_REGISTER_TEST(test_result_iterator_assignment); -PQXX_REGISTER_TEST(test_result_for_each); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_result_slicing.cxx b/ext/libpqxx-7.7.3/test/unit/test_result_slicing.cxx deleted file mode 100644 index be2055ee3..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_result_slicing.cxx +++ /dev/null @@ -1,157 +0,0 @@ -#include - -#include "../test_helpers.hxx" - -#include "pqxx/internal/ignore-deprecated-pre.hxx" - -namespace pqxx -{ -template<> struct nullness : no_null -{}; - -template<> -struct nullness - : no_null -{}; - - -template<> struct string_traits -{ - static constexpr zview text{"[row::const_iterator]"}; - static zview to_buf(char *, char *, row::const_iterator const &) - { - return text; - } - static char *into_buf(char *begin, char *end, row::const_iterator const &) - { - if ((end - begin) <= 30) - throw conversion_overrun{"Not enough buffer for const row iterator."}; - std::memcpy(begin, text.c_str(), std::size(text) + 1); - return begin + std::size(text); - } - static constexpr std::size_t - size_buffer(row::const_iterator const &) noexcept - { - return std::size(text) + 1; - } -}; - - -template<> struct string_traits -{ - static constexpr zview text{"[row::const_reverse_iterator]"}; - static pqxx::zview - to_buf(char *, char *, row::const_reverse_iterator const &) - { - return text; - } - static char * - into_buf(char *begin, char *end, row::const_reverse_iterator const &) - { - if ((end - begin) <= 30) - throw conversion_overrun{"Not enough buffer for const row iterator."}; - std::memcpy(begin, text.c_str(), std::size(text) + 1); - return begin + std::size(text); - } - static constexpr std::size_t - size_buffer(row::const_reverse_iterator const &) noexcept - { - return 100; - } -}; -} // namespace pqxx - -namespace -{ -void test_result_slicing() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - auto r{tx.exec("SELECT 1")}; - - PQXX_CHECK(not std::empty(r[0]), "A plain row shows up as empty."); - - // Empty slice at beginning of row. - pqxx::row s{r[0].slice(0, 0)}; - PQXX_CHECK(std::empty(s), "Empty slice does not show up as empty."); - PQXX_CHECK_EQUAL(std::size(s), 0, "Slicing produces wrong row size."); - PQXX_CHECK_EQUAL( - std::begin(s), std::end(s), "Slice begin()/end() are broken."); - PQXX_CHECK_EQUAL( - std::rbegin(s), std::rend(s), "Slice rbegin()/rend() are broken."); - - PQXX_CHECK_THROWS(s.at(0), pqxx::range_error, "at() does not throw."); - pqxx::row slice; - PQXX_CHECK_THROWS( - slice = r[0].slice(0, 2), pqxx::range_error, "No range check."); - pqxx::ignore_unused(slice); - PQXX_CHECK_THROWS( - slice = r[0].slice(1, 0), pqxx::range_error, "Can reverse-slice."); - pqxx::ignore_unused(slice); - - // Empty slice at end of row. - s = r[0].slice(1, 1); - PQXX_CHECK(std::empty(s), "empty() is broken."); - PQXX_CHECK_EQUAL(std::size(s), 0, "size() is broken."); - PQXX_CHECK_EQUAL(std::begin(s), std::end(s), "begin()/end() are broken."); - PQXX_CHECK_EQUAL( - std::rbegin(s), std::rend(s), "rbegin()/rend() are broken."); - - PQXX_CHECK_THROWS(s.at(0), pqxx::range_error, "at() is inconsistent."); - - // Slice that matches the entire row. - s = r[0].slice(0, 1); - PQXX_CHECK(not std::empty(s), "Nonempty slice shows up as empty."); - PQXX_CHECK_EQUAL(std::size(s), 1, "size() breaks for non-empty slice."); - PQXX_CHECK_EQUAL(std::begin(s) + 1, std::end(s), "Iteration is broken."); - PQXX_CHECK_EQUAL( - std::rbegin(s) + 1, std::rend(s), "Reverse iteration is broken."); - PQXX_CHECK_EQUAL(s.at(0).as(), 1, "Accessing a slice is broken."); - PQXX_CHECK_EQUAL(s[0].as(), 1, "operator[] is broken."); - PQXX_CHECK_THROWS(s.at(1).as(), pqxx::range_error, "at() is off."); - - // Meaningful slice at beginning of row. - r = tx.exec("SELECT 1, 2, 3"); - s = r[0].slice(0, 1); - PQXX_CHECK(not std::empty(s), "Slicing confuses empty()."); - PQXX_CHECK_THROWS( - s.at(1).as(), pqxx::range_error, "at() does not enforce slice."); - - // Meaningful slice that skips an initial column. - s = r[0].slice(1, 2); - PQXX_CHECK( - not std::empty(s), "Slicing away leading columns confuses empty()."); - PQXX_CHECK_EQUAL(s[0].as(), 2, "Slicing offset is broken."); - PQXX_CHECK_EQUAL( - std::begin(s)->as(), 2, "Iteration uses wrong offset."); - PQXX_CHECK_EQUAL( - std::begin(s) + 1, std::end(s), "Iteration has wrong range."); - PQXX_CHECK_EQUAL( - std::rbegin(s) + 1, std::rend(s), "Reverse iteration has wrong range."); - PQXX_CHECK_THROWS( - s.at(1).as(), pqxx::range_error, "Offset slicing is broken."); - - // Column names in a slice. - r = tx.exec("SELECT 1 AS one, 2 AS two, 3 AS three"); - s = r[0].slice(1, 2); - PQXX_CHECK_EQUAL(s["two"].as(), 2, "Column addressing breaks."); - PQXX_CHECK_THROWS( - pqxx::ignore_unused(s.column_number("one")), pqxx::argument_error, - "Can access column name before slice."); - PQXX_CHECK_THROWS( - pqxx::ignore_unused(s.column_number("three")), pqxx::argument_error, - "Can access column name after slice."); - PQXX_CHECK_EQUAL( - s.column_number("Two"), 0, "Column name is case sensitive."); - - // Identical column names. - r = tx.exec("SELECT 1 AS x, 2 AS x"); - s = r[0].slice(1, 2); - PQXX_CHECK_EQUAL(s["x"].as(), 2, "Identical column names break slice."); -} - - -PQXX_REGISTER_TEST(test_result_slicing); -} // namespace - -#include "pqxx/internal/ignore-deprecated-post.hxx" diff --git a/ext/libpqxx-7.7.3/test/unit/test_row.cxx b/ext/libpqxx-7.7.3/test/unit/test_row.cxx deleted file mode 100644 index 41770e3b1..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_row.cxx +++ /dev/null @@ -1,84 +0,0 @@ -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_row() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::result rows{tx.exec("SELECT 1, 2, 3")}; - pqxx::row r{rows[0]}; - PQXX_CHECK_EQUAL(std::size(r), 3, "Unexpected row size."); - PQXX_CHECK_EQUAL(r.at(0).as(), 1, "Wrong value at index 0."); - PQXX_CHECK(std::begin(r) != std::end(r), "Broken row iteration."); - PQXX_CHECK(std::begin(r) < std::end(r), "Row begin does not precede end."); - PQXX_CHECK(std::cbegin(r) == std::begin(r), "Wrong cbegin."); - PQXX_CHECK(std::cend(r) == std::end(r), "Wrong cend."); - PQXX_CHECK(std::rbegin(r) != std::rend(r), "Broken reverse row iteration."); - PQXX_CHECK(std::crbegin(r) == std::rbegin(r), "Wrong crbegin."); - PQXX_CHECK(std::crend(r) == std::rend(r), "Wrong crend."); - PQXX_CHECK_EQUAL(r.front().as(), 1, "Wrong row front()."); - PQXX_CHECK_EQUAL(r.back().as(), 3, "Wrong row back()."); -} - - -void test_row_iterator() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::result rows{tx.exec("SELECT 1, 2, 3")}; - - auto i{std::begin(rows[0])}; - PQXX_CHECK_EQUAL(i->as(), 1, "Row iterator is wrong."); - auto i2{i}; - PQXX_CHECK_EQUAL(i2->as(), 1, "Row iterator copy is wrong."); - i2++; - PQXX_CHECK_EQUAL(i2->as(), 2, "Row iterator increment is wrong."); - pqxx::row::const_iterator i3; - i3 = i2; - PQXX_CHECK_EQUAL(i3->as(), 2, "Row iterator assignment is wrong."); - - auto r{std::rbegin(rows[0])}; - PQXX_CHECK_EQUAL(r->as(), 3, "Row reverse iterator is wrong."); - auto r2{r}; - PQXX_CHECK_EQUAL(r2->as(), 3, "Row reverse iterator copy is wrong."); - r2++; - PQXX_CHECK_EQUAL( - r2->as(), 2, "Row reverse iterator increment is wrong."); - pqxx::row::const_reverse_iterator r3; - r3 = r2; - PQXX_CHECK_EQUAL( - i3->as(), 2, "Row reverse iterator assignment is wrong."); -} - - -void test_row_as() -{ - using pqxx::operator"" _zv; - - pqxx::connection conn; - pqxx::work tx{conn}; - - pqxx::row const r{tx.exec1("SELECT 1, 2, 3")}; - auto [one, two, three]{r.as()}; - static_assert(std::is_same_v); - static_assert(std::is_same_v); - static_assert(std::is_same_v); - PQXX_CHECK_EQUAL(one, 1, "row::as() did not produce the right int."); - PQXX_CHECK_GREATER(two, 1.9, "row::as() did not produce the right float."); - PQXX_CHECK_LESS(two, 2.1, "row::as() did not produce the right float."); - PQXX_CHECK_EQUAL( - three, "3"_zv, "row::as() did not produce the right zview."); - - PQXX_CHECK_EQUAL( - std::get<0>(tx.exec1("SELECT 999").as()), 999, - "Unary tuple did not extract right."); -} - - -PQXX_REGISTER_TEST(test_row); -PQXX_REGISTER_TEST(test_row_iterator); -PQXX_REGISTER_TEST(test_row_as); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_separated_list.cxx b/ext/libpqxx-7.7.3/test/unit/test_separated_list.cxx deleted file mode 100644 index 748379b47..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_separated_list.cxx +++ /dev/null @@ -1,33 +0,0 @@ -#include - -#include "../test_helpers.hxx" - -// Test program for separated_list. - -namespace -{ -void test_separated_list() -{ - PQXX_CHECK_EQUAL( - pqxx::separated_list(",", std::vector{}), "", - "Empty list came out wrong."); - - PQXX_CHECK_EQUAL( - pqxx::separated_list(",", std::vector{5}), "5", - "Single-element list came out wrong."); - - PQXX_CHECK_EQUAL( - pqxx::separated_list(",", std::vector{3, 6}), "3,6", - "Things go wrong once separators come in."); - - std::vector const nums{1, 2, 3}; - PQXX_CHECK_EQUAL( - pqxx::separated_list( - "+", std::begin(nums), std::end(nums), - [](auto elt) { return *elt * 2; }), - "2+4+6", "Accessors don't seem to work."); -} - - -PQXX_REGISTER_TEST(test_separated_list); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_simultaneous_transactions.cxx b/ext/libpqxx-7.7.3/test/unit/test_simultaneous_transactions.cxx deleted file mode 100644 index 9c1e2fe9c..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_simultaneous_transactions.cxx +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_simultaneous_transactions() -{ - pqxx::connection conn; - - pqxx::nontransaction n1{conn}; - PQXX_CHECK_THROWS( - pqxx::nontransaction n2{conn}, std::logic_error, - "Allowed to open simultaneous nontransactions."); -} - - -PQXX_REGISTER_TEST(test_simultaneous_transactions); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_sql_cursor.cxx b/ext/libpqxx-7.7.3/test/unit/test_sql_cursor.cxx deleted file mode 100644 index a0109a00b..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_sql_cursor.cxx +++ /dev/null @@ -1,270 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_forward_sql_cursor() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - - // Plain owned, scoped, forward-only read-only cursor. - pqxx::internal::sql_cursor forward( - tx, "SELECT generate_series(1, 4)", "forward", - pqxx::cursor_base::forward_only, pqxx::cursor_base::read_only, - pqxx::cursor_base::owned, false); - - PQXX_CHECK_EQUAL(forward.pos(), 0, "Wrong initial position"); - PQXX_CHECK_EQUAL(forward.endpos(), -1, "Wrong initial endpos()"); - - auto empty_result{forward.empty_result()}; - PQXX_CHECK_EQUAL(std::size(empty_result), 0, "Empty result not empty"); - - auto displacement{0}; - auto one{forward.fetch(1, displacement)}; - PQXX_CHECK_EQUAL(std::size(one), 1, "Fetched wrong number of rows"); - PQXX_CHECK_EQUAL(one[0][0].as(), "1", "Unexpected result"); - PQXX_CHECK_EQUAL(displacement, 1, "Wrong displacement"); - PQXX_CHECK_EQUAL(forward.pos(), 1, "In wrong position"); - - auto offset{forward.move(1, displacement)}; - PQXX_CHECK_EQUAL(offset, 1, "Unexpected offset from move()"); - PQXX_CHECK_EQUAL(displacement, 1, "Unexpected displacement after move()"); - PQXX_CHECK_EQUAL(forward.pos(), 2, "Wrong position after move()"); - PQXX_CHECK_EQUAL(forward.endpos(), -1, "endpos() unexpectedly set"); - - auto row{forward.fetch(0, displacement)}; - PQXX_CHECK_EQUAL(std::size(row), 0, "fetch(0, displacement) returns rows"); - PQXX_CHECK_EQUAL(displacement, 0, "Unexpected displacement after fetch(0)"); - PQXX_CHECK_EQUAL(forward.pos(), 2, "fetch(0, displacement) affected pos()"); - - row = forward.fetch(0); - PQXX_CHECK_EQUAL(std::size(row), 0, "fetch(0) fetched wrong number of rows"); - PQXX_CHECK_EQUAL(forward.pos(), 2, "fetch(0) moved cursor"); - PQXX_CHECK_EQUAL(forward.pos(), 2, "fetch(0) affected pos()"); - - offset = forward.move(1); - PQXX_CHECK_EQUAL(offset, 1, "move(1) returned unexpected value"); - PQXX_CHECK_EQUAL(forward.pos(), 3, "move(1) after fetch(0) broke"); - - row = forward.fetch(1); - PQXX_CHECK_EQUAL( - std::size(row), 1, "fetch(1) returned wrong number of rows"); - PQXX_CHECK_EQUAL(forward.pos(), 4, "fetch(1) results in bad pos()"); - PQXX_CHECK_EQUAL(row[0][0].as(), "4", "pos() is lying"); - - empty_result = forward.fetch(1, displacement); - PQXX_CHECK_EQUAL(std::size(empty_result), 0, "Got rows at end of cursor"); - PQXX_CHECK_EQUAL(forward.pos(), 5, "Not at one-past-end position"); - PQXX_CHECK_EQUAL(forward.endpos(), 5, "Failed to notice end position"); - PQXX_CHECK_EQUAL(displacement, 1, "Wrong displacement at end position"); - - offset = forward.move(5, displacement); - PQXX_CHECK_EQUAL(offset, 0, "move() lied at end of result set"); - PQXX_CHECK_EQUAL(forward.pos(), 5, "pos() is beyond end"); - PQXX_CHECK_EQUAL(forward.endpos(), 5, "endpos() changed after end position"); - PQXX_CHECK_EQUAL(displacement, 0, "Wrong displacement after end position"); - - // Move through entire result set at once. - pqxx::internal::sql_cursor forward2( - tx, "SELECT generate_series(1, 4)", "forward", - pqxx::cursor_base::forward_only, pqxx::cursor_base::read_only, - pqxx::cursor_base::owned, false); - - // Move through entire result set at once. - offset = forward2.move(pqxx::cursor_base::all(), displacement); - PQXX_CHECK_EQUAL(offset, 4, "Unexpected number of rows in result set"); - PQXX_CHECK_EQUAL(displacement, 5, "displacement != rows+1"); - PQXX_CHECK_EQUAL(forward2.pos(), 5, "Bad pos() after skipping all rows"); - PQXX_CHECK_EQUAL(forward2.endpos(), 5, "Bad endpos() after skipping"); - - pqxx::internal::sql_cursor forward3( - tx, "SELECT generate_series(1, 4)", "forward", - pqxx::cursor_base::forward_only, pqxx::cursor_base::read_only, - pqxx::cursor_base::owned, false); - - // Fetch entire result set at once. - auto rows{forward3.fetch(pqxx::cursor_base::all(), displacement)}; - PQXX_CHECK_EQUAL( - std::size(rows), 4, "Unexpected number of rows in result set"); - PQXX_CHECK_EQUAL(displacement, 5, "displacement != rows+1"); - PQXX_CHECK_EQUAL(forward3.pos(), 5, "Bad pos() after fetching all rows"); - PQXX_CHECK_EQUAL(forward3.endpos(), 5, "Bad endpos() after fetching"); - - pqxx::internal::sql_cursor forward_empty( - tx, "SELECT generate_series(0, -1)", "forward_empty", - pqxx::cursor_base::forward_only, pqxx::cursor_base::read_only, - pqxx::cursor_base::owned, false); - - offset = forward_empty.move(3, displacement); - PQXX_CHECK_EQUAL(forward_empty.pos(), 1, "Bad pos() at end of result"); - PQXX_CHECK_EQUAL(forward_empty.endpos(), 1, "Bad endpos() in empty result"); - PQXX_CHECK_EQUAL(displacement, 1, "Bad displacement in empty result"); - PQXX_CHECK_EQUAL(offset, 0, "move() in empty result counted rows"); -} - -void test_scroll_sql_cursor() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - pqxx::internal::sql_cursor scroll( - tx, "SELECT generate_series(1, 10)", "scroll", - pqxx::cursor_base::random_access, pqxx::cursor_base::read_only, - pqxx::cursor_base::owned, false); - - PQXX_CHECK_EQUAL(scroll.pos(), 0, "Scroll cursor's initial pos() is wrong"); - PQXX_CHECK_EQUAL(scroll.endpos(), -1, "New scroll cursor has endpos() set"); - - auto rows{scroll.fetch(pqxx::cursor_base::next())}; - PQXX_CHECK_EQUAL(std::size(rows), 1, "Scroll cursor is broken"); - PQXX_CHECK_EQUAL(scroll.pos(), 1, "Scroll cursor's pos() is broken"); - PQXX_CHECK_EQUAL(scroll.endpos(), -1, "endpos() set prematurely"); - - // Turn cursor around. This is where we begin to feel SQL cursors' - // semantics: we pre-decrement, ending up on the position in front of the - // first row and returning no rows. - rows = scroll.fetch(pqxx::cursor_base::prior()); - PQXX_CHECK_EQUAL(std::empty(rows), true, "Turning around on fetch() broke"); - PQXX_CHECK_EQUAL(scroll.pos(), 0, "pos() is not back at zero"); - PQXX_CHECK_EQUAL( - scroll.endpos(), -1, "endpos() set on wrong side of result"); - - // Bounce off the left-hand side of the result set. Can't move before the - // starting position. - auto offset{0}, displacement{0}; - offset = scroll.move(-3, displacement); - PQXX_CHECK_EQUAL(offset, 0, "Rows found before beginning"); - PQXX_CHECK_EQUAL(displacement, 0, "Failed to bounce off beginning"); - PQXX_CHECK_EQUAL(scroll.pos(), 0, "pos() moved back from zero"); - PQXX_CHECK_EQUAL(scroll.endpos(), -1, "endpos() set on left-side bounce"); - - // Try bouncing off the left-hand side a little harder. Take 4 paces away - // from the boundary and run into it. - offset = scroll.move(4, displacement); - PQXX_CHECK_EQUAL(offset, 4, "Offset mismatch"); - PQXX_CHECK_EQUAL(displacement, 4, "Displacement mismatch"); - PQXX_CHECK_EQUAL(scroll.pos(), 4, "Position mismatch"); - PQXX_CHECK_EQUAL(scroll.endpos(), -1, "endpos() set at weird time"); - - offset = scroll.move(-10, displacement); - PQXX_CHECK_EQUAL(offset, 3, "Offset mismatch"); - PQXX_CHECK_EQUAL(displacement, -4, "Displacement mismatch"); - PQXX_CHECK_EQUAL(scroll.pos(), 0, "Hard bounce failed"); - PQXX_CHECK_EQUAL(scroll.endpos(), -1, "endpos() set during hard bounce"); - - rows = scroll.fetch(3); - PQXX_CHECK_EQUAL(scroll.pos(), 3, "Bad pos()"); - PQXX_CHECK_EQUAL(std::size(rows), 3, "Wrong number of rows"); - PQXX_CHECK_EQUAL(rows[2][0].as(), 3, "pos() does not match data"); - rows = scroll.fetch(-1); - PQXX_CHECK_EQUAL(scroll.pos(), 2, "Bad pos()"); - PQXX_CHECK_EQUAL(rows[0][0].as(), 2, "pos() does not match data"); - - rows = scroll.fetch(1); - PQXX_CHECK_EQUAL(scroll.pos(), 3, "Bad pos() after inverse turnaround"); - PQXX_CHECK_EQUAL(rows[0][0].as(), 3, "Data position mismatch"); -} - - -void test_adopted_sql_cursor() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - - tx.exec0( - "DECLARE adopted SCROLL CURSOR FOR " - "SELECT generate_series(1, 3)"); - pqxx::internal::sql_cursor adopted(tx, "adopted", pqxx::cursor_base::owned); - PQXX_CHECK_EQUAL(adopted.pos(), -1, "Adopted cursor has known pos()"); - PQXX_CHECK_EQUAL(adopted.endpos(), -1, "Adopted cursor has known endpos()"); - - auto displacement{0}; - auto rows{adopted.fetch(pqxx::cursor_base::all(), displacement)}; - PQXX_CHECK_EQUAL(std::size(rows), 3, "Wrong number of rows in result"); - PQXX_CHECK_EQUAL(rows[0][0].as(), 1, "Wrong result data"); - PQXX_CHECK_EQUAL(rows[2][0].as(), 3, "Wrong result data"); - PQXX_CHECK_EQUAL(displacement, 4, "Wrong displacement"); - PQXX_CHECK_EQUAL( - adopted.pos(), -1, "End-of-result set pos() on adopted cur"); - PQXX_CHECK_EQUAL(adopted.endpos(), -1, "endpos() set too early"); - - rows = adopted.fetch(pqxx::cursor_base::backward_all(), displacement); - PQXX_CHECK_EQUAL(std::size(rows), 3, "Wrong number of rows in result"); - PQXX_CHECK_EQUAL(rows[0][0].as(), 3, "Wrong result data"); - PQXX_CHECK_EQUAL(rows[2][0].as(), 1, "Wrong result data"); - PQXX_CHECK_EQUAL(displacement, -4, "Wrong displacement"); - PQXX_CHECK_EQUAL(adopted.pos(), 0, "Failed to recognize starting position"); - PQXX_CHECK_EQUAL(adopted.endpos(), -1, "endpos() set too early"); - - auto offset{adopted.move(pqxx::cursor_base::all())}; - PQXX_CHECK_EQUAL(offset, 3, "Unexpected move() offset"); - PQXX_CHECK_EQUAL(adopted.pos(), 4, "Bad position on adopted cursor"); - PQXX_CHECK_EQUAL(adopted.endpos(), 4, "endpos() not set properly"); - - // Owned adopted cursors are cleaned up on destruction. - pqxx::connection conn2; - pqxx::work tx2(conn2, "tx2"); - tx2.exec0( - "DECLARE adopted2 CURSOR FOR " - "SELECT generate_series(1, 3)"); - { - pqxx::internal::sql_cursor(tx2, "adopted2", pqxx::cursor_base::owned); - } - // Modern backends: accessing the cursor now is an error, as you'd expect. - PQXX_CHECK_THROWS( - tx2.exec("FETCH 1 IN adopted2"), pqxx::sql_error, - "Owned adopted cursor not cleaned up"); - - tx2.abort(); - - pqxx::work tx3(conn2, "tx3"); - tx3.exec( - "DECLARE adopted3 CURSOR FOR " - "SELECT generate_series(1, 3)"); - { - pqxx::internal::sql_cursor(tx3, "adopted3", pqxx::cursor_base::loose); - } - tx3.exec("MOVE 1 IN adopted3"); -} - -void test_hold_cursor() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - - // "With hold" cursor is kept after commit. - pqxx::internal::sql_cursor with_hold( - tx, "SELECT generate_series(1, 3)", "hold_cursor", - pqxx::cursor_base::forward_only, pqxx::cursor_base::read_only, - pqxx::cursor_base::owned, true); - tx.commit(); - pqxx::work tx2(conn, "tx2"); - auto rows{with_hold.fetch(1)}; - PQXX_CHECK_EQUAL( - std::size(rows), 1, "Did not get 1 row from with-hold cursor"); - - // Cursor without hold is closed on commit. - pqxx::internal::sql_cursor no_hold( - tx2, "SELECT generate_series(1, 3)", "no_hold_cursor", - pqxx::cursor_base::forward_only, pqxx::cursor_base::read_only, - pqxx::cursor_base::owned, false); - tx2.commit(); - pqxx::work tx3(conn, "tx3"); - PQXX_CHECK_THROWS( - no_hold.fetch(1), pqxx::sql_error, "Cursor not closed on commit"); -} - - -void cursor_tests() -{ - test_forward_sql_cursor(); - test_scroll_sql_cursor(); - test_adopted_sql_cursor(); - test_hold_cursor(); -} - - -PQXX_REGISTER_TEST(cursor_tests); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_stateless_cursor.cxx b/ext/libpqxx-7.7.3/test/unit/test_stateless_cursor.cxx deleted file mode 100644 index 79307c19e..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_stateless_cursor.cxx +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_stateless_cursor() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - - pqxx::stateless_cursor< - pqxx::cursor_base::read_only, pqxx::cursor_base::owned> - empty(tx, "SELECT generate_series(0, -1)", "empty", false); - - auto rows{empty.retrieve(0, 0)}; - PQXX_CHECK_EQUAL(std::empty(rows), true, "Empty result not empty"); - rows = empty.retrieve(0, 1); - PQXX_CHECK_EQUAL(std::size(rows), 0, "Empty result returned rows"); - - PQXX_CHECK_EQUAL(empty.size(), 0, "Empty cursor not empty"); - - PQXX_CHECK_THROWS( - empty.retrieve(1, 0), std::out_of_range, "Empty cursor tries to retrieve"); - - pqxx::stateless_cursor< - pqxx::cursor_base::read_only, pqxx::cursor_base::owned> - stateless(tx, "SELECT generate_series(0, 9)", "stateless", false); - - PQXX_CHECK_EQUAL(stateless.size(), 10, "stateless_cursor::size() mismatch"); - - // Retrieve nothing. - rows = stateless.retrieve(1, 1); - PQXX_CHECK_EQUAL(std::size(rows), 0, "1-to-1 retrieval not empty"); - - // Retrieve two rows. - rows = stateless.retrieve(1, 3); - PQXX_CHECK_EQUAL(std::size(rows), 2, "Retrieved wrong number of rows"); - PQXX_CHECK_EQUAL(rows[0][0].as(), 1, "Data/position mismatch"); - PQXX_CHECK_EQUAL(rows[1][0].as(), 2, "Data/position mismatch"); - - // Retrieve same rows in reverse. - rows = stateless.retrieve(2, 0); - PQXX_CHECK_EQUAL(std::size(rows), 2, "Retrieved wrong number of rows"); - PQXX_CHECK_EQUAL(rows[0][0].as(), 2, "Data/position mismatch"); - PQXX_CHECK_EQUAL(rows[1][0].as(), 1, "Data/position mismatch"); - - // Retrieve beyond end. - rows = stateless.retrieve(9, 13); - PQXX_CHECK_EQUAL(std::size(rows), 1, "Row count wrong at end"); - PQXX_CHECK_EQUAL(rows[0][0].as(), 9, "Data/pos mismatch at end"); - - // Retrieve beyond beginning. - rows = stateless.retrieve(0, -4); - PQXX_CHECK_EQUAL(std::size(rows), 1, "Row count wrong at beginning"); - PQXX_CHECK_EQUAL(rows[0][0].as(), 0, "Data/pos mismatch at beginning"); - - // Retrieve entire result set backwards. - rows = stateless.retrieve(10, -15); - PQXX_CHECK_EQUAL( - std::size(rows), 10, "Reverse complete retrieval is broken"); - PQXX_CHECK_EQUAL(rows[0][0].as(), 9, "Data mismatch"); - PQXX_CHECK_EQUAL(rows[9][0].as(), 0, "Data mismatch"); - - // Normal usage pattern: step through result set, 4 rows at a time. - rows = stateless.retrieve(0, 4); - PQXX_CHECK_EQUAL(std::size(rows), 4, "Wrong batch size"); - PQXX_CHECK_EQUAL(rows[0][0].as(), 0, "Batch in wrong place"); - PQXX_CHECK_EQUAL(rows[3][0].as(), 3, "Batch in wrong place"); - - rows = stateless.retrieve(4, 8); - PQXX_CHECK_EQUAL(std::size(rows), 4, "Wrong batch size"); - PQXX_CHECK_EQUAL(rows[0][0].as(), 4, "Batch in wrong place"); - PQXX_CHECK_EQUAL(rows[3][0].as(), 7, "Batch in wrong place"); - - rows = stateless.retrieve(8, 12); - PQXX_CHECK_EQUAL(std::size(rows), 2, "Wrong batch size"); - PQXX_CHECK_EQUAL(rows[0][0].as(), 8, "Batch in wrong place"); - PQXX_CHECK_EQUAL(rows[1][0].as(), 9, "Batch in wrong place"); -} - - -PQXX_REGISTER_TEST(test_stateless_cursor); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_strconv.cxx b/ext/libpqxx-7.7.3/test/unit/test_strconv.cxx deleted file mode 100644 index 602084e18..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_strconv.cxx +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -enum colour -{ - red, - green, - blue -}; -enum class weather : short -{ - hot, - cold, - wet -}; -enum class many : unsigned long long -{ - bottom = 0, - top = std::numeric_limits::max(), -}; -} // namespace - -namespace pqxx -{ -PQXX_DECLARE_ENUM_CONVERSION(colour); -PQXX_DECLARE_ENUM_CONVERSION(weather); -PQXX_DECLARE_ENUM_CONVERSION(many); -} // namespace pqxx - - -namespace -{ -void test_strconv_bool() -{ - PQXX_CHECK_EQUAL(pqxx::to_string(false), "false", "Wrong to_string(false)."); - PQXX_CHECK_EQUAL(pqxx::to_string(true), "true", "Wrong to_string(true)."); - - bool result; - pqxx::from_string("false", result); - PQXX_CHECK_EQUAL(result, false, "Wrong from_string('false')."); - pqxx::from_string("FALSE", result); - PQXX_CHECK_EQUAL(result, false, "Wrong from_string('FALSE')."); - pqxx::from_string("f", result); - PQXX_CHECK_EQUAL(result, false, "Wrong from_string('f')."); - pqxx::from_string("F", result); - PQXX_CHECK_EQUAL(result, false, "Wrong from_string('F')."); - pqxx::from_string("0", result); - PQXX_CHECK_EQUAL(result, false, "Wrong from_string('0')."); - pqxx::from_string("true", result); - PQXX_CHECK_EQUAL(result, true, "Wrong from_string('true')."); - pqxx::from_string("TRUE", result); - PQXX_CHECK_EQUAL(result, true, "Wrong from_string('TRUE')."); - pqxx::from_string("t", result); - PQXX_CHECK_EQUAL(result, true, "Wrong from_string('t')."); - pqxx::from_string("T", result); - PQXX_CHECK_EQUAL(result, true, "Wrong from_string('T')."); - pqxx::from_string("1", result); - PQXX_CHECK_EQUAL(result, true, "Wrong from_string('1')."); -} - - -void test_strconv_enum() -{ - PQXX_CHECK_EQUAL(pqxx::to_string(red), "0", "Enum value did not convert."); - PQXX_CHECK_EQUAL(pqxx::to_string(green), "1", "Enum value did not convert."); - PQXX_CHECK_EQUAL(pqxx::to_string(blue), "2", "Enum value did not convert."); - - colour col; - pqxx::from_string("2", col); - PQXX_CHECK_EQUAL(col, blue, "Could not recover enum value from string."); -} - - -void test_strconv_class_enum() -{ - PQXX_CHECK_EQUAL( - pqxx::to_string(weather::hot), "0", "Class enum value did not convert."); - PQXX_CHECK_EQUAL( - pqxx::to_string(weather::wet), "2", "Enum value did not convert."); - - weather w; - pqxx::from_string("2", w); - PQXX_CHECK_EQUAL( - w, weather::wet, "Could not recover class enum value from string."); - - PQXX_CHECK_EQUAL( - pqxx::to_string(many::bottom), "0", - "Small wide enum did not convert right."); - PQXX_CHECK_EQUAL( - pqxx::to_string(many::top), - pqxx::to_string(std::numeric_limits::max()), - "Large wide enum did not convert right."); -} - - -void test_strconv_optional() -{ - PQXX_CHECK_THROWS( - pqxx::to_string(std::optional{}), pqxx::conversion_error, - "Converting an empty optional did not throw conversion error."); - PQXX_CHECK_EQUAL( - pqxx::to_string(std::optional{std::in_place, 10}), "10", - "std::optional does not convert right."); - PQXX_CHECK_EQUAL( - pqxx::to_string(std::optional{std::in_place, -10000}), "-10000", - "std::optional does not convert right."); -} - - -void test_strconv_smart_pointer() -{ - PQXX_CHECK_THROWS( - pqxx::to_string(std::unique_ptr{}), pqxx::conversion_error, - "Converting an empty unique_ptr did not throw conversion error."); - PQXX_CHECK_EQUAL( - pqxx::to_string(std::make_unique(10)), "10", - "std::unique_ptr does not convert right."); - PQXX_CHECK_EQUAL( - pqxx::to_string(std::make_unique(-10000)), "-10000", - "std::unique_ptr does not convert right."); - - PQXX_CHECK_THROWS( - pqxx::to_string(std::shared_ptr{}), pqxx::conversion_error, - "Converting an empty shared_ptr did not throw conversion error."); - PQXX_CHECK_EQUAL( - pqxx::to_string(std::make_shared(10)), "10", - "std::shared_ptr does not convert right."); - PQXX_CHECK_EQUAL( - pqxx::to_string(std::make_shared(-10000)), "-10000", - "std::shared_ptr does not convert right."); -} - - -PQXX_REGISTER_TEST(test_strconv_bool); -PQXX_REGISTER_TEST(test_strconv_enum); -PQXX_REGISTER_TEST(test_strconv_class_enum); -PQXX_REGISTER_TEST(test_strconv_optional); -PQXX_REGISTER_TEST(test_strconv_smart_pointer); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_stream_from.cxx b/ext/libpqxx-7.7.3/test/unit/test_stream_from.cxx deleted file mode 100644 index d8adb8bd1..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_stream_from.cxx +++ /dev/null @@ -1,344 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" -#include "../test_types.hxx" - -#include -#include -#include -#include -#include -#include - -#include - - -namespace -{ -void test_nonoptionals(pqxx::connection &connection) -{ - pqxx::work tx{connection}; - auto extractor{pqxx::stream_from::query( - tx, "SELECT * FROM stream_from_test ORDER BY number0")}; - PQXX_CHECK(extractor, "stream_from failed to initialize."); - - std::tuple got_tuple; - - try - { - // We can't read the "910" row -- it contains nulls, which our tuple does - // not accept. - extractor >> got_tuple; - PQXX_CHECK_NOTREACHED( - "Failed to fail to stream null values into null-less fields."); - } - catch (pqxx::conversion_error const &e) - { - std::string const what{e.what()}; - if (what.find("null") == std::string::npos) - throw; - pqxx::test::expected_exception( - "Could not stream nulls into null-less fields: " + what); - } - - // The stream is still good though. - // The second tuple is fine. - extractor >> got_tuple; - PQXX_CHECK(extractor, "Stream ended prematurely."); - - PQXX_CHECK_EQUAL(std::get<0>(got_tuple), 1234, "Bad value."); - // Don't know much about the timestamp, but let's assume it starts with a - // year in the second millennium. - PQXX_CHECK( - std::get<1>(got_tuple).at(0) == '2', "Bad value. Expected timestamp."); - PQXX_CHECK_LESS( - std::size(std::get<1>(got_tuple)), 40u, "Unexpected length."); - PQXX_CHECK_GREATER( - std::size(std::get<1>(got_tuple)), 20u, "Unexpected length."); - PQXX_CHECK_EQUAL(std::get<2>(got_tuple), 4321, "Bad value."); - PQXX_CHECK_EQUAL(std::get<3>(got_tuple), (ipv4{8, 8, 8, 8}), "Bad value."); - PQXX_CHECK_EQUAL(std::get<4>(got_tuple), "hello\n \tworld", "Bad value."); - PQXX_CHECK_EQUAL( - std::get<5>(got_tuple), (bytea{'\x00', '\x01', '\x02'}), "Bad value."); - - // The third tuple contains some nulls. For what it's worth, when we *know* - // that we're getting nulls, we can stream them into nullptr_t fields. - std::tuple< - int, std::string, std::nullptr_t, std::nullptr_t, std::string, bytea> - tup_w_nulls; - - extractor >> tup_w_nulls; - PQXX_CHECK(extractor, "Stream ended prematurely."); - - PQXX_CHECK_EQUAL(std::get<0>(tup_w_nulls), 5678, "Bad value."); - PQXX_CHECK(std::get<2>(tup_w_nulls) == nullptr, "Bad null."); - PQXX_CHECK(std::get<3>(tup_w_nulls) == nullptr, "Bad null."); - - // We're at the end of the stream. - extractor >> tup_w_nulls; - PQXX_CHECK(not extractor, "Stream did not end."); - - // Of course we can't stream a non-null value into a nullptr field. - auto ex2{pqxx::stream_from::query(tx, "SELECT 1")}; - std::tuple null_tup; - try - { - ex2 >> null_tup; - PQXX_CHECK_NOTREACHED( - "stream_from should have refused to convert non-null value to " - "nullptr_t."); - } - catch (pqxx::conversion_error const &e) - { - std::string const what{e.what()}; - if (what.find("null") == std::string::npos) - throw; - pqxx::test::expected_exception( - std::string{"Could not extract row: "} + what); - } - ex2 >> null_tup; - PQXX_CHECK(not ex2, "Stream did not end."); - - PQXX_CHECK_SUCCEEDS( - tx.exec1("SELECT 1"), "Could not use transaction after stream_from."); -} - - -void test_bad_tuples(pqxx::connection &conn) -{ - pqxx::work tx{conn}; - auto extractor{pqxx::stream_from::table(tx, {"stream_from_test"})}; - PQXX_CHECK(extractor, "stream_from failed to initialize"); - - std::tuple got_tuple_too_short; - try - { - extractor >> got_tuple_too_short; - PQXX_CHECK_NOTREACHED("stream_from improperly read first row"); - } - catch (pqxx::usage_error const &e) - { - std::string what{e.what()}; - if ( - what.find("1") == std::string::npos or - what.find("6") == std::string::npos) - throw; - pqxx::test::expected_exception("Tuple is wrong size: " + what); - } - - std::tuple - got_tuple_too_long; - try - { - extractor >> got_tuple_too_long; - PQXX_CHECK_NOTREACHED("stream_from improperly read first row"); - } - catch (pqxx::usage_error const &e) - { - std::string what{e.what()}; - if ( - what.find("6") == std::string::npos or - what.find("7") == std::string::npos) - throw; - pqxx::test::expected_exception("Could not extract row: " + what); - } - - extractor.complete(); -} - - -#define ASSERT_FIELD_EQUAL(OPT, VAL) \ - PQXX_CHECK(static_cast(OPT), "unexpected null field"); \ - PQXX_CHECK_EQUAL(*OPT, VAL, "field value mismatch") -#define ASSERT_FIELD_NULL(OPT) \ - PQXX_CHECK(not static_cast(OPT), "expected null field") - - -template class O> -void test_optional(pqxx::connection &connection) -{ - pqxx::work tx{connection}; - auto extractor{pqxx::stream_from::query( - tx, "SELECT * FROM stream_from_test ORDER BY number0")}; - PQXX_CHECK(extractor, "stream_from failed to initialize"); - - std::tuple, O, O, O, O> - got_tuple; - - extractor >> got_tuple; - PQXX_CHECK(extractor, "stream_from failed to read third row"); - PQXX_CHECK_EQUAL(std::get<0>(got_tuple), 910, "field value mismatch"); - ASSERT_FIELD_NULL(std::get<1>(got_tuple)); - ASSERT_FIELD_NULL(std::get<2>(got_tuple)); - ASSERT_FIELD_NULL(std::get<3>(got_tuple)); - ASSERT_FIELD_EQUAL(std::get<4>(got_tuple), "\\N"); - ASSERT_FIELD_EQUAL(std::get<5>(got_tuple), bytea{}); - - extractor >> got_tuple; - PQXX_CHECK(extractor, "stream_from failed to read first row."); - PQXX_CHECK_EQUAL(std::get<0>(got_tuple), 1234, "Field value mismatch."); - PQXX_CHECK( - static_cast(std::get<1>(got_tuple)), "Unexpected null field."); - // PQXX_CHECK_EQUAL(*std::get<1>(got_tuple), , "field value mismatch"); - ASSERT_FIELD_EQUAL(std::get<2>(got_tuple), 4321); - ASSERT_FIELD_EQUAL(std::get<3>(got_tuple), (ipv4{8, 8, 8, 8})); - ASSERT_FIELD_EQUAL(std::get<4>(got_tuple), "hello\n \tworld"); - ASSERT_FIELD_EQUAL(std::get<5>(got_tuple), (bytea{'\x00', '\x01', '\x02'})); - - extractor >> got_tuple; - PQXX_CHECK(extractor, "stream_from failed to read second row"); - PQXX_CHECK_EQUAL(std::get<0>(got_tuple), 5678, "field value mismatch"); - ASSERT_FIELD_EQUAL(std::get<1>(got_tuple), "2018-11-17 21:23:00"); - ASSERT_FIELD_NULL(std::get<2>(got_tuple)); - ASSERT_FIELD_NULL(std::get<3>(got_tuple)); - ASSERT_FIELD_EQUAL(std::get<4>(got_tuple), "\u3053\u3093\u306b\u3061\u308f"); - ASSERT_FIELD_EQUAL( - std::get<5>(got_tuple), (bytea{'f', 'o', 'o', ' ', 'b', 'a', 'r', '\0'})); - - extractor >> got_tuple; - PQXX_CHECK(not extractor, "stream_from failed to detect end of stream"); - - extractor.complete(); -} - - -void test_stream_from() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - tx.exec0( - "CREATE TEMP TABLE stream_from_test (" - "number0 INT NOT NULL," - "ts1 TIMESTAMP NULL," - "number2 INT NULL," - "addr3 INET NULL," - "txt4 TEXT NULL," - "bin5 BYTEA NOT NULL" - ")"); - tx.exec_params( - "INSERT INTO stream_from_test VALUES ($1,$2,$3,$4,$5,$6)", 910, nullptr, - nullptr, nullptr, "\\N", bytea{}); - tx.exec_params( - "INSERT INTO stream_from_test VALUES ($1,$2,$3,$4,$5,$6)", 1234, "now", - 4321, ipv4{8, 8, 8, 8}, "hello\n \tworld", bytea{'\x00', '\x01', '\x02'}); - tx.exec_params( - "INSERT INTO stream_from_test VALUES ($1,$2,$3,$4,$5,$6)", 5678, - "2018-11-17 21:23:00", nullptr, nullptr, "\u3053\u3093\u306b\u3061\u308f", - bytea{'f', 'o', 'o', ' ', 'b', 'a', 'r', '\0'}); - tx.commit(); - - test_nonoptionals(conn); - test_bad_tuples(conn); - std::cout << "testing `std::unique_ptr` as optional...\n"; - test_optional(conn); - std::cout << "testing `std::optional` as optional...\n"; - test_optional(conn); -} - - -void test_stream_from_does_escaping() -{ - std::string const input{"a\t\n\n\n \\b\nc"}; - pqxx::connection conn; - pqxx::work tx{conn}; - tx.exec0("CREATE TEMP TABLE badstr (str text)"); - tx.exec0("INSERT INTO badstr (str) VALUES (" + tx.quote(input) + ")"); - auto reader{pqxx::stream_from::table(tx, {"badstr"})}; - std::tuple out; - reader >> out; - PQXX_CHECK_EQUAL( - std::get<0>(out), input, "stream_from got weird characters wrong."); -} - - -void test_stream_from_does_iteration() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - tx.exec0("CREATE TEMP TABLE str (s text)"); - tx.exec0("INSERT INTO str (s) VALUES ('foo')"); - auto reader{pqxx::stream_from::table(tx, {"str"})}; - - int i{0}; - std::string out; - for (std::tuple t : reader.iter()) - { - i++; - out = std::get<0>(t); - } - PQXX_CHECK_EQUAL(i, 1, "Wrong number of iterations."); - PQXX_CHECK_EQUAL(out, "foo", "Got wrong string."); - - tx.exec0("INSERT INTO str (s) VALUES ('bar')"); - i = 0; - std::set strings; - auto reader2{pqxx::stream_from::table(tx, {"str"})}; - for (std::tuple t : reader2.iter()) - { - i++; - strings.insert(std::get<0>(t)); - } - PQXX_CHECK_EQUAL(i, 2, "Wrong number of iterations."); - PQXX_CHECK_EQUAL( - std::size(strings), 2u, "Wrong number of strings retrieved."); - PQXX_CHECK(strings.find("foo") != std::end(strings), "Missing key."); - PQXX_CHECK(strings.find("bar") != std::end(strings), "Missing key."); -} - - -void test_transaction_stream_from() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - tx.exec0("CREATE TEMP TABLE sample (id integer, name varchar)"); - tx.exec0("INSERT INTO sample (id, name) VALUES (321, 'something')"); - - int items{0}; - int id{0}; - std::string name; - - for (auto [iid, iname] : - tx.stream("SELECT id, name FROM sample")) - { - items++; - id = iid; - name = iname; - } - PQXX_CHECK_EQUAL(items, 1, "Wrong number of iterations."); - PQXX_CHECK_EQUAL(id, 321, "Got wrong int."); - PQXX_CHECK_EQUAL(name, std::string{"something"}, "Got wrong string."); - - PQXX_CHECK_EQUAL( - tx.query_value("SELECT 4"), 4, - "Loop did not relinquish transaction."); -} - - -void test_stream_from_read_row() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - tx.exec0("CREATE TEMP TABLE sample (id integer, name varchar, opt integer)"); - tx.exec0("INSERT INTO sample (id, name) VALUES (321, 'something')"); - - auto stream{pqxx::stream_from::table(tx, {"sample"})}; - auto fields{stream.read_row()}; - PQXX_CHECK_EQUAL(fields->size(), 3ul, "Wrong number of fields."); - PQXX_CHECK_EQUAL( - std::string((*fields)[0]), "321", "Integer field came out wrong."); - PQXX_CHECK_EQUAL( - std::string((*fields)[1]), "something", "Text field came out wrong."); - PQXX_CHECK(std::data((*fields)[2]) == nullptr, "Null field came out wrong."); - - auto last{stream.read_row()}; - PQXX_CHECK(last == nullptr, "No null pointer at end of stream."); -} - - -PQXX_REGISTER_TEST(test_stream_from); -PQXX_REGISTER_TEST(test_stream_from_does_escaping); -PQXX_REGISTER_TEST(test_stream_from_does_iteration); -PQXX_REGISTER_TEST(test_transaction_stream_from); -PQXX_REGISTER_TEST(test_stream_from_read_row); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_stream_to.cxx b/ext/libpqxx-7.7.3/test/unit/test_stream_to.cxx deleted file mode 100644 index ae4eb3c65..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_stream_to.cxx +++ /dev/null @@ -1,445 +0,0 @@ -#include -#include - -#include -#include - -#include "../test_helpers.hxx" -#include "../test_types.hxx" - -namespace -{ -std::string truncate_sql_error(std::string const &what) -{ - auto trunc{what.substr(0, what.find('\n'))}; - if (std::size(trunc) > 64) - trunc = trunc.substr(0, 61) + "..."; - return trunc; -} - - -void test_nonoptionals(pqxx::connection &connection) -{ - pqxx::work tx{connection}; - auto inserter{pqxx::stream_to::table(tx, {"stream_to_test"})}; - PQXX_CHECK(inserter, "stream_to failed to initialize"); - - auto const nonascii{"\u3053\u3093\u306b\u3061\u308f"}; - bytea const binary{'\x00', '\x01', '\x02'}, - text{'f', 'o', 'o', ' ', 'b', 'a', 'r', '\0'}; - - inserter << std::make_tuple( - 1234, "now", 4321, ipv4{8, 8, 4, 4}, "hello nonoptional world", binary); - inserter << std::make_tuple( - 5678, "2018-11-17 21:23:00", nullptr, nullptr, nonascii, text); - inserter << std::make_tuple(910, nullptr, nullptr, nullptr, "\\N", bytea{}); - - inserter.complete(); - - auto r1{tx.exec1("SELECT * FROM stream_to_test WHERE number0 = 1234")}; - PQXX_CHECK_EQUAL(r1[0].as(), 1234, "Read back wrong first int."); - PQXX_CHECK_EQUAL( - r1[4].as(), "hello nonoptional world", - "Read back wrong string."); - PQXX_CHECK_EQUAL(r1[3].as(), ipv4(8, 8, 4, 4), "Read back wrong ip."); - PQXX_CHECK_EQUAL(r1[5].as(), binary, "Read back wrong bytea."); - - auto r2{tx.exec1("SELECT * FROM stream_to_test WHERE number0 = 5678")}; - PQXX_CHECK_EQUAL(r2[0].as(), 5678, "Wrong int on second row."); - PQXX_CHECK(r2[2].is_null(), "Field 2 was meant to be null."); - PQXX_CHECK(r2[3].is_null(), "Field 3 was meant to be null."); - PQXX_CHECK_EQUAL(r2[4].as(), nonascii, "Wrong non-ascii text."); - tx.commit(); -} - -void test_nonoptionals_fold(pqxx::connection &connection) -{ - pqxx::work tx{connection}; - auto inserter{pqxx::stream_to::table(tx, {"stream_to_test"})}; - PQXX_CHECK(inserter, "stream_to failed to initialize"); - - auto const nonascii{"\u3053\u3093\u306b\u3061\u308f"}; - bytea const binary{'\x00', '\x01', '\x02'}, - text{'f', 'o', 'o', ' ', 'b', 'a', 'r', '\0'}; - - inserter.write_values( - 1234, "now", 4321, ipv4{8, 8, 4, 4}, "hello nonoptional world", binary); - inserter.write_values( - 5678, "2018-11-17 21:23:00", nullptr, nullptr, nonascii, text); - inserter.write_values(910, nullptr, nullptr, nullptr, "\\N", bytea{}); - - inserter.complete(); - - auto r1{tx.exec1("SELECT * FROM stream_to_test WHERE number0 = 1234")}; - PQXX_CHECK_EQUAL(r1[0].as(), 1234, "Read back wrong first int."); - PQXX_CHECK_EQUAL( - r1[4].as(), "hello nonoptional world", - "Read back wrong string."); - PQXX_CHECK_EQUAL(r1[3].as(), ipv4(8, 8, 4, 4), "Read back wrong ip."); - PQXX_CHECK_EQUAL(r1[5].as(), binary, "Read back wrong bytera."); - - auto r2{tx.exec1("SELECT * FROM stream_to_test WHERE number0 = 5678")}; - PQXX_CHECK_EQUAL(r2[0].as(), 5678, "Wrong int on second row."); - PQXX_CHECK(r2[2].is_null(), "Field 2 was meant to be null."); - PQXX_CHECK(r2[3].is_null(), "Field 3 was meant to be null."); - PQXX_CHECK_EQUAL(r2[4].as(), nonascii, "Wrong non-ascii text."); - tx.commit(); -} - - -/// Try to violate stream_to_test's not-null constraint using a stream_to. -void insert_bad_null_tuple(pqxx::stream_to &inserter) -{ - inserter << std::make_tuple( - nullptr, "now", 4321, ipv4{8, 8, 8, 8}, "hello world", - bytea{'\x00', '\x01', '\x02'}); - inserter.complete(); -} - - -void test_bad_null(pqxx::connection &connection) -{ - pqxx::work tx{connection}; - auto inserter{pqxx::stream_to::table(tx, {"stream_to_test"})}; - PQXX_CHECK(inserter, "stream_to failed to initialize"); - PQXX_CHECK_THROWS( - insert_bad_null_tuple(inserter), pqxx::not_null_violation, - "Did not expected not_null_violation when stream_to inserts a bad null."); -} - - -/// Try to violate stream_to_test's not-null construct using a stream_to. -void insert_bad_null_write(pqxx::stream_to &inserter) -{ - inserter.write_values( - nullptr, "now", 4321, ipv4{8, 8, 8, 8}, "hello world", - bytea{'\x00', '\x01', '\x02'}); - inserter.complete(); -} - - -void test_bad_null_fold(pqxx::connection &connection) -{ - pqxx::work tx{connection}; - auto inserter{pqxx::stream_to::table(tx, {"stream_to_test"})}; - PQXX_CHECK(inserter, "stream_to failed to initialize"); - PQXX_CHECK_THROWS( - insert_bad_null_write(inserter), pqxx::not_null_violation, - "Did not expected not_null_violation when stream_to inserts a bad null."); -} - - -void test_too_few_fields(pqxx::connection &connection) -{ - pqxx::work tx{connection}; - auto inserter{pqxx::stream_to::table(tx, {"stream_to_test"})}; - PQXX_CHECK(inserter, "stream_to failed to initialize"); - - try - { - inserter << std::make_tuple(1234, "now", 4321, ipv4{8, 8, 8, 8}); - inserter.complete(); - tx.commit(); - PQXX_CHECK_NOTREACHED("stream_from improperly inserted row"); - } - catch (pqxx::sql_error const &e) - { - std::string what{e.what()}; - if (what.find("missing data for column") == std::string::npos) - throw; - pqxx::test::expected_exception( - "Could not insert row: " + truncate_sql_error(what)); - } -} - -void test_too_few_fields_fold(pqxx::connection &connection) -{ - pqxx::work tx{connection}; - auto inserter{pqxx::stream_to::table(tx, {"stream_to_test"})}; - PQXX_CHECK(inserter, "stream_to failed to initialize"); - - try - { - inserter.write_values(1234, "now", 4321, ipv4{8, 8, 8, 8}); - inserter.complete(); - tx.commit(); - PQXX_CHECK_NOTREACHED("stream_from_fold improperly inserted row"); - } - catch (pqxx::sql_error const &e) - { - std::string what{e.what()}; - if (what.find("missing data for column") == std::string::npos) - throw; - pqxx::test::expected_exception( - "Fold - Could not insert row: " + truncate_sql_error(what)); - } -} - - -void test_too_many_fields(pqxx::connection &connection) -{ - pqxx::work tx{connection}; - auto inserter{pqxx::stream_to::table(tx, {"stream_to_test"})}; - PQXX_CHECK(inserter, "stream_to failed to initialize"); - - try - { - inserter << std::make_tuple( - 1234, "now", 4321, ipv4{8, 8, 8, 8}, "hello world", - bytea{'\x00', '\x01', '\x02'}, 5678); - inserter.complete(); - tx.commit(); - PQXX_CHECK_NOTREACHED("stream_from improperly inserted row"); - } - catch (pqxx::sql_error const &e) - { - std::string what{e.what()}; - if (what.find("extra data") == std::string::npos) - throw; - pqxx::test::expected_exception( - "Could not insert row: " + truncate_sql_error(what)); - } -} - -void test_too_many_fields_fold(pqxx::connection &connection) -{ - pqxx::work tx{connection}; - auto inserter{pqxx::stream_to::table(tx, {"stream_to_test"})}; - PQXX_CHECK(inserter, "stream_to failed to initialize"); - - try - { - inserter.write_values( - 1234, "now", 4321, ipv4{8, 8, 8, 8}, "hello world", - bytea{'\x00', '\x01', '\x02'}, 5678); - inserter.complete(); - tx.commit(); - PQXX_CHECK_NOTREACHED("stream_from_fold improperly inserted row"); - } - catch (pqxx::sql_error const &e) - { - std::string what{e.what()}; - if (what.find("extra data") == std::string::npos) - throw; - pqxx::test::expected_exception( - "Fold - Could not insert row: " + truncate_sql_error(what)); - } -} - - -void test_stream_to_does_nonnull_optional() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - tx.exec0("CREATE TEMP TABLE foo(x integer, y text)"); - auto inserter{pqxx::stream_to::table(tx, {"foo"})}; - inserter.write_values( - std::optional{368}, std::optional{"Text"}); - inserter.complete(); - auto const row{tx.exec1("SELECT x, y FROM foo")}; - PQXX_CHECK_EQUAL( - row[0].as(), "368", "Non-null int optional came out wrong."); - PQXX_CHECK_EQUAL( - row[1].as(), "Text", - "Non-null string optional came out wrong."); -} - - -template class O> -void test_optional(pqxx::connection &connection) -{ - pqxx::work tx{connection}; - auto inserter{pqxx::stream_to::table(tx, {"stream_to_test"})}; - PQXX_CHECK(inserter, "stream_to failed to initialize"); - - inserter << std::make_tuple( - 910, O{pqxx::nullness>::null()}, - O{pqxx::nullness>::null()}, - O{pqxx::nullness>::null()}, "\\N", bytea{}); - - inserter.complete(); - tx.commit(); -} - -template class O> -void test_optional_fold(pqxx::connection &connection) -{ - pqxx::work tx{connection}; - auto inserter{pqxx::stream_to::table(tx, {"stream_to_test"})}; - PQXX_CHECK(inserter, "stream_to failed to initialize"); - - inserter.write_values( - 910, O{pqxx::nullness>::null()}, - O{pqxx::nullness>::null()}, - O{pqxx::nullness>::null()}, "\\N", bytea{}); - - inserter.complete(); - tx.commit(); -} - - -// As an alternative to a tuple, you can also insert a container. -void test_container_stream_to() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - tx.exec0("CREATE TEMP TABLE test_container(a integer, b integer)"); - - auto inserter{pqxx::stream_to::table(tx, {"test_container"})}; - - inserter << std::vector{112, 244}; - inserter.complete(); - - auto read{tx.exec1("SELECT * FROM test_container")}; - PQXX_CHECK_EQUAL( - read[0].as(), 112, "stream_to on container went wrong."); - PQXX_CHECK_EQUAL( - read[1].as(), 244, "Second container field went wrong."); - tx.commit(); -} - -void test_variant_fold(pqxx::connection_base &connection) -{ - pqxx::work tx{connection}; - auto inserter{pqxx::stream_to::table(tx, {"stream_to_test"})}; - PQXX_CHECK(inserter, "stream_to failed to initialize"); - - inserter.write_values( - std::variant{1234}, - std::variant{"now"}, 4321, ipv4{8, 8, 8, 8}, - "hello world", bytea{'\x00', '\x01', '\x02'}); - inserter.write_values( - 5678, "2018-11-17 21:23:00", nullptr, nullptr, - "\u3053\u3093\u306b\u3061\u308f", - bytea{'f', 'o', 'o', ' ', 'b', 'a', 'r', '\0'}); - inserter.write_values(910, nullptr, nullptr, nullptr, "\\N", bytea{}); - - inserter.complete(); - tx.commit(); -} - -void clear_table(pqxx::connection &conn) -{ - pqxx::work tx{conn}; - tx.exec0("DELETE FROM stream_to_test"); - tx.commit(); -} - - -void test_stream_to() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - - tx.exec0( - "CREATE TEMP TABLE stream_to_test (" - "number0 INT NOT NULL," - "ts1 TIMESTAMP NULL," - "number2 INT NULL," - "addr3 INET NULL," - "txt4 TEXT NULL," - "bin5 BYTEA NOT NULL" - ")"); - tx.commit(); - - test_nonoptionals(conn); - clear_table(conn); - test_nonoptionals_fold(conn); - clear_table(conn); - test_bad_null(conn); - clear_table(conn); - test_bad_null_fold(conn); - clear_table(conn); - test_too_few_fields(conn); - clear_table(conn); - test_too_few_fields_fold(conn); - clear_table(conn); - test_too_many_fields(conn); - clear_table(conn); - test_too_many_fields_fold(conn); - clear_table(conn); - test_optional(conn); - clear_table(conn); - test_optional_fold(conn); - clear_table(conn); - test_optional(conn); - clear_table(conn); - test_optional_fold(conn); - clear_table(conn); - test_variant_fold(conn); -} - - -void test_stream_to_factory_with_static_columns() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - - tx.exec0("CREATE TEMP TABLE pqxx_stream_to(a integer, b varchar)"); - - auto stream{pqxx::stream_to::table(tx, {"pqxx_stream_to"}, {"a", "b"})}; - stream.write_values(3, "three"); - stream.complete(); - - auto r{tx.exec1("SELECT a, b FROM pqxx_stream_to")}; - PQXX_CHECK_EQUAL(r[0].as(), 3, "Failed to stream_to a table."); - PQXX_CHECK_EQUAL( - r[1].as(), "three", - "Failed to stream_to a string to a table."); -} - - -void test_stream_to_factory_with_dynamic_columns() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - - tx.exec0("CREATE TEMP TABLE pqxx_stream_to(a integer, b varchar)"); - - std::vector columns{"a", "b"}; -#if defined(PQXX_HAVE_CONCEPTS) - auto stream{pqxx::stream_to::table(tx, {"pqxx_stream_to"}, columns)}; -#else - auto stream{pqxx::stream_to::raw_table( - tx, conn.quote_table({"pqxx_stream_to"}), conn.quote_columns(columns))}; -#endif - stream.write_values(4, "four"); - stream.complete(); - - auto r{tx.exec1("SELECT a, b FROM pqxx_stream_to")}; - PQXX_CHECK_EQUAL( - r[0].as(), 4, "Failed to stream_to a table with dynamic columns."); - PQXX_CHECK_EQUAL( - r[1].as(), "four", - "Failed to stream_to a string to a table with dynamic columns."); -} - - -void test_stream_to_quotes_arguments() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - - std::string const table{R"--(pqxx_Stream"'x)--"}, column{R"--(a'"b)--"}; - - tx.exec0( - "CREATE TEMP TABLE " + tx.quote_name(table) + "(" + tx.quote_name(column) + - " integer)"); - auto write{pqxx::stream_to::table(tx, {table}, {column})}; - write.write_values(12); - write.complete(); - - PQXX_CHECK_EQUAL( - tx.query_value( - "SELECT " + tx.quote_name(column) + " FROM " + tx.quote_name(table)), - 12, "Stream wrote wrong value."); -} - - -PQXX_REGISTER_TEST(test_stream_to); -PQXX_REGISTER_TEST(test_container_stream_to); -PQXX_REGISTER_TEST(test_stream_to_does_nonnull_optional); -PQXX_REGISTER_TEST(test_stream_to_factory_with_static_columns); -PQXX_REGISTER_TEST(test_stream_to_factory_with_dynamic_columns); -PQXX_REGISTER_TEST(test_stream_to_quotes_arguments); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_string_conversion.cxx b/ext/libpqxx-7.7.3/test/unit/test_string_conversion.cxx deleted file mode 100644 index 30bc084f5..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_string_conversion.cxx +++ /dev/null @@ -1,178 +0,0 @@ -#include -#include - -#include -#include - -#include "../test_helpers.hxx" - -// Some enums with string conversions. -enum EnumA -{ - ea0, - ea1, - ea2 -}; -enum EnumB -{ - eb0, - eb1, - eb2 -}; -namespace pqxx -{ -PQXX_DECLARE_ENUM_CONVERSION(EnumA); -PQXX_DECLARE_ENUM_CONVERSION(EnumB); -} // namespace pqxx - - -namespace -{ -// "A minimal difference." -constexpr double thres{0.00001}; - - -void test_string_conversion() -{ - PQXX_CHECK_EQUAL( - "C string array", pqxx::to_string("C string array"), - "C-style string constant does not convert to string properly."); - - char text_array[]{"C char array"}; - PQXX_CHECK_EQUAL( - "C char array", pqxx::to_string(text_array), - "C-style non-const char array does not convert to string properly."); - - char const *text_ptr{"C string pointer"}; - PQXX_CHECK_EQUAL( - "C string pointer", pqxx::to_string(text_ptr), - "C-style string pointer does not convert to string properly."); - - std::string const cxx_string{"C++ string"}; - PQXX_CHECK_EQUAL( - "C++ string", pqxx::to_string(cxx_string), - "C++-style string object does not convert to string properly."); - - PQXX_CHECK_EQUAL("0", pqxx::to_string(0), "Zero does not convert right."); - PQXX_CHECK_EQUAL( - "1", pqxx::to_string(1), "Basic integer does not convert right."); - PQXX_CHECK_EQUAL("-1", pqxx::to_string(-1), "Negative numbers don't work."); - PQXX_CHECK_EQUAL( - "9999", pqxx::to_string(9999), "Larger numbers don't work."); - PQXX_CHECK_EQUAL( - "-9999", pqxx::to_string(-9999), "Larger negative numbers don't work."); - - int x; - pqxx::from_string("0", x); - PQXX_CHECK_EQUAL(0, x, "Zero does not parse right."); - pqxx::from_string("1", x); - PQXX_CHECK_EQUAL(1, x, "Basic integer does not parse right."); - pqxx::from_string("-1", x); - PQXX_CHECK_EQUAL(-1, x, "Negative numbers don't work."); - pqxx::from_string("9999", x); - PQXX_CHECK_EQUAL(9999, x, "Larger numbers don't work."); - pqxx::from_string("-9999", x); - PQXX_CHECK_EQUAL(-9999, x, "Larger negative numbers don't work."); - - // Bug #263 describes a case where this kind of overflow went undetected. - if (sizeof(unsigned int) == 4) - { - std::uint32_t u; - PQXX_CHECK_THROWS( - pqxx::from_string("4772185884", u), pqxx::conversion_error, - "Overflow not detected."); - } - - // We can convert to and from long double. The implementation may fall - // back on a thread-local std::stringstream. Each call does its own - // cleanup, so the conversion works multiple times. - constexpr long double ld1{123456789.25}, ld2{9876543210.5}; - constexpr char lds1[]{"123456789.25"}, lds2[]{"9876543210.5"}; - PQXX_CHECK_EQUAL( - pqxx::to_string(ld1).substr(0, 12), lds1, - "Wrong conversion from long double."); - PQXX_CHECK_EQUAL( - pqxx::to_string(ld2).substr(0, 12), lds2, - "Wrong value on repeated conversion from long double."); - long double ldi1, ldi2; - pqxx::from_string(lds1, ldi1); - PQXX_CHECK_BOUNDS( - ldi1, ld1 - thres, ld1 + thres, "Wrong conversion to long double."); - pqxx::from_string(lds2, ldi2); - PQXX_CHECK_BOUNDS( - ldi2, ld2 - thres, ld2 + thres, - "Wrong repeated conversion to long double."); - - // We can define string conversions for enums. - PQXX_CHECK_EQUAL( - pqxx::to_string(ea0), "0", "Enum-to-string conversion is broken."); - PQXX_CHECK_EQUAL( - pqxx::to_string(eb0), "0", - "Enum-to-string conversion is inconsistent between enum types."); - PQXX_CHECK_EQUAL( - pqxx::to_string(ea1), "1", - "Enum-to-string conversion breaks for nonzero value."); - - EnumA ea; - pqxx::from_string("2", ea); - PQXX_CHECK_EQUAL(ea, ea2, "String-to-enum conversion is broken."); -} - - -void test_convert_variant_to_string() -{ - PQXX_CHECK_EQUAL( - pqxx::to_string(std::variant{99}), "99", - "First variant field did not convert right."); - - PQXX_CHECK_EQUAL( - pqxx::to_string(std::variant{"Text"}), "Text", - "Second variant field did not convert right."); -} - - -void test_integer_conversion() -{ - PQXX_CHECK_EQUAL( - pqxx::from_string("12"), 12, "Basic integer conversion failed."); - PQXX_CHECK_EQUAL( - pqxx::from_string(" 12"), 12, - "Leading whitespace confused integer conversion."); - PQXX_CHECK_THROWS( - pqxx::ignore_unused(pqxx::from_string("")), pqxx::conversion_error, - "Converting empty string to integer did not throw conversion error."); - PQXX_CHECK_THROWS( - pqxx::ignore_unused(pqxx::from_string(" ")), pqxx::conversion_error, - "Converting whitespace to integer did not throw conversion error."); - PQXX_CHECK_EQUAL( - pqxx::from_string("-6"), -6, - "Leading whitespace did not work with negative number."); - PQXX_CHECK_THROWS( - pqxx::ignore_unused(pqxx::from_string("- 3")), pqxx::conversion_error, - "A space between negation and number was not properly flagged."); - PQXX_CHECK_THROWS( - pqxx::ignore_unused(pqxx::from_string("-")), pqxx::conversion_error, - "Just a minus sign should not parse as an integer."); -} - - -void test_convert_null() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - PQXX_CHECK_EQUAL( - tx.quote(nullptr), "NULL", "Null pointer did not come out as SQL 'null'."); - PQXX_CHECK_EQUAL( - tx.quote(std::nullopt), "NULL", - "std::nullopt did not come out as SQL 'null'."); - PQXX_CHECK_EQUAL( - tx.quote(std::monostate{}), "NULL", - "std::monostate did not come out as SQL 'null'."); -} - - -PQXX_REGISTER_TEST(test_string_conversion); -PQXX_REGISTER_TEST(test_convert_variant_to_string); -PQXX_REGISTER_TEST(test_integer_conversion); -PQXX_REGISTER_TEST(test_convert_null); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_subtransaction.cxx b/ext/libpqxx-7.7.3/test/unit/test_subtransaction.cxx deleted file mode 100644 index 4ba909bec..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_subtransaction.cxx +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -void make_table(pqxx::transaction_base &trans) -{ - trans.exec0("CREATE TEMP TABLE foo (x INTEGER)"); -} - - -void insert_row(pqxx::transaction_base &trans) -{ - trans.exec0("INSERT INTO foo(x) VALUES (1)"); -} - - -int count_rows(pqxx::transaction_base &trans) -{ - return trans.query_value("SELECT count(*) FROM foo"); -} - - -void test_subtransaction_commits_if_commit_called(pqxx::connection &conn) -{ - pqxx::work trans(conn); - make_table(trans); - { - pqxx::subtransaction sub(trans); - insert_row(sub); - sub.commit(); - } - PQXX_CHECK_EQUAL( - count_rows(trans), 1, "Work done in committed subtransaction was lost."); -} - - -void test_subtransaction_aborts_if_abort_called(pqxx::connection &conn) -{ - pqxx::work trans(conn); - make_table(trans); - { - pqxx::subtransaction sub(trans); - insert_row(sub); - sub.abort(); - } - PQXX_CHECK_EQUAL( - count_rows(trans), 0, "Aborted subtransaction was not rolled back."); -} - - -void test_subtransaction_aborts_implicitly(pqxx::connection &conn) -{ - pqxx::work trans(conn); - make_table(trans); - { - pqxx::subtransaction sub(trans); - insert_row(sub); - } - PQXX_CHECK_EQUAL( - count_rows(trans), 0, - "Uncommitted subtransaction was not rolled back uring destruction."); -} - - -void test_subtransaction() -{ - pqxx::connection conn; - test_subtransaction_commits_if_commit_called(conn); - test_subtransaction_aborts_if_abort_called(conn); - test_subtransaction_aborts_implicitly(conn); -} - - -PQXX_REGISTER_TEST(test_subtransaction); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_test_helpers.cxx b/ext/libpqxx-7.7.3/test/unit/test_test_helpers.cxx deleted file mode 100644 index 89cde627e..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_test_helpers.cxx +++ /dev/null @@ -1,214 +0,0 @@ -#include "../test_helpers.hxx" - -namespace -{ -void empty() {} - - -void test_check_notreached() -{ - // At a minimum, PQXX_CHECK_NOTREACHED must work. - bool failed{true}; - try - { - PQXX_CHECK_NOTREACHED("(expected)"); - failed = false; - } - catch (pqxx::test::test_failure const &) - { - // This is what we expect. - } - if (not failed) - throw pqxx::test::test_failure( - __FILE__, __LINE__, "PQXX_CHECK_NOTREACHED is broken."); -} - - -// Test PQXX_CHECK. -void test_check() -{ - PQXX_CHECK(true, "PQXX_CHECK is broken."); - - bool failed{true}; - try - { - PQXX_CHECK(false, "(expected)"); - failed = false; - } - catch (pqxx::test::test_failure const &) - {} - if (not failed) - PQXX_CHECK_NOTREACHED("PQXX_CHECK failed to notice failure."); -} - - -// Test PQXX_CHECK_THROWS_EXCEPTION. -void test_check_throws_exception() -{ - // PQXX_CHECK_THROWS_EXCEPTION expects std::exception... - PQXX_CHECK_THROWS_EXCEPTION( - throw std::exception(), - "PQXX_CHECK_THROWS_EXCEPTION did not catch std::exception."); - - // ...or any exception type derived from it. - PQXX_CHECK_THROWS_EXCEPTION( - throw pqxx::test::test_failure(__FILE__, __LINE__, "(expected)"), - "PQXX_CHECK_THROWS_EXCEPTION() failed to catch expected exception."); - - // Any other type is an error. - bool failed{true}; - try - { - PQXX_CHECK_THROWS_EXCEPTION(throw 1, "(expected)"); - failed = false; - } - catch (pqxx::test::test_failure const &) - {} - PQXX_CHECK( - failed, - "PQXX_CHECK_THROWS_EXCEPTION did not complain about non-exception."); - - // But there _must_ be an exception. - failed = true; - try - { - // If the test fails to throw, this throws a failure. - PQXX_CHECK_THROWS_EXCEPTION(empty(), "(expected)"); - // So we shouldn't get to this point. - failed = false; - } - catch (pqxx::test::test_failure const &) - { - // Instead, we go straight here. - } - PQXX_CHECK( - failed, "PQXX_CHECK_THROWS_EXCEPTION did not notice missing exception."); - - // PQXX_CHECK_THROWS_EXCEPTION can test itself... - PQXX_CHECK_THROWS_EXCEPTION( - PQXX_CHECK_THROWS_EXCEPTION(empty(), "(expected)"), - "PQXX_CHECK_THROWS_EXCEPTION failed to throw for missing exception."); - - PQXX_CHECK_THROWS_EXCEPTION( - PQXX_CHECK_THROWS_EXCEPTION(throw 1, "(expected)"), - "PQXX_CHECK_THROWS_EXCEPTION ignored wrong exception type."); -} - - -// Test PQXX_CHECK_THROWS. -void test_check_throws() -{ - PQXX_CHECK_THROWS( - throw pqxx::test::test_failure(__FILE__, __LINE__, "(expected)"), - pqxx::test::test_failure, - "PQXX_CHECK_THROWS() failed to catch expected exception."); - - // Even if it's not std::exception-derived. - PQXX_CHECK_THROWS(throw 1, int, "(expected)"); - - // PQXX_CHECK_THROWS means there _must_ be an exception. - bool failed{true}; - try - { - // If the test fails to throw, PQXX_CHECK_THROWS throws a failure. - PQXX_CHECK_THROWS(empty(), std::runtime_error, "(expected)"); - // So we shouldn't get to this point. - failed = false; - } - catch (pqxx::test::test_failure const &) - { - // Instead, we go straight here. - } - PQXX_CHECK(failed, "PQXX_CHECK_THROWS did not notice missing exception."); - - // The exception must be of the right type (or a subclass of the right type). - failed = true; - try - { - // If the test throws the wrong type, PQXX_CHECK_THROWS throws a failure. - PQXX_CHECK_THROWS( - throw std::exception(), pqxx::test::test_failure, "(expected)"); - failed = false; - } - catch (pqxx::test::test_failure const &) - { - // Instead, we go straight here. - } - PQXX_CHECK(failed, "PQXX_CHECK_THROWS did not notice wrong exception type."); - - // PQXX_CHECK_THROWS can test itself... - PQXX_CHECK_THROWS( - PQXX_CHECK_THROWS(empty(), pqxx::test::test_failure, "(expected)"), - pqxx::test::test_failure, - "PQXX_CHECK_THROWS failed to throw for missing exception."); - - PQXX_CHECK_THROWS( - PQXX_CHECK_THROWS(throw 1, std::runtime_error, "(expected)"), - pqxx::test::test_failure, - "PQXX_CHECK_THROWS failed to throw for wrong exception type."); -} - - -void test_test_helpers() -{ - test_check_notreached(); - test_check(); - test_check_throws_exception(); - test_check_throws(); - - // Test other helpers against PQXX_CHECK_THROWS. - PQXX_CHECK_THROWS( - PQXX_CHECK_NOTREACHED("(expected)"), pqxx::test::test_failure, - "PQXX_CHECK_THROWS did not catch PQXX_CHECK_NOTREACHED."); - - PQXX_CHECK_THROWS( - PQXX_CHECK(false, "(expected)"), pqxx::test::test_failure, - "PQXX_CHECK_THROWS did not catch failing PQXX_CHECK."); - - PQXX_CHECK_THROWS( - PQXX_CHECK_THROWS( - PQXX_CHECK(true, "(shouldn't happen)"), pqxx::test::test_failure, - "(expected)"), - pqxx::test::test_failure, - "PQXX_CHECK_THROWS on successful PQXX_CHECK failed to throw."); - - // PQXX_CHECK_EQUAL tests for equality. Its arguments need not be of the - // same type, as long as equality between them is defined. - PQXX_CHECK_EQUAL(1, 1, "PQXX_CHECK_EQUAL is broken."); - PQXX_CHECK_EQUAL(1, 1L, "PQXX_CHECK_EQUAL breaks on type mismatch."); - - PQXX_CHECK_THROWS( - PQXX_CHECK_EQUAL(1, 2, "(expected)"), pqxx::test::test_failure, - "PQXX_CHECK_EQUAL fails to spot inequality."); - - // PQXX_CHECK_NOT_EQUAL is like PQXX_CHECK_EQUAL, but tests for inequality. - PQXX_CHECK_NOT_EQUAL(1, 2, "PQXX_CHECK_NOT_EQUAL is broken."); - PQXX_CHECK_THROWS( - PQXX_CHECK_NOT_EQUAL(1, 1, "(expected)"), pqxx::test::test_failure, - "PQXX_CHECK_NOT_EQUAL fails to fail when arguments are equal."); - PQXX_CHECK_THROWS( - PQXX_CHECK_NOT_EQUAL(1, 1L, "(expected)"), pqxx::test::test_failure, - "PQXX_CHECK_NOT_EQUAL breaks on type mismatch."); - - // PQXX_CHECK_BOUNDS checks a value against a range. - PQXX_CHECK_BOUNDS(2, 1, 3, "PQXX_CHECK_BOUNDS wrongly finds fault."); - - PQXX_CHECK_THROWS( - PQXX_CHECK_BOUNDS(1, 2, 3, "(Expected)"), pqxx::test::test_failure, - "PQXX_CHECK_BOUNDS did not detect value below permitted range."); - - // PQXX_CHECK_BOUNDS tests against a half-open interval. - PQXX_CHECK_BOUNDS(1, 1, 3, "PQXX_CHECK_BOUNDS goes wrong on lower bound."); - PQXX_CHECK_THROWS( - PQXX_CHECK_BOUNDS(3, 1, 3, "(Expected)"), pqxx::test::test_failure, - "PQXX_CHECK_BOUNDS interval is not half-open."); - - // PQXX_CHECK_BOUNDS deals well with empty intervals. - PQXX_CHECK_THROWS( - PQXX_CHECK_BOUNDS(1, 2, 1, "(Expected)"), pqxx::test::test_failure, - "PQXX_CHECK_BOUNDS did not detect empty interval."); -} - - -PQXX_REGISTER_TEST(test_test_helpers); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_thread_safety_model.cxx b/ext/libpqxx-7.7.3/test/unit/test_thread_safety_model.cxx deleted file mode 100644 index cf7627cb3..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_thread_safety_model.cxx +++ /dev/null @@ -1,23 +0,0 @@ -#include "../test_helpers.hxx" - -#include - -namespace -{ -void test_thread_safety_model() -{ - auto const model{pqxx::describe_thread_safety()}; - - if (model.safe_libpq and model.safe_kerberos) - PQXX_CHECK_EQUAL( - model.description, "", - "Thread-safety looks okay but model description is nonempty."); - else - PQXX_CHECK_NOT_EQUAL( - model.description, "", - "Thread-safety model is imperfect but lacks description."); -} - - -PQXX_REGISTER_TEST(test_thread_safety_model); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_time.cxx b/ext/libpqxx-7.7.3/test/unit/test_time.cxx deleted file mode 100644 index 2fb79d472..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_time.cxx +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -#if defined(PQXX_HAVE_YEAR_MONTH_DAY) -using namespace std::literals; - - -void test_date_string_conversion() -{ - pqxx::connection conn; - pqxx::work tx{conn}; - std::tuple const conversions[]{ - {-542, 1, 1, "0543-01-01 BC"sv}, - {-1, 2, 3, "0002-02-03 BC"sv}, - {0, 9, 14, "0001-09-14 BC"sv}, - {1, 12, 8, "0001-12-08"sv}, - {2021, 10, 24, "2021-10-24"sv}, - {10191, 8, 30, "10191-08-30"sv}, - {-4712, 1, 1, "4713-01-01 BC"sv}, - {32767, 12, 31, "32767-12-31"sv}, - {2000, 2, 29, "2000-02-29"sv}, - {2004, 2, 29, "2004-02-29"sv}, - // This one won't work in postgres, but we can test the conversions. - {-32767, 11, 3, "32768-11-03 BC"sv}, - }; - for (auto const &[y, m, d, text] : conversions) - { - std::chrono::year_month_day const date{ - std::chrono::year{y}, std::chrono::month{m}, std::chrono::day{d}}; - PQXX_CHECK_EQUAL( - pqxx::to_string(date), text, "Date did not convert right."); - PQXX_CHECK_EQUAL( - pqxx::from_string(text), date, - "Date did not parse right."); - if (int{date.year()} > -4712) - { - // We can't test this for years before 4713 BC (4712 BCE), because - // postgres doesn't handle earlier years. - PQXX_CHECK_EQUAL( - tx.query_value( - "SELECT '" + pqxx::to_string(date) + "'::date"), - text, "Backend interpreted date differently."); - } - } - - std::string_view const invalid[]{ - ""sv, - "yesterday"sv, - "1981-01"sv, - "2010"sv, - "2010-8-9"sv, - "1900-02-29"sv, - "2021-02-29"sv, - "2000-11-29-3"sv, - "1900-02-29"sv, - "2003-02-29"sv, - "12-12-12"sv, - "0000-09-16"sv, - "-01-01"sv, - "-1000-01-01"sv, - "1000-00-01"sv, - "1000-01-00"sv, - "2001y-01-01"sv, - "10-09-08"sv, - "0-01-01"sv, - "0000-01-01"sv, - "2021-13-01"sv, - "2021-+02-01"sv, - "2021-12-32"sv, - }; - for (auto const text : invalid) - PQXX_CHECK_THROWS( - pqxx::ignore_unused( - pqxx::from_string(text)), - pqxx::conversion_error, - pqxx::internal::concat("Invalid date '", text, "' parsed as if valid.")); -} - - -PQXX_REGISTER_TEST(test_date_string_conversion); -#endif // PQXX_HAVE_YEAR_MONTH_DAY -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_transaction.cxx b/ext/libpqxx-7.7.3/test/unit/test_transaction.cxx deleted file mode 100644 index 2ae016a26..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_transaction.cxx +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - - -namespace -{ -void test_nontransaction_continues_after_error() -{ - pqxx::connection c; - pqxx::nontransaction tx{c}; - - PQXX_CHECK_EQUAL( - tx.query_value("SELECT 9"), 9, "Simple query went wrong."); - PQXX_CHECK_THROWS( - tx.exec("SELECT 1/0"), pqxx::sql_error, "Expected error did not happen."); - - PQXX_CHECK_EQUAL( - tx.query_value("SELECT 5"), 5, "Wrong result after error."); -} - - -std::string const table{"pqxx_test_transaction"}; - - -void delete_temp_table(pqxx::transaction_base &tx) -{ - tx.exec0(std::string{"DROP TABLE IF EXISTS "} + table); -} - - -void create_temp_table(pqxx::transaction_base &tx) -{ - tx.exec0("CREATE TEMP TABLE " + table + " (x integer)"); -} - - -void insert_temp_table(pqxx::transaction_base &tx, int value) -{ - tx.exec0( - "INSERT INTO " + table + " (x) VALUES (" + pqxx::to_string(value) + ")"); -} - -int count_temp_table(pqxx::transaction_base &tx) -{ - return tx.query_value("SELECT count(*) FROM " + table); -} - - -void test_nontransaction_autocommits() -{ - pqxx::connection c; - - pqxx::nontransaction tx1{c}; - delete_temp_table(tx1); - create_temp_table(tx1); - tx1.commit(); - - pqxx::nontransaction tx2{c}; - insert_temp_table(tx2, 4); - tx2.abort(); - - pqxx::nontransaction tx3{c}; - PQXX_CHECK_EQUAL( - count_temp_table(tx3), 1, - "Did not keep effect of aborted nontransaction."); - delete_temp_table(tx3); -} - - -template void test_double_close() -{ - pqxx::connection c; - - TX tx1{c}; - tx1.exec1("SELECT 1"); - tx1.commit(); - tx1.commit(); - - TX tx2{c}; - tx2.exec1("SELECT 2"); - tx2.abort(); - tx2.abort(); - - TX tx3{c}; - tx3.exec1("SELECT 3"); - tx3.commit(); - PQXX_CHECK_THROWS( - tx3.abort(), pqxx::usage_error, "Abort after commit not caught."); - ; - - TX tx4{c}; - tx4.exec1("SELECT 4"); - tx4.abort(); - PQXX_CHECK_THROWS( - tx4.commit(), pqxx::usage_error, "Commit after abort not caught."); -} - - -void test_transaction() -{ - test_nontransaction_continues_after_error(); - test_nontransaction_autocommits(); - test_double_close>(); - test_double_close(); - test_double_close(); - test_double_close>(); -} - - -PQXX_REGISTER_TEST(test_transaction); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_transaction_base.cxx b/ext/libpqxx-7.7.3/test/unit/test_transaction_base.cxx deleted file mode 100644 index bea15b190..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_transaction_base.cxx +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_exec0(pqxx::transaction_base &trans) -{ - pqxx::result E{trans.exec0("SELECT * FROM pg_tables WHERE 0 = 1")}; - PQXX_CHECK(std::empty(E), "Nonempty result from exec0."); - - PQXX_CHECK_THROWS( - trans.exec0("SELECT 99"), pqxx::unexpected_rows, - "Nonempty exec0 result did not throw unexpected_rows."); -} - - -void test_exec1(pqxx::transaction_base &trans) -{ - pqxx::row R{trans.exec1("SELECT 99")}; - PQXX_CHECK_EQUAL(std::size(R), 1, "Wrong size result from exec1."); - PQXX_CHECK_EQUAL(R.front().as(), 99, "Wrong result from exec1."); - - PQXX_CHECK_THROWS( - trans.exec1("SELECT * FROM pg_tables WHERE 0 = 1"), pqxx::unexpected_rows, - "Empty exec1 result did not throw unexpected_rows."); - PQXX_CHECK_THROWS( - trans.exec1("SELECT * FROM generate_series(1, 2)"), pqxx::unexpected_rows, - "Two-row exec1 result did not throw unexpected_rows."); -} - - -void test_exec_n(pqxx::transaction_base &trans) -{ - pqxx::result R{trans.exec_n(3, "SELECT * FROM generate_series(1, 3)")}; - PQXX_CHECK_EQUAL(std::size(R), 3, "Wrong result size from exec_n."); - - PQXX_CHECK_THROWS( - trans.exec_n(2, "SELECT * FROM generate_series(1, 3)"), - pqxx::unexpected_rows, - "exec_n did not throw unexpected_rows for an undersized result."); - PQXX_CHECK_THROWS( - trans.exec_n(4, "SELECT * FROM generate_series(1, 3)"), - pqxx::unexpected_rows, - "exec_n did not throw unexpected_rows for an oversized result."); -} - - -void test_query_value(pqxx::connection &conn) -{ - pqxx::work tx{conn}; - - PQXX_CHECK_EQUAL( - tx.query_value("SELECT 84 / 2"), 42, - "Got wrong value from query_value."); - PQXX_CHECK_THROWS( - tx.query_value("SAVEPOINT dummy"), pqxx::unexpected_rows, - "Got field when none expected."); - PQXX_CHECK_THROWS( - tx.query_value("SELECT generate_series(1, 2)"), pqxx::unexpected_rows, - "Failed to fail for multiple rows."); - PQXX_CHECK_THROWS( - tx.query_value("SELECT 1, 2"), pqxx::usage_error, - "No error for too many fields."); - PQXX_CHECK_THROWS( - tx.query_value("SELECT 3.141"), pqxx::conversion_error, - "Got int field from float string."); -} - - -void test_transaction_base() -{ - pqxx::connection conn; - { - pqxx::work tx{conn}; - test_exec_n(tx); - test_exec0(tx); - test_exec1(tx); - } - test_query_value(conn); -} - - -void test_transaction_for_each() -{ - constexpr auto query{ - "SELECT i, concat('x', (2*i)::text) " - "FROM generate_series(1, 3) AS i " - "ORDER BY i"}; - pqxx::connection conn; - pqxx::work tx{conn}; - std::string ints; - std::string strings; - tx.for_each(query, [&ints, &strings](int i, std::string const &s) { - ints += pqxx::to_string(i) + " "; - strings += s + " "; - }); - PQXX_CHECK_EQUAL(ints, "1 2 3 ", "Unexpected int sequence."); - PQXX_CHECK_EQUAL(strings, "x2 x4 x6 ", "Unexpected string sequence."); -} - - -PQXX_REGISTER_TEST(test_transaction_base); -PQXX_REGISTER_TEST(test_transaction_for_each); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_transaction_focus.cxx b/ext/libpqxx-7.7.3/test/unit/test_transaction_focus.cxx deleted file mode 100644 index 48fdfdd3f..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_transaction_focus.cxx +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -auto make_focus(pqxx::dbtransaction &tx) -{ - return pqxx::stream_from::query(tx, "SELECT * from generate_series(1, 10)"); -} - - -void test_cannot_run_statement_during_focus() -{ - pqxx::connection conn; - pqxx::transaction tx{conn}; - tx.exec("SELECT 1"); - auto focus{make_focus(tx)}; - PQXX_CHECK_THROWS( - tx.exec("SELECT 1"), pqxx::usage_error, - "Command during focus did not throw expected error."); -} - - -void test_cannot_run_prepared_statement_during_focus() -{ - pqxx::connection conn; - conn.prepare("foo", "SELECT 1"); - pqxx::transaction tx{conn}; - tx.exec_prepared("foo"); - auto focus{make_focus(tx)}; - PQXX_CHECK_THROWS( - tx.exec_prepared("foo"), pqxx::usage_error, - "Prepared statement during focus did not throw expected error."); -} - -void test_cannot_run_params_statement_during_focus() -{ - pqxx::connection conn; - pqxx::transaction tx{conn}; - tx.exec_params("select $1", 10); - auto focus{make_focus(tx)}; - PQXX_CHECK_THROWS( - tx.exec_params("select $1", 10), pqxx::usage_error, - "Parameterized statement during focus did not throw expected error."); -} - - -PQXX_REGISTER_TEST(test_cannot_run_statement_during_focus); -PQXX_REGISTER_TEST(test_cannot_run_prepared_statement_during_focus); -PQXX_REGISTER_TEST(test_cannot_run_params_statement_during_focus); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_transactor.cxx b/ext/libpqxx-7.7.3/test/unit/test_transactor.cxx deleted file mode 100644 index 43034807e..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_transactor.cxx +++ /dev/null @@ -1,130 +0,0 @@ -#include -#include - -#include "../test_helpers.hxx" - -namespace -{ -void test_transactor_newstyle_executes_simple_query() -{ - pqxx::connection conn; - auto const r{pqxx::perform([&conn] { - return pqxx::work{conn}.exec("SELECT generate_series(1, 4)"); - })}; - - PQXX_CHECK_EQUAL(std::size(r), 4, "Unexpected result size."); - PQXX_CHECK_EQUAL(r.columns(), 1, "Unexpected number of columns."); - PQXX_CHECK_EQUAL(r[0][0].as(), 1, "Unexpected first row."); - PQXX_CHECK_EQUAL(r[3][0].as(), 4, "Unexpected last row."); -} - - -void test_transactor_newstyle_can_return_void() -{ - bool done{false}; - pqxx::perform([&done]() noexcept { done = true; }); - PQXX_CHECK(done, "Callback was not executed."); -} - - -void test_transactor_newstyle_completes_upon_success() -{ - int attempts{0}; - pqxx::perform([&attempts]() noexcept { attempts++; }); - PQXX_CHECK_EQUAL(attempts, 1, "Successful transactor didn't run 1 time."); -} - - -void test_transactor_newstyle_retries_broken_connection() -{ - int counter{0}; - auto const &callback{[&counter] { - ++counter; - if (counter == 1) - throw pqxx::broken_connection(); - return counter; - }}; - - int const result{pqxx::perform(callback)}; - PQXX_CHECK_EQUAL(result, 2, "Transactor run returned wrong result."); - PQXX_CHECK_EQUAL(counter, result, "Number of retries does not match."); -} - - -void test_transactor_newstyle_retries_rollback() -{ - int counter{0}; - auto const &callback{[&counter] { - ++counter; - if (counter == 1) - throw pqxx::transaction_rollback("Simulated error"); - return counter; - }}; - - int const result{pqxx::perform(callback)}; - PQXX_CHECK_EQUAL(result, 2, "Transactor run returned wrong result."); - PQXX_CHECK_EQUAL(counter, result, "Number of retries does not match."); -} - - -void test_transactor_newstyle_does_not_retry_in_doubt_error() -{ - int counter{0}; - auto const &callback{[&counter] { - ++counter; - throw pqxx::in_doubt_error("Simulated error"); - }}; - - PQXX_CHECK_THROWS( - pqxx::perform(callback), pqxx::in_doubt_error, - "Transactor did not propagate in_doubt_error."); - PQXX_CHECK_EQUAL(counter, 1, "Transactor retried after in_doubt_error."); -} - - -void test_transactor_newstyle_does_not_retry_other_error() -{ - int counter{0}; - auto const &callback{[&counter] { - ++counter; - throw std::runtime_error("Simulated error"); - }}; - - PQXX_CHECK_THROWS( - pqxx::perform(callback), std::runtime_error, - "Transactor did not propagate std exception."); - PQXX_CHECK_EQUAL(counter, 1, "Transactor retried after std exception."); -} - - -void test_transactor_newstyle_repeats_up_to_given_number_of_attempts() -{ - int const attempts{5}; - int counter{0}; - auto const &callback{[&counter] { - ++counter; - throw pqxx::transaction_rollback("Simulated error"); - }}; - - PQXX_CHECK_THROWS( - pqxx::perform(callback, attempts), pqxx::transaction_rollback, - "Not propagating original exception."); - PQXX_CHECK_EQUAL(counter, attempts, "Number of retries does not match."); -} - - -void test_transactor() -{ - test_transactor_newstyle_executes_simple_query(); - test_transactor_newstyle_can_return_void(); - test_transactor_newstyle_completes_upon_success(); - test_transactor_newstyle_retries_broken_connection(); - test_transactor_newstyle_retries_rollback(); - test_transactor_newstyle_does_not_retry_in_doubt_error(); - test_transactor_newstyle_does_not_retry_other_error(); - test_transactor_newstyle_repeats_up_to_given_number_of_attempts(); -} - - -PQXX_REGISTER_TEST(test_transactor); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_type_name.cxx b/ext/libpqxx-7.7.3/test/unit/test_type_name.cxx deleted file mode 100644 index af1c93eb5..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_type_name.cxx +++ /dev/null @@ -1,19 +0,0 @@ -#include "../test_helpers.hxx" - -namespace -{ -void test_type_name() -{ - // It's hard to test in more detail, because spellings may differ. - // For instance, one compiler might call "const unsigned int*" what another - // might call "unsigned const *". And Visual Studio prefixes "class" to - // class types. - std::string const i{pqxx::type_name}; - PQXX_CHECK_LESS(std::size(i), 5u, "type_name is suspiciously long."); - PQXX_CHECK_EQUAL( - i.substr(0, 1), "i", "type_name does not start with 'i'."); -} - - -PQXX_REGISTER_TEST(test_type_name); -} // namespace diff --git a/ext/libpqxx-7.7.3/test/unit/test_zview.cxx b/ext/libpqxx-7.7.3/test/unit/test_zview.cxx deleted file mode 100644 index f8ce5b9e1..000000000 --- a/ext/libpqxx-7.7.3/test/unit/test_zview.cxx +++ /dev/null @@ -1,16 +0,0 @@ -#include - -#include "../test_helpers.hxx" - - -namespace -{ -void test_zview_literal() -{ - using pqxx::operator"" _zv; - - PQXX_CHECK_EQUAL(("foo"_zv), pqxx::zview{"foo"}, "zview literal is broken."); -} - -PQXX_REGISTER_TEST(test_zview_literal); -} // namespace diff --git a/ext/libpqxx-7.7.3/tools/Makefile.am b/ext/libpqxx-7.7.3/tools/Makefile.am deleted file mode 100644 index 9f918cd5a..000000000 --- a/ext/libpqxx-7.7.3/tools/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -EXTRA_DIST = \ - extract_version \ - lint \ - rmlo.cxx \ - splitconfig \ - template2mak.py \ - pqxxthreadsafety.cxx - -AM_CPPFLAGS=-I$(top_builddir)/include -I$(top_srcdir)/include ${POSTGRES_INCLUDE} -# Override automatically generated list of default includes. It contains only -# unnecessary entries, and incorrectly mentions include/pqxx directly. -DEFAULT_INCLUDES= - -noinst_PROGRAMS = rmlo pqxxthreadsafety - -rmlo_SOURCES = rmlo.cxx -rmlo_LDADD = $(top_builddir)/src/libpqxx.la ${POSTGRES_LIB} - -pqxxthreadsafety_SOURCES = pqxxthreadsafety.cxx -pqxxthreadsafety_LDADD = $(top_builddir)/src/libpqxx.la ${POSTGRES_LIB} diff --git a/ext/libpqxx-7.7.3/tools/Makefile.in b/ext/libpqxx-7.7.3/tools/Makefile.in deleted file mode 100644 index 4e21cb265..000000000 --- a/ext/libpqxx-7.7.3/tools/Makefile.in +++ /dev/null @@ -1,638 +0,0 @@ -# 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@ -noinst_PROGRAMS = rmlo$(EXEEXT) pqxxthreadsafety$(EXEEXT) -subdir = tools -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 = -PROGRAMS = $(noinst_PROGRAMS) -am_pqxxthreadsafety_OBJECTS = pqxxthreadsafety.$(OBJEXT) -pqxxthreadsafety_OBJECTS = $(am_pqxxthreadsafety_OBJECTS) -pqxxthreadsafety_DEPENDENCIES = $(top_builddir)/src/libpqxx.la -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -am_rmlo_OBJECTS = rmlo.$(OBJEXT) -rmlo_OBJECTS = $(am_rmlo_OBJECTS) -rmlo_DEPENDENCIES = $(top_builddir)/src/libpqxx.la -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 = -depcomp = $(SHELL) $(top_srcdir)/config/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/pqxxthreadsafety.Po \ - ./$(DEPDIR)/rmlo.Po -am__mv = mv -f -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -AM_V_CXX = $(am__v_CXX_@AM_V@) -am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) -am__v_CXX_0 = @echo " CXX " $@; -am__v_CXX_1 = -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) -am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) -am__v_CXXLD_0 = @echo " CXXLD " $@; -am__v_CXXLD_1 = -SOURCES = $(pqxxthreadsafety_SOURCES) $(rmlo_SOURCES) -DIST_SOURCES = $(pqxxthreadsafety_SOURCES) $(rmlo_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) -# 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 $(top_srcdir)/config/depcomp \ - $(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@ -EXTRA_DIST = \ - extract_version \ - lint \ - rmlo.cxx \ - splitconfig \ - template2mak.py \ - pqxxthreadsafety.cxx - -AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include ${POSTGRES_INCLUDE} -# Override automatically generated list of default includes. It contains only -# unnecessary entries, and incorrectly mentions include/pqxx directly. -DEFAULT_INCLUDES = -rmlo_SOURCES = rmlo.cxx -rmlo_LDADD = $(top_builddir)/src/libpqxx.la ${POSTGRES_LIB} -pqxxthreadsafety_SOURCES = pqxxthreadsafety.cxx -pqxxthreadsafety_LDADD = $(top_builddir)/src/libpqxx.la ${POSTGRES_LIB} -all: all-am - -.SUFFIXES: -.SUFFIXES: .cxx .lo .o .obj -$(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 tools/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu tools/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): - -clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -pqxxthreadsafety$(EXEEXT): $(pqxxthreadsafety_OBJECTS) $(pqxxthreadsafety_DEPENDENCIES) $(EXTRA_pqxxthreadsafety_DEPENDENCIES) - @rm -f pqxxthreadsafety$(EXEEXT) - $(AM_V_CXXLD)$(CXXLINK) $(pqxxthreadsafety_OBJECTS) $(pqxxthreadsafety_LDADD) $(LIBS) - -rmlo$(EXEEXT): $(rmlo_OBJECTS) $(rmlo_DEPENDENCIES) $(EXTRA_rmlo_DEPENDENCIES) - @rm -f rmlo$(EXEEXT) - $(AM_V_CXXLD)$(CXXLINK) $(rmlo_OBJECTS) $(rmlo_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pqxxthreadsafety.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmlo.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.cxx.o: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< - -.cxx.obj: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.cxx.lo: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(PROGRAMS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ - mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/pqxxthreadsafety.Po - -rm -f ./$(DEPDIR)/rmlo.Po - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/pqxxthreadsafety.Po - -rm -f ./$(DEPDIR)/rmlo.Po - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - - -# 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/tools/deprecations b/ext/libpqxx-7.7.3/tools/deprecations deleted file mode 100755 index f3970838b..000000000 --- a/ext/libpqxx-7.7.3/tools/deprecations +++ /dev/null @@ -1,6 +0,0 @@ -#! /bin/sh -set -eu - -MARKER='include.*ignore-deprecated-pre' -FILES="src include tools/*.cxx test config-tests" -grep -Ircl $MARKER $FILES | sort diff --git a/ext/libpqxx-7.7.3/tools/extract_version b/ext/libpqxx-7.7.3/tools/extract_version deleted file mode 100755 index 920ed9aad..000000000 --- a/ext/libpqxx-7.7.3/tools/extract_version +++ /dev/null @@ -1,73 +0,0 @@ -#! /bin/sh -set -eu - -ARG="${1:-}" - -# Source directory. In out-of-tree builds, Automake sets this for us. -srcdir=${srcdir:-.} - - -# Print usage information. -usage() { - cat <... - -Acceptable option values are: - -h, --help Print this message, and exit. - -a, --abi Show libpqxx ABI version; leave out revision number. - -f, --full Show full libpqxx version string (the default). - -M, --major Show major libpqxx version. - -m, --minor Show minor libpqxx version (between major and revision). -EOF -} - - -# Print "unknown argument" error. -unknown_arg() { - cat <&2 -Unknown argument: $1. -Try - - $0 --help - -for usage information. -EOF -} - - -case "$ARG" in -''|-f|--full) - # Default: Print full version. - cat $srcdir/VERSION - ;; - --h|--help) - # Print usage information, and exit. - usage - exit - ;; - --a|--abi) - # Print just the ABI version (major & minor). - sed -e 's/^\([^.]*\.[^.]*\)\..*/\1/' $srcdir/VERSION - ;; - --M|--major) - # Print the major version number. - sed -e 's/^\([^.]*\)\..*/\1/' $srcdir/VERSION - ;; - --m|--minor) - # Print the minor version number. - sed -e 's/^[^.]*\.\([^.]*\)\..*/\1/' $srcdir/VERSION - ;; - -*) - unknown_arg $ARG - exit 1 - ;; -esac diff --git a/ext/libpqxx-7.7.3/tools/format b/ext/libpqxx-7.7.3/tools/format deleted file mode 100755 index 2645ccdf6..000000000 --- a/ext/libpqxx-7.7.3/tools/format +++ /dev/null @@ -1,20 +0,0 @@ -#! /bin/bash -# -# Reformat source code using clang-format. -# -# This script is not portable: as of Ubuntu 21.04, virtualenv's "activate" -# seems to rely on a non-POSIX variable, $OSTYPE. - -set -C -u -e - -# Reformat C++ files. -find -name \*.cxx -o -name \*.hxx | xargs clang-format -i - - -# Reformat CMake files. -WORKDIR=$(mktemp -d) -virtualenv -q --python=$(which python3) "$WORKDIR/venv" -. "$WORKDIR/venv/bin/activate" -pip install -q six pyaml cmake-format -(find -name CMakeLists.txt | xargs cmake-format -i) || /bin/true -rm -rf "$WORKDIR" diff --git a/ext/libpqxx-7.7.3/tools/lint b/ext/libpqxx-7.7.3/tools/lint deleted file mode 100755 index 7beadbb27..000000000 --- a/ext/libpqxx-7.7.3/tools/lint +++ /dev/null @@ -1,197 +0,0 @@ -#! /bin/bash -# -# Routine sanity checks for libpqxx source tree. -# -# Optionally, set environment variable "srcdir" to the source directory. It -# defaults to the parent directory of the one where this script is. This trick -# requires bash (or a close equivalent) as the shell. - -set -eu -o pipefail - -SRCDIR="${srcdir:-$(dirname "${BASH_SOURCE[0]}")/..}" -PQXXVERSION="$(cd "$SRCDIR" && "$SRCDIR/tools/extract_version")" - -ARGS="${1:-}" - - -# Check that all source code is ASCII. -# -# I'd love to have rich Unicode, but I can live without it. But we don't want -# any surprises in contributions. -check_ascii() { - local exotics=$( - find -name \*.cxx -o -name \*.hxx | - xargs cat | - tr -d '\011-\176' | - wc -c - ) - if [ $exotics != 0 ] - then - echo >&2 "There's a non-ASCII character somewhere." - exit 1 - fi -} - - -# This version must be at the top of the NEWS file. -check_news_version() { - if ! head -n1 $SRCDIR/NEWS | grep -q "^$PQXXVERSION\$" - then - cat <&2 -Version $PQXXVERSION is not at the top of NEWS. -EOF - exit 1 - fi -} - - -# Count number of times header $1 is included from each of given input files. -# Output is lines of :, one line per file, sorted. -count_includes() { - local HEADER_NAME WS PAT - HEADER_NAME="$1" - shift - WS="[[:space:]]*" - PAT="^${WS}#${WS}include${WS}[<\"]$HEADER_NAME[>\"]" - # It's OK for the grep to fail. - (grep -c "$PAT" $* || /bin/true) | sort -} - - -# Check that any includes of $1-pre.hxx are matched by $1-post.hxx ones. -match_pre_post_headers() { - local NAME TEMPDIR PRE POST HEADERS - NAME="$1" - TEMPDIR="$(mktemp -d)" - if test -z "$TEMPDIR" - then - echo >&2 "Could not create temporary directory." - exit 1 - fi - PRE="$TEMPDIR/pre" - POST="$TEMPDIR/post" - HEADERS=$(find include/pqxx/* -type f | grep -v '\.swp$') - count_includes \ - $SRCDIR/NAME-pre.hxx $HEADERS >"$PRE" - count_includes \ - $SRCDIR/NAME-post.hxx $HEADERS >"$POST" - DIFF="$(diff "$PRE" "$POST")" || /bin/true - rm -r -- "$TEMPDIR" - if test -n "$DIFF" - then - cat <&2 -Mismatched pre/post header pairs: - -$DIFF -EOF - exit 1 - fi -} - - -# Any file that includes header-pre.hxx must also include header-post.hxx, and -# vice versa. Similar for ignore-deprecated-{pre|post}.hxx. -check_compiler_internal_headers() { - match_pre_post_headers "pqxx/internal/header" - match_pre_post_headers "pqxx/internal/ignore-deprecated" -} - - -cpplint() { - local cxxflags dialect includes - - if which clang-tidy >/dev/null - then - if [ -e compile_flags ] - then - # Pick out relevant flags, but leave out the rest. - # If we're not compiling with clang, compile_flags may contain - # options that clang-tidy doesn't recognise. - dialect="$(grep -o -- '-std=[^[:space:]]*' compile_flags || true)" - includes="$( - grep -o -- '-I[[:space:]]*[^[:space:]]*' compile_flags || - true)" - else - dialect="" - includes="" - fi - - cxxflags="$dialect $includes" - -# TODO: Please, is there any way we can parallelise this? -# TODO: I'd like cppcoreguidelines-*, but it's a tsunami of false positives. -# TODO: Some useful checks in abseil-*, but it recommends "use our library." -# TODO: Check test/, but tolerate some of the dubious stuff tests do. - clang-tidy \ - $(find $SRCDIR/src $SRCDIR/tools -name \*.cxx) \ - --checks=boost-*, \ - -- \ - -I$SRCDIR/include -Iinclude $cxxflags - fi - - # Run Facebook's "infer" static analyser, if available. - # Instructions here: https://fbinfer.com/docs/getting-started/ - if which infer >/dev/null - then - # This will work in an out-of-tree build, but either way it does - # require a successful "configure", or a cmake with the "make" - # generator. - infer capture -- make -j$(nproc) - infer run - fi -} - - -pylint() { - local PYFILES="$SRCDIR/tools/*.py $SRCDIR/tools/splitconfig" - echo "Skipping pocketlint; it's not up to date with Python3." - # if which pocketlint >/dev/null - # then - # pocketlint $PYFILES - # fi - - if which pyflakes3 >/dev/null - then - pyflakes3 $PYFILES - fi -} - - -main() { - local full="no" - for arg in $ARGS - do - case $arg in - -h|--help) - cat <&2 "Unknown argument: '$arg'" - exit 1 - ;; - esac - done - - check_ascii - pylint - check_news_version - check_compiler_internal_headers - if [ $full == "yes" ] - then - cpplint - fi -} - - -main diff --git a/ext/libpqxx-7.7.3/tools/m4esc.py b/ext/libpqxx-7.7.3/tools/m4esc.py deleted file mode 100755 index 355169db2..000000000 --- a/ext/libpqxx-7.7.3/tools/m4esc.py +++ /dev/null @@ -1,70 +0,0 @@ -#! /usr/bin/env python3 - -"""M4-quote text, for use as a literal in configure.ac. - -Produces M4 "code" which evaluates to the input text. - -It's not easy to read plain text from an input file in M4, without having it -expanded as M4. Sometimes all we want is literal text! -""" -from __future__ import ( - absolute_import, - print_function, - unicode_literals, - ) - -from argparse import ArgumentParser -from sys import ( - stdin, - stdout, - ) - - -def parse_args(): - parser = ArgumentParser(description=__doc__) - parser.add_argument( - '--open', '-a', default='[[', help="Current open-quote symbol.") - parser.add_argument( - '--close', '-b', default=']]', help="Current close-quote symbol.") - parser.add_argument( - '--input', '-i', default='-', help="Input file, or '-' for stdin.") - parser.add_argument( - '--output', '-o', default='-', help="Output file, or '-' for stdout.") - return parser.parse_args() - - -def open_input(in_file): - if in_file == '-': - return stdin - else: - return open(in_file) - - -def open_output(out_file): - if out_file == '-': - return stdout - else: - return open(out_file, 'w') - - -def escape(line): - return ( - line - .replace('[', '@<:@') - .replace(']', '@:>@') - .replace('#', '@%:@') - .replace('$', '@S|@') - ) - - -def main(args): - with open_input(args.input) as istr, open_output(args.output) as ostr: - ostr.write(args.open) - for line in istr: - ostr.write(escape(line)) - ostr.write('\n') - ostr.write(args.close) - - -if __name__ == '__main__': - main(parse_args()) diff --git a/ext/libpqxx-7.7.3/tools/pqxxthreadsafety.cxx b/ext/libpqxx-7.7.3/tools/pqxxthreadsafety.cxx deleted file mode 100644 index afa8fb01f..000000000 --- a/ext/libpqxx-7.7.3/tools/pqxxthreadsafety.cxx +++ /dev/null @@ -1,10 +0,0 @@ -// Print thread-safety information for present libpqxx build. -#include - -#include "pqxx/util" - - -int main() -{ - std::cout << pqxx::describe_thread_safety().description << std::endl; -} diff --git a/ext/libpqxx-7.7.3/tools/rmlo.cxx b/ext/libpqxx-7.7.3/tools/rmlo.cxx deleted file mode 100644 index 5db9605f1..000000000 --- a/ext/libpqxx-7.7.3/tools/rmlo.cxx +++ /dev/null @@ -1,39 +0,0 @@ -// Remove large objects given on the command line from the default database. -#include - -#include "pqxx/pqxx" - - -int main(int, char *argv[]) -{ - pqxx::connection conn; - bool failures = false; - - try - { - for (int i{1}; argv[i]; ++i) - { - auto o{pqxx::from_string(argv[i])}; - try - { - pqxx::perform([o, &conn] { - pqxx::work tx{conn}; - pqxx::blob::remove(tx, o); - tx.commit(); - }); - } - catch (std::exception const &e) - { - std::cerr << e.what() << std::endl; - failures = true; - } - } - } - catch (std::exception const &e) - { - std::cerr << e.what() << std::endl; - return 2; - } - - return failures; -} diff --git a/ext/libpqxx-7.7.3/tools/splitconfig b/ext/libpqxx-7.7.3/tools/splitconfig deleted file mode 100755 index 2f4be957f..000000000 --- a/ext/libpqxx-7.7.3/tools/splitconfig +++ /dev/null @@ -1,244 +0,0 @@ -#! /usr/bin/env python3 - -"""Extract configuration items into various configuration headers. - -This uses the configitems file, a database consisting of text lines with the -following single-tab-separated fields: - - Name of the configuration item, e.g. PQXX_HAVE_PTRDIFF_T. - - Publication marker: public or internal. - - A single environmental factor determining the item, e.g. libpq or compiler. -""" - -from __future__ import ( - absolute_import, - print_function, - unicode_literals, - ) - -from argparse import ArgumentParser -import codecs -from errno import ENOENT -import os.path -from os import getcwd -import re -from sys import ( - getdefaultencoding, - getfilesystemencoding, - stdout, - ) - -__metaclass__ = type - - -def guess_fs_encoding(): - """Try to establish the filesystem encoding. - - It's a sad thing: some guesswork is involved. The encoding often seems to - be conservatively, and incorrectly, set to ascii. - """ - candidates = [ - getfilesystemencoding(), - getdefaultencoding(), - 'utf-8', - ] - for encoding in candidates: - lower = encoding.lower() - if lower != 'ascii' and lower != 'ansi_x3.4-1968': - return encoding - raise AssertionError("unreachable code reached.") - - -def guess_output_encoding(): - """Return the encoding of standard output.""" - # Apparently builds in Docker containers may have None as an encoding. - # Fall back to ASCII. If this ever happens in a non-ASCII path, well, - # there may be a more difficult decision to be made. We'll burn that - # bridge when we get to it, as they almost say. - return stdout.encoding or 'ascii' - - -def decode_path(path): - """Decode a path element from bytes to unicode string.""" - return path.decode(guess_fs_encoding()) - - -def encode_path(path): - """Encode a path element from unicode string to bytes.""" - # Nasty detail: unicode strings are stored as UTF-16. Which can contain - # surrogate pairs. And those break in encoding, unless you use this - # special error handler. - return path.encode(guess_fs_encoding(), 'surrogateescape') - - -def read_text_file(path, encoding='utf-8'): - """Read text file, return as string, or `None` if file is not there.""" - assert isinstance(path, type('')) - try: - with codecs.open(encode_path(path), encoding=encoding) as stream: - return stream.read() - except IOError as error: - if error.errno == ENOENT: - return None - else: - raise - - -def read_lines(path, encoding='utf-8'): - """Read text file, return as list of lines.""" - assert isinstance(path, type('')) - with codecs.open(encode_path(path), encoding=encoding) as stream: - return list(stream) - - -def read_configitems(filename): - """Read the configuration-items database. - - :param filename: Path to the configitems file. - :return: Sequence of text lines from configitems file. - """ - return [line.split() for line in read_lines(filename)] - - -def map_configitems(items): - """Map each config item to publication/factor. - - :param items: Sequence of config items: (name, publication, factor). - :return: Dict mapping each item name to a tuple (publication, factor). - """ - return { - item: (publication, factor) - for item, publication, factor in items - } - - -def read_header(source_tree, filename): - """Read the original config.h generated by autoconf. - - :param source_tree: Path to libpqxx source tree. - :param filename: Path to the config.h file. - :return: Sequence of text lines from config.h. - """ - assert isinstance(source_tree, type('')) - assert isinstance(filename, type('')) - return read_lines(os.path.join(source_tree, filename)) - - -def extract_macro_name(config_line): - """Extract a cpp macro name from a configuration line. - - :param config_line: Text line from config.h which may define a macro. - :return: Name of macro defined in `config_line` if it is a `#define` - statement, or None. - """ - config_line = config_line.strip() - match = re.match('\s*#\s*define\s+([^\s]+)', config_line) - if match is None: - return None - else: - return match.group(1) - - -def extract_section(header_lines, items, publication, factor): - """Extract config items for given publication/factor from header lines. - - :param header_lines: Sequence of header lines from config.h. - :param items: Dict mapping macro names to (publication, factor). - :param publication: Extract only macros for this publication tag. - :param factor: Extract only macros for this environmental factor. - :return: Sequence of `#define` lines from `header_lines` insofar they - fall within the requested section. - """ - return sorted( - line.strip() - for line in header_lines - if items.get(extract_macro_name(line)) == (publication, factor) - ) - - -def compose_header(lines, publication, factor): - """Generate header text containing given lines.""" - intro = ( - "/* Automatically generated from config.h: %s/%s config. */" - % (publication, factor) - ) - return '\n'.join([intro, ''] + lines + ['']) - - -def generate_config(source_tree, header_lines, items, publication, factor): - """Generate config file for a given section, if appropriate. - - Writes nothing if the configuration file ends up identical to one that's - already there. - - :param source_tree: Location of the libpqxx source tree. - :param header_lines: Sequence of header lines from config.h. - :param items: Dict mapping macro names to (publication, factor). - :param publication: Extract only macros for this publication tag. - :param factor: Extract only macros for this environmental factor. - """ - assert isinstance(source_tree, type('')) - config_file = os.path.join( - source_tree, 'include', 'pqxx', - 'config-%s-%s.h' % (publication, factor)) - unicode_path = config_file.encode(guess_output_encoding(), 'replace') - section = extract_section(header_lines, items, publication, factor) - contents = compose_header(section, publication, factor) - if read_text_file(config_file) == contents: - print("Generating %s: no changes--skipping." % unicode_path) - return - - print("Generating %s: %d item(s)." % (unicode_path, len(section))) - path = encode_path(config_file) - with codecs.open(path, 'wb', encoding='ascii') as header: - header.write(contents) - - -def parse_args(): - """Parse command-line arguments.""" - default_source_tree = os.path.dirname( - os.path.dirname(os.path.normpath(os.path.abspath(__file__)))) - parser = ArgumentParser(description=__doc__) - parser.add_argument( - 'sourcetree', metavar='PATH', default=default_source_tree, - help="Location of libpqxx source tree. Defaults to '%(default)s'.") - return parser.parse_args() - - -def check_args(args): - """Validate command-line arguments.""" - if not os.path.isdir(args.sourcetree): - raise Exception("Not a directory: '%s'." % args.sourcetree) - - -def get_current_dir(): - cwd = getcwd() - if isinstance(cwd, bytes): - return decode_path(cwd) - else: - return cwd - - -def main(): - """Main program entry point.""" - args = parse_args() - check_args(args) - # The configitems file is under revision control; it's in sourcetree. - items = read_configitems(os.path.join(args.sourcetree, 'configitems')) - publications = sorted(set(item[1] for item in items)) - factors = sorted(set(item[2] for item in items)) - # The config.h header is generated; it's in the build tree, which should - # be where we are. - directory = get_current_dir() - original_header = read_header( - directory, - os.path.join('include', 'pqxx', 'config.h')) - items_map = map_configitems(items) - - for publication in publications: - for factor in factors: - generate_config( - directory, original_header, items_map, publication, factor) - - -if __name__ == '__main__': - main() diff --git a/ext/libpqxx-7.7.3/tools/template2mak.py b/ext/libpqxx-7.7.3/tools/template2mak.py deleted file mode 100755 index 9a5286d95..000000000 --- a/ext/libpqxx-7.7.3/tools/template2mak.py +++ /dev/null @@ -1,194 +0,0 @@ -#! /usr/bin/env python3 -"""Minimal macro processor. Used for generating VC++ makefiles. - -The available template commands are: - - Expand a template section for each file in a list of file patterns:: - ###MAKTEMPLATE:FOREACH my/path*/*.cxx,other*.cxx - ... - ###MAKTEMPLATE:ENDFOREACH - - In the template section, you can use `###BASENAME###` to get the base name - of the file being processed (e.g. "base" for "../base.cxx"), and you can - use `###FILENAME###` to get the full filename. - - -Copyright (c) 2000-2022, Bart Samwel and Jeroen T. Vermeulen. -""" - -from __future__ import ( - absolute_import, - print_function, - unicode_literals, - ) - -from argparse import ( - ArgumentError, - ArgumentParser, - RawDescriptionHelpFormatter, - ) -from contextlib import contextmanager -from glob import glob -import os -from sys import ( - argv, - stdin, - stderr, - stdout, - ) -import sys -from textwrap import dedent - - -def expand_foreach_file(path, block, outfile): - """Expand a "foreach" block for a single file path. - - Write the results to outfile. - """ - basepath, _ = os.path.splitext(os.path.basename(path)) - for line in block: - line = line.replace("###FILENAME###", path) - line = line.replace("###BASENAME###", basepath) - outfile.write(line) - - -def match_globs(globs): - """List all files matching any item in globs. - - Eliminates duplicates. - """ - return sorted({ - path - for pattern in globs - for path in glob(pattern) - }) - - -def expand_foreach(globs, block, outfile): - """Expand a foreach block for each file matching one of globs. - - Write the results to outfile. - """ - # We'll be iterating over block a variable number of times. Turn it - # from a generic iterable into an immutable array. - block = tuple(block) - for path in match_globs(globs): - expand_foreach_file(path, block, outfile) - - -# Header to be prefixed to the generated file. -OUTPUT_HEADER = dedent("""\ - # AUTOMATICALLY GENERATED FILE -- DO NOT EDIT. - # - # This file is generated automatically by libpqxx's {script} script, and - # will be rewritten from time to time. - # - # If you modify this file, chances are your modifications will be lost. - # - # The {script} script should be available in the tools directory of the - # libpqxx source archive. - """) - - -foreach_marker = r"###MAKTEMPLATE:FOREACH " -end_foreach_marker = r"###MAKTEMPLATE:ENDFOREACH" - - -def parse_foreach(line): - """Parse FOREACH directive, if line contains one. - - :param line: One line of template input. - :return: A list of FOREACH globs, or None if this was not a FOREACH line. - """ - line = line.strip() - if line.startswith(foreach_marker): - return line[len(foreach_marker):].split(',') - else: - return None - - -def read_foreach_block(infile): - """Read a FOREACH block from infile (not including the FOREACH directive). - - Assumes that the FOREACH directive was in the preceding line. Consumes - the line with the ENDFOREACH directive, but does not yield it. - - :return: Iterable of lines. - """ - for line in infile: - if line.strip().startswith(end_foreach_marker): - return - yield line - - -def expand_template(infile, outfile): - """Expand the template in infile, and write the results to outfile.""" - for line in infile: - globs = parse_foreach(line) - if globs is None: - # Not a FOREACH line. Copy to output. - outfile.write(line) - else: - block = read_foreach_block(infile) - expand_foreach(globs, block, outfile) - - -@contextmanager -def open_stream(path=None, default=None, mode='r'): - """Open file at given path, or yield default. Close as appropriate. - - The default should be a stream, not a path; closing the context will not - close it. - """ - if path is None: - yield default - else: - with open(path, mode) as stream: - yield stream - - -def parse_args(): - """Parse command-line arguments. - - :return: Tuple of: input path (or None for stdin), output path (or None - for stdout). - """ - parser = ArgumentParser( - description=__doc__, formatter_class=RawDescriptionHelpFormatter) - - parser.add_argument( - 'template', nargs='?', - help="Input template. Defaults to standard input.") - parser.add_argument( - 'output', nargs='?', - help="Output file. Defaults to standard output.") - - args = parser.parse_args() - return args.template, args.output - - -def write_header(stream, template_path=None): - """Write header to stream.""" - hr = ('# ' + '#' * 78) + "\n" - script = os.path.basename(argv[0]) - - outstream.write(hr) - outstream.write(OUTPUT_HEADER.format(script=script)) - if template_path is not None: - outstream.write("#\n") - outstream.write("# Generated from template '%s'.\n" % template_path) - outstream.write(hr) - - -if __name__ == '__main__': - try: - template_path, output_path = parse_args() - except ArgumentError as error: - stderr.write('%s\n' % error) - sys.exit(2) - - input_stream = open_stream(template_path, stdin, 'r') - output_stream = open_stream(output_path, stdout, 'w') - with input_stream as instream, output_stream as outstream: - write_header(outstream, template_path) - expand_template(instream, outstream) diff --git a/ext/libpqxx-7.7.3/tools/test_all.py b/ext/libpqxx-7.7.3/tools/test_all.py deleted file mode 100755 index 29f33050c..000000000 --- a/ext/libpqxx-7.7.3/tools/test_all.py +++ /dev/null @@ -1,630 +0,0 @@ -#! /usr/bin/env python3 -"""Brute-force test script: test libpqxx against many compilers etc. - -This script makes no changes in the source tree; all builds happen in -temporary directories. - -To make this possible, you may need to run "make distclean" in the -source tree. The configure script will refuse to configure otherwise. -""" - -# Without this, pocketlint does not yet understand the print function. -from __future__ import print_function - -from abc import ( - ABCMeta, - abstractmethod, - ) -from argparse import ArgumentParser -from contextlib import contextmanager -from datetime import datetime -from functools import partial -import json -from multiprocessing import ( - JoinableQueue, - Process, - Queue, - ) -from multiprocessing.pool import ( - Pool, - ) -from os import ( - cpu_count, - getcwd, - ) -import os.path -from queue import Empty -from shutil import rmtree -from subprocess import ( - CalledProcessError, - check_call, - check_output, - DEVNULL, - ) -from sys import ( - stderr, - stdout, - ) -from tempfile import mkdtemp -from textwrap import dedent - - -CPUS = cpu_count() - -GCC_VERSIONS = list(range(8, 14)) -GCC = ['g++-%d' % ver for ver in GCC_VERSIONS] -CLANG_VERSIONS = list(range(7, 15)) -CLANG = ['clang++-6.0'] + ['clang++-%d' % ver for ver in CLANG_VERSIONS] -CXX = GCC + CLANG - -STDLIB = ( - '', - '-stdlib=libc++', - ) - -OPT = ('-O0', '-O3') - -LINK = { - 'static': ['--enable-static', '--disable-shared'], - 'dynamic': ['--disable-static', '--enable-shared'], -} - -DEBUG = { - 'plain': [], - 'audit': ['--enable-audit'], - 'maintainer': ['--enable-maintainer-mode'], - 'full': ['--enable-audit', '--enable-maintainer-mode'], -} - - -# CMake "generators." Maps a value for cmake's -G option to a command line to -# run. -# -# I prefer Ninja if available, because it's fast. But hey, the default will -# work. -# -# Maps the name of the generator (as used with cmake's -G option) to the -# actual command line needed to do the build. -CMAKE_GENERATORS = { - 'Ninja': ['ninja'], - 'Unix Makefiles': ['make', '-j%d' % CPUS], -} - - -class Fail(Exception): - """A known, well-handled exception. Doesn't need a traceback.""" - - -class Skip(Exception): - """"We're not doing this build. It's not an error though.""" - - -def run(cmd, output, cwd=None): - """Run a command, write output to file-like object.""" - command_line = ' '.join(cmd) - output.write("%s\n\n" % command_line) - check_call(cmd, stdout=output, stderr=output, cwd=cwd) - - -def report(output, message): - """Report a message to output, and standard output.""" - print(message, flush=True) - output.write('\n\n') - output.write(message) - output.write('\n') - - -def file_contains(path, text): - """Does the file at path contain text?""" - with open(path) as stream: - for line in stream: - if text in line: - return True - return False - - -@contextmanager -def tmp_dir(): - """Create a temporary directory, and clean it up again.""" - tmp = mkdtemp() - try: - yield tmp - finally: - rmtree(tmp) - - -def write_check_code(work_dir): - """Write a simple C++ program so we can tesst whether we can compile it. - - Returns the file's full path. - """ - path = os.path.join(work_dir, "check.cxx") - with open(path, 'w') as source: - source.write(dedent("""\ - #include - int main() - { - std::cout << "Hello world." << std::endl; - } - """)) - - return path - - -def check_compiler(work_dir, cxx, stdlib, check, verbose=False): - """Is the given compiler combo available?""" - err_file = os.path.join(work_dir, 'stderr.log') - if verbose: - err_output = open(err_file, 'w') - else: - err_output = DEVNULL - try: - command = [cxx, check] - if stdlib != '': - command.append(stdlib) - check_call(command, cwd=work_dir, stderr=err_output) - except (OSError, CalledProcessError): - if verbose: - with open(err_file) as errors: - stdout.write(errors.read()) - print("Can't build with '%s %s'. Skipping." % (cxx, stdlib)) - return False - else: - return True - - -# TODO: Use Pool. -def check_compilers(compilers, stdlibs, verbose=False): - """Check which compiler configurations are viable.""" - with tmp_dir() as work_dir: - check = write_check_code(work_dir) - return [ - (cxx, stdlib) - for stdlib in stdlibs - for cxx in compilers - if check_compiler( - work_dir, cxx, stdlib, check=check, verbose=verbose) - ] - - -def find_cmake_command(): - """Figure out a CMake generator we can use, or None.""" - try: - caps = check_output(['cmake', '-E', 'capabilities']) - except FileNotFoundError: - return None - - names = {generator['name'] for generator in json.loads(caps)['generators']} - for gen in CMAKE_GENERATORS.keys(): - if gen in names: - return gen - return None - - -class Config: - """Configuration for a build. - - These classes must be suitable for pickling, so we can send its objects to - worker processes. - """ - __metaclass__ = ABCMeta - - @abstractmethod - def name(self): - """Return an identifier for this build configuration.""" - - def make_log_name(self): - """Compose log file name for this build.""" - return "build-%s.out" % self.name() - - -class Build: - """A pending or ondoing build, in its own directory. - - Each step returns True for Success, or False for failure. - - These classes must be suitable for pickling, so we can send its objects to - worker processes. - """ - def __init__(self, logs_dir, config=None): - self.config = config - self.log = os.path.join(logs_dir, config.make_log_name()) - # Start a fresh log file. - with open(self.log, 'w') as log: - log.write("Starting %s.\n" % datetime.utcnow()) - self.work_dir = mkdtemp() - - def clean_up(self): - """Delete the build tree.""" - rmtree(self.work_dir) - - @abstractmethod - def configure(self, log): - """Prepare for a build.""" - - @abstractmethod - def build(self, log): - """Build the code, including the tests. Don't run tests though.""" - - def test(self, log): - """Run tests.""" - run( - [os.path.join(os.path.curdir, 'test', 'runner')], log, - cwd=self.work_dir) - - def logging(self, function): - """Call function, pass open write handle for `self.log`.""" -# TODO: Should probably be a decorator. - with open(self.log, 'a') as log: - try: - function(log) - except Exception as error: - log.write("%s\n" % error) - raise - - def do_configure(self): - """Call `configure`, writing output to `self.log`.""" - self.logging(self.configure) - - def do_build(self): - """Call `build`, writing output to `self.log`.""" - self.logging(self.build) - - def do_test(self): - """Call `test`, writing output to `self.log`.""" - self.logging(self.test) - - -class AutotoolsConfig(Config): - """A combination of build options for the "configure" script.""" - def __init__(self, cxx, opt, stdlib, link, link_opts, debug, debug_opts): - self.cxx = cxx - self.opt = opt - self.stdlib = stdlib - self.link = link - self.link_opts = link_opts - self.debug = debug - self.debug_opts = debug_opts - - def name(self): - return '_'.join([ - self.cxx, self.opt, self.stdlib, self.link, self.debug]) - - -class AutotoolsBuild(Build): - """Build using the "configure" script.""" - __metaclass__ = ABCMeta - - def configure(self, log): - configure = [ - os.path.join(getcwd(), "configure"), - "CXX=%s" % self.config.cxx, - ] - - if self.config.stdlib == '': - configure += [ - "CXXFLAGS=%s" % self.config.opt, - ] - else: - configure += [ - "CXXFLAGS=%s %s" % (self.config.opt, self.config.stdlib), - "LDFLAGS=%s" % self.config.stdlib, - ] - - configure += [ - "--disable-documentation", - ] + self.config.link_opts + self.config.debug_opts - - run(configure, log, cwd=self.work_dir) - - def build(self, log): - run(['make', '-j%d' % CPUS], log, cwd=self.work_dir) - # Passing "TESTS=" like this will suppress the actual running of - # the tests. We run them in the "test" stage. - run(['make', '-j%d' % CPUS, 'check', 'TESTS='], log, cwd=self.work_dir) - - -class CMakeConfig(Config): - """Configuration for a CMake build.""" - def __init__(self, generator): - self.generator = generator - self.builder = CMAKE_GENERATORS[generator] - - def name(self): - return "cmake" - - -class CMakeBuild(Build): - """Build using CMake. - - Ignores the config for now. - """ - __metaclass__ = ABCMeta - - def configure(self, log): - source_dir = getcwd() - generator = self.config.generator - run( - ['cmake', '-G', generator, source_dir], output=log, - cwd=self.work_dir) - - def build(self, log): - run(self.config.builder, log, cwd=self.work_dir) - - -def parse_args(): - """Parse command-line arguments.""" - parser = ArgumentParser(description=__doc__) - parser.add_argument('--verbose', '-v', action='store_true') - parser.add_argument( - '--compilers', '-c', default=','.join(CXX), - help="Compilers, separated by commas. Default is %(default)s.") - parser.add_argument( - '--optimize', '-O', default=','.join(OPT), - help=( - "Alternative optimisation options, separated by commas. " - "Default is %(default)s.")) - parser.add_argument( - '--stdlibs', '-L', default=','.join(STDLIB), - help=( - "Comma-separated options for choosing standard library. " - "Defaults to %(default)s.")) - parser.add_argument( - '--logs', '-l', default='.', metavar='DIRECTORY', - help="Write build logs to DIRECTORY.") - parser.add_argument( - '--jobs', '-j', default=CPUS, metavar='CPUS', - help=( - "When running 'make', run up to CPUS concurrent processes. " - "Defaults to %(default)s.")) - parser.add_argument( - '--minimal', '-m', action='store_true', - help="Make it as short a run as possible. For testing this script.") - return parser.parse_args() - - -def soft_get(queue, block=True): - """Get an item off `queue`, or `None` if the queue is empty.""" - try: - return queue.get(block) - except Empty: - return None - - -def read_queue(queue, block=True): - """Read entries off `queue`, terminating when it gets a `None`. - - Also terminates when the queue is empty. - """ - entry = soft_get(queue, block) - while entry is not None: - yield entry - entry = soft_get(queue, block) - - -def service_builds(in_queue, fail_queue, out_queue): - """Worker process for "build" stage: process one job at a time. - - Sends successful builds to `out_queue`, and failed builds to `fail_queue`. - - Terminates when it receives a `None`, at which point it will send a `None` - into `out_queue` in turn. - """ - for build in read_queue(in_queue): - try: - build.do_build() - except Exception as error: - fail_queue.put((build, "%s" % error)) - else: - out_queue.put(build) - in_queue.task_done() - - # Mark the end of the queue. - out_queue.put(None) - - -def service_tests(in_queue, fail_queue, out_queue): - """Worker process for "test" stage: test one build at a time. - - Sends successful builds to `out_queue`, and failed builds to `fail_queue`. - - Terminates when it receives a final `None`. Does not send out a final - `None` of its own. - """ - for build in read_queue(in_queue): - try: - build.do_test() - except Exception as error: - fail_queue.put((build, "%s" % error)) - else: - out_queue.put(build) - in_queue.task_done() - - -def report_failures(queue, message): - """Report failures from a failure queue. Return total number.""" - failures = 0 - for build, error in read_queue(queue, block=False): - print("%s: %s - %s" % (message, build.config.name(), error)) - failures += 1 - return failures - - -def count_entries(queue): - """Get and discard all entries from `queue`, return the total count.""" - total = 0 - for _ in read_queue(queue, block=False): - total += 1 - return total - - -def gather_builds(args): - """Produce the list of builds we want to perform.""" - if args.verbose: - print("\nChecking available compilers.") - - compiler_candidates = args.compilers.split(',') - compilers = check_compilers( - compiler_candidates, args.stdlibs.split(','), - verbose=args.verbose) - if list(compilers) == []: - raise Fail( - "Did not find any viable compilers. Tried: %s." - % ', '.join(compiler_candidates)) - - opt_levels = args.optimize.split(',') - link_types = LINK.items() - debug_mixes = DEBUG.items() - - if args.minimal: - compilers = compilers[:1] - opt_levels = opt_levels[:1] - link_types = list(link_types)[:1] - debug_mixes = list(debug_mixes)[:1] - - builds = [ - AutotoolsBuild( - args.logs, - AutotoolsConfig( - opt=opt, link=link, link_opts=link_opts, debug=debug, - debug_opts=debug_opts, cxx=cxx, stdlib=stdlib)) - for opt in sorted(opt_levels) - for link, link_opts in sorted(link_types) - for debug, debug_opts in sorted(debug_mixes) - for cxx, stdlib in compilers - ] - - cmake = find_cmake_command() - if cmake is not None: - builds.append(CMakeBuild(args.logs, CMakeConfig(cmake))) - return builds - - -def enqueue(queue, build, *args): - """Put `build` on `queue`. - - Ignores additional arguments, so that it can be used as a clalback for - `Pool`. - - We do this instead of a lambda in order to get the closure right. We want - the build for the current iteration, not the last one that was executed - before the lambda runs. - """ - queue.put(build) - - -def enqueue_error(queue, build, error): - """Put the pair of `build` and `error` on `queue`.""" - queue.put((build, error)) - - -def main(args): - """Do it all.""" - if not os.path.isdir(args.logs): - raise Fail("Logs location '%s' is not a directory." % args.logs) - - builds = gather_builds(args) - if args.verbose: - print("Lined up %d builds." % len(builds)) - - # The "configure" step is single-threaded. We can run many at the same - # time, even when we're also running a "build" step at the same time. - # This means we may run a lot more processes than we have CPUs, but there's - # no law against that. There's also I/O time to be covered. - configure_pool = Pool() - - # Builds which have failed the "configure" stage, with their errors. This - # queue must never stall, so that we can let results pile up here while the - # work continues. - configure_fails = Queue(len(builds)) - - # Waiting list for the "build" stage. It contains Build objects, - # terminated by a final None to signify that there are no more builds to be - # done. - build_queue = JoinableQueue(10) - - # Builds that have failed the "build" stage. - build_fails = Queue(len(builds)) - - # Waiting list for the "test" stage. It contains Build objects, terminated - # by a final None. - test_queue = JoinableQueue(10) - - # The "build" step tries to utilise all CPUs, and it may use a fair bit of - # memory. Run only one of these at a time, in a single worker process. - build_worker = Process( - target=service_builds, args=(build_queue, build_fails, test_queue)) - build_worker.start() - - # Builds that have failed the "test" stage. - test_fails = Queue(len(builds)) - - # Completed builds. This must never stall. - done_queue = JoinableQueue(len(builds)) - - # The "test" step can not run concurrently (yet). So, run tests serially - # in a single worker process. It takes its jobs directly from the "build" - # worker. - test_worker = Process( - target=service_tests, args=(test_queue, test_fails, done_queue)) - test_worker.start() - - # Feed all builds into the "configure" pool. Each build which passes this - # stage goes into the "build" queue. - for build in builds: - configure_pool.apply_async( - build.do_configure, callback=partial(enqueue, build_queue, build), - error_callback=partial(enqueue_error, configure_fails, build)) - if args.verbose: - print("All jobs are underway.") - configure_pool.close() - configure_pool.join() - -# TODO: Async reporting for faster feedback. - configure_fail_count = report_failures(configure_fails, "CONFIGURE FAIL") - if args.verbose: - print("Configure stage done.") - - # Mark the end of the build queue for the build worker. - build_queue.put(None) - - build_worker.join() -# TODO: Async reporting for faster feedback. - build_fail_count = report_failures(build_fails, "BUILD FAIL") - if args.verbose: - print("Build step done.") - - # Mark the end of the test queue for the test worker. - test_queue.put(None) - - test_worker.join() -# TODO: Async reporting for faster feedback. -# TODO: Collate failures into meaningful output, e.g. "shared library fails." - test_fail_count = report_failures(test_fails, "TEST FAIL") - if args.verbose: - print("Test step done.") - - # All done. Clean up. - for build in builds: - build.clean_up() - - ok_count = count_entries(done_queue) - if ok_count == len(builds): - print("All tests OK.") - else: - print( - "Failures during configure: %d - build: %d - test: %d. OK: %d." - % ( - configure_fail_count, - build_fail_count, - test_fail_count, - ok_count, - )) - - -if __name__ == '__main__': - try: - exit(main(parse_args())) - except Fail as failure: - stderr.write("%s\n" % failure) - exit(2) diff --git a/ext/libpqxx-7.7.3/tools/todo b/ext/libpqxx-7.7.3/tools/todo deleted file mode 100755 index 87429f4b2..000000000 --- a/ext/libpqxx-7.7.3/tools/todo +++ /dev/null @@ -1,31 +0,0 @@ -#! /bin/bash -# -# List "TODO" and "XXX" items in the given files, or throughout the source -# code. - -set -e -u -o pipefail - -# TODO: Make location-independent? -find_source() { - echo configure.ac - find . -name \*.cxx -o -name \*.hxx | sed -e 's|^\./||' | sort - for f in $(ls tools) - do - echo tools/$f - done -} - - -FILES=${*:-$(find_source)} - - -# Search for "$1:" in files $2. -# (This function adds the colon. That way, the search statement itself won't -# show up in the search.) -search_for() { - grep $1: $2 -} - - -search_for XXX "$FILES" || true -search_for TODO "$FILES" || true diff --git a/ext/libpqxx-7.7.3/tools/update-copyright b/ext/libpqxx-7.7.3/tools/update-copyright deleted file mode 100755 index 9d1eb5a97..000000000 --- a/ext/libpqxx-7.7.3/tools/update-copyright +++ /dev/null @@ -1,29 +0,0 @@ -#! /bin/bash -# -# Update the libpqxx copyright strings in the current directory. -# -# Usage: update-copyright [year] -# -# Where "year" is the new copyright year. Defaults to the current year. -# -# Assumes GNU grep and GNU sed. -set -eu -o pipefail - -# The regexes are a bit awkward because they must work in both grep and sed. -# -# F'rinstance, PREFIX can't include the dash because our replacement string in -# sed would have a backreference (e.g. "\3") immediately followed by a year -# (e.g. 2022), and there's no clear boundary between the backreference number -# and the year: "\32022". -PREFIX='Copyright (c),* 2000' -YEAR='20[0-9][0-9]' -NEW_YEAR="${1:-$(date '+%Y')}" -SUFFIX=',* \(.* and \)*Jeroen T\. Vermeulen' -grep -rIl "$PREFIX-$YEAR$SUFFIX" | - xargs -r sed -i -e "s/\\($PREFIX\\)-$YEAR\\($SUFFIX\\)/\\1-$NEW_YEAR\\2/" - -# This one is so different that I'd rather keep it a special case. -sed \ - -i \ - -e "s/\\(2000\\)-$YEAR\\(,* Jeroen T\\. Vermeulen\\)/\1-$NEW_YEAR\\2/" \ - doc/conf.py diff --git a/ext/lz4/lz4.c b/ext/lz4/lz4.c new file mode 100644 index 000000000..881d1af02 --- /dev/null +++ b/ext/lz4/lz4.c @@ -0,0 +1,1367 @@ +/* + LZ4 - Fast LZ compression algorithm + Copyright (C) 2011-2015, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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. + + 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. + + You can contact the author at : + - LZ4 source repository : https://github.com/Cyan4973/lz4 + - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c +*/ + + +/************************************** + Tuning parameters +**************************************/ +/* + * HEAPMODE : + * Select how default compression functions will allocate memory for their hash table, + * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()). + */ +#define HEAPMODE 0 + +/* + * CPU_HAS_EFFICIENT_UNALIGNED_MEMORY_ACCESS : + * By default, the source code expects the compiler to correctly optimize + * 4-bytes and 8-bytes read on architectures able to handle it efficiently. + * This is not always the case. In some circumstances (ARM notably), + * the compiler will issue cautious code even when target is able to correctly handle unaligned memory accesses. + * + * You can force the compiler to use unaligned memory access by uncommenting the line below. + * One of the below scenarios will happen : + * 1 - Your target CPU correctly handle unaligned access, and was not well optimized by compiler (good case). + * You will witness large performance improvements (+50% and up). + * Keep the line uncommented and send a word to upstream (https://groups.google.com/forum/#!forum/lz4c) + * The goal is to automatically detect such situations by adding your target CPU within an exception list. + * 2 - Your target CPU correctly handle unaligned access, and was already already optimized by compiler + * No change will be experienced. + * 3 - Your target CPU inefficiently handle unaligned access. + * You will experience a performance loss. Comment back the line. + * 4 - Your target CPU does not handle unaligned access. + * Program will crash. + * If uncommenting results in better performance (case 1) + * please report your configuration to upstream (https://groups.google.com/forum/#!forum/lz4c) + * This way, an automatic detection macro can be added to match your case within later versions of the library. + */ +/* #define CPU_HAS_EFFICIENT_UNALIGNED_MEMORY_ACCESS 1 */ + + +/************************************** + CPU Feature Detection +**************************************/ +/* + * Automated efficient unaligned memory access detection + * Based on known hardware architectures + * This list will be updated thanks to feedbacks + */ +#if defined(CPU_HAS_EFFICIENT_UNALIGNED_MEMORY_ACCESS) \ + || defined(__ARM_FEATURE_UNALIGNED) \ + || defined(__i386__) || defined(__x86_64__) \ + || defined(_M_IX86) || defined(_M_X64) \ + || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__) \ + || (defined(_M_ARM) && (_M_ARM >= 7)) +# define LZ4_UNALIGNED_ACCESS 1 +#else +# define LZ4_UNALIGNED_ACCESS 0 +#endif + +/* + * LZ4_FORCE_SW_BITCOUNT + * Define this parameter if your target system or compiler does not support hardware bit count + */ +#if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */ +# define LZ4_FORCE_SW_BITCOUNT +#endif + + +/************************************** +* Compiler Options +**************************************/ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ +/* "restrict" is a known keyword */ +#else +# define restrict /* Disable restrict */ +#endif + +#ifdef _MSC_VER /* Visual Studio */ +# define FORCE_INLINE static __forceinline +# include +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */ +#else +# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ +# ifdef __GNUC__ +# define FORCE_INLINE static inline __attribute__((always_inline)) +# else +# define FORCE_INLINE static inline +# endif +# else +# define FORCE_INLINE static +# endif /* __STDC_VERSION__ */ +#endif /* _MSC_VER */ + +#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) + +#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) +# define expect(expr,value) (__builtin_expect ((expr),(value)) ) +#else +# define expect(expr,value) (expr) +#endif + +#define likely(expr) expect((expr) != 0, 1) +#define unlikely(expr) expect((expr) != 0, 0) + + +/************************************** + Memory routines +**************************************/ +#include /* malloc, calloc, free */ +#define ALLOCATOR(n,s) calloc(n,s) +#define FREEMEM free +#include /* memset, memcpy */ +#define MEM_INIT memset + + +/************************************** + Includes +**************************************/ +#include "lz4.h" + + +/************************************** + Basic Types +**************************************/ +#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ +# include + typedef uint8_t BYTE; + typedef uint16_t U16; + typedef uint32_t U32; + typedef int32_t S32; + typedef uint64_t U64; +#else + typedef unsigned char BYTE; + typedef unsigned short U16; + typedef unsigned int U32; + typedef signed int S32; + typedef unsigned long long U64; +#endif + + +/************************************** + Reading and writing into memory +**************************************/ +#define STEPSIZE sizeof(size_t) + +static unsigned LZ4_64bits(void) { return sizeof(void*)==8; } + +static unsigned LZ4_isLittleEndian(void) +{ + const union { U32 i; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + return one.c[0]; +} + + +static U16 LZ4_readLE16(const void* memPtr) +{ + if ((LZ4_UNALIGNED_ACCESS) && (LZ4_isLittleEndian())) + return *(U16*)memPtr; + else + { + const BYTE* p = (const BYTE*)memPtr; + return (U16)((U16)p[0] + (p[1]<<8)); + } +} + +static void LZ4_writeLE16(void* memPtr, U16 value) +{ + if ((LZ4_UNALIGNED_ACCESS) && (LZ4_isLittleEndian())) + { + *(U16*)memPtr = value; + return; + } + else + { + BYTE* p = (BYTE*)memPtr; + p[0] = (BYTE) value; + p[1] = (BYTE)(value>>8); + } +} + + +static U16 LZ4_read16(const void* memPtr) +{ + if (LZ4_UNALIGNED_ACCESS) + return *(U16*)memPtr; + else + { + U16 val16; + memcpy(&val16, memPtr, 2); + return val16; + } +} + +static U32 LZ4_read32(const void* memPtr) +{ + if (LZ4_UNALIGNED_ACCESS) + return *(U32*)memPtr; + else + { + U32 val32; + memcpy(&val32, memPtr, 4); + return val32; + } +} + +static U64 LZ4_read64(const void* memPtr) +{ + if (LZ4_UNALIGNED_ACCESS) + return *(U64*)memPtr; + else + { + U64 val64; + memcpy(&val64, memPtr, 8); + return val64; + } +} + +static size_t LZ4_read_ARCH(const void* p) +{ + if (LZ4_64bits()) + return (size_t)LZ4_read64(p); + else + return (size_t)LZ4_read32(p); +} + + +static void LZ4_copy4(void* dstPtr, const void* srcPtr) +{ + if (LZ4_UNALIGNED_ACCESS) + { + *(U32*)dstPtr = *(U32*)srcPtr; + return; + } + memcpy(dstPtr, srcPtr, 4); +} + +static void LZ4_copy8(void* dstPtr, const void* srcPtr) +{ +#if GCC_VERSION!=409 /* disabled on GCC 4.9, as it generates invalid opcode (crash) */ + if (LZ4_UNALIGNED_ACCESS) + { + if (LZ4_64bits()) + *(U64*)dstPtr = *(U64*)srcPtr; + else + ((U32*)dstPtr)[0] = ((U32*)srcPtr)[0], + ((U32*)dstPtr)[1] = ((U32*)srcPtr)[1]; + return; + } +#endif + memcpy(dstPtr, srcPtr, 8); +} + +/* customized version of memcpy, which may overwrite up to 7 bytes beyond dstEnd */ +static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd) +{ + BYTE* d = (BYTE*)dstPtr; + const BYTE* s = (const BYTE*)srcPtr; + BYTE* e = (BYTE*)dstEnd; + do { LZ4_copy8(d,s); d+=8; s+=8; } while (d>3); +# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_ctzll((U64)val) >> 3); +# else + static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; + return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; +# endif + } + else /* 32 bits */ + { +# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r; + _BitScanForward( &r, (U32)val ); + return (int)(r>>3); +# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_ctz((U32)val) >> 3); +# else + static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; + return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; +# endif + } + } + else /* Big Endian CPU */ + { + if (LZ4_64bits()) + { +# if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanReverse64( &r, val ); + return (unsigned)(r>>3); +# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_clzll(val) >> 3); +# else + unsigned r; + if (!(val>>32)) { r=4; } else { r=0; val>>=32; } + if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } + r += (!val); + return r; +# endif + } + else /* 32 bits */ + { +# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanReverse( &r, (unsigned long)val ); + return (unsigned)(r>>3); +# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_clz(val) >> 3); +# else + unsigned r; + if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } + r += (!val); + return r; +# endif + } + } +} + +static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit) +{ + const BYTE* const pStart = pIn; + + while (likely(pIn compression run slower on incompressible data */ + + +/************************************** +* Local Utils +**************************************/ +int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; } +int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } + + +/************************************** +* Local Structures and types +**************************************/ +typedef struct { + U32 hashTable[HASH_SIZE_U32]; + U32 currentOffset; + U32 initCheck; + const BYTE* dictionary; + const BYTE* bufferStart; + U32 dictSize; +} LZ4_stream_t_internal; + +typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive; +typedef enum { byPtr, byU32, byU16 } tableType_t; + +typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive; +typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive; + +typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive; +typedef enum { full = 0, partial = 1 } earlyEnd_directive; + + + +/******************************** +* Compression functions +********************************/ + +static U32 LZ4_hashSequence(U32 sequence, tableType_t const tableType) +{ + if (tableType == byU16) + return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); + else + return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); +} + +static U32 LZ4_hashPosition(const BYTE* p, tableType_t tableType) { return LZ4_hashSequence(LZ4_read32(p), tableType); } + +static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType, const BYTE* srcBase) +{ + switch (tableType) + { + case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; } + case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; } + case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; } + } +} + +static void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) +{ + U32 h = LZ4_hashPosition(p, tableType); + LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); +} + +static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) +{ + if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; } + if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } + { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ +} + +static const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) +{ + U32 h = LZ4_hashPosition(p, tableType); + return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); +} + +static int LZ4_compress_generic( + void* ctx, + const char* source, + char* dest, + int inputSize, + int maxOutputSize, + limitedOutput_directive outputLimited, + tableType_t const tableType, + dict_directive dict, + dictIssue_directive dictIssue) +{ + LZ4_stream_t_internal* const dictPtr = (LZ4_stream_t_internal*)ctx; + + const BYTE* ip = (const BYTE*) source; + const BYTE* base; + const BYTE* lowLimit; + const BYTE* const lowRefLimit = ip - dictPtr->dictSize; + const BYTE* const dictionary = dictPtr->dictionary; + const BYTE* const dictEnd = dictionary + dictPtr->dictSize; + const size_t dictDelta = dictEnd - (const BYTE*)source; + const BYTE* anchor = (const BYTE*) source; + const BYTE* const iend = ip + inputSize; + const BYTE* const mflimit = iend - MFLIMIT; + const BYTE* const matchlimit = iend - LASTLITERALS; + + BYTE* op = (BYTE*) dest; + BYTE* const olimit = op + maxOutputSize; + + U32 forwardH; + size_t refDelta=0; + + /* Init conditions */ + if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ + switch(dict) + { + case noDict: + default: + base = (const BYTE*)source; + lowLimit = (const BYTE*)source; + break; + case withPrefix64k: + base = (const BYTE*)source - dictPtr->currentOffset; + lowLimit = (const BYTE*)source - dictPtr->dictSize; + break; + case usingExtDict: + base = (const BYTE*)source - dictPtr->currentOffset; + lowLimit = (const BYTE*)source; + break; + } + if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */ + if (inputSize> LZ4_skipTrigger; + + if (unlikely(forwardIp > mflimit)) goto _last_literals; + + match = LZ4_getPositionOnHash(h, ctx, tableType, base); + if (dict==usingExtDict) + { + if (match<(const BYTE*)source) + { + refDelta = dictDelta; + lowLimit = dictionary; + } + else + { + refDelta = 0; + lowLimit = (const BYTE*)source; + } + } + forwardH = LZ4_hashPosition(forwardIp, tableType); + LZ4_putPositionOnHash(ip, h, ctx, tableType, base); + + } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0) + || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip)) + || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) ); + } + + /* Catch up */ + while ((ip>anchor) && (match+refDelta > lowLimit) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; } + + { + /* Encode Literal length */ + unsigned litLength = (unsigned)(ip - anchor); + token = op++; + if ((outputLimited) && (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit))) + return 0; /* Check output limit */ + if (litLength>=RUN_MASK) + { + int len = (int)litLength-RUN_MASK; + *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; + *op++ = (BYTE)len; + } + else *token = (BYTE)(litLength< matchlimit) limit = matchlimit; + matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); + ip += MINMATCH + matchLength; + if (ip==limit) + { + unsigned more = LZ4_count(ip, (const BYTE*)source, matchlimit); + matchLength += more; + ip += more; + } + } + else + { + matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); + ip += MINMATCH + matchLength; + } + + if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + (matchLength>>8) > olimit))) + return 0; /* Check output limit */ + if (matchLength>=ML_MASK) + { + *token += ML_MASK; + matchLength -= ML_MASK; + for (; matchLength >= 510 ; matchLength-=510) { *op++ = 255; *op++ = 255; } + if (matchLength >= 255) { matchLength-=255; *op++ = 255; } + *op++ = (BYTE)matchLength; + } + else *token += (BYTE)(matchLength); + } + + anchor = ip; + + /* Test end of chunk */ + if (ip > mflimit) break; + + /* Fill table */ + LZ4_putPosition(ip-2, ctx, tableType, base); + + /* Test next position */ + match = LZ4_getPosition(ip, ctx, tableType, base); + if (dict==usingExtDict) + { + if (match<(const BYTE*)source) + { + refDelta = dictDelta; + lowLimit = dictionary; + } + else + { + refDelta = 0; + lowLimit = (const BYTE*)source; + } + } + LZ4_putPosition(ip, ctx, tableType, base); + if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1) + && (match+MAX_DISTANCE>=ip) + && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) ) + { token=op++; *token=0; goto _next_match; } + + /* Prepare next loop */ + forwardH = LZ4_hashPosition(++ip, tableType); + } + +_last_literals: + /* Encode Last Literals */ + { + int lastRun = (int)(iend - anchor); + if ((outputLimited) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) + return 0; /* Check output limit */ + if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<= 255 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } + else *op++ = (BYTE)(lastRun<= sizeof(LZ4_stream_t_internal)); /* A compilation error here means LZ4_STREAMSIZE is not large enough */ + LZ4_resetStream(lz4s); + return lz4s; +} + +int LZ4_freeStream (LZ4_stream_t* LZ4_stream) +{ + FREEMEM(LZ4_stream); + return (0); +} + + +int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) +{ + LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; + const BYTE* p = (const BYTE*)dictionary; + const BYTE* const dictEnd = p + dictSize; + const BYTE* base; + + if (dict->initCheck) LZ4_resetStream(LZ4_dict); /* Uninitialized structure detected */ + + if (dictSize < MINMATCH) + { + dict->dictionary = NULL; + dict->dictSize = 0; + return 0; + } + + if (p <= dictEnd - 64 KB) p = dictEnd - 64 KB; + base = p - dict->currentOffset; + dict->dictionary = p; + dict->dictSize = (U32)(dictEnd - p); + dict->currentOffset += dict->dictSize; + + while (p <= dictEnd-MINMATCH) + { + LZ4_putPosition(p, dict, byU32, base); + p+=3; + } + + return dict->dictSize; +} + + +static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src) +{ + if ((LZ4_dict->currentOffset > 0x80000000) || + ((size_t)LZ4_dict->currentOffset > (size_t)src)) /* address space overflow */ + { + /* rescale hash table */ + U32 delta = LZ4_dict->currentOffset - 64 KB; + const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize; + int i; + for (i=0; ihashTable[i] < delta) LZ4_dict->hashTable[i]=0; + else LZ4_dict->hashTable[i] -= delta; + } + LZ4_dict->currentOffset = 64 KB; + if (LZ4_dict->dictSize > 64 KB) LZ4_dict->dictSize = 64 KB; + LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize; + } +} + + +FORCE_INLINE int LZ4_compress_continue_generic (void* LZ4_stream, const char* source, char* dest, int inputSize, + int maxOutputSize, limitedOutput_directive limit) +{ + LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_stream; + const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; + + const BYTE* smallest = (const BYTE*) source; + if (streamPtr->initCheck) return 0; /* Uninitialized structure detected */ + if ((streamPtr->dictSize>0) && (smallest>dictEnd)) smallest = dictEnd; + LZ4_renormDictT(streamPtr, smallest); + + /* Check overlapping input/dictionary space */ + { + const BYTE* sourceEnd = (const BYTE*) source + inputSize; + if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) + { + streamPtr->dictSize = (U32)(dictEnd - sourceEnd); + if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB; + if (streamPtr->dictSize < 4) streamPtr->dictSize = 0; + streamPtr->dictionary = dictEnd - streamPtr->dictSize; + } + } + + /* prefix mode : source data follows dictionary */ + if (dictEnd == (const BYTE*)source) + { + int result; + if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) + result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, withPrefix64k, dictSmall); + else + result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, withPrefix64k, noDictIssue); + streamPtr->dictSize += (U32)inputSize; + streamPtr->currentOffset += (U32)inputSize; + return result; + } + + /* external dictionary mode */ + { + int result; + if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) + result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, usingExtDict, dictSmall); + else + result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, usingExtDict, noDictIssue); + streamPtr->dictionary = (const BYTE*)source; + streamPtr->dictSize = (U32)inputSize; + streamPtr->currentOffset += (U32)inputSize; + return result; + } +} + +int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize) +{ + return LZ4_compress_continue_generic(LZ4_stream, source, dest, inputSize, 0, notLimited); +} + +int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize) +{ + return LZ4_compress_continue_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput); +} + + +/* Hidden debug function, to force separate dictionary mode */ +int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize) +{ + LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_dict; + int result; + const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; + + const BYTE* smallest = dictEnd; + if (smallest > (const BYTE*) source) smallest = (const BYTE*) source; + LZ4_renormDictT((LZ4_stream_t_internal*)LZ4_dict, smallest); + + result = LZ4_compress_generic(LZ4_dict, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue); + + streamPtr->dictionary = (const BYTE*)source; + streamPtr->dictSize = (U32)inputSize; + streamPtr->currentOffset += (U32)inputSize; + + return result; +} + + +int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize) +{ + LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; + const BYTE* previousDictEnd = dict->dictionary + dict->dictSize; + + if ((U32)dictSize > 64 KB) dictSize = 64 KB; /* useless to define a dictionary > 64 KB */ + if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize; + + memmove(safeBuffer, previousDictEnd - dictSize, dictSize); + + dict->dictionary = (const BYTE*)safeBuffer; + dict->dictSize = (U32)dictSize; + + return dictSize; +} + + + +/******************************* +* Decompression functions +*******************************/ +/* + * This generic decompression function cover all use cases. + * It shall be instantiated several times, using different sets of directives + * Note that it is essential this generic function is really inlined, + * in order to remove useless branches during compilation optimization. + */ +FORCE_INLINE int LZ4_decompress_generic( + const char* const source, + char* const dest, + int inputSize, + int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */ + + int endOnInput, /* endOnOutputSize, endOnInputSize */ + int partialDecoding, /* full, partial */ + int targetOutputSize, /* only used if partialDecoding==partial */ + int dict, /* noDict, withPrefix64k, usingExtDict */ + const BYTE* const lowPrefix, /* == dest if dict == noDict */ + const BYTE* const dictStart, /* only if dict==usingExtDict */ + const size_t dictSize /* note : = 0 if noDict */ + ) +{ + /* Local Variables */ + const BYTE* restrict ip = (const BYTE*) source; + const BYTE* const iend = ip + inputSize; + + BYTE* op = (BYTE*) dest; + BYTE* const oend = op + outputSize; + BYTE* cpy; + BYTE* oexit = op + targetOutputSize; + const BYTE* const lowLimit = lowPrefix - dictSize; + + const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize; + const size_t dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4}; + const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3}; + + const int safeDecode = (endOnInput==endOnInputSize); + const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB))); + + + /* Special cases */ + if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */ + if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */ + if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1); + + + /* Main Loop */ + while (1) + { + unsigned token; + size_t length; + const BYTE* match; + + /* get literal length */ + token = *ip++; + if ((length=(token>>ML_BITS)) == RUN_MASK) + { + unsigned s; + do + { + s = *ip++; + length += s; + } + while (likely((endOnInput)?ip(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) + || ((!endOnInput) && (cpy>oend-COPYLENGTH))) + { + if (partialDecoding) + { + if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */ + if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */ + } + else + { + if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */ + if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */ + } + memcpy(op, ip, length); + ip += length; + op += length; + break; /* Necessarily EOF, due to parsing restrictions */ + } + LZ4_wildCopy(op, ip, cpy); + ip += length; op = cpy; + + /* get offset */ + match = cpy - LZ4_readLE16(ip); ip+=2; + if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error; /* Error : offset outside destination buffer */ + + /* get matchlength */ + length = token & ML_MASK; + if (length == ML_MASK) + { + unsigned s; + do + { + if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error; + s = *ip++; + length += s; + } while (s==255); + if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error; /* overflow detection */ + } + length += MINMATCH; + + /* check external dictionary */ + if ((dict==usingExtDict) && (match < lowPrefix)) + { + if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error; /* doesn't respect parsing restriction */ + + if (length <= (size_t)(lowPrefix-match)) + { + /* match can be copied as a single segment from external dictionary */ + match = dictEnd - (lowPrefix-match); + memcpy(op, match, length); + op += length; + } + else + { + /* match encompass external dictionary and current segment */ + size_t copySize = (size_t)(lowPrefix-match); + memcpy(op, dictEnd - copySize, copySize); + op += copySize; + copySize = length - copySize; + if (copySize > (size_t)(op-lowPrefix)) /* overlap within current segment */ + { + BYTE* const endOfMatch = op + copySize; + const BYTE* copyFrom = lowPrefix; + while (op < endOfMatch) *op++ = *copyFrom++; + } + else + { + memcpy(op, lowPrefix, copySize); + op += copySize; + } + } + continue; + } + + /* copy repeated sequence */ + cpy = op + length; + if (unlikely((op-match)<8)) + { + const size_t dec64 = dec64table[op-match]; + op[0] = match[0]; + op[1] = match[1]; + op[2] = match[2]; + op[3] = match[3]; + match += dec32table[op-match]; + LZ4_copy4(op+4, match); + op += 8; match -= dec64; + } else { LZ4_copy8(op, match); op+=8; match+=8; } + + if (unlikely(cpy>oend-12)) + { + if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals */ + if (op < oend-8) + { + LZ4_wildCopy(op, match, oend-8); + match += (oend-8) - op; + op = oend-8; + } + while (opprefixSize = (size_t) dictSize; + lz4sd->prefixEnd = (BYTE*) dictionary + dictSize; + lz4sd->externalDict = NULL; + lz4sd->extDictSize = 0; + return 1; +} + +/* +*_continue() : + These decoding functions allow decompression of multiple blocks in "streaming" mode. + Previously decoded blocks must still be available at the memory position where they were decoded. + If it's not possible, save the relevant part of decoded data into a safe buffer, + and indicate where it stands using LZ4_setStreamDecode() +*/ +int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize) +{ + LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; + int result; + + if (lz4sd->prefixEnd == (BYTE*)dest) + { + result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, + endOnInputSize, full, 0, + usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize += result; + lz4sd->prefixEnd += result; + } + else + { + lz4sd->extDictSize = lz4sd->prefixSize; + lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; + result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, + endOnInputSize, full, 0, + usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize = result; + lz4sd->prefixEnd = (BYTE*)dest + result; + } + + return result; +} + +int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize) +{ + LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; + int result; + + if (lz4sd->prefixEnd == (BYTE*)dest) + { + result = LZ4_decompress_generic(source, dest, 0, originalSize, + endOnOutputSize, full, 0, + usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize += originalSize; + lz4sd->prefixEnd += originalSize; + } + else + { + lz4sd->extDictSize = lz4sd->prefixSize; + lz4sd->externalDict = (BYTE*)dest - lz4sd->extDictSize; + result = LZ4_decompress_generic(source, dest, 0, originalSize, + endOnOutputSize, full, 0, + usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize = originalSize; + lz4sd->prefixEnd = (BYTE*)dest + originalSize; + } + + return result; +} + + +/* +Advanced decoding functions : +*_usingDict() : + These decoding functions work the same as "_continue" ones, + the dictionary must be explicitly provided within parameters +*/ + +FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize) +{ + if (dictSize==0) + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0); + if (dictStart+dictSize == dest) + { + if (dictSize >= (int)(64 KB - 1)) + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0); + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0); + } + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (BYTE*)dictStart, dictSize); +} + +int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) +{ + return LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize); +} + +int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize) +{ + return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize); +} + +/* debug function */ +int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) +{ + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (BYTE*)dictStart, dictSize); +} + + +/*************************************************** +* Obsolete Functions +***************************************************/ +/* +These function names are deprecated and should no longer be used. +They are only provided here for compatibility with older user programs. +- LZ4_uncompress is totally equivalent to LZ4_decompress_fast +- LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe +*/ +int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); } +int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); } + + +/* Obsolete Streaming functions */ + +int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; } + +static void LZ4_init(LZ4_stream_t_internal* lz4ds, const BYTE* base) +{ + MEM_INIT(lz4ds, 0, LZ4_STREAMSIZE); + lz4ds->bufferStart = base; +} + +int LZ4_resetStreamState(void* state, const char* inputBuffer) +{ + if ((((size_t)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */ + LZ4_init((LZ4_stream_t_internal*)state, (const BYTE*)inputBuffer); + return 0; +} + +void* LZ4_create (const char* inputBuffer) +{ + void* lz4ds = ALLOCATOR(8, LZ4_STREAMSIZE_U64); + LZ4_init ((LZ4_stream_t_internal*)lz4ds, (const BYTE*)inputBuffer); + return lz4ds; +} + +char* LZ4_slideInputBuffer (void* LZ4_Data) +{ + LZ4_stream_t_internal* ctx = (LZ4_stream_t_internal*)LZ4_Data; + int dictSize = LZ4_saveDict((LZ4_stream_t*)LZ4_Data, (char*)ctx->bufferStart, 64 KB); + return (char*)(ctx->bufferStart + dictSize); +} + +/* Obsolete compresson functions using User-allocated state */ + +int LZ4_sizeofState() { return LZ4_STREAMSIZE; } + +int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize) +{ + if (((size_t)(state)&3) != 0) return 0; /* Error : state is not aligned on 4-bytes boundary */ + MEM_INIT(state, 0, LZ4_STREAMSIZE); + + if (inputSize < LZ4_64Klimit) + return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue); + else + return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue); +} + +int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize) +{ + if (((size_t)(state)&3) != 0) return 0; /* Error : state is not aligned on 4-bytes boundary */ + MEM_INIT(state, 0, LZ4_STREAMSIZE); + + if (inputSize < LZ4_64Klimit) + return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue); + else + return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue); +} + +/* Obsolete streaming decompression functions */ + +int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize) +{ + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB); +} + +int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize) +{ + return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB); +} + +#endif /* LZ4_COMMONDEFS_ONLY */ + diff --git a/ext/lz4/lz4.h b/ext/lz4/lz4.h new file mode 100644 index 000000000..de43fc0a2 --- /dev/null +++ b/ext/lz4/lz4.h @@ -0,0 +1,316 @@ +/* + LZ4 - Fast LZ compression algorithm + Header File + Copyright (C) 2011-2015, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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. + + 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. + + You can contact the author at : + - LZ4 source repository : https://github.com/Cyan4973/lz4 + - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c +*/ +#pragma once + +#if defined (__cplusplus) +extern "C" { +#endif + +/* + * lz4.h provides block compression functions, for optimal performance. + * If you need to generate inter-operable compressed data (respecting LZ4 frame specification), + * please use lz4frame.h instead. +*/ + +/************************************** +* Version +**************************************/ +#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ +#define LZ4_VERSION_MINOR 6 /* for new (non-breaking) interface capabilities */ +#define LZ4_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */ +#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) +int LZ4_versionNumber (void); + +/************************************** +* Tuning parameter +**************************************/ +/* + * LZ4_MEMORY_USAGE : + * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) + * Increasing memory usage improves compression ratio + * Reduced memory usage can improve speed, due to cache effect + * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache + */ +#define LZ4_MEMORY_USAGE 14 + + +/************************************** +* Simple Functions +**************************************/ + +int LZ4_compress (const char* source, char* dest, int sourceSize); +int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize); + +/* +LZ4_compress() : + Compresses 'sourceSize' bytes from 'source' into 'dest'. + Destination buffer must be already allocated, + and must be sized to handle worst cases situations (input data not compressible) + Worst case size evaluation is provided by function LZ4_compressBound() + inputSize : Max supported value is LZ4_MAX_INPUT_SIZE + return : the number of bytes written in buffer dest + or 0 if the compression fails + +LZ4_decompress_safe() : + compressedSize : is obviously the source size + maxDecompressedSize : is the size of the destination buffer, which must be already allocated. + return : the number of bytes decompressed into the destination buffer (necessarily <= maxDecompressedSize) + If the destination buffer is not large enough, decoding will stop and output an error code (<0). + If the source stream is detected malformed, the function will stop decoding and return a negative result. + This function is protected against buffer overflow exploits, + and never writes outside of output buffer, nor reads outside of input buffer. + It is also protected against malicious data packets. +*/ + + +/************************************** +* Advanced Functions +**************************************/ +#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ +#define LZ4_COMPRESSBOUND(isize) ((unsigned int)(isize) > (unsigned int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) + +/* +LZ4_compressBound() : + Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) + This function is primarily useful for memory allocation purposes (output buffer size). + Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example). + + isize : is the input size. Max supported value is LZ4_MAX_INPUT_SIZE + return : maximum output size in a "worst case" scenario + or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) +*/ +int LZ4_compressBound(int isize); + + +/* +LZ4_compress_limitedOutput() : + Compress 'sourceSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. + If it cannot achieve it, compression will stop, and result of the function will be zero. + This saves time and memory on detecting non-compressible (or barely compressible) data. + This function never writes outside of provided output buffer. + + sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE + maxOutputSize : is the size of the destination buffer (which must be already allocated) + return : the number of bytes written in buffer 'dest' + or 0 if compression fails +*/ +int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize); + + +/* +LZ4_compress_withState() : + Same compression functions, but using an externally allocated memory space to store compression state. + Use LZ4_sizeofState() to know how much memory must be allocated, + and then, provide it as 'void* state' to compression functions. +*/ +int LZ4_sizeofState(void); +int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); +int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); + + +/* +LZ4_decompress_fast() : + originalSize : is the original and therefore uncompressed size + return : the number of bytes read from the source buffer (in other words, the compressed size) + If the source stream is detected malformed, the function will stop decoding and return a negative result. + Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes. + note : This function fully respect memory boundaries for properly formed compressed data. + It is a bit faster than LZ4_decompress_safe(). + However, it does not provide any protection against intentionally modified data stream (malicious input). + Use this function in trusted environment only (data to decode comes from a trusted source). +*/ +int LZ4_decompress_fast (const char* source, char* dest, int originalSize); + + +/* +LZ4_decompress_safe_partial() : + This function decompress a compressed block of size 'compressedSize' at position 'source' + into destination buffer 'dest' of size 'maxDecompressedSize'. + The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, + reducing decompression time. + return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize) + Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. + Always control how many bytes were decoded. + If the source stream is detected malformed, the function will stop decoding and return a negative result. + This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets +*/ +int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize); + + +/*********************************************** +* Streaming Compression Functions +***********************************************/ + +#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) +#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long)) +/* + * LZ4_stream_t + * information structure to track an LZ4 stream. + * important : init this structure content before first use ! + * note : only allocated directly the structure if you are statically linking LZ4 + * If you are using liblz4 as a DLL, please use below construction methods instead. + */ +typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t; + +/* + * LZ4_resetStream + * Use this function to init an allocated LZ4_stream_t structure + */ +void LZ4_resetStream (LZ4_stream_t* LZ4_streamPtr); + +/* + * LZ4_createStream will allocate and initialize an LZ4_stream_t structure + * LZ4_freeStream releases its memory. + * In the context of a DLL (liblz4), please use these methods rather than the static struct. + * They are more future proof, in case of a change of LZ4_stream_t size. + */ +LZ4_stream_t* LZ4_createStream(void); +int LZ4_freeStream (LZ4_stream_t* LZ4_streamPtr); + +/* + * LZ4_loadDict + * Use this function to load a static dictionary into LZ4_stream. + * Any previous data will be forgotten, only 'dictionary' will remain in memory. + * Loading a size of 0 is allowed. + * Return : dictionary size, in bytes (necessarily <= 64 KB) + */ +int LZ4_loadDict (LZ4_stream_t* LZ4_streamPtr, const char* dictionary, int dictSize); + +/* + * LZ4_compress_continue + * Compress data block 'source', using blocks compressed before as dictionary to improve compression ratio + * Previous data blocks are assumed to still be present at their previous location. + * dest buffer must be already allocated, and sized to at least LZ4_compressBound(inputSize) + */ +int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); + +/* + * LZ4_compress_limitedOutput_continue + * Same as before, but also specify a maximum target compressed size (maxOutputSize) + * If objective cannot be met, compression exits, and returns a zero. + */ +int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); + +/* + * LZ4_saveDict + * If previously compressed data block is not guaranteed to remain available at its memory location + * save it into a safer place (char* safeBuffer) + * Note : you don't need to call LZ4_loadDict() afterwards, + * dictionary is immediately usable, you can therefore call again LZ4_compress_continue() + * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error + */ +int LZ4_saveDict (LZ4_stream_t* LZ4_streamPtr, char* safeBuffer, int dictSize); + + +/************************************************ +* Streaming Decompression Functions +************************************************/ + +#define LZ4_STREAMDECODESIZE_U64 4 +#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) +typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t; +/* + * LZ4_streamDecode_t + * information structure to track an LZ4 stream. + * init this structure content using LZ4_setStreamDecode or memset() before first use ! + * + * In the context of a DLL (liblz4) please prefer usage of construction methods below. + * They are more future proof, in case of a change of LZ4_streamDecode_t size in the future. + * LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure + * LZ4_freeStreamDecode releases its memory. + */ +LZ4_streamDecode_t* LZ4_createStreamDecode(void); +int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); + +/* + * LZ4_setStreamDecode + * Use this function to instruct where to find the dictionary. + * Setting a size of 0 is allowed (same effect as reset). + * Return : 1 if OK, 0 if error + */ +int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); + +/* +*_continue() : + These decoding functions allow decompression of multiple blocks in "streaming" mode. + Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB) + If this condition is not possible, save the relevant part of decoded data into a safe buffer, + and indicate where is its new address using LZ4_setStreamDecode() +*/ +int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize); +int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize); + + +/* +Advanced decoding functions : +*_usingDict() : + These decoding functions work the same as + a combination of LZ4_setDictDecode() followed by LZ4_decompress_x_continue() + They are stand-alone and don't use nor update an LZ4_streamDecode_t structure. +*/ +int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize); +int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize); + + + +/************************************** +* Obsolete Functions +**************************************/ +/* +Obsolete decompression functions +These function names are deprecated and should no longer be used. +They are only provided here for compatibility with older user programs. +- LZ4_uncompress is the same as LZ4_decompress_fast +- LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe +These function prototypes are now disabled; uncomment them if you really need them. +It is highly recommended to stop using these functions and migrate to newer ones */ +/* int LZ4_uncompress (const char* source, char* dest, int outputSize); */ +/* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */ + + +/* Obsolete streaming functions; use new streaming interface whenever possible */ +void* LZ4_create (const char* inputBuffer); +int LZ4_sizeofStreamState(void); +int LZ4_resetStreamState(void* state, const char* inputBuffer); +char* LZ4_slideInputBuffer (void* state); + +/* Obsolete streaming decoding functions */ +int LZ4_decompress_safe_withPrefix64k (const char* source, char* dest, int compressedSize, int maxOutputSize); +int LZ4_decompress_fast_withPrefix64k (const char* source, char* dest, int originalSize); + + +#if defined (__cplusplus) +} +#endif diff --git a/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Info.plist b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Info.plist new file mode 100644 index 000000000..a11af6d93 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Info.plist @@ -0,0 +1,50 @@ + + + + + BuildMachineOSBuild + 14E46 + CFBundleDevelopmentRegion + en + CFBundleExecutable + ZeroTier One + CFBundleIconFile + ZeroTierIcon + CFBundleIdentifier + com.zerotier.ZeroTier-One + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ZeroTier One + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 6E35b + DTPlatformVersion + GM + DTSDKBuild + 14D125 + DTSDKName + macosx10.10 + DTXcode + 0640 + DTXcodeBuild + 6E35b + LSApplicationCategoryType + public.app-category.utilities + LSMinimumSystemVersion + 10.7 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/MacOS/ZeroTier One b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/MacOS/ZeroTier One new file mode 100755 index 000000000..429efc0ba Binary files /dev/null and b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/MacOS/ZeroTier One differ diff --git a/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/PkgInfo b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/PkgInfo new file mode 100644 index 000000000..bd04210fb --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPL???? \ No newline at end of file diff --git a/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/ZeroTierIcon.icns b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/ZeroTierIcon.icns new file mode 100644 index 000000000..17e60d587 Binary files /dev/null and b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/ZeroTierIcon.icns differ diff --git a/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/Credits.rtf b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/Credits.rtf new file mode 100644 index 000000000..6f388f662 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/Credits.rtf @@ -0,0 +1,13 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1347\cocoasubrtf570 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\vieww9600\viewh8400\viewkind0 +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 + +\f0\b\fs24 \cf0 (c)2011-2015 ZeroTier, Inc.\ +Licensed under the GNU GPLv3\ +\ +UI Wrapper MacGap (c) Twitter, Inc.\ +Licensed under the MIT License\ +http://macgap.com/\ +} \ No newline at end of file diff --git a/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/InfoPlist.strings b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/InfoPlist.strings new file mode 100644 index 000000000..5e45963c3 Binary files /dev/null and b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/InfoPlist.strings differ diff --git a/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/MainMenu.nib b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/MainMenu.nib new file mode 100644 index 000000000..4cd319b24 Binary files /dev/null and b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/MainMenu.nib differ diff --git a/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/Window.nib b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/Window.nib new file mode 100644 index 000000000..559409d9a Binary files /dev/null and b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/Window.nib differ diff --git a/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/_CodeSignature/CodeResources b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/_CodeSignature/CodeResources new file mode 100644 index 000000000..bd79b1f3f --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/_CodeSignature/CodeResources @@ -0,0 +1,187 @@ + + + + + files + + Resources/ZeroTierIcon.icns + + 430Gd+4+jnim7WxXEEugp6G+Tgk= + + Resources/en.lproj/Credits.rtf + + hash + + ePttkAH2X1GJ6OL0UhDBAktxB3Y= + + optional + + + Resources/en.lproj/InfoPlist.strings + + hash + + MiLKDDnrUKr4EmuvhS5VQwxHGK8= + + optional + + + Resources/en.lproj/MainMenu.nib + + hash + + kkFJZm0JXF9gTUF2keyMJQ9p9SY= + + optional + + + Resources/en.lproj/Window.nib + + hash + + 42zB9+COYMmPW0WlnU1juN2B9SA= + + optional + + + + files2 + + Resources/ZeroTierIcon.icns + + 430Gd+4+jnim7WxXEEugp6G+Tgk= + + Resources/en.lproj/Credits.rtf + + hash + + ePttkAH2X1GJ6OL0UhDBAktxB3Y= + + optional + + + Resources/en.lproj/InfoPlist.strings + + hash + + MiLKDDnrUKr4EmuvhS5VQwxHGK8= + + optional + + + Resources/en.lproj/MainMenu.nib + + hash + + kkFJZm0JXF9gTUF2keyMJQ9p9SY= + + optional + + + Resources/en.lproj/Window.nib + + hash + + 42zB9+COYMmPW0WlnU1juN2B9SA= + + optional + + + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/ext/mac-ui-macgap1-wrapper/src/LICENSE b/ext/mac-ui-macgap1-wrapper/src/LICENSE new file mode 100644 index 000000000..c7fd4a4a5 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/LICENSE @@ -0,0 +1,25 @@ +MacGap was ported from phonegap-mac, and is under the same license (MIT) + +The MIT License +***************** + +Copyright (c) <2012> + + 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/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.pbxproj b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.pbxproj new file mode 100644 index 000000000..08d72d060 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.pbxproj @@ -0,0 +1,488 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1495814F15C15CCC00E1CFE5 /* Notice.m in Sources */ = {isa = PBXBuildFile; fileRef = 1495814E15C15CCC00E1CFE5 /* Notice.m */; }; + 6F169DA718CC332E005EDDF3 /* Command.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DA618CC332E005EDDF3 /* Command.m */; }; + 6F169DAA18CC35FD005EDDF3 /* CallbackDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DA918CC35FD005EDDF3 /* CallbackDelegate.m */; }; + 6F169DAC18CD8A4A005EDDF3 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F169DAB18CD8A4A005EDDF3 /* JavaScriptCore.framework */; }; + 6F169DB118CD906F005EDDF3 /* MenuItemProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DAE18CD906F005EDDF3 /* MenuItemProxy.m */; }; + 6F169DB218CD906F005EDDF3 /* MenuProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DB018CD906F005EDDF3 /* MenuProxy.m */; }; + 6FD672B618FE618E00C0DAAD /* UserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FD672B518FE618E00C0DAAD /* UserDefaults.m */; }; + 6FD6E4ED18C2D48C00DFFBE6 /* fonts.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FD6E4EC18C2D48C00DFFBE6 /* fonts.m */; }; + 88746BEE14CCA435001E160E /* JSEventHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 88746BED14CCA435001E160E /* JSEventHelper.m */; }; + 88C0646014BDE10A00E4BCE2 /* Window.m in Sources */ = {isa = PBXBuildFile; fileRef = 88C0645F14BDE10A00E4BCE2 /* Window.m */; }; + 88C0646614BDEC5800E4BCE2 /* Window.xib in Resources */ = {isa = PBXBuildFile; fileRef = 88C0646414BDEC5800E4BCE2 /* Window.xib */; }; + 88C0646D14BDF6A600E4BCE2 /* WindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 88C0646C14BDF6A600E4BCE2 /* WindowController.m */; }; + C14EFCA71B0986AF00894B5F /* ZeroTierIcon.icns in Resources */ = {isa = PBXBuildFile; fileRef = C14EFCA61B0986AF00894B5F /* ZeroTierIcon.icns */; }; + C1C2B9911AFB0CF10060D7C2 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1C2B9901AFB0CF10060D7C2 /* Security.framework */; }; + F2B80016179E0FC100B069A8 /* Clipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = F2B80015179E0FC100B069A8 /* Clipboard.m */; }; + FA32509D14BA813600BF0781 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA32509C14BA813600BF0781 /* WebKit.framework */; }; + FA3250C314BA85E700BF0781 /* ContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250BC14BA85E700BF0781 /* ContentView.m */; }; + FA3250C514BA85E700BF0781 /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250BE14BA85E700BF0781 /* Utils.m */; }; + FA3250C714BA85E700BF0781 /* WebViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250C014BA85E700BF0781 /* WebViewDelegate.m */; }; + FA3250D314BA860800BF0781 /* App.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250C914BA860800BF0781 /* App.m */; }; + FA3250D514BA860800BF0781 /* Dock.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250CB14BA860800BF0781 /* Dock.m */; }; + FA3250D914BA860800BF0781 /* Path.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250CF14BA860800BF0781 /* Path.m */; }; + FA3250DB14BA860800BF0781 /* Sound.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250D114BA860800BF0781 /* Sound.m */; }; + FA3F7742168F70790027B324 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA3F7741168F70780027B324 /* Cocoa.framework */; }; + FAE451C914BA79C600190544 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = FAE451C714BA79C600190544 /* InfoPlist.strings */; }; + FAE451CB14BA79C600190544 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FAE451CA14BA79C600190544 /* main.m */; }; + FAE451CF14BA79C600190544 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = FAE451CD14BA79C600190544 /* Credits.rtf */; }; + FAE451D214BA79C600190544 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FAE451D114BA79C600190544 /* AppDelegate.m */; }; + FAE451D514BA79C600190544 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = FAE451D314BA79C600190544 /* MainMenu.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + FA3250DD14BA876F00BF0781 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1495814D15C15CCC00E1CFE5 /* Notice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Notice.h; path = Classes/Commands/Notice.h; sourceTree = ""; }; + 1495814E15C15CCC00E1CFE5 /* Notice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Notice.m; path = Classes/Commands/Notice.m; sourceTree = ""; }; + 6F169DA518CC332E005EDDF3 /* Command.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Command.h; path = Classes/Commands/Command.h; sourceTree = ""; }; + 6F169DA618CC332E005EDDF3 /* Command.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Command.m; path = Classes/Commands/Command.m; sourceTree = ""; }; + 6F169DA818CC35FD005EDDF3 /* CallbackDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CallbackDelegate.h; path = Classes/CallbackDelegate.h; sourceTree = ""; }; + 6F169DA918CC35FD005EDDF3 /* CallbackDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CallbackDelegate.m; path = Classes/CallbackDelegate.m; sourceTree = ""; }; + 6F169DAB18CD8A4A005EDDF3 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; + 6F169DAD18CD906F005EDDF3 /* MenuItemProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MenuItemProxy.h; path = Classes/Commands/MenuItemProxy.h; sourceTree = ""; }; + 6F169DAE18CD906F005EDDF3 /* MenuItemProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MenuItemProxy.m; path = Classes/Commands/MenuItemProxy.m; sourceTree = ""; }; + 6F169DAF18CD906F005EDDF3 /* MenuProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MenuProxy.h; path = Classes/Commands/MenuProxy.h; sourceTree = ""; }; + 6F169DB018CD906F005EDDF3 /* MenuProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MenuProxy.m; path = Classes/Commands/MenuProxy.m; sourceTree = ""; }; + 6FD672B418FE618E00C0DAAD /* UserDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UserDefaults.h; path = Classes/Commands/UserDefaults.h; sourceTree = ""; }; + 6FD672B518FE618E00C0DAAD /* UserDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UserDefaults.m; path = Classes/Commands/UserDefaults.m; sourceTree = ""; }; + 6FD6E4EB18C2D48200DFFBE6 /* fonts.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = fonts.h; path = Classes/Commands/fonts.h; sourceTree = ""; }; + 6FD6E4EC18C2D48C00DFFBE6 /* fonts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = fonts.m; path = Classes/Commands/fonts.m; sourceTree = ""; }; + 88746BEC14CCA435001E160E /* JSEventHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSEventHelper.h; path = Classes/JSEventHelper.h; sourceTree = ""; }; + 88746BED14CCA435001E160E /* JSEventHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JSEventHelper.m; path = Classes/JSEventHelper.m; sourceTree = ""; }; + 88C0645E14BDE10A00E4BCE2 /* Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Window.h; path = Classes/Window.h; sourceTree = ""; }; + 88C0645F14BDE10A00E4BCE2 /* Window.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Window.m; path = Classes/Window.m; sourceTree = ""; }; + 88C0646514BDEC5800E4BCE2 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/Window.xib; sourceTree = ""; }; + 88C0646B14BDF6A600E4BCE2 /* WindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowController.h; sourceTree = ""; }; + 88C0646C14BDF6A600E4BCE2 /* WindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WindowController.m; sourceTree = ""; }; + C14EFCA61B0986AF00894B5F /* ZeroTierIcon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = ZeroTierIcon.icns; path = ../../../../artwork/ZeroTierIcon.icns; sourceTree = ""; }; + C1C2B9901AFB0CF10060D7C2 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; + F2B80014179E0FC100B069A8 /* Clipboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Clipboard.h; sourceTree = ""; }; + F2B80015179E0FC100B069A8 /* Clipboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Clipboard.m; sourceTree = ""; }; + FA32509C14BA813600BF0781 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + FA3250BA14BA85E700BF0781 /* Constants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Constants.h; path = Classes/Constants.h; sourceTree = ""; }; + FA3250BB14BA85E700BF0781 /* ContentView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ContentView.h; path = Classes/ContentView.h; sourceTree = ""; }; + FA3250BC14BA85E700BF0781 /* ContentView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ContentView.m; path = Classes/ContentView.m; sourceTree = ""; }; + FA3250BD14BA85E700BF0781 /* Utils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = Classes/Utils.h; sourceTree = ""; }; + FA3250BE14BA85E700BF0781 /* Utils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Utils.m; path = Classes/Utils.m; sourceTree = ""; }; + FA3250BF14BA85E700BF0781 /* WebViewDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WebViewDelegate.h; path = Classes/WebViewDelegate.h; sourceTree = ""; }; + FA3250C014BA85E700BF0781 /* WebViewDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = WebViewDelegate.m; path = Classes/WebViewDelegate.m; sourceTree = ""; }; + FA3250C814BA860800BF0781 /* App.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = App.h; path = Classes/Commands/App.h; sourceTree = ""; }; + FA3250C914BA860800BF0781 /* App.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = App.m; path = Classes/Commands/App.m; sourceTree = ""; }; + FA3250CA14BA860800BF0781 /* Dock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Dock.h; path = Classes/Commands/Dock.h; sourceTree = ""; }; + FA3250CB14BA860800BF0781 /* Dock.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Dock.m; path = Classes/Commands/Dock.m; sourceTree = ""; }; + FA3250CE14BA860800BF0781 /* Path.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Path.h; path = Classes/Commands/Path.h; sourceTree = ""; }; + FA3250CF14BA860800BF0781 /* Path.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Path.m; path = Classes/Commands/Path.m; sourceTree = ""; }; + FA3250D014BA860800BF0781 /* Sound.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Sound.h; path = Classes/Commands/Sound.h; sourceTree = ""; }; + FA3250D114BA860800BF0781 /* Sound.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Sound.m; path = Classes/Commands/Sound.m; sourceTree = ""; }; + FA3F7741168F70780027B324 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; + FAE451BA14BA79C600190544 /* ZeroTier One.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ZeroTier One.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + FAE451BE14BA79C600190544 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + FAE451C114BA79C600190544 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + FAE451C214BA79C600190544 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + FAE451C314BA79C600190544 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + FAE451C614BA79C600190544 /* MacGap-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "MacGap-Info.plist"; sourceTree = ""; }; + FAE451C814BA79C600190544 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + FAE451CA14BA79C600190544 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + FAE451CC14BA79C600190544 /* MacGap-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MacGap-Prefix.pch"; sourceTree = ""; }; + FAE451CE14BA79C600190544 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; }; + FAE451D014BA79C600190544 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + FAE451D114BA79C600190544 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + FAE451D414BA79C600190544 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + FAE451B714BA79C600190544 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C1C2B9911AFB0CF10060D7C2 /* Security.framework in Frameworks */, + 6F169DAC18CD8A4A005EDDF3 /* JavaScriptCore.framework in Frameworks */, + FA3F7742168F70790027B324 /* Cocoa.framework in Frameworks */, + FA32509D14BA813600BF0781 /* WebKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + FA3250E014BA87B800BF0781 /* Classes */ = { + isa = PBXGroup; + children = ( + FA3250E114BA87DD00BF0781 /* Commands */, + FA3250BA14BA85E700BF0781 /* Constants.h */, + 6F169DA818CC35FD005EDDF3 /* CallbackDelegate.h */, + 6F169DA918CC35FD005EDDF3 /* CallbackDelegate.m */, + FA3250BB14BA85E700BF0781 /* ContentView.h */, + FA3250BC14BA85E700BF0781 /* ContentView.m */, + FA3250BF14BA85E700BF0781 /* WebViewDelegate.h */, + FA3250C014BA85E700BF0781 /* WebViewDelegate.m */, + 88C0646B14BDF6A600E4BCE2 /* WindowController.h */, + 88C0646C14BDF6A600E4BCE2 /* WindowController.m */, + ); + name = Classes; + sourceTree = ""; + }; + FA3250E114BA87DD00BF0781 /* Commands */ = { + isa = PBXGroup; + children = ( + 6F169DA518CC332E005EDDF3 /* Command.h */, + 6F169DA618CC332E005EDDF3 /* Command.m */, + 1495814D15C15CCC00E1CFE5 /* Notice.h */, + 1495814E15C15CCC00E1CFE5 /* Notice.m */, + FA3250CA14BA860800BF0781 /* Dock.h */, + FA3250CB14BA860800BF0781 /* Dock.m */, + 6FD6E4EB18C2D48200DFFBE6 /* fonts.h */, + 6FD6E4EC18C2D48C00DFFBE6 /* fonts.m */, + FA3250BD14BA85E700BF0781 /* Utils.h */, + FA3250BE14BA85E700BF0781 /* Utils.m */, + 6FD672B418FE618E00C0DAAD /* UserDefaults.h */, + 6FD672B518FE618E00C0DAAD /* UserDefaults.m */, + FA3250CE14BA860800BF0781 /* Path.h */, + FA3250CF14BA860800BF0781 /* Path.m */, + FA3250D014BA860800BF0781 /* Sound.h */, + FA3250D114BA860800BF0781 /* Sound.m */, + FA3250C814BA860800BF0781 /* App.h */, + FA3250C914BA860800BF0781 /* App.m */, + 6F169DAD18CD906F005EDDF3 /* MenuItemProxy.h */, + 6F169DAE18CD906F005EDDF3 /* MenuItemProxy.m */, + 6F169DAF18CD906F005EDDF3 /* MenuProxy.h */, + 6F169DB018CD906F005EDDF3 /* MenuProxy.m */, + 88C0645E14BDE10A00E4BCE2 /* Window.h */, + 88C0645F14BDE10A00E4BCE2 /* Window.m */, + 88746BEC14CCA435001E160E /* JSEventHelper.h */, + 88746BED14CCA435001E160E /* JSEventHelper.m */, + F2B80014179E0FC100B069A8 /* Clipboard.h */, + F2B80015179E0FC100B069A8 /* Clipboard.m */, + ); + name = Commands; + sourceTree = ""; + }; + FAE451AF14BA79C600190544 = { + isa = PBXGroup; + children = ( + FA3F7741168F70780027B324 /* Cocoa.framework */, + FAE451C414BA79C600190544 /* MacGap */, + FAE451BD14BA79C600190544 /* Frameworks */, + FAE451BB14BA79C600190544 /* Products */, + ); + sourceTree = ""; + }; + FAE451BB14BA79C600190544 /* Products */ = { + isa = PBXGroup; + children = ( + FAE451BA14BA79C600190544 /* ZeroTier One.app */, + ); + name = Products; + sourceTree = ""; + }; + FAE451BD14BA79C600190544 /* Frameworks */ = { + isa = PBXGroup; + children = ( + C1C2B9901AFB0CF10060D7C2 /* Security.framework */, + 6F169DAB18CD8A4A005EDDF3 /* JavaScriptCore.framework */, + FA32509C14BA813600BF0781 /* WebKit.framework */, + FAE451BE14BA79C600190544 /* Cocoa.framework */, + FAE451C014BA79C600190544 /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; + FAE451C014BA79C600190544 /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + FAE451C114BA79C600190544 /* AppKit.framework */, + FAE451C214BA79C600190544 /* CoreData.framework */, + FAE451C314BA79C600190544 /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + FAE451C414BA79C600190544 /* MacGap */ = { + isa = PBXGroup; + children = ( + FA3250E014BA87B800BF0781 /* Classes */, + FAE451D014BA79C600190544 /* AppDelegate.h */, + FAE451D114BA79C600190544 /* AppDelegate.m */, + C14EFCA61B0986AF00894B5F /* ZeroTierIcon.icns */, + FAE451D314BA79C600190544 /* MainMenu.xib */, + 88C0646414BDEC5800E4BCE2 /* Window.xib */, + FAE451C514BA79C600190544 /* Supporting Files */, + ); + path = MacGap; + sourceTree = ""; + }; + FAE451C514BA79C600190544 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + FAE451C614BA79C600190544 /* MacGap-Info.plist */, + FAE451C714BA79C600190544 /* InfoPlist.strings */, + FAE451CA14BA79C600190544 /* main.m */, + FAE451CC14BA79C600190544 /* MacGap-Prefix.pch */, + FAE451CD14BA79C600190544 /* Credits.rtf */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + FAE451B914BA79C600190544 /* MacGap */ = { + isa = PBXNativeTarget; + buildConfigurationList = FAE451D814BA79C600190544 /* Build configuration list for PBXNativeTarget "MacGap" */; + buildPhases = ( + FAE451B814BA79C600190544 /* Resources */, + FAE451B614BA79C600190544 /* Sources */, + FAE451B714BA79C600190544 /* Frameworks */, + FA3250DD14BA876F00BF0781 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MacGap; + productName = MacGap; + productReference = FAE451BA14BA79C600190544 /* ZeroTier One.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + FAE451B114BA79C600190544 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0450; + ORGANIZATIONNAME = Twitter; + }; + buildConfigurationList = FAE451B414BA79C600190544 /* Build configuration list for PBXProject "MacGap" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = FAE451AF14BA79C600190544; + productRefGroup = FAE451BB14BA79C600190544 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + FAE451B914BA79C600190544 /* MacGap */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + FAE451B814BA79C600190544 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C14EFCA71B0986AF00894B5F /* ZeroTierIcon.icns in Resources */, + FAE451C914BA79C600190544 /* InfoPlist.strings in Resources */, + FAE451CF14BA79C600190544 /* Credits.rtf in Resources */, + FAE451D514BA79C600190544 /* MainMenu.xib in Resources */, + 88C0646614BDEC5800E4BCE2 /* Window.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + FAE451B614BA79C600190544 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6F169DAA18CC35FD005EDDF3 /* CallbackDelegate.m in Sources */, + FA3250D314BA860800BF0781 /* App.m in Sources */, + FA3250D514BA860800BF0781 /* Dock.m in Sources */, + FA3250D914BA860800BF0781 /* Path.m in Sources */, + FA3250DB14BA860800BF0781 /* Sound.m in Sources */, + FA3250C314BA85E700BF0781 /* ContentView.m in Sources */, + FA3250C514BA85E700BF0781 /* Utils.m in Sources */, + FA3250C714BA85E700BF0781 /* WebViewDelegate.m in Sources */, + FAE451CB14BA79C600190544 /* main.m in Sources */, + 6F169DB118CD906F005EDDF3 /* MenuItemProxy.m in Sources */, + FAE451D214BA79C600190544 /* AppDelegate.m in Sources */, + 6F169DA718CC332E005EDDF3 /* Command.m in Sources */, + 6FD672B618FE618E00C0DAAD /* UserDefaults.m in Sources */, + 88C0646014BDE10A00E4BCE2 /* Window.m in Sources */, + 6F169DB218CD906F005EDDF3 /* MenuProxy.m in Sources */, + 88C0646D14BDF6A600E4BCE2 /* WindowController.m in Sources */, + 6FD6E4ED18C2D48C00DFFBE6 /* fonts.m in Sources */, + 88746BEE14CCA435001E160E /* JSEventHelper.m in Sources */, + 1495814F15C15CCC00E1CFE5 /* Notice.m in Sources */, + F2B80016179E0FC100B069A8 /* Clipboard.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 88C0646414BDEC5800E4BCE2 /* Window.xib */ = { + isa = PBXVariantGroup; + children = ( + 88C0646514BDEC5800E4BCE2 /* en */, + ); + name = Window.xib; + sourceTree = ""; + }; + FAE451C714BA79C600190544 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + FAE451C814BA79C600190544 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + FAE451CD14BA79C600190544 /* Credits.rtf */ = { + isa = PBXVariantGroup; + children = ( + FAE451CE14BA79C600190544 /* en */, + ); + name = Credits.rtf; + sourceTree = ""; + }; + FAE451D314BA79C600190544 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + FAE451D414BA79C600190544 /* en */, + ); + name = MainMenu.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + FAE451D614BA79C600190544 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_ENABLE_OBJC_ARC = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_VERSION = ""; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "ZeroTier One"; + SDKROOT = ""; + }; + name = Debug; + }; + FAE451D714BA79C600190544 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_ENABLE_OBJC_ARC = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_VERSION = ""; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; + PRODUCT_NAME = "ZeroTier One"; + SDKROOT = ""; + }; + name = Release; + }; + FAE451D914BA79C600190544 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "compiler-default"; + CLANG_CXX_LIBRARY = "compiler-default"; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/MacGap\"", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "MacGap/MacGap-Prefix.pch"; + GCC_VERSION = ""; + INFOPLIST_FILE = "MacGap/MacGap-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.7; + PRODUCT_NAME = "ZeroTier One"; + SDKROOT = macosx; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + FAE451DA14BA79C600190544 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "compiler-default"; + CLANG_CXX_LIBRARY = "compiler-default"; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/MacGap\"", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "MacGap/MacGap-Prefix.pch"; + GCC_VERSION = ""; + INFOPLIST_FILE = "MacGap/MacGap-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.7; + PRODUCT_NAME = "ZeroTier One"; + SDKROOT = macosx; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + FAE451B414BA79C600190544 /* Build configuration list for PBXProject "MacGap" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FAE451D614BA79C600190544 /* Debug */, + FAE451D714BA79C600190544 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FAE451D814BA79C600190544 /* Build configuration list for PBXNativeTarget "MacGap" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FAE451D914BA79C600190544 /* Debug */, + FAE451DA14BA79C600190544 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = FAE451B114BA79C600190544 /* Project object */; +} diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..88f36fc7b --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcshareddata/MacGap.xccheckout b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcshareddata/MacGap.xccheckout new file mode 100644 index 000000000..7fdde8531 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcshareddata/MacGap.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 4D486E78-E297-4CC3-AAAE-1A58EDAC87E6 + IDESourceControlProjectName + MacGap + IDESourceControlProjectOriginsDictionary + + ABA3617E9F0148F844A82502F0D808DE6591AA97 + http://adam.ierymenko@git.int.zerotier.com/zerotier/zerotierone + + IDESourceControlProjectPath + ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj + IDESourceControlProjectRelativeInstallPathDictionary + + ABA3617E9F0148F844A82502F0D808DE6591AA97 + ../../../../.. + + IDESourceControlProjectURL + http://adam.ierymenko@git.int.zerotier.com/zerotier/zerotierone + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + ABA3617E9F0148F844A82502F0D808DE6591AA97 + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + ABA3617E9F0148F844A82502F0D808DE6591AA97 + IDESourceControlWCCName + ZeroTierOne + + + + diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcuserdata/Alex.xcuserdatad/UserInterfaceState.xcuserstate b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcuserdata/Alex.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 000000000..20281812b Binary files /dev/null and b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcuserdata/Alex.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcuserdata/api.xcuserdatad/WorkspaceSettings.xcsettings b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcuserdata/api.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..659c8766e --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcuserdata/api.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,10 @@ + + + + + HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges + + SnapshotAutomaticallyBeforeSignificantChanges + + + diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcuserdata/liamks.xcuserdatad/UserInterfaceState.xcuserstate b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcuserdata/liamks.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 000000000..822ed3cb6 Binary files /dev/null and b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcuserdata/liamks.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcuserdata/liamks.xcuserdatad/WorkspaceSettings.xcsettings b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcuserdata/liamks.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..6ff33e603 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj/project.xcworkspace/xcuserdata/liamks.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,10 @@ + + + + + IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges + + IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges + + + diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/AppDelegate.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/AppDelegate.h new file mode 100644 index 000000000..bf7370b50 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/AppDelegate.h @@ -0,0 +1,18 @@ +// +// AppDelegate.h +// MacGap +// +// Created by Alex MacCaw on 08/01/2012. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import +#import "Classes/ContentView.h" + +#import "WindowController.h" + +@interface AppDelegate : NSObject + +@property (retain, nonatomic) WindowController *windowController; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/AppDelegate.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/AppDelegate.m new file mode 100644 index 000000000..3e25ca13f --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/AppDelegate.m @@ -0,0 +1,145 @@ +// +// AppDelegate.m +// MacGap +// +// Created by Alex MacCaw on 08/01/2012. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import "AppDelegate.h" +#include +#include + +@implementation AppDelegate + +@synthesize windowController; + +- (void) applicationWillFinishLaunching:(NSNotification *)aNotification +{ +} + +-(BOOL)applicationShouldHandleReopen:(NSApplication*)application + hasVisibleWindows:(BOOL)visibleWindows{ + if(!visibleWindows){ + [self.windowController.window makeKeyAndOrderFront: nil]; + } + return YES; +} + +- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication { + return YES; +} + +- (void) applicationDidFinishLaunching:(NSNotification *)aNotification { + char buf[16384],userAuthTokenPath[4096]; + + FILE *pf = fopen("/Library/Application Support/ZeroTier/One/zerotier-one.port","r"); + long port = 9993; // default + if (pf) { + long n = fread(buf,1,sizeof(buf)-1,pf); + if (n > 0) { + buf[n] = (char)0; + port = strtol(buf,(char **)0,10); + } + fclose(pf); + } + + char url[16384]; + memset(url,0,sizeof(url)); + + const char *homeDir = getenv("HOME"); + if (homeDir) { + snprintf(userAuthTokenPath,sizeof(userAuthTokenPath),"%s/Library/Application Support/ZeroTier/One/authtoken.secret",homeDir); + pf = fopen(userAuthTokenPath,"r"); + if (pf) { + long n = fread(buf,1,sizeof(buf)-1,pf); + if (n > 0) { + buf[n] = (char)0; + snprintf(url,sizeof(url),"http://127.0.0.1:%ld/index.html?authToken=%s",port,buf); + } + fclose(pf); + } + } + + if (!url[0]) { + // Create authorization reference + OSStatus status; + AuthorizationRef authorizationRef; + + // AuthorizationCreate and pass NULL as the initial + // AuthorizationRights set so that the AuthorizationRef gets created + // successfully, and then later call AuthorizationCopyRights to + // determine or extend the allowable rights. + // http://developer.apple.com/qa/qa2001/qa1172.html + status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef); + if (status != errAuthorizationSuccess) + { + NSLog(@"Error Creating Initial Authorization: %d", status); + return; + } + + // kAuthorizationRightExecute == "system.privilege.admin" + AuthorizationItem right = {kAuthorizationRightExecute, 0, NULL, 0}; + AuthorizationRights rights = {1, &right}; + AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | + kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights; + + // Call AuthorizationCopyRights to determine or extend the allowable rights. + status = AuthorizationCopyRights(authorizationRef, &rights, NULL, flags, NULL); + if (status != errAuthorizationSuccess) + { + NSLog(@"Copy Rights Unsuccessful: %d", status); + return; + } + + // use rm tool with -rf + char *tool = "/bin/cat"; + char *args[] = {"/Library/Application Support/ZeroTier/One/authtoken.secret", NULL}; + FILE *pipe = NULL; + + status = AuthorizationExecuteWithPrivileges(authorizationRef, tool, kAuthorizationFlagDefaults, args, &pipe); + if (status != errAuthorizationSuccess) + { + NSLog(@"Error: %d", status); + } + + if (pipe) { + long n = (long)fread(buf,1,sizeof(buf)-1,pipe); + if (n > 0) { + buf[n] = (char)0; + snprintf(url,sizeof(url),"http://127.0.0.1:%ld/index.html?authToken=%s",port,buf); + + if (homeDir) { + snprintf(userAuthTokenPath,sizeof(userAuthTokenPath),"%s/Library/Application Support/ZeroTier",homeDir); + mkdir(userAuthTokenPath,0755); + snprintf(userAuthTokenPath,sizeof(userAuthTokenPath),"%s/Library/Application Support/ZeroTier/One",homeDir); + mkdir(userAuthTokenPath,0755); + snprintf(userAuthTokenPath,sizeof(userAuthTokenPath),"%s/Library/Application Support/ZeroTier/One/authtoken.secret",homeDir); + pf = fopen(userAuthTokenPath,"w"); + if (pf) { + fwrite(buf,1,strlen(buf),pf); + fclose(pf); + chmod(userAuthTokenPath,0600); + } + } + } + fclose(pipe); + } + + // The only way to guarantee that a credential acquired when you + // request a right is not shared with other authorization instances is + // to destroy the credential. To do so, call the AuthorizationFree + // function with the flag kAuthorizationFlagDestroyRights. + // http://developer.apple.com/documentation/Security/Conceptual/authorization_concepts/02authconcepts/chapter_2_section_7.html + status = AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights); + } + + NSString *urlStr = [[NSString alloc] initWithCString:url]; + self.windowController = [[WindowController alloc] initWithURL: urlStr]; + [self.windowController showWindow: [NSApplication sharedApplication].delegate]; + self.windowController.contentView.webView.alphaValue = 1.0; + self.windowController.contentView.alphaValue = 1.0; + [self.windowController showWindow:self]; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/CallbackDelegate.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/CallbackDelegate.h new file mode 100755 index 000000000..0f31ee417 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/CallbackDelegate.h @@ -0,0 +1,20 @@ +// +// CallbackDelegate.h +// MacGap +// +// Created by Joe Hildebrand on 1/10/12. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import "Command.h" + +@interface CallbackDelegate : Command { +} + +@property JSObjectRef callback; + +- (id) initWithContext:(JSContextRef)aContext forCallback:(WebScriptObject*)aCallback; +- (id) call; +- (id) callWithParams:(id)firstOrNil, ... NS_REQUIRES_NIL_TERMINATION; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/CallbackDelegate.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/CallbackDelegate.m new file mode 100755 index 000000000..5ce8fbe33 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/CallbackDelegate.m @@ -0,0 +1,168 @@ +// +// CallbackDelegate.m +// MacGap +// +// Created by Joe Hildebrand on 1/10/12. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import "CallbackDelegate.h" +#import + +@implementation CallbackDelegate + +@synthesize callback; + +- (id) initWithContext:(JSContextRef)aContext forCallback:(WebScriptObject*)aCallback +{ + if (!aCallback) + return nil; + if ([aCallback isKindOfClass:[WebUndefined class]]) + return nil; + + self = [super initWithContext:aContext]; + if (!self) + return nil; + + callback = [aCallback JSObject]; + JSValueProtect(context, callback); + return self; +} + +- (void) dealloc +{ + if (callback) + { + JSValueUnprotect(context, callback); + callback = nil; + } +} + +- (id) objectFromValue:(JSValueRef)val +{ + JSStringRef jstr; + NSString *rets; + + switch(JSValueGetType(context, val)) + { + case kJSTypeUndefined: + case kJSTypeNull: + return nil; + case kJSTypeBoolean: + return [NSNumber numberWithBool:JSValueToBoolean(context, val)]; + case kJSTypeNumber: + return [NSNumber numberWithDouble:JSValueToNumber(context, val, NULL)]; + case kJSTypeString: + jstr = JSValueToStringCopy(context, val, NULL); + size_t sz = JSStringGetMaximumUTF8CStringSize(jstr); + char *buf = (char*)malloc(sz); + JSStringGetUTF8CString(jstr, buf, sz); + rets = [NSString stringWithUTF8String:buf]; + free(buf); + return rets; + case kJSTypeObject: + // TODO: dictionary or something + return nil; + default: + NSAssert(false, @"Invalid JavaScript type"); + return nil; + } +} + +- (JSValueRef) valueFromObject:(id)obj +{ + JSValueRef val = nil; + if (!obj) + { + val = JSValueMakeNull(context); + } + else if ([obj isKindOfClass:[NSString class]]) + { + JSStringRef jstr = JSStringCreateWithUTF8CString([obj UTF8String]); + val = JSValueMakeString(context, jstr); + JSStringRelease(jstr); + } + else if ([obj isKindOfClass:[NSNumber class]]) + { + val = JSValueMakeNumber(context, [obj doubleValue]); + } + else if ([obj isKindOfClass:[NSDictionary class]]) + { + JSObjectRef o = JSObjectMake(context, NULL, NULL); + for (NSString *key in obj) + { + JSStringRef kstr = JSStringCreateWithUTF8CString([key UTF8String]); + JSValueRef v = [self valueFromObject:[obj objectForKey:key]]; + + JSObjectSetProperty(context, o, kstr, v, kJSPropertyAttributeNone, NULL); + JSStringRelease(kstr); + } + val = o; + } + else if ([obj isKindOfClass:[NSArray class]]) + { + NSUInteger pcount = [obj count]; + JSValueRef jsArgs[pcount]; + NSUInteger i=0; + for (id v in obj) + { + jsArgs[i++] = [self valueFromObject:v]; + } + val = JSObjectMakeArray(context, pcount, jsArgs, NULL); + } + else if ([obj isKindOfClass:[NSDate class]]) + { + NSTimeInterval secs = [obj timeIntervalSince1970]; + JSValueRef jsArgs[1]; + // call the Date(milliseconds) constructor in JS + jsArgs[0] = JSValueMakeNumber(context, secs * 1000.0); + val = JSObjectMakeDate(context, 1, jsArgs, NULL); + } + else + { + NSLog(@"Warning: unknown object type for: %@", obj); + val = JSValueMakeUndefined(context); + } + return val; +} + +- (id) call +{ + NSAssert(callback, @"Callback required"); + if (!JSObjectIsFunction(context, callback)) + return nil; + + JSValueRef jsArgs[0]; + JSValueRef ret = JSObjectCallAsFunction(context, callback, NULL, 0, jsArgs, NULL); + return [self objectFromValue:ret]; +} + +- (id) callWithParams:(id)firstOrNil, ... +{ + NSAssert(callback, @"Callback required"); + if (!JSObjectIsFunction(context, callback)) + return nil; + NSUInteger pcount = 0; + id p; + va_list args; + va_start(args, firstOrNil); + for (p=firstOrNil; p; p=va_arg(args, id)) + { + pcount++; + } + va_end(args); + + JSValueRef jsArgs[pcount]; + NSUInteger j = 0; + va_start(args, firstOrNil); + for (p=firstOrNil; p; p=va_arg(args, id)) + { + jsArgs[j++] = [self valueFromObject:p]; + } + va_end(args); + + JSValueRef ret = JSObjectCallAsFunction(context, callback, NULL, j, jsArgs, NULL); + return [self objectFromValue:ret]; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/App.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/App.h new file mode 100644 index 000000000..f65ba61e1 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/App.h @@ -0,0 +1,21 @@ +#import + +#import "WindowController.h" + +@interface App : NSObject { + +} + +@property (nonatomic, retain) WebView *webView; + +- (id) initWithWebView:(WebView *)view; + +- (void) terminate; +- (void) activate; +- (void) hide; +- (void) unhide; +- (void) beep; +- (void) bounce; +- (void) setCustomUserAgent:(NSString *)userAgentString; +- (NSNumber*) systemIdleTime; +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/App.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/App.m new file mode 100644 index 000000000..6d47a17e1 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/App.m @@ -0,0 +1,128 @@ +#import "App.h" + +#import "JSEventHelper.h" + +@implementation App + +@synthesize webView; + +- (id) initWithWebView:(WebView *) view{ + self = [super init]; + + if (self) { + self.webView = view; + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self + selector: @selector(receiveSleepNotification:) + name: NSWorkspaceWillSleepNotification object: NULL]; + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self + selector: @selector(receiveWakeNotification:) + name: NSWorkspaceDidWakeNotification object: NULL]; + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self + selector: @selector(receiveActivateNotification:) + name: NSWorkspaceDidActivateApplicationNotification object: NULL]; + } + + return self; +} + +- (void) terminate { + [NSApp terminate:nil]; +} + +- (void) activate { + [NSApp activateIgnoringOtherApps:YES]; +} + +- (void) hide { + [NSApp hide:nil]; +} + +- (void) unhide { + [NSApp unhide:nil]; +} + +- (void)beep { + NSBeep(); +} + +- (void) bounce { + [NSApp requestUserAttention:NSInformationalRequest]; +} + +- (void)setCustomUserAgent:(NSString *)userAgentString { + [self.webView setCustomUserAgent: userAgentString]; +} + +- (void) open:(NSString*)url { + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]]; +} + +- (void) launch:(NSString *)name { + [[NSWorkspace sharedWorkspace] launchApplication:name]; +} + +- (void)receiveSleepNotification:(NSNotification*)note{ + [JSEventHelper triggerEvent:@"sleep" forWebView:self.webView]; +} + +- (void) receiveWakeNotification:(NSNotification*)note{ + [JSEventHelper triggerEvent:@"wake" forWebView:self.webView]; +} + +- (void) receiveActivateNotification:(NSNotification*)notification{ + NSDictionary* userInfo = [notification userInfo]; + NSRunningApplication* runningApplication = [userInfo objectForKey:NSWorkspaceApplicationKey]; + if (runningApplication) { + NSMutableDictionary* applicationDidGetFocusDict = [[NSMutableDictionary alloc] initWithCapacity:2]; + [applicationDidGetFocusDict setObject:runningApplication.localizedName + forKey:@"localizedName"]; + [applicationDidGetFocusDict setObject:[runningApplication.bundleURL absoluteString] + forKey:@"bundleURL"]; + + [JSEventHelper triggerEvent:@"appActivated" withArgs:applicationDidGetFocusDict forWebView:self.webView]; + } +} + + + + +/* + To get the elapsed time since the previous input event—keyboard, mouse, or tablet—specify kCGAnyInputEventType. + */ +- (NSNumber*)systemIdleTime { + CFTimeInterval timeSinceLastEvent = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateHIDSystemState, kCGAnyInputEventType); + + return [NSNumber numberWithDouble:timeSinceLastEvent]; +} + + + + ++ (NSString*) webScriptNameForSelector:(SEL)selector +{ + id result = nil; + + if (selector == @selector(open:)) { + result = @"open"; + } else if (selector == @selector(launch:)) { + result = @"launch"; + } else if (selector == @selector(setCustomUserAgent:)) { + result = @"setCustomUserAgent"; + } else if (selector == @selector(systemIdleTime)) { + result = @"systemIdleTime"; + } + + return result; +} + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector +{ + return NO; +} + ++ (BOOL) isKeyExcludedFromWebScript:(const char*)name +{ + return YES; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Command.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Command.h new file mode 100755 index 000000000..65d6b6d48 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Command.h @@ -0,0 +1,18 @@ +// +// Command.h +// MacGap +// +// Created by Joe Hildebrand on 1/10/12. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import +#import + +@interface Command : NSObject { + JSContextRef context; +} + +- (id) initWithContext:(JSContextRef)aContext; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Command.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Command.m new file mode 100755 index 000000000..39b85630a --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Command.m @@ -0,0 +1,28 @@ +// +// Command.m +// MacGap +// +// Created by Joe Hildebrand on 1/10/12. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import "Command.h" +#import + +@implementation Command + +- (id) initWithContext:(JSContextRef)aContext { + self = [super init]; + if (!self) + return nil; + context = aContext; + JSGlobalContextRetain((JSGlobalContextRef)context); + return self; +} + +- (void)dealloc +{ + if (context) + JSGlobalContextRelease((JSGlobalContextRef)context); +} +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Dock.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Dock.h new file mode 100644 index 000000000..b3c533d79 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Dock.h @@ -0,0 +1,11 @@ +#import + +@interface Dock : NSObject { + +} +- (void) setBadge:(NSString*)value; +- (NSString *) badge; + +@property (readwrite, copy) NSString *badge; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Dock.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Dock.m new file mode 100644 index 000000000..a4494d165 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Dock.m @@ -0,0 +1,31 @@ +#import "Dock.h" + +@implementation Dock + +@synthesize badge; + +- (void) setBadge:(NSString *)value +{ + NSDockTile *tile = [[NSApplication sharedApplication] dockTile]; + [tile setBadgeLabel:value]; +} + +- (NSString *) badge +{ + NSDockTile *tile = [[NSApplication sharedApplication] dockTile]; + return [tile badgeLabel]; +} + +#pragma mark WebScripting Protocol + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector +{ + return NO; +} + ++ (BOOL) isKeyExcludedFromWebScript:(const char*)name +{ + return NO; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuItemProxy.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuItemProxy.h new file mode 100755 index 000000000..d765978fa --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuItemProxy.h @@ -0,0 +1,31 @@ +// +// MenuItemProxy.h +// MacGap +// +// Created by Joe Hildebrand on 1/15/12. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import "Command.h" +#import "CallbackDelegate.h" + +@class MenuProxy; + +@interface MenuItemProxy : Command { + NSMenuItem *item; + CallbackDelegate *callback; +} + ++ (MenuItemProxy*) proxyWithContext:(JSContextRef)aContext andMenuItem:(NSMenuItem*)anItem; + +- (MenuProxy*)addSubmenu; + +- (void) remove; +- (void) setCallback:(WebScriptObject*)aCallback; +- (void) setKey:(NSString*)keyCommand; +- (void) setTitle:(NSString*)title; +- (void) enable; +- (void) disable; +- (MenuProxy*)submenu; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuItemProxy.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuItemProxy.m new file mode 100755 index 000000000..7b9702cc4 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuItemProxy.m @@ -0,0 +1,150 @@ +// +// MenuItemProxy.m +// MacGap +// +// Created by Joe Hildebrand on 1/15/12. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import "MenuItemProxy.h" +#import "MenuProxy.h" + +@implementation MenuItemProxy + +- (id) initWithContext:(JSContextRef)aContext andMenuItem:(NSMenuItem*)anItem +{ + NSAssert(anItem, @"anItem required"); + self = [super initWithContext:aContext]; + if (!self) + return nil; + item = anItem; + item.representedObject = self; + + return self; +} + ++ (MenuItemProxy*) proxyWithContext:(JSContextRef)aContext andMenuItem:(NSMenuItem*)anItem +{ + MenuItemProxy *proxy = [anItem representedObject]; + if (proxy) + { + NSLog(@"MIP Cache hit"); + NSAssert([proxy class] == [MenuItemProxy class], @"Bad proxy"); + return proxy; + } + return [[MenuItemProxy alloc] initWithContext:aContext andMenuItem:anItem]; +} + +- (NSString*) description +{ + return [item description]; +} + +- (MenuProxy*)addSubmenu +{ + NSMenu *s = [item submenu]; + if (!s) + { + s = [[NSMenu alloc] initWithTitle:@"FFFFFFOOOOO"]; + [item setSubmenu:s]; + } + return [MenuProxy proxyWithContext:context andMenu:s]; +} + +- (void) remove +{ + NSMenu *menu = [item menu]; + [menu removeItem:item]; +} + +- (void)callCallback:(id)sender +{ + [callback callWithParams:[sender title], nil]; +} + +- (void) setCallback:(WebScriptObject*)aCallback +{ + NSAssert(item, @"item required"); + callback = [[CallbackDelegate alloc] initWithContext:context forCallback:aCallback]; + [item setAction:@selector(callCallback:)]; + [item setTarget:self]; +} + +- (void)setKey:(NSString*)keyCommand +{ + NSString *aKey = [MenuProxy getKeyFromString:keyCommand]; + [item setKeyEquivalent:aKey]; + + NSUInteger modifiers = [MenuProxy getModifiersFromString:keyCommand]; + [item setKeyEquivalentModifierMask:modifiers]; +} + +- (void) setTitle:(NSString*)title +{ + [item setTitle:title]; +} + +- (MenuProxy*)submenu; +{ + // TODO: make this work as a property + NSMenu *s = [item submenu]; + if (!s) + return nil; + return [MenuProxy proxyWithContext:context andMenu:s]; +} + +- (void) enable +{ + [item setEnabled:YES]; +} + +- (void) disable +{ + [item setEnabled:NO]; +} + +#pragma mark WebScripting protocol + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector +{ + return [self webScriptNameForSelector:selector] == nil; +} + ++ (BOOL) isKeyExcludedFromWebScript:(const char*)name +{ + return YES; +} + ++ (NSString*) webScriptNameForSelector:(SEL)selector +{ + id result = nil; + + if (selector == @selector(addSubmenu)) { + result = @"addSubmenu"; + } + else if (selector == @selector(remove)) { + result = @"remove"; + } + else if (selector == @selector(setCallback:)) { + result = @"setCallback"; + } + else if (selector == @selector(setKey:)) { + result = @"setKey"; + } + else if (selector == @selector(setTitle:)) { + result = @"setTitle"; + } + else if (selector == @selector(submenu)) { + result = @"submenu"; + } + else if (selector == @selector(enable)) { + result = @"enable"; + } + else if (selector == @selector(disable)) { + result = @"disable"; + } + + return result; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuProxy.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuProxy.h new file mode 100755 index 000000000..afd6c6edb --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuProxy.h @@ -0,0 +1,31 @@ +// +// MenuProxy.h +// MacGap +// +// Created by Joe Hildebrand on 1/14/12. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import "Command.h" + +@class MenuItemProxy; + +@interface MenuProxy : Command { + NSMenu *menu; +} + ++ (MenuProxy*)proxyWithContext:(JSContextRef)aContext andMenu:(NSMenu*)aMenu; + +- (MenuItemProxy*)addItemWithTitle:(NSString*)title + keyEquivalent:(NSString*)aKey + callback:(WebScriptObject*)aCallback + atIndex:(NSInteger)index; + +- (MenuItemProxy*)addSeparator; +- (MenuItemProxy*)itemForKey:(id)key; +- (MenuProxy*)removeItem:(id)key; + ++ (NSString*)getKeyFromString:(NSString*)keyCommand; ++ (NSUInteger*)getModifiersFromString:(NSString*)keyCommand; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuProxy.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuProxy.m new file mode 100755 index 000000000..5bc10a763 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuProxy.m @@ -0,0 +1,233 @@ +// +// MenuProxy.m +// MacGap +// +// Created by Joe Hildebrand on 1/14/12. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import +#import + +#import "MenuProxy.h" +#import "MenuItemProxy.h" + +static char REPRESENTED_OBJECT; + +@interface NSMenu (represented) +@property (strong) id representedObject; +@end + +@implementation NSMenu (represented) + +- (id) representedObject +{ + return objc_getAssociatedObject(self, &REPRESENTED_OBJECT); +} + +- (void) setRepresentedObject:(id)representedObject +{ + objc_setAssociatedObject(self, + &REPRESENTED_OBJECT, + representedObject, + OBJC_ASSOCIATION_RETAIN); +} + +@end + +@implementation MenuProxy + +- (id) initWithContext:(JSContextRef)aContext andMenu:(NSMenu*)aMenu +{ + self = [super initWithContext:aContext]; + if (!self) + return nil; + menu = aMenu; + menu.representedObject = self; + return self; +} + ++ (MenuProxy*)proxyWithContext:(JSContextRef)aContext andMenu:(NSMenu*)aMenu +{ + // singleton-ish. + MenuProxy *ret = [aMenu representedObject]; + if (ret) + { + NSLog(@"MP cache hit"); + return ret; + } + return [[MenuProxy alloc] initWithContext:aContext andMenu:aMenu]; +} + +- (void) dealloc +{ + menu.representedObject = nil; +} + +- (NSString*) description +{ + return [menu description]; +} + +static BOOL isNullish(id o) +{ + if (!o) + return YES; + if ([o isKindOfClass:[WebUndefined class]]) + return YES; + return NO; +} + +- (MenuItemProxy*)addItemWithTitle:(NSString*)title + keyEquivalent:(NSString*)keyCommand + callback:(WebScriptObject*)aCallback + atIndex:(NSInteger)index +{ + if (isNullish(title)) + title = @""; + + NSString *aKey = [MenuProxy getKeyFromString:keyCommand]; + NSMenuItem *item = nil; + + if(index) { + item = [menu insertItemWithTitle:title action:nil keyEquivalent:aKey atIndex:index ]; + } else { + item = [menu addItemWithTitle:title action:nil keyEquivalent:aKey ]; + + } + + // Set the modifiers. + NSUInteger modifiers = [MenuProxy getModifiersFromString:keyCommand]; + [item setKeyEquivalentModifierMask:modifiers]; + + if(!menu.supermenu) { + NSMenu *s = [[NSMenu alloc] initWithTitle:title]; + [item setSubmenu:s]; + } + + MenuItemProxy *mip = [MenuItemProxy proxyWithContext:context andMenuItem:item]; + if (!isNullish(aCallback)) + [mip setCallback:aCallback]; + + + return mip; +} + ++ (NSString*)getKeyFromString:(NSString*)keyCommand { + if (isNullish(keyCommand)) + keyCommand = @""; + + // Obtain the key (if there are modifiers, it will be the last character). + NSString *aKey = @""; + if ([keyCommand length] > 0) { + aKey = [keyCommand substringFromIndex:[keyCommand length] - 1]; + } + + return aKey; +} + ++ (NSUInteger*)getModifiersFromString:(NSString*)keyCommand { + // aKeys may optionally specify one or more modifiers. + NSUInteger modifiers = 0; + + if ([keyCommand rangeOfString:@"caps"].location != NSNotFound) modifiers += NSAlphaShiftKeyMask; + if ([keyCommand rangeOfString:@"shift"].location != NSNotFound) modifiers += NSShiftKeyMask; + if ([keyCommand rangeOfString:@"cmd"].location != NSNotFound) modifiers += NSCommandKeyMask; + if ([keyCommand rangeOfString:@"ctrl"].location != NSNotFound) modifiers += NSControlKeyMask; + if ([keyCommand rangeOfString:@"opt"].location != NSNotFound) modifiers += NSAlternateKeyMask; + if ([keyCommand rangeOfString:@"alt"].location != NSNotFound) modifiers += NSAlternateKeyMask; + + return modifiers; +} + +- (MenuItemProxy*)addSeparator +{ + NSMenuItem *sep = [NSMenuItem separatorItem]; + [menu addItem:sep]; + return [MenuItemProxy proxyWithContext:context andMenuItem:sep]; +} + +- (MenuItemProxy*)itemForKey:(id)key +{ + if (isNullish(key)) + return nil; + NSMenuItem *item = nil; + if ([key isKindOfClass:[NSNumber class]]) + { + item = [menu itemAtIndex:[key intValue]]; + } + else if ([key isKindOfClass:[NSString class]]) + { + item = [menu itemWithTitle:key]; + if (!item) + { + // Try again, with ... appended. e.g. "Save..." + item = [menu itemWithTitle: + [key stringByAppendingString:@"\u2026"]]; + } + } + if (!item) + return nil; + + return [MenuItemProxy proxyWithContext:context andMenuItem:item]; +} + +- (MenuProxy*)removeItem:(id)key +{ + if (isNullish(key)) + return nil; + + NSMenuItem *item = nil; + if ([key isKindOfClass:[NSNumber class]]) + { + item = [menu itemAtIndex:[key intValue]]; + } + else if ([key isKindOfClass:[NSString class]]) + { + item = [menu itemWithTitle:key]; + if (!item) + { + // Try again, with ... appended. e.g. "Save..." + item = [menu itemWithTitle: + [key stringByAppendingString:@"\u2026"]]; + } + } + if (!item) + return nil; + + [menu removeItem:item]; + return [MenuProxy proxyWithContext:context andMenu:menu]; +} + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector +{ + return [self webScriptNameForSelector:selector] == nil; +} + ++ (BOOL) isKeyExcludedFromWebScript:(const char*)name +{ + return YES; +} + ++ (NSString*) webScriptNameForSelector:(SEL)selector +{ + id result = nil; + + if (selector == @selector(addItemWithTitle:keyEquivalent:callback:atIndex:)) { + result = @"addItem"; + } + else if (selector == @selector(addSeparator)) { + result = @"addSeparator"; + } + else if (selector == @selector(itemForKey:)) { + result = @"getItem"; + } + else if (selector == @selector(removeItem:)) { + result = @"removeMenu"; + } + + return result; +} + + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Notice.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Notice.h new file mode 100644 index 000000000..51077a434 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Notice.h @@ -0,0 +1,26 @@ +// +// Notice.h +// MacGap +// +// Created by Christian Sullivan on 7/26/12. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import +#import "WindowController.h" + +#define APP_NOTICE_NOTIFICATION @"Notice" + +@interface Notice : NSObject { + +} + +@property (nonatomic, retain) WebView *webView; + +- (id) initWithWebView:(WebView *)view; +- (void) notify:(NSDictionary*)message; +- (void) close:(NSString*)notificationId; ++ (BOOL) available; + +@end + diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Notice.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Notice.m new file mode 100644 index 000000000..a4095f9f2 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Notice.m @@ -0,0 +1,108 @@ +// +// Notice.m +// MacGap +// +// Created by Christian Sullivan on 7/26/12. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import "Notice.h" + +#import "JSEventHelper.h" + +@implementation Notice + +- (id) initWithWebView:(WebView*)view +{ + if(self = [super init]) { + self.webView = view; + [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self]; + } + return self; +} + +- (void) notify:(NSDictionary *)message { + NSUserNotification *notification = [[NSUserNotification alloc] init]; + [notification setTitle:[message valueForKey:@"title"]]; + [notification setInformativeText:[message valueForKey:@"content"]]; + [notification setDeliveryDate:[NSDate dateWithTimeInterval:0 sinceDate:[NSDate date]]]; + BOOL playSound = true; // optional parameter, false only when {sound: false} + @try { + NSNumber *s = [message valueForKey:@"sound"]; + if ([[s className] isEqual: @"__NSCFBoolean"]) { + playSound = [s boolValue]; + } + } + @catch (NSException *exception) { + } + if (playSound) { + [notification setSoundName:NSUserNotificationDefaultSoundName]; + } + NSString *id = @""; // optional, needed for close + @try { + id = [message valueForKey:@"id"]; + } + @catch (NSException *exception) { + } + [notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:id, @"id", nil]]; + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + [center scheduleNotification:notification]; +} + +// close all notifications with id == notificationId or close all notifications if notificationId == "*" +- (void) close:(NSString*)notificationId { + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + for(NSUserNotification * deliveredNote in center.deliveredNotifications) { + if ([notificationId isEqualToString:@"*"] || [deliveredNote.userInfo[@"id"] isEqualToString:notificationId]) { + [center removeDeliveredNotification: deliveredNote]; + } + } +} + ++ (BOOL) available { + if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)]) + return YES; + + return NO; +} + +- (void) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification +{ + NSString *notificationId = [notification.userInfo valueForKey:@"id"]; + [JSEventHelper triggerEvent:@"macgap.notify.activated" forDetail:notificationId forWebView:self.webView]; +} + +#pragma mark WebScripting Protocol + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector +{ + BOOL result = YES; + if (selector == @selector(notify:)) + result = NO; + if (selector == @selector(close:)) + result = NO; + + return result; +} + ++ (NSString*) webScriptNameForSelector:(SEL)selector +{ + id result = nil; + + if (selector == @selector(notify:)) { + result = @"notify"; + } + if (selector == @selector(close:)) { + result = @"close"; + } + + return result; +} + +// right now exclude all properties (eg keys) ++ (BOOL) isKeyExcludedFromWebScript:(const char*)name +{ + return YES; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Path.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Path.h new file mode 100644 index 000000000..f931340d0 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Path.h @@ -0,0 +1,21 @@ +#import + +@interface Path : NSObject { + +} + +- (NSString *) application; +- (NSString *) resource; +- (NSString *) documents; +- (NSString *) library; +- (NSString *) home; +- (NSString *) temp; + +@property (readonly,copy) NSString* application; +@property (readonly,copy) NSString* resource; +@property (readonly,copy) NSString* documents; +@property (readonly,copy) NSString* library; +@property (readonly,copy) NSString* home; +@property (readonly,copy) NSString* temp; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Path.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Path.m new file mode 100644 index 000000000..8c54100f7 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Path.m @@ -0,0 +1,53 @@ +#import "Path.h" + +@implementation Path + +@synthesize application; +@synthesize resource; +@synthesize documents; +@synthesize library; +@synthesize home; +@synthesize temp; + +- (NSString *)application { + return [[NSBundle mainBundle] bundlePath]; +} + +- (NSString *)resource { + return [[NSBundle mainBundle] resourcePath]; +} + +- (NSString *)documents { + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + return [paths objectAtIndex:0]; +} + +- (NSString *)library { + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); + NSLog( @"%@", paths ); + return [paths objectAtIndex:0]; +} + +- (NSString *)home { + return NSHomeDirectory(); +} + +- (NSString *)temp { + return NSTemporaryDirectory(); +} + +#pragma mark WebScripting Protocol + +/* checks whether a selector is acceptable to be called from JavaScript */ ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector +{ + return NO; +} + +// right now exclude all properties (eg keys) ++ (BOOL) isKeyExcludedFromWebScript:(const char*)name +{ + return NO; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Sound.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Sound.h new file mode 100644 index 000000000..067076439 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Sound.h @@ -0,0 +1,17 @@ +#import +#import "Command.h" +#import "CallbackDelegate.h" + + +@interface Sound : Command { + +} + +// pending callbacks for sounds being played, to keep +// ARC from freeing them too early +@property (nonatomic, strong) NSMutableSet *pending; + +- (void) play:(NSString*)file onComplete:(WebScriptObject*)callback; +- (void) playSystem:(NSString*)name onComplete:(WebScriptObject*)callback; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Sound.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Sound.m new file mode 100644 index 000000000..9f4a44dbc --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Sound.m @@ -0,0 +1,97 @@ +#import "Sound.h" + + +@interface PlayDelegate : CallbackDelegate { +} + +@property (nonatomic, weak) Sound *sound; + +- (id) initWithContext:(JSContextRef)aContext + forCallback:(WebScriptObject*)aCallback + withSound:(Sound*)aSound; +@end + +@implementation PlayDelegate + +@synthesize sound; + +- (id) initWithContext:(JSContextRef)aContext + forCallback:(WebScriptObject*)aCallback + withSound:(Sound*)aSound +{ + self = [super initWithContext:aContext forCallback:aCallback]; + if (!self) + return nil; + sound = aSound; + return self; +} + +- (void)sound:(NSSound *)aSound didFinishPlaying:(BOOL)finishedPlaying { + [self callWithParams:[aSound name], nil]; + [sound.pending removeObject:self]; +} + +@end + +@implementation Sound + +@synthesize pending; + +- (id) initWithContext:(JSContextRef)aContext { + self = [super initWithContext:aContext]; + if (!self) { + return nil; + } + + pending = [NSMutableSet new]; + return self; +} + +- (void) playSound:(NSSound*)sound onComplete:(WebScriptObject*)callback { + if (callback != (id)[WebUndefined undefined]) { + PlayDelegate *d = [[PlayDelegate alloc] initWithContext:context + forCallback:callback + withSound:self]; + [pending addObject:d]; + [sound setDelegate:d]; + } + [sound play]; +} + +- (void) play:(NSString*)file onComplete:(WebScriptObject*)callback { + NSURL* fileUrl = [NSURL fileURLWithPath:[[Utils sharedInstance] pathForResource:file]]; + DebugNSLog(@"Sound file:%@", [fileUrl description]); + + NSSound* sound = [[NSSound alloc] initWithContentsOfURL:fileUrl byReference:YES]; + [self playSound:sound onComplete:callback]; +} + +- (void) playSystem:(NSString*)name onComplete:(WebScriptObject*)callback { + NSSound *systemSound = [NSSound soundNamed:name]; + [self playSound:systemSound onComplete:callback]; +} + +#pragma mark WebScripting Protocol + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector { + return [self webScriptNameForSelector:selector] == nil; +} + ++ (BOOL) isKeyExcludedFromWebScript:(const char*)name { + return YES; +} + ++ (NSString*) webScriptNameForSelector:(SEL)selector { + id result = nil; + + if (selector == @selector(play:onComplete:)) { + result = @"play"; + } + else if (selector == @selector(playSystem:onComplete:)) { + result = @"playSystem"; + } + + return result; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/UserDefaults.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/UserDefaults.h new file mode 100644 index 000000000..269191b39 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/UserDefaults.h @@ -0,0 +1,43 @@ +// +// UserDefaults.h +// MacGap +// +// Created by Jeff Hanbury on 16/04/2014. +// Copyright (c) 2014 Twitter. All rights reserved. +// + +#import + +#import "WindowController.h" + +@interface UserDefaults : NSObject + +@property (nonatomic, retain) WebView *webView; + +- (id) initWithWebView:(WebView *)view; +- (NSString*) getMyDefaults; +- (NSDictionary*) myDefaultsDictionary; +- (void) removeObjectForKey:(NSString*)key; +- (NSArray*) getUserDefaultsKeys; + +- (NSString*) addPrefix:(NSString*)key; + +- (void) setString:(NSString*)key withValue:(NSString*)value; +- (NSString*) getString:(NSString*)key; + +- (void) setInteger:(NSString*)key withValue:(NSString*)value; +- (NSNumber*) getInteger:(NSString*)key; + +- (void) setBool:(NSString*)key withValue:(NSString*)value; +- (NSNumber*) getBool:(NSString*)key; + +- (void) setFloat:(NSString*)key withValue:(NSString*)value; +- (NSNumber*) getFloat:(NSString*)key; + +// Could also be implemented: +//– setObject:forKey: +//– setDouble:forKey: +//– setURL:forKey: + +@end + diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/UserDefaults.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/UserDefaults.m new file mode 100644 index 000000000..485687108 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/UserDefaults.m @@ -0,0 +1,211 @@ +// +// UserDefaults.m +// MacGap +// +// Created by Jeff Hanbury on 16/04/2014. +// Copyright (c) 2014 Twitter. All rights reserved. +// + +#import "UserDefaults.h" +#import "JSEventHelper.h" + +@interface UserDefaults() { + +} + +-(void) setupNotificationCenter; + +@end + + +@implementation UserDefaults + +- (id) initWithWebView:(WebView *) view{ + self = [super init]; + + if (self) { + self.webView = view; + [self setupNotificationCenter]; + } + + return self; +} + + +-(void) setupNotificationCenter{ + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(defaultsChanged:) + name:NSUserDefaultsDidChangeNotification + object:nil]; +} + +- (void)defaultsChanged:(NSNotification *)notification { + NSDictionary* returnDict = [self myDefaultsDictionary]; + [JSEventHelper triggerEvent:@"userDefaultsChanged" withArgs:returnDict forWebView:self.webView]; +} + +- (NSString*) getMyDefaults { + NSDictionary* myDefaults = [self myDefaultsDictionary]; + + return [[Utils sharedInstance] convertDictionaryToJSON:myDefaults]; +} + +- (NSDictionary*) myDefaultsDictionary { + NSString* prefix = [kWebScriptNamespace stringByAppendingString:@"_"]; + NSMutableDictionary* returnDict = [[NSMutableDictionary alloc] init]; + + // Get the user defaults. + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + + // Build up a dictionary containing just the items beginning with our + // prefix. + for (NSString* key in [self getUserDefaultsKeys]) { + if ([key hasPrefix:prefix]) { + id val = [defaults valueForKey:key]; + [returnDict setObject:val forKey:key]; + } + } + + return returnDict; +} + +- (NSArray*) getUserDefaultsKeys { + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; + return [[prefs dictionaryRepresentation] allKeys]; +} + +- (void) removeObjectForKey:(NSString*)key { + NSString* prefixedKey; + prefixedKey = [self addPrefix:key]; + + [[NSUserDefaults standardUserDefaults] removeObjectForKey:prefixedKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +// Check we have a standard prefix for JS-modified keys, for security purposes. +// If not, add it. This stops JavaScript from ever being able to modify keys +// it did not create. +- (NSString*) addPrefix:(NSString*)key { + NSString* prefix; + prefix = [kWebScriptNamespace stringByAppendingString:@"_"]; + + if (![key hasPrefix:prefix]) { + key = [prefix stringByAppendingString:key]; + } + return key; +} + +// String + +- (void) setString:(NSString*)key withValue:(NSString*)value { + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; + NSString* prefixedKey; + prefixedKey = [self addPrefix:key]; + [prefs setObject:value forKey:prefixedKey]; +} + +- (NSString*) getString:(NSString *)key { + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; + return [prefs stringForKey:key]; +} + +// All the following must convert their type to NSNumber for JavaScript. + +// Integer + +- (void) setInteger:(NSString*)key withValue:(NSString*)value { + NSString* prefixedKey; + prefixedKey = [self addPrefix:key]; + + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; + NSInteger myInt = [value intValue]; + [prefs setInteger:myInt forKey:prefixedKey]; +} + +- (NSNumber*) getInteger:(NSString *)key { + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; + return [NSNumber numberWithInteger:[prefs integerForKey:key]]; +} + +// Boolean + +- (void) setBool:(NSString*)key withValue:(NSString*)value { + NSString* prefixedKey; + prefixedKey = [self addPrefix:key]; + + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; + BOOL myBool = [value boolValue]; + [prefs setBool:myBool forKey:prefixedKey]; +} + +- (NSNumber*) getBool:(NSString *)key { + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; + return [NSNumber numberWithBool:[prefs boolForKey:key]]; +} + +// Float + +- (void) setFloat:(NSString*)key withValue:(NSString*)value { + NSString* prefixedKey; + prefixedKey = [self addPrefix:key]; + + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; + float myFloat = [value floatValue]; + [prefs setFloat:myFloat forKey:prefixedKey]; +} + +- (NSNumber*) getFloat:(NSString *)key { + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; + return [NSNumber numberWithFloat:[prefs floatForKey:key]]; +} + + +#pragma mark WebScripting Protocol + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector { + return NO; +} + ++ (NSString*) webScriptNameForSelector:(SEL)selector { + id result = nil; + + if (selector == @selector(getMyDefaults)) { + result = @"getMyDefaults"; + } + + if (selector == @selector(removeObjectForKey:)) { + result = @"removeObjectForKey"; + } + + else if (selector == @selector(setString:withValue:)) { + result = @"setString"; + } else if (selector == @selector(getString:)) { + result = @"getString"; + } + + else if (selector == @selector(setInteger:withValue:)) { + result = @"setInteger"; + } else if (selector == @selector(getInteger:)) { + result = @"getInteger"; + } + + else if (selector == @selector(setBool:withValue:)) { + result = @"setBool"; + } else if (selector == @selector(getBool:)) { + result = @"getBool"; + } + + else if (selector == @selector(setFloat:withValue:)) { + result = @"setFloat"; + } else if (selector == @selector(getFloat:)) { + result = @"getFloat"; + } + + return result; +} + ++ (BOOL) isKeyExcludedFromWebScript:(const char*)name { + return NO; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/fonts.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/fonts.h new file mode 100644 index 000000000..62c7b7e83 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/fonts.h @@ -0,0 +1,9 @@ +@interface Fonts : NSObject { +} + +- (NSArray*) availableFonts; +- (NSArray*) availableFontFamilies; +- (NSArray*) availableMembersOfFontFamily:(NSString*)fontFamily; +- (CGFloat) defaultLineHeightForFont:(NSString *)theFontName ofSize:(CGFloat)theFontSize; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/fonts.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/fonts.m new file mode 100644 index 000000000..b17818a53 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/fonts.m @@ -0,0 +1,48 @@ +#import "fonts.h" + +@implementation Fonts + + +- (NSArray*) availableFonts { + return [[NSFontManager sharedFontManager] availableFonts]; +} + +- (NSArray*) availableFontFamilies { + return [[NSFontManager sharedFontManager] availableFontFamilies]; +} + +- (NSArray*) availableMembersOfFontFamily:(NSString *)fontFamily { + return [[NSFontManager sharedFontManager] availableMembersOfFontFamily:fontFamily]; +} + +- (CGFloat) defaultLineHeightForFont:(NSString*)theFontName ofSize:(CGFloat)theFontSize { + NSFont *theFont = [NSFont fontWithName:theFontName size:theFontSize]; + NSLayoutManager *lm = [[NSLayoutManager alloc] init]; + + return [lm defaultLineHeightForFont:theFont]; +} + + +#pragma mark WebScripting Protocol + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector { + return NO; +} + ++ (NSString*) webScriptNameForSelector:(SEL)selector { + id result = nil; + + if (selector == @selector(availableMembersOfFontFamily:)) { + result = @"availableMembersOfFontFamily"; + } else if (selector == @selector(defaultLineHeightForFont:ofSize:)) { + result = @"defaultLineHeightForFont"; + } + + return result; +} + ++ (BOOL) isKeyExcludedFromWebScript:(const char*)name { + return NO; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Constants.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Constants.h new file mode 100644 index 000000000..1fe59d6cc --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Constants.h @@ -0,0 +1,7 @@ +// Application constants + +#define kStartPage @"http://127.0.0.1:9993/" + +#define kStartFolder @"." + +#define kWebScriptNamespace @"macgap" \ No newline at end of file diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/ContentView.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/ContentView.h new file mode 100644 index 000000000..65890a5ee --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/ContentView.h @@ -0,0 +1,15 @@ +#import +#import + +@class WebViewDelegate; + +@interface ContentView : NSView { + IBOutlet WebView* webView; + WebViewDelegate* delegate; +} + +@property (retain) WebView* webView; +@property (retain) WebViewDelegate* delegate; +@property (strong) IBOutlet NSMenu *mainMenu; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/ContentView.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/ContentView.m new file mode 100644 index 000000000..24e58cd1c --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/ContentView.m @@ -0,0 +1,68 @@ +#import "ContentView.h" +#import "WebViewDelegate.h" +#import "AppDelegate.h" +#import "JSEventHelper.h" + +@interface WebPreferences (WebPreferencesPrivate) + - (void)_setLocalStorageDatabasePath:(NSString *)path; + - (void) setLocalStorageEnabled: (BOOL) localStorageEnabled; + - (void) setDatabasesEnabled:(BOOL)databasesEnabled; + - (void) setDeveloperExtrasEnabled:(BOOL)developerExtrasEnabled; + - (void) setWebGLEnabled:(BOOL)webGLEnabled; + - (void) setOfflineWebApplicationCacheEnabled:(BOOL)offlineWebApplicationCacheEnabled; +@end + +@implementation ContentView + +@synthesize webView, delegate, mainMenu; + +- (void) awakeFromNib +{ + WebPreferences *webPrefs = [WebPreferences standardPreferences]; + + NSString *cappBundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; + NSString *applicationSupportFile = [@"~/Library/Application Support/" stringByExpandingTildeInPath]; + NSString *savePath = [NSString pathWithComponents:[NSArray arrayWithObjects:applicationSupportFile, cappBundleName, @"LocalStorage", nil]]; + [webPrefs _setLocalStorageDatabasePath:savePath]; + [webPrefs setLocalStorageEnabled:YES]; + [webPrefs setDatabasesEnabled:YES]; + [webPrefs setDeveloperExtrasEnabled:[[NSUserDefaults standardUserDefaults] boolForKey: @"developer"]]; + [webPrefs setOfflineWebApplicationCacheEnabled:YES]; + [webPrefs setWebGLEnabled:YES]; + + [self.webView setPreferences:webPrefs]; + + NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage + sharedHTTPCookieStorage]; + [cookieStorage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; + + [self.webView setApplicationNameForUserAgent: @"MacGap"]; + + self.delegate = [[WebViewDelegate alloc] initWithMenu:[NSApp mainMenu]]; + [self.webView setFrameLoadDelegate:self.delegate]; + [self.webView setUIDelegate:self.delegate]; + [self.webView setResourceLoadDelegate:self.delegate]; + [self.webView setDownloadDelegate:self.delegate]; + [self.webView setPolicyDelegate:self.delegate]; + [self.webView setDrawsBackground:NO]; + [self.webView setShouldCloseWithWindow:NO]; + + [self.webView setGroupName:@"MacGap"]; + +} + +- (void) windowResized:(NSNotification*)notification; +{ + NSWindow* window = (NSWindow*)notification.object; + NSSize size = [window frame].size; + + DebugNSLog(@"window width = %f, window height = %f", size.width, size.height); + + bool isFullScreen = (window.styleMask & NSFullScreenWindowMask) == NSFullScreenWindowMask; + int titleBarHeight = isFullScreen ? 0 : [[Utils sharedInstance] titleBarHeight:window]; + + [self.webView setFrame:NSMakeRect(0, 0, size.width, size.height - titleBarHeight)]; + [JSEventHelper triggerEvent:@"orientationchange" forWebView:self.webView]; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/JSEventHelper.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/JSEventHelper.h new file mode 100644 index 000000000..401f3e396 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/JSEventHelper.h @@ -0,0 +1,20 @@ +// +// Helper.h +// MacGap +// +// Created by Liam Kaufman Simpkins on 12-01-22. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import +#import "WindowController.h" + +@interface JSEventHelper : NSObject + ++ (void) triggerEvent:(NSString *)event forWebView:(WebView *)webView; ++ (void) triggerEvent:(NSString *)event withArgs:(NSDictionary *)args forWebView:(WebView *)webView; ++ (void) triggerEvent:(NSString *)event withArgs:(NSDictionary *)args forObject:(NSString *)objName forWebView:(WebView *)webView; ++ (void) triggerEvent:(NSString *)event forDetail:(NSString *)detail forWebView:(WebView *)webView; ++ (void) triggerEvent:(NSString *)event forDetail:(NSString *)detail forObject:(NSString *)objName forWebView:(WebView *)webView; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/JSEventHelper.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/JSEventHelper.m new file mode 100644 index 000000000..65406b3c0 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/JSEventHelper.m @@ -0,0 +1,41 @@ +// +// Helper.m +// MacGap +// +// Created by Liam Kaufman Simpkins on 12-01-22. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import "JSEventHelper.h" + +@implementation JSEventHelper + ++ (void) triggerEvent:(NSString *)event forWebView:(WebView *)webView { + [self triggerEvent:event withArgs:[NSMutableDictionary dictionary] forObject:@"document" forWebView:webView]; +} + ++ (void) triggerEvent:(NSString *)event withArgs:(NSDictionary *)args forWebView:(WebView *)webView { + [self triggerEvent:event withArgs:args forObject:@"document" forWebView:webView]; +} + ++ (void) triggerEvent:(NSString *)event withArgs:(NSDictionary *)args forObject:(NSString *)objName forWebView:(WebView *)webView { + + // Convert args Dictionary to JSON. + NSString* jsonString = [[Utils sharedInstance] convertDictionaryToJSON:args]; + + // Create the event JavaScript and run it. + NSString * str = [NSString stringWithFormat:@"var e = document.createEvent('Events'); e.initEvent('%@', true, false); e.data=%@; %@.dispatchEvent(e); ", event, jsonString, objName]; + [webView stringByEvaluatingJavaScriptFromString:str]; +} + ++ (void) triggerEvent:(NSString *)event forDetail:(NSString *)detail forWebView:(WebView *)webView { + [self triggerEvent:event forDetail:detail forObject:@"document" forWebView:webView]; +} + ++ (void) triggerEvent:(NSString *)event forDetail:(NSString *)detail forObject:(NSString *)objName forWebView:(WebView *)webView { + NSString *detailEscaped = [detail stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; + NSString *str = [NSString stringWithFormat:@"var e = new CustomEvent('%@', { 'detail': decodeURIComponent(\"%@\") }); %@.dispatchEvent(e); ", event, detailEscaped, objName]; + [webView stringByEvaluatingJavaScriptFromString:str]; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Utils.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Utils.h new file mode 100644 index 000000000..f573d881a --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Utils.h @@ -0,0 +1,20 @@ +#import +#import + +#define DEG_EPS 0.001 +#define fequal(a,b) (fabs((a) - (b)) < DEG_EPS) +#define fequalzero(a) (fabs(a) < DEG_EPS) + +@class LoadingView; + +@interface Utils : NSObject { +} + +- (float) titleBarHeight:(NSWindow*)aWindow; +- (NSString*) pathForResource:(NSString*)resourcepath; +- (NSString*) convertDictionaryToJSON:(NSDictionary*)dict; +- (NSArray*) convertJSarrayToNSArray:(WebScriptObject*)jsArray; + ++ (Utils*) sharedInstance; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Utils.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Utils.m new file mode 100644 index 000000000..8d85c2949 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Utils.m @@ -0,0 +1,93 @@ +#import "Utils.h" +#import + +static Utils* sharedInstance = nil; + +@implementation Utils + +- (float) titleBarHeight:(NSWindow*)aWindow +{ + NSRect frame = [aWindow frame]; + NSRect contentRect = [NSWindow contentRectForFrameRect: frame + styleMask: NSTitledWindowMask]; + + return (frame.size.height - contentRect.size.height); +} + +- (NSString*) pathForResource:(NSString*)resourcepath +{ + NSBundle * mainBundle = [NSBundle mainBundle]; + NSMutableArray *directoryParts = [NSMutableArray arrayWithArray:[resourcepath componentsSeparatedByString:@"/"]]; + NSString *filename = [directoryParts lastObject]; + [directoryParts removeLastObject]; + + NSString *directoryStr = [NSString stringWithFormat:@"%@/%@", kStartFolder, [directoryParts componentsJoinedByString:@"/"]]; + return [mainBundle pathForResource:filename + ofType:@"" + inDirectory:directoryStr]; +} + +- (NSString*) convertDictionaryToJSON:(NSDictionary*)dict { + // Convert defaults Dictionary to JSON. + NSError *error; + NSData *jsonData = [NSJSONSerialization + dataWithJSONObject:dict + options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string + error:&error]; + + NSString *jsonString; + if (! jsonData) { + NSLog(@"Got an error converting to JSON: %@", error); + } + else { + jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + } + + return jsonString; +} + +// Convert JavaScript array (arrives as a WebScriptObject) into an NSArray of strings. +- (NSArray*) convertJSarrayToNSArray:(WebScriptObject*)jsArray { + NSInteger count = [[jsArray valueForKey:@"length"] integerValue]; + + NSMutableArray *args = [NSMutableArray array]; + for (int i = 0; i < count; i++) { + NSString *item = [jsArray webScriptValueAtIndex:i]; + if ([item isKindOfClass:[NSString class]]) { + [args addObject:item]; + } + } + + return args; +} + +#pragma mark - +#pragma mark Singleton methods + ++ (Utils*) sharedInstance +{ + @synchronized(self) + { + if (sharedInstance == nil){ + sharedInstance = [[Utils alloc] init]; + } + } + return sharedInstance; +} + ++ (id) allocWithZone:(NSZone *)zone { + @synchronized(self) { + if (sharedInstance == nil) { + sharedInstance = [super allocWithZone:zone]; + return sharedInstance; // assignment and return on first allocation + } + } + return nil; // on subsequent allocation attempts return nil +} + +- (id) copyWithZone:(NSZone *)zone +{ + return self; +} + +@end \ No newline at end of file diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/WebViewDelegate.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/WebViewDelegate.h new file mode 100644 index 000000000..49c6da6b9 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/WebViewDelegate.h @@ -0,0 +1,49 @@ +#import +#import + +@class Sound; +@class Dock; +@class Growl; +@class Notice; +@class Path; +@class App; +@class Window; +@class Clipboard; +@class Fonts; +@class MenuProxy; +@class UserDefaults; + +@class WindowController; + +@interface WebViewDelegate : NSObject { + Sound* sound; + Dock* dock; + Growl* growl; + Notice* notice; + Path* path; + App* app; + Window* window; + Clipboard* clipboard; + Fonts* fonts; + NSMenu *mainMenu; + UserDefaults* userDefaults; +} + + + +@property (nonatomic, retain) Sound* sound; +@property (nonatomic, retain) Dock* dock; +@property (nonatomic, retain) Growl* growl; +@property (nonatomic, retain) Notice* notice; +@property (nonatomic, retain) Path* path; +@property (nonatomic, retain) App* app; +@property (nonatomic, retain) Window* window; +@property (nonatomic, retain) Clipboard* clipboard; +@property (nonatomic, retain) Fonts* fonts; +@property (nonatomic, retain) MenuProxy* menu; +@property (nonatomic, retain) UserDefaults* userDefaults; + +@property (nonatomic, retain) WindowController *requestedWindow; + +- (id) initWithMenu:(NSMenu*)menu; +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/WebViewDelegate.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/WebViewDelegate.m new file mode 100644 index 000000000..505780183 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/WebViewDelegate.m @@ -0,0 +1,206 @@ +#import "WebViewDelegate.h" +#import "Sound.h" +#import "Dock.h" +#import "Notice.h" +#import "Path.h" +#import "App.h" +#import "Window.h" +#import "WindowController.h" +#import "Clipboard.h" +#import "Fonts.h" +#import "MenuProxy.h" +#import "UserDefaults.h" + +@implementation WebViewDelegate + +@synthesize sound; +@synthesize dock; +@synthesize growl; +@synthesize notice; +@synthesize path; +@synthesize app; +@synthesize window; +@synthesize requestedWindow; +@synthesize clipboard; +@synthesize fonts; +@synthesize menu; +@synthesize userDefaults; + +- (id) initWithMenu:(NSMenu*)aMenu +{ + self = [super init]; + if (!self) + return nil; + + mainMenu = aMenu; + return self; +} + +- (void) webView:(WebView*)webView didClearWindowObject:(WebScriptObject*)windowScriptObject forFrame:(WebFrame *)frame +{ + JSContextRef context = [frame globalContext]; + if (self.sound == nil) { self.sound = [[Sound alloc] initWithContext:context]; } + if (self.dock == nil) { self.dock = [Dock new]; } + if (self.path == nil) { self.path = [Path new]; } + if (self.clipboard == nil) { self.clipboard = [Clipboard new]; } + if (self.fonts == nil) { self.fonts = [Fonts new]; } + + if (self.notice == nil && [Notice available] == YES) { + self.notice = [[Notice alloc] initWithWebView:webView]; + } + + if (self.app == nil) { + self.app = [[App alloc] initWithWebView:webView]; + } + + if (self.window == nil) { + self.window = [[Window alloc] initWithWebView:webView]; + } + + if (self.menu == nil) { + self.menu = [MenuProxy proxyWithContext:context andMenu:mainMenu]; + } + + if (self.userDefaults == nil) { + self.userDefaults = [[UserDefaults alloc] initWithWebView:webView]; + } + + [windowScriptObject setValue:self forKey:kWebScriptNamespace]; +} + + +- (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(id < WebOpenPanelResultListener >)resultListener allowMultipleFiles:(BOOL)allowMultipleFiles{ + + NSOpenPanel * openDlg = [NSOpenPanel openPanel]; + + [openDlg setCanChooseFiles:YES]; + [openDlg setCanChooseDirectories:NO]; + + [openDlg beginWithCompletionHandler:^(NSInteger result){ + if (result == NSFileHandlingPanelOKButton) { + NSArray * files = [[openDlg URLs] valueForKey: @"relativePath"]; + [resultListener chooseFilenames: files]; + } else { + [resultListener cancel]; + } + }]; +} + +- (void) webView:(WebView*)webView addMessageToConsole:(NSDictionary*)message +{ + if (![message isKindOfClass:[NSDictionary class]]) { + return; + } + + NSLog(@"JavaScript console: %@:%@: %@", + [[message objectForKey:@"sourceURL"] lastPathComponent], // could be nil + [message objectForKey:@"lineNumber"], + [message objectForKey:@"message"]); +} + +- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame +{ + NSAlert *alert = [[NSAlert alloc] init]; + [alert addButtonWithTitle:@"OK"]; + [alert setMessageText:message]; + [alert setAlertStyle:NSWarningAlertStyle]; + [alert runModal]; +} + +- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame +{ + NSAlert *alert = [[NSAlert alloc] init]; + [alert addButtonWithTitle:@"Yes"]; + [alert addButtonWithTitle:@"No"]; + [alert setMessageText:message]; + [alert setAlertStyle:NSWarningAlertStyle]; + + if ([alert runModal] == NSAlertFirstButtonReturn) + return YES; + else + return NO; +} + +/* + By default the size of a database is set to 0 [1]. When a database is being created + it calls this delegate method to get an increase in quota size - or call an error. + PS this method is defined in WebUIDelegatePrivate and may make it difficult, but + not impossible [2], to get an app accepted into the mac app store. + + Further reading: + [1] http://stackoverflow.com/questions/353808/implementing-a-webview-database-quota-delegate + [2] http://stackoverflow.com/questions/4527905/how-do-i-enable-local-storage-in-my-webkit-based-application/4608549#4608549 + */ +- (void)webView:(WebView *)sender frame:(WebFrame *)frame exceededDatabaseQuotaForSecurityOrigin:(id) origin database:(NSString *)databaseIdentifier +{ + static const unsigned long long defaultQuota = 5 * 1024 * 1024; + if ([origin respondsToSelector: @selector(setQuota:)]) { + [origin performSelector:@selector(setQuota:) withObject:[NSNumber numberWithLongLong: defaultQuota]]; + } else { + NSLog(@"could not increase quota for %lld", defaultQuota); + } +} + +- (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems +{ + NSMutableArray *webViewMenuItems = [defaultMenuItems mutableCopy]; + + if (webViewMenuItems) + { + NSEnumerator *itemEnumerator = [defaultMenuItems objectEnumerator]; + NSMenuItem *menuItem = nil; + while ((menuItem = [itemEnumerator nextObject])) + { + NSInteger tag = [menuItem tag]; + + switch (tag) + { + case WebMenuItemTagOpenLinkInNewWindow: + case WebMenuItemTagDownloadLinkToDisk: + case WebMenuItemTagCopyLinkToClipboard: + case WebMenuItemTagOpenImageInNewWindow: + case WebMenuItemTagDownloadImageToDisk: + case WebMenuItemTagCopyImageToClipboard: + case WebMenuItemTagOpenFrameInNewWindow: + case WebMenuItemTagGoBack: + case WebMenuItemTagGoForward: + case WebMenuItemTagStop: + case WebMenuItemTagOpenWithDefaultApplication: + case WebMenuItemTagReload: + [webViewMenuItems removeObjectIdenticalTo: menuItem]; + } + } + } + + return webViewMenuItems; +} + +- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request{ + requestedWindow = [[WindowController alloc] initWithRequest:request]; + return requestedWindow.contentView.webView; +} + +- (void)webViewShow:(WebView *)sender{ + [requestedWindow showWindow:sender]; +} + +- (void)webView:(WebView *)webView decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id < WebPolicyDecisionListener >)listener +{ + [[NSWorkspace sharedWorkspace] openURL:[request URL]]; + [listener ignore]; +} + +#pragma mark WebScripting protocol + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector +{ + return YES; +} + ++ (BOOL) isKeyExcludedFromWebScript:(const char*)name +{ + return NO; +} + + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Window.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Window.h new file mode 100644 index 000000000..f721376e0 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Window.h @@ -0,0 +1,23 @@ +#import + +#import "WindowController.h" + +@interface Window : NSObject{ + CGRect _oldRestoreFrame; +} + +@property (retain, nonatomic) WindowController *windowController; +@property (nonatomic, retain) WebView *webView; + +- (id) initWithWebView:(WebView *)view; +- (void) open:(NSDictionary *)properties; +- (void) move:(NSDictionary *)properties; +- (void) resize:(NSDictionary *) properties; +- (Boolean) isMaximized; +- (CGFloat) getX; +- (CGFloat) getY; +- (void) maximize; +- (void) restore; +- (void) toggleFullscreen; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Window.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Window.m new file mode 100644 index 000000000..2444f62ea --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Window.m @@ -0,0 +1,94 @@ +#import "Window.h" + +@implementation Window + +@synthesize windowController, webView; + +- (id) initWithWebView:(WebView*)view +{ + if(self = [super init]) { + self.webView = view; + } + return self; +} + +- (void) open:(NSDictionary *)properties +{ + self.windowController = [[WindowController alloc] initWithURL:[properties valueForKey:@"url"]]; + [self.windowController showWindow: [NSApplication sharedApplication].delegate]; + [self.windowController.window makeKeyWindow]; +} + +- (void) minimize { + [[NSApp mainWindow] miniaturize:[NSApp mainWindow]]; +} + +- (void) toggleFullscreen { + [[NSApp mainWindow] toggleFullScreen:[NSApp mainWindow]]; +} + +- (void) maximize { + CGRect a = [NSApp mainWindow].frame; + _oldRestoreFrame = CGRectMake(a.origin.x, a.origin.y, a.size.width, a.size.height); + [[NSApp mainWindow] setFrame:[[NSScreen mainScreen] visibleFrame] display:YES]; +} + +- (Boolean) isMaximized { + NSRect a = [NSApp mainWindow].frame; + NSRect b = [[NSScreen mainScreen] visibleFrame]; + return a.origin.x == b.origin.x && a.origin.y == b.origin.y && a.size.width == b.size.width && a.size.height == b.size.height; +} + +- (CGFloat) getX { + NSRect frame = [self.webView window].frame; + return frame.origin.x; +} + +- (CGFloat) getY { + NSRect frame = [self.webView window].frame; + return frame.origin.y; +} + +- (void) move:(NSDictionary *)properties +{ + NSRect frame = [self.webView window].frame; + frame.origin.x = [[properties valueForKey:@"x"] doubleValue]; + frame.origin.y = [[properties valueForKey:@"y"] doubleValue]; + [[self.webView window] setFrame:frame display:YES]; + +} + +- (void) resize:(NSDictionary *) properties +{ + NSRect frame = [self.webView window].frame; + frame.size.width = [[properties valueForKey:@"width"] doubleValue]; + frame.size.height = [[properties valueForKey:@"height"] doubleValue]; + [[self.webView window] setFrame:frame display:YES]; +} + + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector +{ + return NO; +} + ++ (NSString*) webScriptNameForSelector:(SEL)selector{ + id result = nil; + + if (selector == @selector(open:)) { + result = @"open"; + }else if (selector == @selector(move:)){ + result = @"move"; + }else if (selector == @selector(resize:)){ + result = @"resize"; + } + + return result; +} + ++ (BOOL) isKeyExcludedFromWebScript:(const char*)name +{ + return YES; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Clipboard.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/Clipboard.h new file mode 100644 index 000000000..6c1a2f513 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Clipboard.h @@ -0,0 +1,10 @@ +#import + +@interface Clipboard : NSObject { + +} + +- (void) copy:(NSString*)text; +- (NSString *) paste; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/Clipboard.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/Clipboard.m new file mode 100644 index 000000000..1c18dea38 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/Clipboard.m @@ -0,0 +1,51 @@ +// +// clipboard.m +// MacGap +// +// Created by David Zorychta on 2013-07-22. +// Copyright (c) 2013 Twitter. All rights reserved. +// + +#import "Clipboard.h" + +@implementation Clipboard + +- (void) copy:(NSString*)text { + [[NSPasteboard generalPasteboard] clearContents]; + [[NSPasteboard generalPasteboard] setString:text forType:NSStringPboardType]; +} + +- (NSString *) paste { + NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; + NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; + NSDictionary *options = [NSDictionary dictionary]; + BOOL ok = [pasteboard canReadObjectForClasses:classArray options:options]; + if (ok) { + NSArray *objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options]; + return (NSString *) [objectsToPaste objectAtIndex:0]; + } + return @""; +} + ++ (NSString*) webScriptNameForSelector:(SEL)selector +{ + id result = nil; + + if (selector == @selector(copy:)) { + result = @"copy"; + } + + return result; +} + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector +{ + return NO; +} + ++ (BOOL) isKeyExcludedFromWebScript:(const char*)name +{ + return YES; +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/MacGap-Info.plist b/ext/mac-ui-macgap1-wrapper/src/MacGap/MacGap-Info.plist new file mode 100644 index 000000000..7e10a7a6c --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/MacGap-Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleIconFile + ZeroTierIcon + CFBundleDevelopmentRegion + en + CFBundleExecutable + ZeroTier One + CFBundleIdentifier + com.zerotier.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ZeroTier One + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSApplicationCategoryType + public.app-category.utilities + LSMinimumSystemVersion + ${MACOSX_DEPLOYMENT_TARGET} + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/MacGap-Prefix.pch b/ext/mac-ui-macgap1-wrapper/src/MacGap/MacGap-Prefix.pch new file mode 100644 index 000000000..ad05e8420 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/MacGap-Prefix.pch @@ -0,0 +1,15 @@ +// +// Prefix header for all source files of the 'MacGap' target in the 'MacGap' project +// + +#ifdef __OBJC__ + #ifdef _DEBUG + #define DebugNSLog(format, ...) NSLog(format, ## __VA_ARGS__) + #else + #define DebugNSLog(format, ...) + #endif + + #import + #import "Constants.h" + #import "Utils.h" +#endif diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/WindowController.h b/ext/mac-ui-macgap1-wrapper/src/MacGap/WindowController.h new file mode 100644 index 000000000..72927effa --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/WindowController.h @@ -0,0 +1,13 @@ +#import +#import "ContentView.h" + +@interface WindowController : NSWindowController { + +} + +- (id) initWithURL:(NSString *) url; +- (id) initWithRequest: (NSURLRequest *)request; +@property (retain) NSURL * url; +@property (retain) IBOutlet ContentView *contentView; + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/WindowController.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/WindowController.m new file mode 100644 index 000000000..2765a2e3c --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/WindowController.m @@ -0,0 +1,54 @@ +#import "WindowController.h" + + +@interface WindowController() { + +} + +-(void) notificationCenter; + +@end + +@implementation WindowController + +@synthesize contentView, url; + +- (id) initWithURL:(NSString *) relativeURL{ + self = [super initWithWindowNibName:@"Window"]; + self.url = [NSURL URLWithString:relativeURL relativeToURL:[[NSBundle mainBundle] resourceURL]]; + + [self.window setFrameAutosaveName:@"MacGapWindow"]; + [self notificationCenter]; + + return self; +} + +-(id) initWithRequest: (NSURLRequest *)request{ + self = [super initWithWindowNibName:@"Window"]; + [self notificationCenter]; + [[self.contentView.webView mainFrame] loadRequest:request]; + + return self; +} + +-(void) notificationCenter{ + [[NSNotificationCenter defaultCenter] addObserver:self.contentView + selector:@selector(windowResized:) + name:NSWindowDidResizeNotification + object:[self window]]; +} + +- (void)windowDidLoad +{ + [super windowDidLoad]; + + if (self.url != nil) { + [self.contentView.webView setMainFrameURL:[self.url absoluteString]]; + } + + + // Implement this method to handle any initialization after your + // window controller's window has been loaded from its nib file. +} + +@end diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/Credits.rtf b/ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/Credits.rtf new file mode 100644 index 000000000..6f388f662 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/Credits.rtf @@ -0,0 +1,13 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1347\cocoasubrtf570 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\vieww9600\viewh8400\viewkind0 +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 + +\f0\b\fs24 \cf0 (c)2011-2015 ZeroTier, Inc.\ +Licensed under the GNU GPLv3\ +\ +UI Wrapper MacGap (c) Twitter, Inc.\ +Licensed under the MIT License\ +http://macgap.com/\ +} \ No newline at end of file diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/InfoPlist.strings b/ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/MainMenu.xib b/ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/MainMenu.xib new file mode 100644 index 000000000..dd67a86ae --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/MainMenu.xib @@ -0,0 +1,3404 @@ + + + + 1070 + 14D136 + 7702 + 1347.57 + 758.70 + + com.apple.InterfaceBuilder.CocoaPlugin + 7702 + + + NSCustomObject + NSMenu + NSMenuItem + + + com.apple.InterfaceBuilder.CocoaPlugin + + + PluginDependencyRecalculationVersion + + + + + NSApplication + + + FirstResponder + + + NSApplication + + + AppDelegate + + + AMainMenu + + + + ZeroTier One + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + + ZeroTier One + + + + About ZeroTier One + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Preferences… + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + + Services + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide ZeroTier One + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit ZeroTier One + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + File + + 1048576 + 2147483647 + + + submenuAction: + + + File + + + + New + n + 1048576 + 2147483647 + + + + + + Open… + o + 1048576 + 2147483647 + + + + + + Open Recent + + 1048576 + 2147483647 + + + submenuAction: + + + Open Recent + + + + Clear Menu + + 1048576 + 2147483647 + + + + + _NSRecentDocumentsMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Close + w + 1048576 + 2147483647 + + + + + + Save… + s + 1048576 + 2147483647 + + + + + + Revert to Saved + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Page Setup... + P + 1179648 + 2147483647 + + + + + + + Print… + p + 1048576 + 2147483647 + + + + + + + + + Edit + + 1048576 + 2147483647 + + + submenuAction: + + + Edit + + + + Undo + z + 1048576 + 2147483647 + + + + + + Redo + Z + 1179648 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Cut + x + 1048576 + 2147483647 + + + + + + Copy + c + 1048576 + 2147483647 + + + + + + Paste + v + 1048576 + 2147483647 + + + + + + Paste and Match Style + V + 1572864 + 2147483647 + + + + + + Delete + + 1048576 + 2147483647 + + + + + + Select All + a + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Find + + 1048576 + 2147483647 + + + submenuAction: + + + Find + + + + Find… + f + 1048576 + 2147483647 + + + 1 + + + + Find and Replace… + f + 1572864 + 2147483647 + + + 12 + + + + Find Next + g + 1048576 + 2147483647 + + + 2 + + + + Find Previous + G + 1179648 + 2147483647 + + + 3 + + + + Use Selection for Find + e + 1048576 + 2147483647 + + + 7 + + + + Jump to Selection + j + 1048576 + 2147483647 + + + + + + + + + Spelling and Grammar + + 1048576 + 2147483647 + + + submenuAction: + + + Spelling and Grammar + + + + Show Spelling and Grammar + : + 1048576 + 2147483647 + + + + + + Check Document Now + ; + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Check Spelling While Typing + + 1048576 + 2147483647 + + + + + + Check Grammar With Spelling + + 1048576 + 2147483647 + + + + + + Correct Spelling Automatically + + 2147483647 + + + + + + + + + Substitutions + + 1048576 + 2147483647 + + + submenuAction: + + + Substitutions + + + + Show Substitutions + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Smart Copy/Paste + f + 1048576 + 2147483647 + + + 1 + + + + Smart Quotes + g + 1048576 + 2147483647 + + + 2 + + + + Smart Dashes + + 2147483647 + + + + + + Smart Links + G + 1179648 + 2147483647 + + + 3 + + + + Text Replacement + + 2147483647 + + + + + + + + + Transformations + + 2147483647 + + + submenuAction: + + + Transformations + + + + Make Upper Case + + 2147483647 + + + + + + Make Lower Case + + 2147483647 + + + + + + Capitalize + + 2147483647 + + + + + + + + + Speech + + 1048576 + 2147483647 + + + submenuAction: + + + Speech + + + + Start Speaking + + 1048576 + 2147483647 + + + + + + Stop Speaking + + 1048576 + 2147483647 + + + + + + + + + + + + Format + + 2147483647 + + + submenuAction: + + + Format + + + + Font + + 2147483647 + + + submenuAction: + + + Font + + + + Show Fonts + t + 1048576 + 2147483647 + + + + + + Bold + b + 1048576 + 2147483647 + + + 2 + + + + Italic + i + 1048576 + 2147483647 + + + 1 + + + + Underline + u + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Bigger + + + 1048576 + 2147483647 + + + 3 + + + + Smaller + - + 1048576 + 2147483647 + + + 4 + + + + YES + YES + + + 2147483647 + + + + + + Kern + + 2147483647 + + + submenuAction: + + + Kern + + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Tighten + + 2147483647 + + + + + + Loosen + + 2147483647 + + + + + + + + + Ligature + + 2147483647 + + + submenuAction: + + + Ligature + + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Use All + + 2147483647 + + + + + + + + + Baseline + + 2147483647 + + + submenuAction: + + + Baseline + + + + Use Default + + 2147483647 + + + + + + Superscript + + 2147483647 + + + + + + Subscript + + 2147483647 + + + + + + Raise + + 2147483647 + + + + + + Lower + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Colors + C + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Copy Style + c + 1572864 + 2147483647 + + + + + + Paste Style + v + 1572864 + 2147483647 + + + + + _NSFontMenu + + + + + Text + + 2147483647 + + + submenuAction: + + + Text + + + + Align Left + { + 1048576 + 2147483647 + + + + + + Center + | + 1048576 + 2147483647 + + + + + + Justify + + 2147483647 + + + + + + Align Right + } + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Writing Direction + + 2147483647 + + + submenuAction: + + + Writing Direction + + + + YES + Paragraph + + 2147483647 + + + + + + CURlZmF1bHQ + + 2147483647 + + + + + + CUxlZnQgdG8gUmlnaHQ + + 2147483647 + + + + + + CVJpZ2h0IHRvIExlZnQ + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + YES + Selection + + 2147483647 + + + + + + CURlZmF1bHQ + + 2147483647 + + + + + + CUxlZnQgdG8gUmlnaHQ + + 2147483647 + + + + + + CVJpZ2h0IHRvIExlZnQ + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Ruler + + 2147483647 + + + + + + Copy Ruler + c + 1310720 + 2147483647 + + + + + + Paste Ruler + v + 1310720 + 2147483647 + + + + + + + + + + + + View + + 1048576 + 2147483647 + + + submenuAction: + + + View + + + + Show Toolbar + t + 1572864 + 2147483647 + + + + + + Customize Toolbar… + + 1048576 + 2147483647 + + + + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + + Window + + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Help + + 2147483647 + + + submenuAction: + + + Help + + + + ZeroTier One Help + ? + 1048576 + 2147483647 + + + + + _NSHelpMenu + + + + _NSMainMenu + + + + + + + terminate: + + + + 449 + + + + orderFrontStandardAboutPanel: + + + + 142 + + + + delegate + + + + 547 + + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + print: + + + + 86 + + + + runPageLayout: + + + + 87 + + + + clearRecentDocuments: + + + + 127 + + + + performClose: + + + + 193 + + + + toggleContinuousSpellChecking: + + + + 222 + + + + undo: + + + + 223 + + + + copy: + + + + 224 + + + + checkSpelling: + + + + 225 + + + + paste: + + + + 226 + + + + stopSpeaking: + + + + 227 + + + + cut: + + + + 228 + + + + showGuessPanel: + + + + 230 + + + + redo: + + + + 231 + + + + selectAll: + + + + 232 + + + + startSpeaking: + + + + 233 + + + + delete: + + + + 235 + + + + performZoom: + + + + 240 + + + + performFindPanelAction: + + + + 241 + + + + centerSelectionInVisibleArea: + + + + 245 + + + + toggleGrammarChecking: + + + + 347 + + + + toggleSmartInsertDelete: + + + + 355 + + + + toggleAutomaticQuoteSubstitution: + + + + 356 + + + + toggleAutomaticLinkDetection: + + + + 357 + + + + saveDocument: + + + + 362 + + + + revertDocumentToSaved: + + + + 364 + + + + runToolbarCustomizationPalette: + + + + 365 + + + + toggleToolbarShown: + + + + 366 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + newDocument: + + + + 373 + + + + openDocument: + + + + 374 + + + + raiseBaseline: + + + + 426 + + + + lowerBaseline: + + + + 427 + + + + copyFont: + + + + 428 + + + + subscript: + + + + 429 + + + + superscript: + + + + 430 + + + + tightenKerning: + + + + 431 + + + + underline: + + + + 432 + + + + orderFrontColorPanel: + + + + 433 + + + + useAllLigatures: + + + + 434 + + + + loosenKerning: + + + + 435 + + + + pasteFont: + + + + 436 + + + + unscript: + + + + 437 + + + + useStandardKerning: + + + + 438 + + + + useStandardLigatures: + + + + 439 + + + + turnOffLigatures: + + + + 440 + + + + turnOffKerning: + + + + 441 + + + + toggleAutomaticSpellingCorrection: + + + + 456 + + + + orderFrontSubstitutionsPanel: + + + + 458 + + + + toggleAutomaticDashSubstitution: + + + + 461 + + + + toggleAutomaticTextReplacement: + + + + 463 + + + + uppercaseWord: + + + + 464 + + + + capitalizeWord: + + + + 467 + + + + lowercaseWord: + + + + 468 + + + + pasteAsPlainText: + + + + 486 + + + + performFindPanelAction: + + + + 487 + + + + performFindPanelAction: + + + + 488 + + + + performFindPanelAction: + + + + 489 + + + + showHelp: + + + + 493 + + + + alignCenter: + + + + 518 + + + + pasteRuler: + + + + 519 + + + + toggleRuler: + + + + 520 + + + + alignRight: + + + + 521 + + + + copyRuler: + + + + 522 + + + + alignJustified: + + + + 523 + + + + alignLeft: + + + + 524 + + + + makeBaseWritingDirectionNatural: + + + + 525 + + + + makeBaseWritingDirectionLeftToRight: + + + + 526 + + + + makeBaseWritingDirectionRightToLeft: + + + + 527 + + + + makeTextWritingDirectionNatural: + + + + 528 + + + + makeTextWritingDirectionLeftToRight: + + + + 529 + + + + makeTextWritingDirectionRightToLeft: + + + + 530 + + + + performFindPanelAction: + + + + 535 + + + + delegate + + + + 545 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + + + + + + + + + + + + 19 + + + + + + + + 56 + + + + + + + + 217 + + + + + + + + 83 + + + + + + + + 81 + + + + + + + + + + + + + + + + + 75 + + + + + 78 + + + + + 72 + + + + + 82 + + + + + 124 + + + + + + + + 77 + + + + + 73 + + + + + 79 + + + + + 112 + + + + + 74 + + + + + 125 + + + + + + + + 126 + + + + + 205 + + + + + + + + + + + + + + + + + + + + + + 202 + + + + + 198 + + + + + 207 + + + + + 214 + + + + + 199 + + + + + 203 + + + + + 197 + + + + + 206 + + + + + 215 + + + + + 218 + + + + + + + + 216 + + + + + + + + 200 + + + + + + + + + + + + + 219 + + + + + 201 + + + + + 204 + + + + + 220 + + + + + + + + + + + + + 213 + + + + + 210 + + + + + 221 + + + + + 208 + + + + + 209 + + + + + 57 + + + + + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + + + 144 + + + + + 129 + + + + + 143 + + + + + 236 + + + + + 131 + + + + + + + + 149 + + + + + 145 + + + + + 130 + + + + + 24 + + + + + + + + + + + 92 + + + + + 5 + + + + + 239 + + + + + 23 + + + + + 295 + + + + + + + + 296 + + + + + + + + + 297 + + + + + 298 + + + + + 211 + + + + + + + + 212 + + + + + + + + + 195 + + + + + 196 + + + + + 346 + + + + + 348 + + + + + + + + 349 + + + + + + + + + + + + + + 350 + + + + + 351 + + + + + 354 + + + + + 375 + + + + + + + + 376 + + + + + + + + + 377 + + + + + + + + 388 + + + + + + + + + + + + + + + + + + + + + + + 389 + + + + + 390 + + + + + 391 + + + + + 392 + + + + + 393 + + + + + 394 + + + + + 395 + + + + + 396 + + + + + 397 + + + + + + + + 398 + + + + + + + + 399 + + + + + + + + 400 + + + + + 401 + + + + + 402 + + + + + 403 + + + + + 404 + + + + + 405 + + + + + + + + + + + + 406 + + + + + 407 + + + + + 408 + + + + + 409 + + + + + 410 + + + + + 411 + + + + + + + + + + 412 + + + + + 413 + + + + + 414 + + + + + 415 + + + + + + + + + + + 416 + + + + + 417 + + + + + 418 + + + + + 419 + + + + + 450 + + + + + + + + 451 + + + + + + + + + + 452 + + + + + 453 + + + + + 454 + + + + + 457 + + + + + 459 + + + + + 460 + + + + + 462 + + + + + 465 + + + + + 466 + + + + + 485 + + + + + 490 + + + + + + + + 491 + + + + + + + + 492 + + + + + 496 + + + + + + + + 497 + + + + + + + + + + + + + + + + + 498 + + + + + 499 + + + + + 500 + + + + + 501 + + + + + 502 + + + + + 503 + + + + + + + + 504 + + + + + 505 + + + + + 506 + + + + + 507 + + + + + 508 + + + + + + + + + + + + + + + + 509 + + + + + 510 + + + + + 511 + + + + + 512 + + + + + 513 + + + + + 514 + + + + + 515 + + + + + 516 + + + + + 517 + + + + + 534 + + + + + 546 + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + 547 + + + + + AppDelegate + NSObject + + IBProjectSource + ../MacGap/AppDelegate.h + + + + + + NSApplication + NSResponder + + IBFrameworkSource + AppKit.framework/Headers/NSApplication.h + + + + NSBrowser + NSControl + + IBFrameworkSource + AppKit.framework/Headers/NSBrowser.h + + + + NSControl + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSControl.h + + + + NSDocument + NSObject + + id + id + id + id + id + id + + + + printDocument: + id + + + revertDocumentToSaved: + id + + + runPageLayout: + id + + + saveDocument: + id + + + saveDocumentAs: + id + + + saveDocumentTo: + id + + + + IBFrameworkSource + AppKit.framework/Headers/NSDocument.h + + + + NSDocumentController + NSObject + + id + id + id + id + + + + clearRecentDocuments: + id + + + newDocument: + id + + + openDocument: + id + + + saveAllDocuments: + id + + + + IBFrameworkSource + AppKit.framework/Headers/NSDocumentController.h + + + + NSFormatter + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFormatter.h + + + + NSMatrix + NSControl + + IBFrameworkSource + AppKit.framework/Headers/NSMatrix.h + + + + NSMenu + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSMenu.h + + + + NSMenuItem + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSMenuItem.h + + + + NSMovieView + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSMovieView.h + + + + NSPopover + NSResponder + + IBFrameworkSource + AppKit.framework/Headers/NSPopover.h + + + + NSResponder + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSResponder.h + + + + NSTableView + NSControl + + IBFrameworkSource + AppKit.framework/Headers/NSTableView.h + + + + NSText + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSText.h + + + + NSTextView + NSText + + IBFrameworkSource + AppKit.framework/Headers/NSTextView.h + + + + NSView + NSResponder + + IBFrameworkSource + AppKit.framework/Headers/NSView.h + + + + NSViewController + NSResponder + + view + NSView + + + view + + view + NSView + + + + IBFrameworkSource + AppKit.framework/Headers/NSViewController.h + + + + NSWindow + NSResponder + + IBFrameworkSource + AppKit.framework/Headers/NSWindow.h + + + + WebView + NSView + + id + id + id + id + id + id + id + id + id + id + id + + + + goBack: + id + + + goForward: + id + + + makeTextLarger: + id + + + makeTextSmaller: + id + + + makeTextStandardSize: + id + + + reload: + id + + + reloadFromOrigin: + id + + + stopLoading: + id + + + takeStringURLFrom: + id + + + toggleContinuousSpellChecking: + id + + + toggleSmartInsertDelete: + id + + + + IBFrameworkSource + WebKit.framework/Headers/WebView.h + + + + + 0 + IBCocoaFramework + NO + + com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 + + + YES + 3 + + {12, 12} + {10, 2} + + + diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/Window.xib b/ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/Window.xib new file mode 100644 index 000000000..70d0c57b8 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/Window.xib @@ -0,0 +1,337 @@ + + + + 1070 + 11C74 + 1938 + 1138.23 + 567.00 + + YES + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin + + + YES + 1938 + 822 + + + + YES + NSWindowTemplate + NSView + NSCustomObject + WebView + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin + + + PluginDependencyRecalculationVersion + + + + YES + + WindowController + + + FirstResponder + + + NSApplication + + + 15 + 2 + {{196, 240}, {758, 410}} + 544735232 + Window + NSWindow + + + + + 256 + + YES + + + 274 + + YES + + YES + Apple HTML pasteboard type + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple URL pasteboard type + Apple Web Archive pasteboard type + NSColor pasteboard type + NSFilenamesPboardType + NSStringPboardType + NeXT RTFD pasteboard type + NeXT Rich Text Format v1.0 pasteboard type + NeXT TIFF v4.0 pasteboard type + WebURLsWithTitlesPboardType + public.png + public.url + public.url-name + + + {758, 410} + + + + 2 + _NS:51 + + + + + + YES + + YES + WebKitDefaultFixedFontSize + WebKitDefaultFontSize + WebKitMinimumFontSize + + + YES + + + + + + + YES + YES + + + {758, 410} + + + + + {{0, 0}, {1920, 1178}} + {10000000000000, 10000000000000} + 128 + YES + + + + + YES + + + contentView + + + + 23 + + + + window + + + + 25 + + + + title: contentView.webView.mainFrameTitle + + + + + + title: contentView.webView.mainFrameTitle + title + contentView.webView.mainFrameTitle + 2 + + + 31 + + + + webView + + + + 19 + + + + + YES + + 0 + + YES + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 1 + + + YES + + + + + + 2 + + + YES + + + + + + 5 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.IBPluginDependency + -3.IBPluginDependency + 1.IBPluginDependency + 1.IBWindowTemplateEditedContentRect + 1.NSWindowTemplate.visibleAtLaunch + 2.CustomClassName + 2.IBPluginDependency + 5.IBPluginDependency + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{357, 418}, {480, 270}} + + ContentView + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin + + + + YES + + + + + + YES + + + + + 31 + + + + YES + + ContentView + NSView + + webView + WebView + + + webView + + webView + WebView + + + + IBProjectSource + ./Classes/ContentView.h + + + + WebView + + reloadFromOrigin: + id + + + reloadFromOrigin: + + reloadFromOrigin: + id + + + + IBProjectSource + ./Classes/WebView.h + + + + WindowController + NSWindowController + + contentView + ContentView + + + contentView + + contentView + ContentView + + + + IBProjectSource + ./Classes/WindowController.h + + + + + 0 + IBCocoaFramework + + com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 + + + YES + 3 + + diff --git a/ext/mac-ui-macgap1-wrapper/src/MacGap/main.m b/ext/mac-ui-macgap1-wrapper/src/MacGap/main.m new file mode 100644 index 000000000..4ad50ad59 --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/MacGap/main.m @@ -0,0 +1,14 @@ +// +// main.m +// MacGap +// +// Created by Alex MacCaw on 08/01/2012. +// Copyright (c) 2012 Twitter. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) +{ + return NSApplicationMain(argc, (const char **)argv); +} diff --git a/ext/mac-ui-macgap1-wrapper/src/README.md b/ext/mac-ui-macgap1-wrapper/src/README.md new file mode 100644 index 000000000..daf3eae9c --- /dev/null +++ b/ext/mac-ui-macgap1-wrapper/src/README.md @@ -0,0 +1,6 @@ +Mac Web UI Wrapper +====== + +This is a modified version of MacGap1 which launches a WebKit view and accesses the local ZeroTier service at its web URL. It builds the URL from the authtoken.secret file in the system home (or the user home) and the zerotier-one.port file that ZeroTier creates to advertise its control port. + +It's based on the original MacGap1 source by Twitter, Inc. which is licensed under the MIT license. diff --git a/ext/miniupnpc/README b/ext/miniupnpc/README deleted file mode 100644 index 0d3b8054c..000000000 --- a/ext/miniupnpc/README +++ /dev/null @@ -1,63 +0,0 @@ -Project: miniupnp -Project web page: http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ -github: https://github.com/miniupnp/miniupnp -Author: Thomas Bernard -Copyright (c) 2005-2017 Thomas Bernard -This software is subject to the conditions detailed in the -LICENSE file provided within this distribution. - - -* miniUPnP Client - miniUPnPc * - -To compile, simply run 'gmake' (could be 'make' on your system). -Under win32, to compile with MinGW, type "mingw32make.bat". -MS Visual C solution and project files are supplied in the msvc/ subdirectory. - -The compilation is known to work under linux, FreeBSD, -OpenBSD, MacOS X, AmigaOS and cygwin. -The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3. -upx (http://upx.sourceforge.net) is used to compress the win32 .exe files. - -To install the library and headers on the system use : -> su -> make install -> exit - -alternatively, to install into a specific location, use : -> INSTALLPREFIX=/usr/local make install - -upnpc.c is a sample client using the libminiupnpc. -To use the libminiupnpc in your application, link it with -libminiupnpc.a (or .so) and use the following functions found in miniupnpc.h, -upnpcommands.h and miniwget.h : -- upnpDiscover() -- UPNP_GetValidIGD() -- miniwget() -- parserootdesc() -- GetUPNPUrls() -- UPNP_* (calling UPNP methods) - -Note : use #include etc... for the includes -and -lminiupnpc for the link - -Discovery process is speeded up when MiniSSDPd is running on the machine. - - -* Python module * - -you can build a python module with 'make pythonmodule' -and install it with 'make installpythonmodule'. -setup.py (and setupmingw32.py) are included in the distribution. - - -Feel free to contact me if you have any problem : -e-mail : miniupnp@free.fr - -If you are using libminiupnpc in your application, please -send me an email ! - -For any question, you can use the web forum : -https://miniupnp.tuxfamily.org/forum/ - -Bugs should be reported on github : -https://github.com/miniupnp/miniupnp/issues diff --git a/ext/miniupnpc/VERSION b/ext/miniupnpc/VERSION deleted file mode 100644 index cd5ac039d..000000000 --- a/ext/miniupnpc/VERSION +++ /dev/null @@ -1 +0,0 @@ -2.0 diff --git a/ext/miniupnpc/connecthostport.c b/ext/miniupnpc/connecthostport.c deleted file mode 100644 index aed62c76e..000000000 --- a/ext/miniupnpc/connecthostport.c +++ /dev/null @@ -1,262 +0,0 @@ -/* $Id: connecthostport.c,v 1.17 2017/04/21 09:58:30 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2010-2017 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -/* use getaddrinfo() or gethostbyname() - * uncomment the following line in order to use gethostbyname() */ -#ifdef NO_GETADDRINFO -#define USE_GETHOSTBYNAME -#endif - -#include -#include -#ifdef _WIN32 -#include -#include -#include -#define MAXHOSTNAMELEN 64 -#define snprintf _snprintf -#define herror -#define socklen_t int -#else /* #ifdef _WIN32 */ -#include -#include -#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT -#include -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ -#include -#include -#include -#define closesocket close -#include -#include -/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions - * during the connect() call */ -#define MINIUPNPC_IGNORE_EINTR -#include -#include -#endif /* #else _WIN32 */ - -/* definition of PRINT_SOCKET_ERROR */ -#ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); -#else -#define PRINT_SOCKET_ERROR(x) perror(x) -#endif - -#if defined(__amigaos__) || defined(__amigaos4__) -#define herror(A) printf("%s\n", A) -#endif - -#include "connecthostport.h" - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -/* connecthostport() - * return a socket connected (TCP) to the host and port - * or -1 in case of error */ -int connecthostport(const char * host, unsigned short port, - unsigned int scope_id) -{ - int s, n; -#ifdef USE_GETHOSTBYNAME - struct sockaddr_in dest; - struct hostent *hp; -#else /* #ifdef USE_GETHOSTBYNAME */ - char tmp_host[MAXHOSTNAMELEN+1]; - char port_str[8]; - struct addrinfo *ai, *p; - struct addrinfo hints; -#endif /* #ifdef USE_GETHOSTBYNAME */ -#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT - struct timeval timeout; -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - -#ifdef USE_GETHOSTBYNAME - hp = gethostbyname(host); - if(hp == NULL) - { - herror(host); - return -1; - } - memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr)); - memset(dest.sin_zero, 0, sizeof(dest.sin_zero)); - s = socket(PF_INET, SOCK_STREAM, 0); - if(s < 0) - { - PRINT_SOCKET_ERROR("socket"); - return -1; - } -#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT - /* setting a 3 seconds timeout for the connect() call */ - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt SO_RCVTIMEO"); - } - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt SO_SNDTIMEO"); - } -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - dest.sin_family = AF_INET; - dest.sin_port = htons(port); - n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in)); -#ifdef MINIUPNPC_IGNORE_EINTR - /* EINTR The system call was interrupted by a signal that was caught - * EINPROGRESS The socket is nonblocking and the connection cannot - * be completed immediately. */ - while(n < 0 && (errno == EINTR || errno == EINPROGRESS)) - { - socklen_t len; - fd_set wset; - int err; - FD_ZERO(&wset); - FD_SET(s, &wset); - if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR) - continue; - /*len = 0;*/ - /*n = getpeername(s, NULL, &len);*/ - len = sizeof(err); - if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { - PRINT_SOCKET_ERROR("getsockopt"); - closesocket(s); - return -1; - } - if(err != 0) { - errno = err; - n = -1; - } - } -#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */ - if(n<0) - { - PRINT_SOCKET_ERROR("connect"); - closesocket(s); - return -1; - } -#else /* #ifdef USE_GETHOSTBYNAME */ - /* use getaddrinfo() instead of gethostbyname() */ - memset(&hints, 0, sizeof(hints)); - /* hints.ai_flags = AI_ADDRCONFIG; */ -#ifdef AI_NUMERICSERV - hints.ai_flags = AI_NUMERICSERV; -#endif - hints.ai_socktype = SOCK_STREAM; - hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */ - /* hints.ai_protocol = IPPROTO_TCP; */ - snprintf(port_str, sizeof(port_str), "%hu", port); - if(host[0] == '[') - { - /* literal ip v6 address */ - int i, j; - for(i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++) - { - tmp_host[i] = host[j]; - if(0 == memcmp(host+j, "%25", 3)) /* %25 is just url encoding for '%' */ - j+=2; /* skip "25" */ - } - tmp_host[i] = '\0'; - } - else - { - strncpy(tmp_host, host, MAXHOSTNAMELEN); - } - tmp_host[MAXHOSTNAMELEN] = '\0'; - n = getaddrinfo(tmp_host, port_str, &hints, &ai); - if(n != 0) - { -#ifdef _WIN32 - fprintf(stderr, "getaddrinfo() error : %d\n", n); -#else - fprintf(stderr, "getaddrinfo() error : %s\n", gai_strerror(n)); -#endif - return -1; - } - s = -1; - for(p = ai; p; p = p->ai_next) - { - s = socket(p->ai_family, p->ai_socktype, p->ai_protocol); - if(s < 0) - continue; - if(p->ai_addr->sa_family == AF_INET6 && scope_id > 0) { - struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *)p->ai_addr; - addr6->sin6_scope_id = scope_id; - } -#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT - /* setting a 3 seconds timeout for the connect() call */ - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt"); - } - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt"); - } -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - n = connect(s, p->ai_addr, p->ai_addrlen); -#ifdef MINIUPNPC_IGNORE_EINTR - /* EINTR The system call was interrupted by a signal that was caught - * EINPROGRESS The socket is nonblocking and the connection cannot - * be completed immediately. */ - while(n < 0 && (errno == EINTR || errno == EINPROGRESS)) - { - socklen_t len; - fd_set wset; - int err; - FD_ZERO(&wset); - FD_SET(s, &wset); - if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR) - continue; - /*len = 0;*/ - /*n = getpeername(s, NULL, &len);*/ - len = sizeof(err); - if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { - PRINT_SOCKET_ERROR("getsockopt"); - closesocket(s); - freeaddrinfo(ai); - return -1; - } - if(err != 0) { - errno = err; - n = -1; - } - } -#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */ - if(n < 0) - { - closesocket(s); - continue; - } - else - { - break; - } - } - freeaddrinfo(ai); - if(s < 0) - { - PRINT_SOCKET_ERROR("socket"); - return -1; - } - if(n < 0) - { - PRINT_SOCKET_ERROR("connect"); - return -1; - } -#endif /* #ifdef USE_GETHOSTBYNAME */ - return s; -} - diff --git a/ext/miniupnpc/igd_desc_parse.c b/ext/miniupnpc/igd_desc_parse.c deleted file mode 100644 index d2999ad01..000000000 --- a/ext/miniupnpc/igd_desc_parse.c +++ /dev/null @@ -1,123 +0,0 @@ -/* $Id: igd_desc_parse.c,v 1.17 2015/09/15 13:30:04 nanard Exp $ */ -/* Project : miniupnp - * http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005-2015 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include "igd_desc_parse.h" -#include -#include - -/* Start element handler : - * update nesting level counter and copy element name */ -void IGDstartelt(void * d, const char * name, int l) -{ - struct IGDdatas * datas = (struct IGDdatas *)d; - if(l >= MINIUPNPC_URL_MAXSIZE) - l = MINIUPNPC_URL_MAXSIZE-1; - memcpy(datas->cureltname, name, l); - datas->cureltname[l] = '\0'; - datas->level++; - if( (l==7) && !memcmp(name, "service", l) ) { - datas->tmp.controlurl[0] = '\0'; - datas->tmp.eventsuburl[0] = '\0'; - datas->tmp.scpdurl[0] = '\0'; - datas->tmp.servicetype[0] = '\0'; - } -} - -#define COMPARE(str, cstr) (0==memcmp(str, cstr, sizeof(cstr) - 1)) - -/* End element handler : - * update nesting level counter and update parser state if - * service element is parsed */ -void IGDendelt(void * d, const char * name, int l) -{ - struct IGDdatas * datas = (struct IGDdatas *)d; - datas->level--; - /*printf("endelt %2d %.*s\n", datas->level, l, name);*/ - if( (l==7) && !memcmp(name, "service", l) ) - { - if(COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) { - memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service)); - } else if(COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANIPv6FirewallControl:")) { - memcpy(&datas->IPv6FC, &datas->tmp, sizeof(struct IGDdatas_service)); - } else if(COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANIPConnection:") - || COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANPPPConnection:") ) { - if(datas->first.servicetype[0] == '\0') { - memcpy(&datas->first, &datas->tmp, sizeof(struct IGDdatas_service)); - } else { - memcpy(&datas->second, &datas->tmp, sizeof(struct IGDdatas_service)); - } - } - } -} - -/* Data handler : - * copy data depending on the current element name and state */ -void IGDdata(void * d, const char * data, int l) -{ - struct IGDdatas * datas = (struct IGDdatas *)d; - char * dstmember = 0; - /*printf("%2d %s : %.*s\n", - datas->level, datas->cureltname, l, data); */ - if( !strcmp(datas->cureltname, "URLBase") ) - dstmember = datas->urlbase; - else if( !strcmp(datas->cureltname, "presentationURL") ) - dstmember = datas->presentationurl; - else if( !strcmp(datas->cureltname, "serviceType") ) - dstmember = datas->tmp.servicetype; - else if( !strcmp(datas->cureltname, "controlURL") ) - dstmember = datas->tmp.controlurl; - else if( !strcmp(datas->cureltname, "eventSubURL") ) - dstmember = datas->tmp.eventsuburl; - else if( !strcmp(datas->cureltname, "SCPDURL") ) - dstmember = datas->tmp.scpdurl; -/* else if( !strcmp(datas->cureltname, "deviceType") ) - dstmember = datas->devicetype_tmp;*/ - if(dstmember) - { - if(l>=MINIUPNPC_URL_MAXSIZE) - l = MINIUPNPC_URL_MAXSIZE-1; - memcpy(dstmember, data, l); - dstmember[l] = '\0'; - } -} - -#ifdef DEBUG -void printIGD(struct IGDdatas * d) -{ - printf("urlbase = '%s'\n", d->urlbase); - printf("WAN Device (Common interface config) :\n"); - /*printf(" deviceType = '%s'\n", d->CIF.devicetype);*/ - printf(" serviceType = '%s'\n", d->CIF.servicetype); - printf(" controlURL = '%s'\n", d->CIF.controlurl); - printf(" eventSubURL = '%s'\n", d->CIF.eventsuburl); - printf(" SCPDURL = '%s'\n", d->CIF.scpdurl); - printf("primary WAN Connection Device (IP or PPP Connection):\n"); - /*printf(" deviceType = '%s'\n", d->first.devicetype);*/ - printf(" servicetype = '%s'\n", d->first.servicetype); - printf(" controlURL = '%s'\n", d->first.controlurl); - printf(" eventSubURL = '%s'\n", d->first.eventsuburl); - printf(" SCPDURL = '%s'\n", d->first.scpdurl); - printf("secondary WAN Connection Device (IP or PPP Connection):\n"); - /*printf(" deviceType = '%s'\n", d->second.devicetype);*/ - printf(" servicetype = '%s'\n", d->second.servicetype); - printf(" controlURL = '%s'\n", d->second.controlurl); - printf(" eventSubURL = '%s'\n", d->second.eventsuburl); - printf(" SCPDURL = '%s'\n", d->second.scpdurl); - printf("WAN IPv6 Firewall Control :\n"); - /*printf(" deviceType = '%s'\n", d->IPv6FC.devicetype);*/ - printf(" servicetype = '%s'\n", d->IPv6FC.servicetype); - printf(" controlURL = '%s'\n", d->IPv6FC.controlurl); - printf(" eventSubURL = '%s'\n", d->IPv6FC.eventsuburl); - printf(" SCPDURL = '%s'\n", d->IPv6FC.scpdurl); -} -#endif /* DEBUG */ - diff --git a/ext/miniupnpc/listdevices.c b/ext/miniupnpc/listdevices.c deleted file mode 100644 index a93c29ff4..000000000 --- a/ext/miniupnpc/listdevices.c +++ /dev/null @@ -1,110 +0,0 @@ -/* $Id: listdevices.c,v 1.7 2015/10/08 16:15:47 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2013-2015 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include -#include -#include -#ifdef _WIN32 -#include -#endif /* _WIN32 */ -#include "miniupnpc.h" - -int main(int argc, char * * argv) -{ - const char * searched_device = NULL; - const char * * searched_devices = NULL; - const char * multicastif = 0; - const char * minissdpdpath = 0; - int ipv6 = 0; - unsigned char ttl = 2; - int error = 0; - struct UPNPDev * devlist = 0; - struct UPNPDev * dev; - int i; - -#ifdef _WIN32 - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if(nResult != NO_ERROR) - { - fprintf(stderr, "WSAStartup() failed.\n"); - return -1; - } -#endif - - for(i = 1; i < argc; i++) { - if(strcmp(argv[i], "-6") == 0) - ipv6 = 1; - else if(strcmp(argv[i], "-d") == 0) { - if(++i >= argc) { - fprintf(stderr, "%s option needs one argument\n", "-d"); - return 1; - } - searched_device = argv[i]; - } else if(strcmp(argv[i], "-t") == 0) { - if(++i >= argc) { - fprintf(stderr, "%s option needs one argument\n", "-t"); - return 1; - } - ttl = (unsigned char)atoi(argv[i]); - } else if(strcmp(argv[i], "-l") == 0) { - if(++i >= argc) { - fprintf(stderr, "-l option needs at least one argument\n"); - return 1; - } - searched_devices = (const char * *)(argv + i); - break; - } else if(strcmp(argv[i], "-m") == 0) { - if(++i >= argc) { - fprintf(stderr, "-m option needs one argument\n"); - return 1; - } - multicastif = argv[i]; - } else { - printf("usage : %s [options] [-l ...]\n", argv[0]); - printf("options :\n"); - printf(" -6 : use IPv6\n"); - printf(" -m address/ifname : network interface to use for multicast\n"); - printf(" -d : search only for this type of device\n"); - printf(" -l ... : search only for theses types of device\n"); - printf(" -t ttl : set multicast TTL. Default value is 2.\n"); - printf(" -h : this help\n"); - return 1; - } - } - - if(searched_device) { - printf("searching UPnP device type %s\n", searched_device); - devlist = upnpDiscoverDevice(searched_device, - 2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error); - } else if(searched_devices) { - printf("searching UPnP device types :\n"); - for(i = 0; searched_devices[i]; i++) - printf("\t%s\n", searched_devices[i]); - devlist = upnpDiscoverDevices(searched_devices, - 2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error, 1); - } else { - printf("searching all UPnP devices\n"); - devlist = upnpDiscoverAll(2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error); - } - if(devlist) { - for(dev = devlist, i = 1; dev != NULL; dev = dev->pNext, i++) { - printf("%3d: %-48s\n", i, dev->st); - printf(" %s\n", dev->descURL); - printf(" %s\n", dev->usn); - } - freeUPNPDevlist(devlist); - } else { - printf("no device found.\n"); - } - - return 0; -} - diff --git a/ext/miniupnpc/minisoap.c b/ext/miniupnpc/minisoap.c deleted file mode 100644 index 11f4635ad..000000000 --- a/ext/miniupnpc/minisoap.c +++ /dev/null @@ -1,136 +0,0 @@ -/* $Id: minisoap.c,v 1.25 2017/04/21 10:03:24 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005-2015 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * - * Minimal SOAP implementation for UPnP protocol. - */ -#include -#include -#ifdef _WIN32 -#include -#include -#define snprintf _snprintf -#else -#include -#include -#include -#endif -#include "minisoap.h" - -#ifdef _WIN32 -#undef OS_STRING -#define OS_STRING "Win32" -#define MINIUPNPC_VERSION_STRING "2.0" -#define UPNP_VERSION_STRING "UPnP/1.1" -#endif - -#ifdef __ANDROID__ -#undef OS_STRING -#define OS_STRING "Android" -#define MINIUPNPC_VERSION_STRING "2.0" -#define UPNP_VERSION_STRING "UPnP/1.1" -#endif - -/* only for malloc */ -#include - -#ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); -#else -#define PRINT_SOCKET_ERROR(x) perror(x) -#endif - -/* httpWrite sends the headers and the body to the socket - * and returns the number of bytes sent */ -static int -httpWrite(int fd, const char * body, int bodysize, - const char * headers, int headerssize) -{ - int n = 0; - /*n = write(fd, headers, headerssize);*/ - /*if(bodysize>0) - n += write(fd, body, bodysize);*/ - /* Note : my old linksys router only took into account - * soap request that are sent into only one packet */ - char * p; - /* TODO: AVOID MALLOC, we could use writev() for that */ - p = malloc(headerssize+bodysize); - if(!p) - return -1; - memcpy(p, headers, headerssize); - memcpy(p+headerssize, body, bodysize); - /*n = write(fd, p, headerssize+bodysize);*/ - n = send(fd, p, headerssize+bodysize, 0); - if(n<0) { - PRINT_SOCKET_ERROR("send"); - } - /* disable send on the socket */ - /* draytek routers dont seems to like that... */ -#if 0 -#ifdef _WIN32 - if(shutdown(fd, SD_SEND)<0) { -#else - if(shutdown(fd, SHUT_WR)<0) { /*SD_SEND*/ -#endif - PRINT_SOCKET_ERROR("shutdown"); - } -#endif - free(p); - return n; -} - -/* self explanatory */ -int soapPostSubmit(int fd, - const char * url, - const char * host, - unsigned short port, - const char * action, - const char * body, - const char * httpversion) -{ - int bodysize; - char headerbuf[512]; - int headerssize; - char portstr[8]; - bodysize = (int)strlen(body); - /* We are not using keep-alive HTTP connections. - * HTTP/1.1 needs the header Connection: close to do that. - * This is the default with HTTP/1.0 - * Using HTTP/1.1 means we need to support chunked transfer-encoding : - * When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked - * transfer encoding. */ - /* Connection: Close is normally there only in HTTP/1.1 but who knows */ - portstr[0] = '\0'; - if(port != 80) - snprintf(portstr, sizeof(portstr), ":%hu", port); - headerssize = snprintf(headerbuf, sizeof(headerbuf), - "POST %s HTTP/%s\r\n" - "Host: %s%s\r\n" - "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" - "Content-Length: %d\r\n" - "Content-Type: text/xml\r\n" - "SOAPAction: \"%s\"\r\n" - "Connection: Close\r\n" - "Cache-Control: no-cache\r\n" /* ??? */ - "Pragma: no-cache\r\n" - "\r\n", - url, httpversion, host, portstr, bodysize, action); - if ((unsigned int)headerssize >= sizeof(headerbuf)) - return -1; -#ifdef DEBUG - /*printf("SOAP request : headersize=%d bodysize=%d\n", - headerssize, bodysize); - */ - printf("SOAP request : POST %s HTTP/%s - Host: %s%s\n", - url, httpversion, host, portstr); - printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize); - printf("Headers :\n%s", headerbuf); - printf("Body :\n%s\n", body); -#endif - return httpWrite(fd, body, bodysize, headerbuf, headerssize); -} - - diff --git a/ext/miniupnpc/minissdpc.c b/ext/miniupnpc/minissdpc.c deleted file mode 100644 index 3479de8ec..000000000 --- a/ext/miniupnpc/minissdpc.c +++ /dev/null @@ -1,893 +0,0 @@ -/* $Id: minissdpc.c,v 1.35 2017/11/02 15:34:36 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * Project : miniupnp - * Web : http://miniupnp.free.fr/ - * Author : Thomas BERNARD - * copyright (c) 2005-2017 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -/*#include */ -#include -#include -#include -#include -#if defined (__NetBSD__) -#include -#endif -#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__) -#ifdef _WIN32 -#include -#include -#include -#include -#include -#define snprintf _snprintf -#if !defined(_MSC_VER) -#include -#else /* !defined(_MSC_VER) */ -typedef unsigned short uint16_t; -#endif /* !defined(_MSC_VER) */ -#ifndef strncasecmp -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#define strncasecmp _memicmp -#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ -#define strncasecmp memicmp -#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ -#endif /* #ifndef strncasecmp */ -#endif /* _WIN32 */ -#if defined(__amigaos__) || defined(__amigaos4__) -#include -#endif /* defined(__amigaos__) || defined(__amigaos4__) */ -#if defined(__amigaos__) -#define uint16_t unsigned short -#endif /* defined(__amigaos__) */ -/* Hack */ -#define UNIX_PATH_LEN 108 -struct sockaddr_un { - uint16_t sun_family; - char sun_path[UNIX_PATH_LEN]; -}; -#else /* defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__) */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define closesocket close -#endif - -#ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); -#else -#define PRINT_SOCKET_ERROR(x) perror(x) -#endif - -#if !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__sun) && !defined(__GNU__) && !defined(__FreeBSD_kernel__) -#define HAS_IP_MREQN -#endif - -#if !defined(HAS_IP_MREQN) && !defined(_WIN32) -#include -#if defined(__sun) -#include -#endif -#endif - -#if defined(HAS_IP_MREQN) && defined(NEED_STRUCT_IP_MREQN) -/* Several versions of glibc don't define this structure, - * define it here and compile with CFLAGS NEED_STRUCT_IP_MREQN */ -struct ip_mreqn -{ - struct in_addr imr_multiaddr; /* IP multicast address of group */ - struct in_addr imr_address; /* local IP address of interface */ - int imr_ifindex; /* Interface index */ -}; -#endif - -#if defined(__amigaos__) || defined(__amigaos4__) -/* Amiga OS specific stuff */ -#define TIMEVAL struct timeval -#endif - -#include "minissdpc.h" -#include "miniupnpc.h" -#include "receivedata.h" - -#if !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) - -#include "codelength.h" - -struct UPNPDev * -getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error) -{ - struct UPNPDev * devlist = NULL; - int s; - int res; - - s = connectToMiniSSDPD(socketpath); - if (s < 0) { - if (error) - *error = s; - return NULL; - } - res = requestDevicesFromMiniSSDPD(s, devtype); - if (res < 0) { - if (error) - *error = res; - } else { - devlist = receiveDevicesFromMiniSSDPD(s, error); - } - disconnectFromMiniSSDPD(s); - return devlist; -} - -/* macros used to read from unix socket */ -#define READ_BYTE_BUFFER(c) \ - if((int)bufferindex >= n) { \ - n = read(s, buffer, sizeof(buffer)); \ - if(n<=0) break; \ - bufferindex = 0; \ - } \ - c = buffer[bufferindex++]; - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif /* MIN */ - -#define READ_COPY_BUFFER(dst, len) \ - for(l = len, p = (unsigned char *)dst; l > 0; ) { \ - unsigned int lcopy; \ - if((int)bufferindex >= n) { \ - n = read(s, buffer, sizeof(buffer)); \ - if(n<=0) break; \ - bufferindex = 0; \ - } \ - lcopy = MIN(l, (n - bufferindex)); \ - memcpy(p, buffer + bufferindex, lcopy); \ - l -= lcopy; \ - p += lcopy; \ - bufferindex += lcopy; \ - } - -#define READ_DISCARD_BUFFER(len) \ - for(l = len; l > 0; ) { \ - unsigned int lcopy; \ - if(bufferindex >= n) { \ - n = read(s, buffer, sizeof(buffer)); \ - if(n<=0) break; \ - bufferindex = 0; \ - } \ - lcopy = MIN(l, (n - bufferindex)); \ - l -= lcopy; \ - bufferindex += lcopy; \ - } - -int -connectToMiniSSDPD(const char * socketpath) -{ - int s; - struct sockaddr_un addr; -#if defined(MINIUPNPC_SET_SOCKET_TIMEOUT) && !defined(__sun) - struct timeval timeout; -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - - s = socket(AF_UNIX, SOCK_STREAM, 0); - if(s < 0) - { - /*syslog(LOG_ERR, "socket(unix): %m");*/ - perror("socket(unix)"); - return MINISSDPC_SOCKET_ERROR; - } -#if defined(MINIUPNPC_SET_SOCKET_TIMEOUT) && !defined(__sun) - /* setting a 3 seconds timeout */ - /* not supported for AF_UNIX sockets under Solaris */ - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - perror("setsockopt SO_RCVTIMEO unix"); - } - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - perror("setsockopt SO_SNDTIMEO unix"); - } -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - if(!socketpath) - socketpath = "/var/run/minissdpd.sock"; - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path)); - /* TODO : check if we need to handle the EINTR */ - if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) - { - /*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/ - close(s); - return MINISSDPC_SOCKET_ERROR; - } - return s; -} - -int -disconnectFromMiniSSDPD(int s) -{ - if (close(s) < 0) - return MINISSDPC_SOCKET_ERROR; - return MINISSDPC_SUCCESS; -} - -int -requestDevicesFromMiniSSDPD(int s, const char * devtype) -{ - unsigned char buffer[256]; - unsigned char * p; - unsigned int stsize, l; - - stsize = strlen(devtype); - if(stsize == 8 && 0 == memcmp(devtype, "ssdp:all", 8)) - { - buffer[0] = 3; /* request type 3 : everything */ - } - else - { - buffer[0] = 1; /* request type 1 : request devices/services by type */ - } - p = buffer + 1; - l = stsize; CODELENGTH(l, p); - if(p + stsize > buffer + sizeof(buffer)) - { - /* devtype is too long ! */ -#ifdef DEBUG - fprintf(stderr, "devtype is too long ! stsize=%u sizeof(buffer)=%u\n", - stsize, (unsigned)sizeof(buffer)); -#endif /* DEBUG */ - return MINISSDPC_INVALID_INPUT; - } - memcpy(p, devtype, stsize); - p += stsize; - if(write(s, buffer, p - buffer) < 0) - { - /*syslog(LOG_ERR, "write(): %m");*/ - perror("minissdpc.c: write()"); - return MINISSDPC_SOCKET_ERROR; - } - return MINISSDPC_SUCCESS; -} - -struct UPNPDev * -receiveDevicesFromMiniSSDPD(int s, int * error) -{ - struct UPNPDev * tmp; - struct UPNPDev * devlist = NULL; - unsigned char buffer[256]; - ssize_t n; - unsigned char * p; - unsigned char * url; - unsigned char * st; - unsigned int bufferindex; - unsigned int i, ndev; - unsigned int urlsize, stsize, usnsize, l; - - n = read(s, buffer, sizeof(buffer)); - if(n<=0) - { - perror("minissdpc.c: read()"); - if (error) - *error = MINISSDPC_SOCKET_ERROR; - return NULL; - } - ndev = buffer[0]; - bufferindex = 1; - for(i = 0; i < ndev; i++) - { - DECODELENGTH_READ(urlsize, READ_BYTE_BUFFER); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - return devlist; - } -#ifdef DEBUG - printf(" urlsize=%u", urlsize); -#endif /* DEBUG */ - url = malloc(urlsize); - if(url == NULL) { - if (error) - *error = MINISSDPC_MEMORY_ERROR; - return devlist; - } - READ_COPY_BUFFER(url, urlsize); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_url_and_return; - } - DECODELENGTH_READ(stsize, READ_BYTE_BUFFER); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_url_and_return; - } -#ifdef DEBUG - printf(" stsize=%u", stsize); -#endif /* DEBUG */ - st = malloc(stsize); - if (st == NULL) { - if (error) - *error = MINISSDPC_MEMORY_ERROR; - goto free_url_and_return; - } - READ_COPY_BUFFER(st, stsize); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_url_and_st_and_return; - } - DECODELENGTH_READ(usnsize, READ_BYTE_BUFFER); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_url_and_st_and_return; - } -#ifdef DEBUG - printf(" usnsize=%u\n", usnsize); -#endif /* DEBUG */ - tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize); - if(tmp == NULL) { - if (error) - *error = MINISSDPC_MEMORY_ERROR; - goto free_url_and_st_and_return; - } - tmp->pNext = devlist; - tmp->descURL = tmp->buffer; - tmp->st = tmp->buffer + 1 + urlsize; - memcpy(tmp->buffer, url, urlsize); - tmp->buffer[urlsize] = '\0'; - memcpy(tmp->st, st, stsize); - tmp->buffer[urlsize+1+stsize] = '\0'; - free(url); - free(st); - url = NULL; - st = NULL; - tmp->usn = tmp->buffer + 1 + urlsize + 1 + stsize; - READ_COPY_BUFFER(tmp->usn, usnsize); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_tmp_and_return; - } - tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; - tmp->scope_id = 0; /* default value. scope_id is not available with MiniSSDPd */ - devlist = tmp; - } - if (error) - *error = MINISSDPC_SUCCESS; - return devlist; - -free_url_and_st_and_return: - free(st); -free_url_and_return: - free(url); - return devlist; - -free_tmp_and_return: - free(tmp); - return devlist; -} - -#endif /* !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) */ - -/* parseMSEARCHReply() - * the last 4 arguments are filled during the parsing : - * - location/locationsize : "location:" field of the SSDP reply packet - * - st/stsize : "st:" field of the SSDP reply packet. - * The strings are NOT null terminated */ -static void -parseMSEARCHReply(const char * reply, int size, - const char * * location, int * locationsize, - const char * * st, int * stsize, - const char * * usn, int * usnsize) -{ - int a, b, i; - i = 0; - a = i; /* start of the line */ - b = 0; /* end of the "header" (position of the colon) */ - while(isin6_family = AF_INET6; - if(localport > 0 && localport < 65536) - p->sin6_port = htons((unsigned short)localport); - p->sin6_addr = in6addr_any; /* in6addr_any is not available with MinGW32 3.4.2 */ - } else { - struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r; - p->sin_family = AF_INET; - if(localport > 0 && localport < 65536) - p->sin_port = htons((unsigned short)localport); - p->sin_addr.s_addr = INADDR_ANY; - } -#ifdef _WIN32 -/* This code could help us to use the right Network interface for - * SSDP multicast traffic */ -/* Get IP associated with the index given in the ip_forward struct - * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */ - if(!ipv6 - && (GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR)) { - DWORD dwRetVal = 0; - PMIB_IPADDRTABLE pIPAddrTable; - DWORD dwSize = 0; -#ifdef DEBUG - IN_ADDR IPAddr; -#endif - int i; -#ifdef DEBUG - printf("ifIndex=%lu nextHop=%lx \n", ip_forward.dwForwardIfIndex, ip_forward.dwForwardNextHop); -#endif - pIPAddrTable = (MIB_IPADDRTABLE *) malloc(sizeof (MIB_IPADDRTABLE)); - if(pIPAddrTable) { - if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) { - free(pIPAddrTable); - pIPAddrTable = (MIB_IPADDRTABLE *) malloc(dwSize); - } - } - if(pIPAddrTable) { - dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 ); - if (dwRetVal == NO_ERROR) { -#ifdef DEBUG - printf("\tNum Entries: %ld\n", pIPAddrTable->dwNumEntries); -#endif - for (i=0; i < (int) pIPAddrTable->dwNumEntries; i++) { -#ifdef DEBUG - printf("\n\tInterface Index[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwIndex); - IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr; - printf("\tIP Address[%d]: \t%s\n", i, inet_ntoa(IPAddr) ); - IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwMask; - printf("\tSubnet Mask[%d]: \t%s\n", i, inet_ntoa(IPAddr) ); - IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwBCastAddr; - printf("\tBroadCast[%d]: \t%s (%ld)\n", i, inet_ntoa(IPAddr), pIPAddrTable->table[i].dwBCastAddr); - printf("\tReassembly size[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwReasmSize); - printf("\tType and State[%d]:", i); - printf("\n"); -#endif - if (pIPAddrTable->table[i].dwIndex == ip_forward.dwForwardIfIndex) { - /* Set the address of this interface to be used */ - struct in_addr mc_if; - memset(&mc_if, 0, sizeof(mc_if)); - mc_if.s_addr = pIPAddrTable->table[i].dwAddr; - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) { - PRINT_SOCKET_ERROR("setsockopt"); - } - ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = pIPAddrTable->table[i].dwAddr; -#ifndef DEBUG - break; -#endif - } - } - } - free(pIPAddrTable); - pIPAddrTable = NULL; - } - } -#endif /* _WIN32 */ - -#ifdef _WIN32 - if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0) -#else - if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0) -#endif - { - if(error) - *error = MINISSDPC_SOCKET_ERROR; - PRINT_SOCKET_ERROR("setsockopt(SO_REUSEADDR,...)"); - return NULL; - } - - if(ipv6) { -#ifdef _WIN32 - DWORD mcastHops = ttl; - if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char *)&mcastHops, sizeof(mcastHops)) < 0) -#else /* _WIN32 */ - int mcastHops = ttl; - if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastHops, sizeof(mcastHops)) < 0) -#endif /* _WIN32 */ - { - PRINT_SOCKET_ERROR("setsockopt(IPV6_MULTICAST_HOPS,...)"); - } - } else { -#ifdef _WIN32 - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&_ttl, sizeof(_ttl)) < 0) -#else /* _WIN32 */ - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) -#endif /* _WIN32 */ - { - /* not a fatal error */ - PRINT_SOCKET_ERROR("setsockopt(IP_MULTICAST_TTL,...)"); - } - } - - if(multicastif) - { - if(ipv6) { -#if !defined(_WIN32) - /* according to MSDN, if_nametoindex() is supported since - * MS Windows Vista and MS Windows Server 2008. - * http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */ - unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */ - if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt IPV6_MULTICAST_IF"); - } -#else -#ifdef DEBUG - printf("Setting of multicast interface not supported in IPv6 under Windows.\n"); -#endif -#endif - } else { - struct in_addr mc_if; - mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */ - if(mc_if.s_addr != INADDR_NONE) - { - ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr; - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); - } - } else { -#ifdef HAS_IP_MREQN - /* was not an ip address, try with an interface name */ - struct ip_mreqn reqn; /* only defined with -D_BSD_SOURCE or -D_GNU_SOURCE */ - memset(&reqn, 0, sizeof(struct ip_mreqn)); - reqn.imr_ifindex = if_nametoindex(multicastif); - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); - } -#elif !defined(_WIN32) - struct ifreq ifr; - int ifrlen = sizeof(ifr); - strncpy(ifr.ifr_name, multicastif, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ-1] = '\0'; - if(ioctl(sudp, SIOCGIFADDR, &ifr, &ifrlen) < 0) - { - PRINT_SOCKET_ERROR("ioctl(...SIOCGIFADDR...)"); - } - mc_if.s_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); - } -#else /* _WIN32 */ -#ifdef DEBUG - printf("Setting of multicast interface not supported with interface name.\n"); -#endif -#endif /* #ifdef HAS_IP_MREQN / !defined(_WIN32) */ - } - } - } - - /* Before sending the packed, we first "bind" in order to be able - * to receive the response */ - if (bind(sudp, (const struct sockaddr *)&sockudp_r, - ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) != 0) - { - if(error) - *error = MINISSDPC_SOCKET_ERROR; - PRINT_SOCKET_ERROR("bind"); - closesocket(sudp); - return NULL; - } - - if(error) - *error = MINISSDPC_SUCCESS; - /* Calculating maximum response time in seconds */ - mx = ((unsigned int)delay) / 1000u; - if(mx == 0) { - mx = 1; - delay = 1000; - } - /* receiving SSDP response packet */ - for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) { - sentok = 0; - /* sending the SSDP M-SEARCH packet */ - n = snprintf(bufr, sizeof(bufr), - MSearchMsgFmt, - ipv6 ? - (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]") - : UPNP_MCAST_ADDR, - deviceTypes[deviceIndex], mx); - if ((unsigned int)n >= sizeof(bufr)) { - if(error) - *error = MINISSDPC_MEMORY_ERROR; - goto error; - } -#ifdef DEBUG - /*printf("Sending %s", bufr);*/ - printf("Sending M-SEARCH request to %s with ST: %s\n", - ipv6 ? - (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]") - : UPNP_MCAST_ADDR, - deviceTypes[deviceIndex]); -#endif -#ifdef NO_GETADDRINFO - /* the following code is not using getaddrinfo */ - /* emission */ - memset(&sockudp_w, 0, sizeof(struct sockaddr_storage)); - if(ipv6) { - struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_w; - p->sin6_family = AF_INET6; - p->sin6_port = htons(SSDP_PORT); - inet_pton(AF_INET6, - linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR, - &(p->sin6_addr)); - } else { - struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_w; - p->sin_family = AF_INET; - p->sin_port = htons(SSDP_PORT); - p->sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR); - } - n = sendto(sudp, bufr, n, 0, &sockudp_w, - ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); - if (n < 0) { - if(error) - *error = MINISSDPC_SOCKET_ERROR; - PRINT_SOCKET_ERROR("sendto"); - } else { - sentok = 1; - } -#else /* #ifdef NO_GETADDRINFO */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; /* AF_INET6 or AF_INET */ - hints.ai_socktype = SOCK_DGRAM; - /*hints.ai_flags = */ - if ((rv = getaddrinfo(ipv6 - ? (linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR) - : UPNP_MCAST_ADDR, - XSTR(SSDP_PORT), &hints, &servinfo)) != 0) { - if(error) - *error = MINISSDPC_SOCKET_ERROR; -#ifdef _WIN32 - fprintf(stderr, "getaddrinfo() failed: %d\n", rv); -#else - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); -#endif - break; - } - for(p = servinfo; p; p = p->ai_next) { - n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen); - if (n < 0) { -#ifdef DEBUG - char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; - if (getnameinfo(p->ai_addr, p->ai_addrlen, hbuf, sizeof(hbuf), sbuf, - sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0) { - fprintf(stderr, "host:%s port:%s\n", hbuf, sbuf); - } -#endif - PRINT_SOCKET_ERROR("sendto"); - continue; - } else { - sentok = 1; - } - } - freeaddrinfo(servinfo); - if(!sentok) { - if(error) - *error = MINISSDPC_SOCKET_ERROR; - } -#endif /* #ifdef NO_GETADDRINFO */ - /* Waiting for SSDP REPLY packet to M-SEARCH - * if searchalltypes is set, enter the loop only - * when the last deviceType is reached */ - if((sentok && !searchalltypes) || !deviceTypes[deviceIndex + 1]) do { - n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id); - if (n < 0) { - /* error */ - if(error) - *error = MINISSDPC_SOCKET_ERROR; - goto error; - } else if (n == 0) { - /* no data or Time Out */ -#ifdef DEBUG - printf("NODATA or TIMEOUT\n"); -#endif /* DEBUG */ - if (devlist && !searchalltypes) { - /* found some devices, stop now*/ - if(error) - *error = MINISSDPC_SUCCESS; - goto error; - } - } else { - const char * descURL=NULL; - int urlsize=0; - const char * st=NULL; - int stsize=0; - const char * usn=NULL; - int usnsize=0; - parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize); - if(st&&descURL) { -#ifdef DEBUG - printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n", - stsize, st, usnsize, (usn?usn:""), urlsize, descURL); -#endif /* DEBUG */ - for(tmp=devlist; tmp; tmp = tmp->pNext) { - if(memcmp(tmp->descURL, descURL, urlsize) == 0 && - tmp->descURL[urlsize] == '\0' && - memcmp(tmp->st, st, stsize) == 0 && - tmp->st[stsize] == '\0' && - (usnsize == 0 || memcmp(tmp->usn, usn, usnsize) == 0) && - tmp->usn[usnsize] == '\0') - break; - } - /* at the exit of the loop above, tmp is null if - * no duplicate device was found */ - if(tmp) - continue; - tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize); - if(!tmp) { - /* memory allocation error */ - if(error) - *error = MINISSDPC_MEMORY_ERROR; - goto error; - } - tmp->pNext = devlist; - tmp->descURL = tmp->buffer; - tmp->st = tmp->buffer + 1 + urlsize; - tmp->usn = tmp->st + 1 + stsize; - memcpy(tmp->buffer, descURL, urlsize); - tmp->buffer[urlsize] = '\0'; - memcpy(tmp->st, st, stsize); - tmp->buffer[urlsize+1+stsize] = '\0'; - if(usn != NULL) - memcpy(tmp->usn, usn, usnsize); - tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; - tmp->scope_id = scope_id; - devlist = tmp; - } - } - } while(n > 0); - if(ipv6) { - /* switch linklocal flag */ - if(linklocal) { - linklocal = 0; - --deviceIndex; - } else { - linklocal = 1; - } - } - } -error: - closesocket(sudp); - return devlist; -} - diff --git a/ext/miniupnpc/minissdpc.h b/ext/miniupnpc/minissdpc.h deleted file mode 100644 index a5c622b28..000000000 --- a/ext/miniupnpc/minissdpc.h +++ /dev/null @@ -1,58 +0,0 @@ -/* $Id: minissdpc.h,v 1.7 2015/10/08 16:15:47 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author: Thomas Bernard - * Copyright (c) 2005-2015 Thomas Bernard - * This software is subjects to the conditions detailed - * in the LICENCE file provided within this distribution */ -#ifndef MINISSDPC_H_INCLUDED -#define MINISSDPC_H_INCLUDED - -#include "miniupnpc_declspec.h" -#include "upnpdev.h" - -/* error codes : */ -#define MINISSDPC_SUCCESS (0) -#define MINISSDPC_UNKNOWN_ERROR (-1) -#define MINISSDPC_SOCKET_ERROR (-101) -#define MINISSDPC_MEMORY_ERROR (-102) -#define MINISSDPC_INVALID_INPUT (-103) -#define MINISSDPC_INVALID_SERVER_REPLY (-104) - -#ifdef __cplusplus -extern "C" { -#endif - -#if !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) - -MINIUPNP_LIBSPEC struct UPNPDev * -getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error); - -MINIUPNP_LIBSPEC int -connectToMiniSSDPD(const char * socketpath); - -MINIUPNP_LIBSPEC int -disconnectFromMiniSSDPD(int fd); - -MINIUPNP_LIBSPEC int -requestDevicesFromMiniSSDPD(int fd, const char * devtype); - -MINIUPNP_LIBSPEC struct UPNPDev * -receiveDevicesFromMiniSSDPD(int fd, int * error); - -#endif /* !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) */ - -MINIUPNP_LIBSPEC struct UPNPDev * -ssdpDiscoverDevices(const char * const deviceTypes[], - int delay, const char * multicastif, - int localport, - int ipv6, unsigned char ttl, - int * error, - int searchalltypes); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/ext/miniupnpc/miniupnpc.c b/ext/miniupnpc/miniupnpc.c deleted file mode 100644 index 2dc5c95cd..000000000 --- a/ext/miniupnpc/miniupnpc.c +++ /dev/null @@ -1,722 +0,0 @@ -/* $Id: miniupnpc.c,v 1.149 2016/02/09 09:50:46 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * Project : miniupnp - * Web : http://miniupnp.free.fr/ - * Author : Thomas BERNARD - * copyright (c) 2005-2016 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENSE file. */ -#include -#include -#include -#ifdef _WIN32 -/* Win32 Specific includes and defines */ -#include -#include -#include -#include -#define snprintf _snprintf -#define strdup _strdup -#ifndef strncasecmp -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#define strncasecmp _memicmp -#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ -#define strncasecmp memicmp -#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ -#endif /* #ifndef strncasecmp */ -#define MAXHOSTNAMELEN 64 -#else /* #ifdef _WIN32 */ -/* Standard POSIX includes */ -#include -#if defined(__amigaos__) && !defined(__amigaos4__) -/* Amiga OS 3 specific stuff */ -#define socklen_t int -#else -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#if !defined(__amigaos__) && !defined(__amigaos4__) -#include -#endif -#include -#include -#define closesocket close -#endif /* #else _WIN32 */ -#ifdef __GNU__ -#define MAXHOSTNAMELEN 64 -#endif - - -#include "miniupnpc.h" -#include "minissdpc.h" -#include "miniwget.h" -#include "minisoap.h" -#include "minixml.h" -#include "upnpcommands.h" -#include "connecthostport.h" - -/* compare the begining of a string with a constant string */ -#define COMPARE(str, cstr) (0==memcmp(str, cstr, sizeof(cstr) - 1)) - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -#define SOAPPREFIX "s" -#define SERVICEPREFIX "u" -#define SERVICEPREFIX2 'u' - -/* check if an ip address is a private (LAN) address - * see https://tools.ietf.org/html/rfc1918 */ -static int is_rfc1918addr(const char * addr) -{ - /* 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) */ - if(COMPARE(addr, "192.168.")) - return 1; - /* 10.0.0.0 - 10.255.255.255 (10/8 prefix) */ - if(COMPARE(addr, "10.")) - return 1; - /* 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) */ - if(COMPARE(addr, "172.")) { - int i = atoi(addr + 4); - if((16 <= i) && (i <= 31)) - return 1; - } - return 0; -} - -/* root description parsing */ -MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data) -{ - struct xmlparser parser; - /* xmlparser object */ - parser.xmlstart = buffer; - parser.xmlsize = bufsize; - parser.data = data; - parser.starteltfunc = IGDstartelt; - parser.endeltfunc = IGDendelt; - parser.datafunc = IGDdata; - parser.attfunc = 0; - parsexml(&parser); -#ifdef DEBUG - printIGD(data); -#endif -} - -/* simpleUPnPcommand2 : - * not so simple ! - * return values : - * pointer - OK - * NULL - error */ -char * simpleUPnPcommand2(int s, const char * url, const char * service, - const char * action, struct UPNParg * args, - int * bufsize, const char * httpversion) -{ - char hostname[MAXHOSTNAMELEN+1]; - unsigned short port = 0; - char * path; - char soapact[128]; - char soapbody[2048]; - int soapbodylen; - char * buf; - int n; - int status_code; - - *bufsize = 0; - snprintf(soapact, sizeof(soapact), "%s#%s", service, action); - if(args==NULL) - { - soapbodylen = snprintf(soapbody, sizeof(soapbody), - "\r\n" - "<" SOAPPREFIX ":Envelope " - "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" " - SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" - "<" SOAPPREFIX ":Body>" - "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">" - "" - "" - "\r\n", action, service, action); - if ((unsigned int)soapbodylen >= sizeof(soapbody)) - return NULL; - } - else - { - char * p; - const char * pe, * pv; - const char * const pend = soapbody + sizeof(soapbody); - soapbodylen = snprintf(soapbody, sizeof(soapbody), - "\r\n" - "<" SOAPPREFIX ":Envelope " - "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" " - SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" - "<" SOAPPREFIX ":Body>" - "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">", - action, service); - if ((unsigned int)soapbodylen >= sizeof(soapbody)) - return NULL; - p = soapbody + soapbodylen; - while(args->elt) - { - if(p >= pend) /* check for space to write next byte */ - return NULL; - *(p++) = '<'; - - pe = args->elt; - while(p < pend && *pe) - *(p++) = *(pe++); - - if(p >= pend) /* check for space to write next byte */ - return NULL; - *(p++) = '>'; - - if((pv = args->val)) - { - while(p < pend && *pv) - *(p++) = *(pv++); - } - - if((p+2) > pend) /* check for space to write next 2 bytes */ - return NULL; - *(p++) = '<'; - *(p++) = '/'; - - pe = args->elt; - while(p < pend && *pe) - *(p++) = *(pe++); - - if(p >= pend) /* check for space to write next byte */ - return NULL; - *(p++) = '>'; - - args++; - } - if((p+4) > pend) /* check for space to write next 4 bytes */ - return NULL; - *(p++) = '<'; - *(p++) = '/'; - *(p++) = SERVICEPREFIX2; - *(p++) = ':'; - - pe = action; - while(p < pend && *pe) - *(p++) = *(pe++); - - strncpy(p, ">\r\n", - pend - p); - if(soapbody[sizeof(soapbody)-1]) /* strncpy pads buffer with 0s, so if it doesn't end in 0, could not fit full string */ - return NULL; - } - if(!parseURL(url, hostname, &port, &path, NULL)) return NULL; - if(s < 0) { - s = connecthostport(hostname, port, 0); - if(s < 0) { - /* failed to connect */ - return NULL; - } - } - - n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, httpversion); - if(n<=0) { -#ifdef DEBUG - printf("Error sending SOAP request\n"); -#endif - closesocket(s); - return NULL; - } - - buf = getHTTPResponse(s, bufsize, &status_code); -#ifdef DEBUG - if(*bufsize > 0 && buf) - { - printf("HTTP %d SOAP Response :\n%.*s\n", status_code, *bufsize, buf); - } - else - { - printf("HTTP %d, empty SOAP response. size=%d\n", status_code, *bufsize); - } -#endif - closesocket(s); - return buf; -} - -/* simpleUPnPcommand : - * not so simple ! - * return values : - * pointer - OK - * NULL - error */ -char * simpleUPnPcommand(int s, const char * url, const char * service, - const char * action, struct UPNParg * args, - int * bufsize) -{ - char * buf; - -#if 1 - buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1"); -#else - buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0"); - if (!buf || *bufsize == 0) - { -#if DEBUG - printf("Error or no result from SOAP request; retrying with HTTP/1.1\n"); -#endif - buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1"); - } -#endif - return buf; -} - -/* upnpDiscoverDevices() : - * return a chained list of all devices found or NULL if - * no devices was found. - * It is up to the caller to free the chained list - * delay is in millisecond (poll). - * UDA v1.1 says : - * The TTL for the IP packet SHOULD default to 2 and - * SHOULD be configurable. */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverDevices(const char * const deviceTypes[], - int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error, - int searchalltypes) -{ - struct UPNPDev * tmp; - struct UPNPDev * devlist = 0; -#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) - int deviceIndex; -#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ - - if(error) - *error = UPNPDISCOVER_UNKNOWN_ERROR; -#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) - /* first try to get infos from minissdpd ! */ - if(!minissdpdsock) - minissdpdsock = "/var/run/minissdpd.sock"; - for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) { - struct UPNPDev * minissdpd_devlist; - int only_rootdevice = 1; - minissdpd_devlist = getDevicesFromMiniSSDPD(deviceTypes[deviceIndex], - minissdpdsock, 0); - if(minissdpd_devlist) { -#ifdef DEBUG - printf("returned by MiniSSDPD: %s\t%s\n", - minissdpd_devlist->st, minissdpd_devlist->descURL); -#endif /* DEBUG */ - if(!strstr(minissdpd_devlist->st, "rootdevice")) - only_rootdevice = 0; - for(tmp = minissdpd_devlist; tmp->pNext != NULL; tmp = tmp->pNext) { -#ifdef DEBUG - printf("returned by MiniSSDPD: %s\t%s\n", - tmp->pNext->st, tmp->pNext->descURL); -#endif /* DEBUG */ - if(!strstr(tmp->st, "rootdevice")) - only_rootdevice = 0; - } - tmp->pNext = devlist; - devlist = minissdpd_devlist; - if(!searchalltypes && !only_rootdevice) - break; - } - } - for(tmp = devlist; tmp != NULL; tmp = tmp->pNext) { - /* We return what we have found if it was not only a rootdevice */ - if(!strstr(tmp->st, "rootdevice")) { - if(error) - *error = UPNPDISCOVER_SUCCESS; - return devlist; - } - } -#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ - - /* direct discovery if minissdpd responses are not sufficient */ - { - struct UPNPDev * discovered_devlist; - discovered_devlist = ssdpDiscoverDevices(deviceTypes, delay, multicastif, localport, - ipv6, ttl, error, searchalltypes); - if(devlist == NULL) - devlist = discovered_devlist; - else { - for(tmp = devlist; tmp->pNext != NULL; tmp = tmp->pNext); - tmp->pNext = discovered_devlist; - } - } - return devlist; -} - -/* upnpDiscover() Discover IGD device */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscover(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error) -{ - static const char * const deviceList[] = { -#if 0 - "urn:schemas-upnp-org:device:InternetGatewayDevice:2", - "urn:schemas-upnp-org:service:WANIPConnection:2", -#endif - "urn:schemas-upnp-org:device:InternetGatewayDevice:1", - "urn:schemas-upnp-org:service:WANIPConnection:1", - "urn:schemas-upnp-org:service:WANPPPConnection:1", - "upnp:rootdevice", - /*"ssdp:all",*/ - 0 - }; - return upnpDiscoverDevices(deviceList, - delay, multicastif, minissdpdsock, localport, - ipv6, ttl, error, 0); -} - -/* upnpDiscoverAll() Discover all UPnP devices */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverAll(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error) -{ - static const char * const deviceList[] = { - /*"upnp:rootdevice",*/ - "ssdp:all", - 0 - }; - return upnpDiscoverDevices(deviceList, - delay, multicastif, minissdpdsock, localport, - ipv6, ttl, error, 0); -} - -/* upnpDiscoverDevice() Discover a specific device */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverDevice(const char * device, int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error) -{ - const char * const deviceList[] = { - device, - 0 - }; - return upnpDiscoverDevices(deviceList, - delay, multicastif, minissdpdsock, localport, - ipv6, ttl, error, 0); -} - -static char * -build_absolute_url(const char * baseurl, const char * descURL, - const char * url, unsigned int scope_id) -{ - int l, n; - char * s; - const char * base; - char * p; -#if defined(IF_NAMESIZE) && !defined(_WIN32) - char ifname[IF_NAMESIZE]; -#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - char scope_str[8]; -#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - - if( (url[0] == 'h') - &&(url[1] == 't') - &&(url[2] == 't') - &&(url[3] == 'p') - &&(url[4] == ':') - &&(url[5] == '/') - &&(url[6] == '/')) - return strdup(url); - base = (baseurl[0] == '\0') ? descURL : baseurl; - n = strlen(base); - if(n > 7) { - p = strchr(base + 7, '/'); - if(p) - n = p - base; - } - l = n + strlen(url) + 1; - if(url[0] != '/') - l++; - if(scope_id != 0) { -#if defined(IF_NAMESIZE) && !defined(_WIN32) - if(if_indextoname(scope_id, ifname)) { - l += 3 + strlen(ifname); /* 3 == strlen(%25) */ - } -#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - /* under windows, scope is numerical */ - l += 3 + snprintf(scope_str, sizeof(scope_str), "%u", scope_id); -#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - } - s = malloc(l); - if(s == NULL) return NULL; - memcpy(s, base, n); - if(scope_id != 0) { - s[n] = '\0'; - if(0 == memcmp(s, "http://[fe80:", 13)) { - /* this is a linklocal IPv6 address */ - p = strchr(s, ']'); - if(p) { - /* insert %25 into URL */ -#if defined(IF_NAMESIZE) && !defined(_WIN32) - memmove(p + 3 + strlen(ifname), p, strlen(p) + 1); - memcpy(p, "%25", 3); - memcpy(p + 3, ifname, strlen(ifname)); - n += 3 + strlen(ifname); -#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - memmove(p + 3 + strlen(scope_str), p, strlen(p) + 1); - memcpy(p, "%25", 3); - memcpy(p + 3, scope_str, strlen(scope_str)); - n += 3 + strlen(scope_str); -#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - } - } - } - if(url[0] != '/') - s[n++] = '/'; - memcpy(s + n, url, l - n); - return s; -} - -/* Prepare the Urls for usage... - */ -MINIUPNP_LIBSPEC void -GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, - const char * descURL, unsigned int scope_id) -{ - /* strdup descURL */ - urls->rootdescURL = strdup(descURL); - - /* get description of WANIPConnection */ - urls->ipcondescURL = build_absolute_url(data->urlbase, descURL, - data->first.scpdurl, scope_id); - urls->controlURL = build_absolute_url(data->urlbase, descURL, - data->first.controlurl, scope_id); - urls->controlURL_CIF = build_absolute_url(data->urlbase, descURL, - data->CIF.controlurl, scope_id); - urls->controlURL_6FC = build_absolute_url(data->urlbase, descURL, - data->IPv6FC.controlurl, scope_id); - -#ifdef DEBUG - printf("urls->ipcondescURL='%s'\n", urls->ipcondescURL); - printf("urls->controlURL='%s'\n", urls->controlURL); - printf("urls->controlURL_CIF='%s'\n", urls->controlURL_CIF); - printf("urls->controlURL_6FC='%s'\n", urls->controlURL_6FC); -#endif -} - -MINIUPNP_LIBSPEC void -FreeUPNPUrls(struct UPNPUrls * urls) -{ - if(!urls) - return; - free(urls->controlURL); - urls->controlURL = 0; - free(urls->ipcondescURL); - urls->ipcondescURL = 0; - free(urls->controlURL_CIF); - urls->controlURL_CIF = 0; - free(urls->controlURL_6FC); - urls->controlURL_6FC = 0; - free(urls->rootdescURL); - urls->rootdescURL = 0; -} - -int -UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data) -{ - char status[64]; - unsigned int uptime; - status[0] = '\0'; - UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, - status, &uptime, NULL); - if(0 == strcmp("Connected", status)) - return 1; - else if(0 == strcmp("Up", status)) /* Also accept "Up" */ - return 1; - else - return 0; -} - - -/* UPNP_GetValidIGD() : - * return values : - * -1 = Internal error - * 0 = NO IGD found - * 1 = A valid connected IGD has been found - * 2 = A valid IGD has been found but it reported as - * not connected - * 3 = an UPnP device has been found but was not recognized as an IGD - * - * In any positive non zero return case, the urls and data structures - * passed as parameters are set. Dont forget to call FreeUPNPUrls(urls) to - * free allocated memory. - */ -MINIUPNP_LIBSPEC int -UPNP_GetValidIGD(struct UPNPDev * devlist, - struct UPNPUrls * urls, - struct IGDdatas * data, - char * lanaddr, int lanaddrlen) -{ - struct xml_desc { - char * xml; - int size; - int is_igd; - } * desc = NULL; - struct UPNPDev * dev; - int ndev = 0; - int i; - int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */ - int n_igd = 0; - char extIpAddr[16]; - char myLanAddr[40]; - int status_code = -1; - - if(!devlist) - { -#ifdef DEBUG - printf("Empty devlist\n"); -#endif - return 0; - } - /* counting total number of devices in the list */ - for(dev = devlist; dev; dev = dev->pNext) - ndev++; - if(ndev > 0) - { - desc = calloc(ndev, sizeof(struct xml_desc)); - if(!desc) - return -1; /* memory allocation error */ - } - /* Step 1 : downloading descriptions and testing type */ - for(dev = devlist, i = 0; dev; dev = dev->pNext, i++) - { - /* we should choose an internet gateway device. - * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */ - desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size), - myLanAddr, sizeof(myLanAddr), - dev->scope_id, &status_code); -#ifdef DEBUG - if(!desc[i].xml) - { - printf("error getting XML description %s\n", dev->descURL); - } -#endif - if(desc[i].xml) - { - memset(data, 0, sizeof(struct IGDdatas)); - memset(urls, 0, sizeof(struct UPNPUrls)); - parserootdesc(desc[i].xml, desc[i].size, data); - if(COMPARE(data->CIF.servicetype, - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) - { - desc[i].is_igd = 1; - n_igd++; - if(lanaddr) - strncpy(lanaddr, myLanAddr, lanaddrlen); - } - } - } - /* iterate the list to find a device depending on state */ - for(state = 1; state <= 3; state++) - { - for(dev = devlist, i = 0; dev; dev = dev->pNext, i++) - { - if(desc[i].xml) - { - memset(data, 0, sizeof(struct IGDdatas)); - memset(urls, 0, sizeof(struct UPNPUrls)); - parserootdesc(desc[i].xml, desc[i].size, data); - if(desc[i].is_igd || state >= 3 ) - { - int is_connected; - - GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); - - /* in state 2 and 3 we dont test if device is connected ! */ - if(state >= 2) - goto free_and_return; - is_connected = UPNPIGD_IsConnected(urls, data); -#ifdef DEBUG - printf("UPNPIGD_IsConnected(%s) = %d\n", - urls->controlURL, is_connected); -#endif - /* checks that status is connected AND there is a external IP address assigned */ - if(is_connected && - (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { - if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') - && (0 != strcmp(extIpAddr, "0.0.0.0"))) - goto free_and_return; - } - FreeUPNPUrls(urls); - if(data->second.servicetype[0] != '\0') { -#ifdef DEBUG - printf("We tried %s, now we try %s !\n", - data->first.servicetype, data->second.servicetype); -#endif - /* swaping WANPPPConnection and WANIPConnection ! */ - memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service)); - memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service)); - memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service)); - GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); - is_connected = UPNPIGD_IsConnected(urls, data); -#ifdef DEBUG - printf("UPNPIGD_IsConnected(%s) = %d\n", - urls->controlURL, is_connected); -#endif - if(is_connected && - (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { - if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') - && (0 != strcmp(extIpAddr, "0.0.0.0"))) - goto free_and_return; - } - FreeUPNPUrls(urls); - } - } - memset(data, 0, sizeof(struct IGDdatas)); - } - } - } - state = 0; -free_and_return: - if(desc) { - for(i = 0; i < ndev; i++) { - if(desc[i].xml) { - free(desc[i].xml); - } - } - free(desc); - } - return state; -} - -/* UPNP_GetIGDFromUrl() - * Used when skipping the discovery process. - * return value : - * 0 - Not ok - * 1 - OK */ -int -UPNP_GetIGDFromUrl(const char * rootdescurl, - struct UPNPUrls * urls, - struct IGDdatas * data, - char * lanaddr, int lanaddrlen) -{ - char * descXML; - int descXMLsize = 0; - - descXML = miniwget_getaddr(rootdescurl, &descXMLsize, - lanaddr, lanaddrlen, 0, NULL); - if(descXML) { - memset(data, 0, sizeof(struct IGDdatas)); - memset(urls, 0, sizeof(struct UPNPUrls)); - parserootdesc(descXML, descXMLsize, data); - free(descXML); - descXML = NULL; - GetUPNPUrls(urls, data, rootdescurl, 0); - return 1; - } else { - return 0; - } -} - diff --git a/ext/miniupnpc/miniupnpc.def b/ext/miniupnpc/miniupnpc.def deleted file mode 100644 index 60e0bbe42..000000000 --- a/ext/miniupnpc/miniupnpc.def +++ /dev/null @@ -1,45 +0,0 @@ -LIBRARY -; miniupnpc library - miniupnpc - -EXPORTS -; miniupnpc - upnpDiscover - freeUPNPDevlist - parserootdesc - UPNP_GetValidIGD - UPNP_GetIGDFromUrl - GetUPNPUrls - FreeUPNPUrls -; miniwget - miniwget - miniwget_getaddr -; upnpcommands - UPNP_GetTotalBytesSent - UPNP_GetTotalBytesReceived - UPNP_GetTotalPacketsSent - UPNP_GetTotalPacketsReceived - UPNP_GetStatusInfo - UPNP_GetConnectionTypeInfo - UPNP_GetExternalIPAddress - UPNP_GetLinkLayerMaxBitRates - UPNP_AddPortMapping - UPNP_AddAnyPortMapping - UPNP_DeletePortMapping - UPNP_DeletePortMappingRange - UPNP_GetPortMappingNumberOfEntries - UPNP_GetSpecificPortMappingEntry - UPNP_GetGenericPortMappingEntry - UPNP_GetListOfPortMappings - UPNP_AddPinhole - UPNP_CheckPinholeWorking - UPNP_UpdatePinhole - UPNP_GetPinholePackets - UPNP_DeletePinhole - UPNP_GetFirewallStatus - UPNP_GetOutboundPinholeTimeout -; upnperrors - strupnperror -; portlistingparse - ParsePortListing - FreePortListing diff --git a/ext/miniupnpc/miniupnpcmodule.c b/ext/miniupnpc/miniupnpcmodule.c deleted file mode 100644 index bbff07382..000000000 --- a/ext/miniupnpc/miniupnpcmodule.c +++ /dev/null @@ -1,703 +0,0 @@ -/* $Id: miniupnpcmodule.c,v 1.31 2017/11/02 15:37:28 nanard Exp $*/ -/* Project : miniupnp - * Author : Thomas BERNARD - * website : http://miniupnp.tuxfamily.org/ - * copyright (c) 2007-2016 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#include -#define MINIUPNP_STATICLIB -#include "structmember.h" -#include "miniupnpc.h" -#include "upnpcommands.h" -#include "upnperrors.h" - -#ifdef _WIN32 -#include -#endif - -/* 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 - -/* for compatibility with Python < 3.0 */ -#ifndef PyVarObject_HEAD_INIT -#define PyVarObject_HEAD_INIT(type, size) \ - PyObject_HEAD_INIT(type) size, -#endif - -#ifndef Py_TYPE -#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) -#endif - -typedef struct { - PyObject_HEAD - /* Type-specific fields go here. */ - struct UPNPDev * devlist; - struct UPNPUrls urls; - struct IGDdatas data; - unsigned int discoverdelay; /* value passed to upnpDiscover() */ - unsigned int localport; /* value passed to upnpDiscover() */ - char lanaddr[40]; /* our ip address on the LAN */ - char * multicastif; - char * minissdpdsocket; -} UPnPObject; - -static PyMemberDef UPnP_members[] = { - {"lanaddr", T_STRING_INPLACE, offsetof(UPnPObject, lanaddr), - READONLY, "ip address on the LAN" - }, - {"discoverdelay", T_UINT, offsetof(UPnPObject, discoverdelay), - 0/*READWRITE*/, "value in ms used to wait for SSDP responses" - }, - {"localport", T_UINT, offsetof(UPnPObject, localport), - 0/*READWRITE*/, - "If localport is set to UPNP_LOCAL_PORT_SAME(1) " - "SSDP packets will be sent from the source port " - "1900 (same as destination port), if set to " - "UPNP_LOCAL_PORT_ANY(0) system assign a source " - "port, any other value will be attempted as the " - "source port" - }, - /* T_STRING is allways readonly :( */ - {"multicastif", T_STRING, offsetof(UPnPObject, multicastif), - 0, "IP of the network interface to be used for multicast operations" - }, - {"minissdpdsocket", T_STRING, offsetof(UPnPObject, minissdpdsocket), - 0, "path of the MiniSSDPd unix socket" - }, - {NULL} -}; - - -static int UPnP_init(UPnPObject *self, PyObject *args, PyObject *kwds) -{ - char* multicastif = NULL; - char* minissdpdsocket = NULL; - static char *kwlist[] = { - "multicastif", "minissdpdsocket", "discoverdelay", - "localport", NULL - }; - - if(!PyArg_ParseTupleAndKeywords(args, kwds, "|zzII", kwlist, - &multicastif, - &minissdpdsocket, - &self->discoverdelay, - &self->localport)) - return -1; - - if(self->localport>1 && - (self->localport>65534||self->localport<1024)) { - PyErr_SetString(PyExc_Exception, "Invalid localport value"); - return -1; - } - if(multicastif) - self->multicastif = strdup(multicastif); - if(minissdpdsocket) - self->minissdpdsocket = strdup(minissdpdsocket); - - return 0; -} - -static void -UPnPObject_dealloc(UPnPObject *self) -{ - freeUPNPDevlist(self->devlist); - FreeUPNPUrls(&self->urls); - free(self->multicastif); - free(self->minissdpdsocket); - Py_TYPE(self)->tp_free((PyObject*)self); -} - -static PyObject * -UPnP_discover(UPnPObject *self) -{ - struct UPNPDev * dev; - int i; - PyObject *res = NULL; - if(self->devlist) - { - freeUPNPDevlist(self->devlist); - self->devlist = 0; - } - Py_BEGIN_ALLOW_THREADS - self->devlist = upnpDiscover((int)self->discoverdelay/*timeout in ms*/, - self->multicastif, - self->minissdpdsocket, - (int)self->localport, - 0/*ip v6*/, - 2/* TTL */, - 0/*error */); - Py_END_ALLOW_THREADS - /* Py_RETURN_NONE ??? */ - for(dev = self->devlist, i = 0; dev; dev = dev->pNext) - i++; - res = Py_BuildValue("i", i); - return res; -} - -static PyObject * -UPnP_selectigd(UPnPObject *self) -{ - int r; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetValidIGD(self->devlist, &self->urls, &self->data, - self->lanaddr, sizeof(self->lanaddr)); -Py_END_ALLOW_THREADS - if(r) - { - return Py_BuildValue("s", self->urls.controlURL); - } - else - { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, "No UPnP device discovered"); - return NULL; - } -} - -static PyObject * -UPnP_totalbytesent(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalBytesSent(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_totalbytereceived(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalBytesReceived(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_totalpacketsent(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalPacketsSent(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_totalpacketreceived(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalPacketsReceived(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_statusinfo(UPnPObject *self) -{ - char status[64]; - char lastconnerror[64]; - unsigned int uptime = 0; - int r; - status[0] = '\0'; - lastconnerror[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetStatusInfo(self->urls.controlURL, self->data.first.servicetype, - status, &uptime, lastconnerror); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("(s,I,s)", status, uptime, lastconnerror); -#else - return Py_BuildValue("(s,i,s)", status, (int)uptime, lastconnerror); -#endif - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -static PyObject * -UPnP_connectiontype(UPnPObject *self) -{ - char connectionType[64]; - int r; - connectionType[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetConnectionTypeInfo(self->urls.controlURL, - self->data.first.servicetype, - connectionType); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - return Py_BuildValue("s", connectionType); - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -static PyObject * -UPnP_externalipaddress(UPnPObject *self) -{ - char externalIPAddress[40]; - int r; - externalIPAddress[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetExternalIPAddress(self->urls.controlURL, - self->data.first.servicetype, - externalIPAddress); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - return Py_BuildValue("s", externalIPAddress); - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* AddPortMapping(externalPort, protocol, internalHost, internalPort, desc, - * remoteHost) - * protocol is 'UDP' or 'TCP' */ -static PyObject * -UPnP_addportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - char inPort[6]; - unsigned short iPort; - const char * proto; - const char * host; - const char * desc; - const char * remoteHost; - const char * leaseDuration = "0"; - int r; - if (!PyArg_ParseTuple(args, "HssHzz", &ePort, &proto, - &host, &iPort, &desc, &remoteHost)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - sprintf(inPort, "%hu", iPort); - r = UPNP_AddPortMapping(self->urls.controlURL, self->data.first.servicetype, - extPort, inPort, host, desc, proto, - remoteHost, leaseDuration); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) - { - Py_RETURN_TRUE; - } - else - { - // TODO: RAISE an Exception. See upnpcommands.h for errors codes. - // upnperrors.c - //Py_RETURN_FALSE; - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* AddAnyPortMapping(externalPort, protocol, internalHost, internalPort, desc, - * remoteHost) - * protocol is 'UDP' or 'TCP' */ -static PyObject * -UPnP_addanyportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - char inPort[6]; - unsigned short iPort; - char reservedPort[6]; - const char * proto; - const char * host; - const char * desc; - const char * remoteHost; - const char * leaseDuration = "0"; - int r; - if (!PyArg_ParseTuple(args, "HssHzz", &ePort, &proto, &host, &iPort, &desc, &remoteHost)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - sprintf(inPort, "%hu", iPort); - r = UPNP_AddAnyPortMapping(self->urls.controlURL, self->data.first.servicetype, - extPort, inPort, host, desc, proto, - remoteHost, leaseDuration, reservedPort); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - return Py_BuildValue("i", atoi(reservedPort)); - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - - -/* DeletePortMapping(extPort, proto, removeHost='') - * proto = 'UDP', 'TCP' */ -static PyObject * -UPnP_deleteportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - const char * proto; - const char * remoteHost = ""; - int r; - if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - r = UPNP_DeletePortMapping(self->urls.controlURL, self->data.first.servicetype, - extPort, proto, remoteHost); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - Py_RETURN_TRUE; - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* DeletePortMappingRange(extPort, proto, removeHost='') - * proto = 'UDP', 'TCP' */ -static PyObject * -UPnP_deleteportmappingrange(UPnPObject *self, PyObject *args) -{ - char extPortStart[6]; - unsigned short ePortStart; - char extPortEnd[6]; - unsigned short ePortEnd; - const char * proto; - unsigned char manage; - char manageStr[1]; - int r; - if(!PyArg_ParseTuple(args, "HHsb", &ePortStart, &ePortEnd, &proto, &manage)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPortStart, "%hu", ePortStart); - sprintf(extPortEnd, "%hu", ePortEnd); - sprintf(manageStr, "%hhu", manage); - r = UPNP_DeletePortMappingRange(self->urls.controlURL, self->data.first.servicetype, - extPortStart, extPortEnd, proto, manageStr); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - Py_RETURN_TRUE; - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -static PyObject * -UPnP_getportmappingnumberofentries(UPnPObject *self) -{ - unsigned int n = 0; - int r; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetPortMappingNumberOfEntries(self->urls.controlURL, - self->data.first.servicetype, - &n); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", n); -#else - return Py_BuildValue("i", (int)n); -#endif - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* GetSpecificPortMapping(ePort, proto, remoteHost='') - * proto = 'UDP' or 'TCP' */ -static PyObject * -UPnP_getspecificportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - const char * proto; - const char * remoteHost = ""; - char intClient[40]; - char intPort[6]; - unsigned short iPort; - char desc[80]; - char enabled[4]; - char leaseDuration[16]; - if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost)) - return NULL; - extPort[0] = '\0'; intClient[0] = '\0'; intPort[0] = '\0'; - desc[0] = '\0'; enabled[0] = '\0'; leaseDuration[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - UPNP_GetSpecificPortMappingEntry(self->urls.controlURL, - self->data.first.servicetype, - extPort, proto, remoteHost, - intClient, intPort, - desc, enabled, leaseDuration); -Py_END_ALLOW_THREADS - if(intClient[0]) - { - iPort = (unsigned short)atoi(intPort); - return Py_BuildValue("(s,H,s,O,i)", - intClient, iPort, desc, - PyBool_FromLong(atoi(enabled)), - atoi(leaseDuration)); - } - else - { - Py_RETURN_NONE; - } -} - -/* GetGenericPortMapping(index) */ -static PyObject * -UPnP_getgenericportmapping(UPnPObject *self, PyObject *args) -{ - int i, r; - char index[8]; - char intClient[40]; - char intPort[6]; - unsigned short iPort; - char extPort[6]; - unsigned short ePort; - char protocol[4]; - char desc[80]; - char enabled[6]; - char rHost[64]; - char duration[16]; /* lease duration */ - unsigned int dur; - if(!PyArg_ParseTuple(args, "i", &i)) - return NULL; -Py_BEGIN_ALLOW_THREADS - snprintf(index, sizeof(index), "%d", i); - rHost[0] = '\0'; enabled[0] = '\0'; - duration[0] = '\0'; desc[0] = '\0'; - extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; - r = UPNP_GetGenericPortMappingEntry(self->urls.controlURL, - self->data.first.servicetype, - index, - extPort, intClient, intPort, - protocol, desc, enabled, rHost, - duration); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) - { - ePort = (unsigned short)atoi(extPort); - iPort = (unsigned short)atoi(intPort); - dur = (unsigned int)strtoul(duration, 0, 0); -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("(H,s,(s,H),s,s,s,I)", - ePort, protocol, intClient, iPort, - desc, enabled, rHost, dur); -#else - return Py_BuildValue("(i,s,(s,i),s,s,s,i)", - (int)ePort, protocol, intClient, (int)iPort, - desc, enabled, rHost, (int)dur); -#endif - } - else - { - Py_RETURN_NONE; - } -} - -/* miniupnpc.UPnP object Method Table */ -static PyMethodDef UPnP_methods[] = { - {"discover", (PyCFunction)UPnP_discover, METH_NOARGS, - "discover UPnP IGD devices on the network" - }, - {"selectigd", (PyCFunction)UPnP_selectigd, METH_NOARGS, - "select a valid UPnP IGD among discovered devices" - }, - {"totalbytesent", (PyCFunction)UPnP_totalbytesent, METH_NOARGS, - "return the total number of bytes sent by UPnP IGD" - }, - {"totalbytereceived", (PyCFunction)UPnP_totalbytereceived, METH_NOARGS, - "return the total number of bytes received by UPnP IGD" - }, - {"totalpacketsent", (PyCFunction)UPnP_totalpacketsent, METH_NOARGS, - "return the total number of packets sent by UPnP IGD" - }, - {"totalpacketreceived", (PyCFunction)UPnP_totalpacketreceived, METH_NOARGS, - "return the total number of packets received by UPnP IGD" - }, - {"statusinfo", (PyCFunction)UPnP_statusinfo, METH_NOARGS, - "return status and uptime" - }, - {"connectiontype", (PyCFunction)UPnP_connectiontype, METH_NOARGS, - "return IGD WAN connection type" - }, - {"externalipaddress", (PyCFunction)UPnP_externalipaddress, METH_NOARGS, - "return external IP address" - }, - {"addportmapping", (PyCFunction)UPnP_addportmapping, METH_VARARGS, - "add a port mapping" - }, - {"addanyportmapping", (PyCFunction)UPnP_addanyportmapping, METH_VARARGS, - "add a port mapping, IGD to select alternative if necessary" - }, - {"deleteportmapping", (PyCFunction)UPnP_deleteportmapping, METH_VARARGS, - "delete a port mapping" - }, - {"deleteportmappingrange", (PyCFunction)UPnP_deleteportmappingrange, METH_VARARGS, - "delete a range of port mappings" - }, - {"getportmappingnumberofentries", (PyCFunction)UPnP_getportmappingnumberofentries, METH_NOARGS, - "-- non standard --" - }, - {"getspecificportmapping", (PyCFunction)UPnP_getspecificportmapping, METH_VARARGS, - "get details about a specific port mapping entry" - }, - {"getgenericportmapping", (PyCFunction)UPnP_getgenericportmapping, METH_VARARGS, - "get all details about the port mapping at index" - }, - {NULL} /* Sentinel */ -}; - -static PyTypeObject UPnPType = { - PyVarObject_HEAD_INIT(NULL, - 0) /*ob_size*/ - "miniupnpc.UPnP", /*tp_name*/ - sizeof(UPnPObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)UPnPObject_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*/ - "UPnP objects", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - UPnP_methods, /* tp_methods */ - UPnP_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)UPnP_init, /* tp_init */ - 0, /* tp_alloc */ -#ifndef _WIN32 - PyType_GenericNew,/*UPnP_new,*/ /* tp_new */ -#else - 0, -#endif -}; - -/* module methods */ -static PyMethodDef miniupnpc_methods[] = { - {NULL} /* Sentinel */ -}; - -#if PY_MAJOR_VERSION >= 3 -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "miniupnpc", /* m_name */ - "miniupnpc module.", /* m_doc */ - -1, /* m_size */ - miniupnpc_methods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ -}; -#endif - -#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ -#define PyMODINIT_FUNC void -#endif - -PyMODINIT_FUNC -#if PY_MAJOR_VERSION >= 3 -PyInit_miniupnpc(void) -#else -initminiupnpc(void) -#endif -{ - PyObject* m; - -#ifdef _WIN32 - /* initialize Winsock. */ - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - - UPnPType.tp_new = PyType_GenericNew; -#endif - if (PyType_Ready(&UPnPType) < 0) -#if PY_MAJOR_VERSION >= 3 - return 0; -#else - return; -#endif - -#if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); -#else - m = Py_InitModule3("miniupnpc", miniupnpc_methods, - "miniupnpc module."); -#endif - - Py_INCREF(&UPnPType); - PyModule_AddObject(m, "UPnP", (PyObject *)&UPnPType); - -#if PY_MAJOR_VERSION >= 3 - return m; -#endif -} - diff --git a/ext/miniupnpc/miniwget.c b/ext/miniupnpc/miniwget.c deleted file mode 100644 index 0c461734f..000000000 --- a/ext/miniupnpc/miniwget.c +++ /dev/null @@ -1,675 +0,0 @@ -/* $Id: miniwget.c,v 1.77 2017/05/09 10:04:57 nanard Exp $ */ -/* Project : miniupnp - * Website : http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005-2017 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include -#include -#include -#include -#ifdef _WIN32 -#include -#include -#include -#define MAXHOSTNAMELEN 64 -#define snprintf _snprintf -#define socklen_t int -#ifndef strncasecmp -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#define strncasecmp _memicmp -#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ -#define strncasecmp memicmp -#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ -#endif /* #ifndef strncasecmp */ -#else /* #ifdef _WIN32 */ -#include -#include -#if defined(__amigaos__) && !defined(__amigaos4__) -#define socklen_t int -#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */ -#include -#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */ -#include -#include -#include -#include -#include -#define closesocket close -#include -#endif /* #else _WIN32 */ -#ifdef __GNU__ -#define MAXHOSTNAMELEN 64 -#endif /* __GNU__ */ - -#ifndef MIN -#define MIN(x,y) (((x)<(y))?(x):(y)) -#endif /* MIN */ - -#ifdef _WIN32 -#undef OS_STRING -#define OS_STRING "Win32" -#define MINIUPNPC_VERSION_STRING "2.0" -#define UPNP_VERSION_STRING "UPnP/1.1" -#endif - -#ifdef __ANDROID__ -#undef OS_STRING -#define OS_STRING "Android" -#define MINIUPNPC_VERSION_STRING "2.0" -#define UPNP_VERSION_STRING "UPnP/1.1" -#endif - -#include "miniwget.h" -#include "connecthostport.h" -#include "receivedata.h" - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -/* - * Read a HTTP response from a socket. - * Process Content-Length and Transfer-encoding headers. - * return a pointer to the content buffer, which length is saved - * to the length parameter. - */ -void * -getHTTPResponse(int s, int * size, int * status_code) -{ - char buf[2048]; - int n; - int endofheaders = 0; - int chunked = 0; - int content_length = -1; - unsigned int chunksize = 0; - unsigned int bytestocopy = 0; - /* buffers : */ - char * header_buf; - unsigned int header_buf_len = 2048; - unsigned int header_buf_used = 0; - char * content_buf; - unsigned int content_buf_len = 2048; - unsigned int content_buf_used = 0; - char chunksize_buf[32]; - unsigned int chunksize_buf_index; -#ifdef DEBUG - char * reason_phrase = NULL; - int reason_phrase_len = 0; -#endif - - if(status_code) *status_code = -1; - header_buf = malloc(header_buf_len); - if(header_buf == NULL) - { -#ifdef DEBUG - fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse"); -#endif /* DEBUG */ - *size = -1; - return NULL; - } - content_buf = malloc(content_buf_len); - if(content_buf == NULL) - { - free(header_buf); -#ifdef DEBUG - fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse"); -#endif /* DEBUG */ - *size = -1; - return NULL; - } - chunksize_buf[0] = '\0'; - chunksize_buf_index = 0; - - while((n = receivedata(s, buf, sizeof(buf), 5000, NULL)) > 0) - { - if(endofheaders == 0) - { - int i; - int linestart=0; - int colon=0; - int valuestart=0; - if(header_buf_used + n > header_buf_len) { - char * tmp = realloc(header_buf, header_buf_used + n); - if(tmp == NULL) { - /* memory allocation error */ - free(header_buf); - free(content_buf); - *size = -1; - return NULL; - } - header_buf = tmp; - header_buf_len = header_buf_used + n; - } - memcpy(header_buf + header_buf_used, buf, n); - header_buf_used += n; - /* search for CR LF CR LF (end of headers) - * recognize also LF LF */ - i = 0; - while(i < ((int)header_buf_used-1) && (endofheaders == 0)) { - if(header_buf[i] == '\r') { - i++; - if(header_buf[i] == '\n') { - i++; - if(i < (int)header_buf_used && header_buf[i] == '\r') { - i++; - if(i < (int)header_buf_used && header_buf[i] == '\n') { - endofheaders = i+1; - } - } - } - } else if(header_buf[i] == '\n') { - i++; - if(header_buf[i] == '\n') { - endofheaders = i+1; - } - } - i++; - } - if(endofheaders == 0) - continue; - /* parse header lines */ - for(i = 0; i < endofheaders - 1; i++) { - if(linestart > 0 && colon <= linestart && header_buf[i]==':') - { - colon = i; - while(i < (endofheaders-1) - && (header_buf[i+1] == ' ' || header_buf[i+1] == '\t')) - i++; - valuestart = i + 1; - } - /* detecting end of line */ - else if(header_buf[i]=='\r' || header_buf[i]=='\n') - { - if(linestart == 0 && status_code) - { - /* Status line - * HTTP-Version SP Status-Code SP Reason-Phrase CRLF */ - int sp; - for(sp = 0; sp < i; sp++) - if(header_buf[sp] == ' ') - { - if(*status_code < 0) - *status_code = atoi(header_buf + sp + 1); - else - { -#ifdef DEBUG - reason_phrase = header_buf + sp + 1; - reason_phrase_len = i - sp - 1; -#endif - break; - } - } -#ifdef DEBUG - printf("HTTP status code = %d, Reason phrase = %.*s\n", - *status_code, reason_phrase_len, reason_phrase); -#endif - } - else if(colon > linestart && valuestart > colon) - { -#ifdef DEBUG - printf("header='%.*s', value='%.*s'\n", - colon-linestart, header_buf+linestart, - i-valuestart, header_buf+valuestart); -#endif - if(0==strncasecmp(header_buf+linestart, "content-length", colon-linestart)) - { - content_length = atoi(header_buf+valuestart); -#ifdef DEBUG - printf("Content-Length: %d\n", content_length); -#endif - } - else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart) - && 0==strncasecmp(header_buf+valuestart, "chunked", 7)) - { -#ifdef DEBUG - printf("chunked transfer-encoding!\n"); -#endif - chunked = 1; - } - } - while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n')) - i++; - linestart = i; - colon = linestart; - valuestart = 0; - } - } - /* copy the remaining of the received data back to buf */ - n = header_buf_used - endofheaders; - memcpy(buf, header_buf + endofheaders, n); - /* if(headers) */ - } - if(endofheaders) - { - /* content */ - if(chunked) - { - int i = 0; - while(i < n) - { - if(chunksize == 0) - { - /* reading chunk size */ - if(chunksize_buf_index == 0) { - /* skipping any leading CR LF */ - if(i= '0' - && chunksize_buf[j] <= '9') - chunksize = (chunksize << 4) + (chunksize_buf[j] - '0'); - else - chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10); - } - chunksize_buf[0] = '\0'; - chunksize_buf_index = 0; - i++; - } else { - /* not finished to get chunksize */ - continue; - } -#ifdef DEBUG - printf("chunksize = %u (%x)\n", chunksize, chunksize); -#endif - if(chunksize == 0) - { -#ifdef DEBUG - printf("end of HTTP content - %d %d\n", i, n); - /*printf("'%.*s'\n", n-i, buf+i);*/ -#endif - goto end_of_stream; - } - } - /* it is guaranteed that (n >= i) */ - bytestocopy = (chunksize < (unsigned int)(n - i))?chunksize:(unsigned int)(n - i); - if((content_buf_used + bytestocopy) > content_buf_len) - { - char * tmp; - if((content_length >= 0) && ((unsigned int)content_length >= (content_buf_used + bytestocopy))) { - content_buf_len = content_length; - } else { - content_buf_len = content_buf_used + bytestocopy; - } - tmp = realloc(content_buf, content_buf_len); - if(tmp == NULL) { - /* memory allocation error */ - free(content_buf); - free(header_buf); - *size = -1; - return NULL; - } - content_buf = tmp; - } - memcpy(content_buf + content_buf_used, buf + i, bytestocopy); - content_buf_used += bytestocopy; - i += bytestocopy; - chunksize -= bytestocopy; - } - } - else - { - /* not chunked */ - if(content_length > 0 - && (content_buf_used + n) > (unsigned int)content_length) { - /* skipping additional bytes */ - n = content_length - content_buf_used; - } - if(content_buf_used + n > content_buf_len) - { - char * tmp; - if(content_length >= 0 - && (unsigned int)content_length >= (content_buf_used + n)) { - content_buf_len = content_length; - } else { - content_buf_len = content_buf_used + n; - } - tmp = realloc(content_buf, content_buf_len); - if(tmp == NULL) { - /* memory allocation error */ - free(content_buf); - free(header_buf); - *size = -1; - return NULL; - } - content_buf = tmp; - } - memcpy(content_buf + content_buf_used, buf, n); - content_buf_used += n; - } - } - /* use the Content-Length header value if available */ - if(content_length > 0 && content_buf_used >= (unsigned int)content_length) - { -#ifdef DEBUG - printf("End of HTTP content\n"); -#endif - break; - } - } -end_of_stream: - free(header_buf); header_buf = NULL; - *size = content_buf_used; - if(content_buf_used == 0) - { - free(content_buf); - content_buf = NULL; - } - return content_buf; -} - -/* miniwget3() : - * do all the work. - * Return NULL if something failed. */ -static void * -miniwget3(const char * host, - unsigned short port, const char * path, - int * size, char * addr_str, int addr_str_len, - const char * httpversion, unsigned int scope_id, - int * status_code) -{ - char buf[2048]; - int s; - int n; - int len; - int sent; - void * content; - - *size = 0; - s = connecthostport(host, port, scope_id); - if(s < 0) - return NULL; - - /* get address for caller ! */ - if(addr_str) - { - struct sockaddr_storage saddr; - socklen_t saddrlen; - - saddrlen = sizeof(saddr); - if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0) - { - perror("getsockname"); - } - else - { -#if defined(__amigaos__) && !defined(__amigaos4__) - /* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD); - * But his function make a string with the port : nn.nn.nn.nn:port */ -/* if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr), - NULL, addr_str, (DWORD *)&addr_str_len)) - { - printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError()); - }*/ - /* the following code is only compatible with ip v4 addresses */ - strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len); -#else -#if 0 - if(saddr.sa_family == AF_INET6) { - inet_ntop(AF_INET6, - &(((struct sockaddr_in6 *)&saddr)->sin6_addr), - addr_str, addr_str_len); - } else { - inet_ntop(AF_INET, - &(((struct sockaddr_in *)&saddr)->sin_addr), - addr_str, addr_str_len); - } -#endif - /* getnameinfo return ip v6 address with the scope identifier - * such as : 2a01:e35:8b2b:7330::%4281128194 */ - n = getnameinfo((const struct sockaddr *)&saddr, saddrlen, - addr_str, addr_str_len, - NULL, 0, - NI_NUMERICHOST | NI_NUMERICSERV); - if(n != 0) { -#ifdef _WIN32 - fprintf(stderr, "getnameinfo() failed : %d\n", n); -#else - fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n)); -#endif - } -#endif - } -#ifdef DEBUG - printf("address miniwget : %s\n", addr_str); -#endif - } - - len = snprintf(buf, sizeof(buf), - "GET %s HTTP/%s\r\n" - "Host: %s:%d\r\n" - "Connection: Close\r\n" - "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" - - "\r\n", - path, httpversion, host, port); - if ((unsigned int)len >= sizeof(buf)) - { - closesocket(s); - return NULL; - } - sent = 0; - /* sending the HTTP request */ - while(sent < len) - { - n = send(s, buf+sent, len-sent, 0); - if(n < 0) - { - perror("send"); - closesocket(s); - return NULL; - } - else - { - sent += n; - } - } - content = getHTTPResponse(s, size, status_code); - closesocket(s); - return content; -} - -/* miniwget2() : - * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */ -static void * -miniwget2(const char * host, - unsigned short port, const char * path, - int * size, char * addr_str, int addr_str_len, - unsigned int scope_id, int * status_code) -{ - char * respbuffer; - -#if 1 - respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.1", - scope_id, status_code); -#else - respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.0", - scope_id, status_code); - if (*size == 0) - { -#ifdef DEBUG - printf("Retrying with HTTP/1.1\n"); -#endif - free(respbuffer); - respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.1", - scope_id, status_code); - } -#endif - return respbuffer; -} - - - - -/* parseURL() - * arguments : - * url : source string not modified - * hostname : hostname destination string (size of MAXHOSTNAMELEN+1) - * port : port (destination) - * path : pointer to the path part of the URL - * - * Return values : - * 0 - Failure - * 1 - Success */ -int -parseURL(const char * url, - char * hostname, unsigned short * port, - char * * path, unsigned int * scope_id) -{ - char * p1, *p2, *p3; - if(!url) - return 0; - p1 = strstr(url, "://"); - if(!p1) - return 0; - p1 += 3; - if( (url[0]!='h') || (url[1]!='t') - ||(url[2]!='t') || (url[3]!='p')) - return 0; - memset(hostname, 0, MAXHOSTNAMELEN + 1); - if(*p1 == '[') - { - /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */ - char * scope; - scope = strchr(p1, '%'); - p2 = strchr(p1, ']'); - if(p2 && scope && scope < p2 && scope_id) { - /* parse scope */ -#ifdef IF_NAMESIZE - char tmp[IF_NAMESIZE]; - int l; - scope++; - /* "%25" is just '%' in URL encoding */ - if(scope[0] == '2' && scope[1] == '5') - scope += 2; /* skip "25" */ - l = p2 - scope; - if(l >= IF_NAMESIZE) - l = IF_NAMESIZE - 1; - memcpy(tmp, scope, l); - tmp[l] = '\0'; - *scope_id = if_nametoindex(tmp); - if(*scope_id == 0) { - *scope_id = (unsigned int)strtoul(tmp, NULL, 10); - } -#else - /* under windows, scope is numerical */ - char tmp[8]; - int l; - scope++; - /* "%25" is just '%' in URL encoding */ - if(scope[0] == '2' && scope[1] == '5') - scope += 2; /* skip "25" */ - l = p2 - scope; - if(l >= sizeof(tmp)) - l = sizeof(tmp) - 1; - memcpy(tmp, scope, l); - tmp[l] = '\0'; - *scope_id = (unsigned int)strtoul(tmp, NULL, 10); -#endif - } - p3 = strchr(p1, '/'); - if(p2 && p3) - { - p2++; - strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1))); - if(*p2 == ':') - { - *port = 0; - p2++; - while( (*p2 >= '0') && (*p2 <= '9')) - { - *port *= 10; - *port += (unsigned short)(*p2 - '0'); - p2++; - } - } - else - { - *port = 80; - } - *path = p3; - return 1; - } - } - p2 = strchr(p1, ':'); - p3 = strchr(p1, '/'); - if(!p3) - return 0; - if(!p2 || (p2>p3)) - { - strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1))); - *port = 80; - } - else - { - strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1))); - *port = 0; - p2++; - while( (*p2 >= '0') && (*p2 <= '9')) - { - *port *= 10; - *port += (unsigned short)(*p2 - '0'); - p2++; - } - } - *path = p3; - return 1; -} - -void * -miniwget(const char * url, int * size, - unsigned int scope_id, int * status_code) -{ - unsigned short port; - char * path; - /* protocol://host:port/chemin */ - char hostname[MAXHOSTNAMELEN+1]; - *size = 0; - if(!parseURL(url, hostname, &port, &path, &scope_id)) - return NULL; -#ifdef DEBUG - printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", - hostname, port, path, scope_id); -#endif - return miniwget2(hostname, port, path, size, 0, 0, scope_id, status_code); -} - -void * -miniwget_getaddr(const char * url, int * size, - char * addr, int addrlen, unsigned int scope_id, - int * status_code) -{ - unsigned short port; - char * path; - /* protocol://host:port/path */ - char hostname[MAXHOSTNAMELEN+1]; - *size = 0; - if(addr) - addr[0] = '\0'; - if(!parseURL(url, hostname, &port, &path, &scope_id)) - return NULL; -#ifdef DEBUG - printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", - hostname, port, path, scope_id); -#endif - return miniwget2(hostname, port, path, size, addr, addrlen, scope_id, status_code); -} - diff --git a/ext/miniupnpc/minixml.c b/ext/miniupnpc/minixml.c deleted file mode 100644 index 935ec443e..000000000 --- a/ext/miniupnpc/minixml.c +++ /dev/null @@ -1,231 +0,0 @@ -/* $Id: minixml.c,v 1.12 2017/12/12 11:17:40 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * minixml.c : the minimum size a xml parser can be ! */ -/* Project : miniupnp - * webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author : Thomas Bernard - -Copyright (c) 2005-2017, 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 "minixml.h" - -/* parseatt : used to parse the argument list - * return 0 (false) in case of success and -1 (true) if the end - * of the xmlbuffer is reached. */ -static int parseatt(struct xmlparser * p) -{ - const char * attname; - int attnamelen; - const char * attvalue; - int attvaluelen; - while(p->xml < p->xmlend) - { - if(*p->xml=='/' || *p->xml=='>') - return 0; - if( !IS_WHITE_SPACE(*p->xml) ) - { - char sep; - attname = p->xml; - attnamelen = 0; - while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) ) - { - attnamelen++; p->xml++; - if(p->xml >= p->xmlend) - return -1; - } - while(*(p->xml++) != '=') - { - if(p->xml >= p->xmlend) - return -1; - } - while(IS_WHITE_SPACE(*p->xml)) - { - p->xml++; - if(p->xml >= p->xmlend) - return -1; - } - sep = *p->xml; - if(sep=='\'' || sep=='\"') - { - p->xml++; - if(p->xml >= p->xmlend) - return -1; - attvalue = p->xml; - attvaluelen = 0; - while(*p->xml != sep) - { - attvaluelen++; p->xml++; - if(p->xml >= p->xmlend) - return -1; - } - } - else - { - attvalue = p->xml; - attvaluelen = 0; - while( !IS_WHITE_SPACE(*p->xml) - && *p->xml != '>' && *p->xml != '/') - { - attvaluelen++; p->xml++; - if(p->xml >= p->xmlend) - return -1; - } - } - /*printf("%.*s='%.*s'\n", - attnamelen, attname, attvaluelen, attvalue);*/ - if(p->attfunc) - p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen); - } - p->xml++; - } - return -1; -} - -/* parseelt parse the xml stream and - * call the callback functions when needed... */ -static void parseelt(struct xmlparser * p) -{ - int i; - const char * elementname; - while(p->xml < (p->xmlend - 1)) - { - if((p->xml + 4) <= p->xmlend && (0 == memcmp(p->xml, "", 3) != 0); - p->xml += 3; - } - else if((p->xml)[0]=='<' && (p->xml)[1]!='?') - { - i = 0; elementname = ++p->xml; - while( !IS_WHITE_SPACE(*p->xml) - && (*p->xml!='>') && (*p->xml!='/') - ) - { - i++; p->xml++; - if (p->xml >= p->xmlend) - return; - /* to ignore namespace : */ - if(*p->xml==':') - { - i = 0; - elementname = ++p->xml; - } - } - if(i>0) - { - if(p->starteltfunc) - p->starteltfunc(p->data, elementname, i); - if(parseatt(p)) - return; - if(*p->xml!='/') - { - const char * data; - i = 0; data = ++p->xml; - if (p->xml >= p->xmlend) - return; - while( IS_WHITE_SPACE(*p->xml) ) - { - i++; p->xml++; - if (p->xml >= p->xmlend) - return; - } - /* CDATA are at least 9 + 3 characters long : */ - if((p->xmlend >= (p->xml + (9 + 3))) && (memcmp(p->xml, "xml += 9; - data = p->xml; - i = 0; - while(memcmp(p->xml, "]]>", 3) != 0) - { - i++; p->xml++; - if ((p->xml + 3) >= p->xmlend) - return; - } - if(i>0 && p->datafunc) - p->datafunc(p->data, data, i); - while(*p->xml!='<') - { - p->xml++; - if (p->xml >= p->xmlend) - return; - } - } - else - { - while(*p->xml!='<') - { - i++; p->xml++; - if ((p->xml + 1) >= p->xmlend) - return; - } - if(i>0 && p->datafunc && *(p->xml + 1) == '/') - p->datafunc(p->data, data, i); - } - } - } - else if(*p->xml == '/') - { - i = 0; elementname = ++p->xml; - if (p->xml >= p->xmlend) - return; - while((*p->xml != '>')) - { - i++; p->xml++; - if (p->xml >= p->xmlend) - return; - } - if(p->endeltfunc) - p->endeltfunc(p->data, elementname, i); - p->xml++; - } - } - else - { - p->xml++; - } - } -} - -/* the parser must be initialized before calling this function */ -void parsexml(struct xmlparser * parser) -{ - parser->xml = parser->xmlstart; - parser->xmlend = parser->xmlstart + parser->xmlsize; - parseelt(parser); -} - - diff --git a/ext/miniupnpc/minixmlvalid.c b/ext/miniupnpc/minixmlvalid.c deleted file mode 100644 index dad148812..000000000 --- a/ext/miniupnpc/minixmlvalid.c +++ /dev/null @@ -1,163 +0,0 @@ -/* $Id: minixmlvalid.c,v 1.7 2015/07/15 12:41:15 nanard Exp $ */ -/* MiniUPnP Project - * http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/ - * minixmlvalid.c : - * validation program for the minixml parser - * - * (c) 2006-2011 Thomas Bernard */ - -#include -#include -#include -#include "minixml.h" - -/* xml event structure */ -struct event { - enum { ELTSTART, ELTEND, ATT, CHARDATA } type; - const char * data; - int len; -}; - -struct eventlist { - int n; - struct event * events; -}; - -/* compare 2 xml event lists - * return 0 if the two lists are equals */ -int evtlistcmp(struct eventlist * a, struct eventlist * b) -{ - int i; - struct event * ae, * be; - if(a->n != b->n) - { - printf("event number not matching : %d != %d\n", a->n, b->n); - /*return 1;*/ - } - for(i=0; in; i++) - { - ae = a->events + i; - be = b->events + i; - if( (ae->type != be->type) - ||(ae->len != be->len) - ||memcmp(ae->data, be->data, ae->len)) - { - printf("Found a difference : %d '%.*s' != %d '%.*s'\n", - ae->type, ae->len, ae->data, - be->type, be->len, be->data); - return 1; - } - } - return 0; -} - -/* Test data */ -static const char xmldata[] = -"\n" -" " -"character data" -" \n \t" -"" -"\nstuff !\n ]]> \n\n" -" \tchardata1 chardata2 " -""; - -static const struct event evtref[] = -{ - {ELTSTART, "xmlroot", 7}, - {ELTSTART, "elt1", 4}, - /* attributes */ - {CHARDATA, "character data", 14}, - {ELTEND, "elt1", 4}, - {ELTSTART, "elt1b", 5}, - {ELTSTART, "elt1", 4}, - {CHARDATA, " stuff !\n ", 16}, - {ELTEND, "elt1", 4}, - {ELTSTART, "elt2a", 5}, - {ELTSTART, "elt2b", 5}, - {CHARDATA, "chardata1", 9}, - {ELTEND, "elt2b", 5}, - {ELTSTART, "elt2b", 5}, - {CHARDATA, " chardata2 ", 11}, - {ELTEND, "elt2b", 5}, - {ELTEND, "elt2a", 5}, - {ELTEND, "xmlroot", 7} -}; - -void startelt(void * data, const char * p, int l) -{ - struct eventlist * evtlist = data; - struct event * evt; - evt = evtlist->events + evtlist->n; - /*printf("startelt : %.*s\n", l, p);*/ - evt->type = ELTSTART; - evt->data = p; - evt->len = l; - evtlist->n++; -} - -void endelt(void * data, const char * p, int l) -{ - struct eventlist * evtlist = data; - struct event * evt; - evt = evtlist->events + evtlist->n; - /*printf("endelt : %.*s\n", l, p);*/ - evt->type = ELTEND; - evt->data = p; - evt->len = l; - evtlist->n++; -} - -void chardata(void * data, const char * p, int l) -{ - struct eventlist * evtlist = data; - struct event * evt; - evt = evtlist->events + evtlist->n; - /*printf("chardata : '%.*s'\n", l, p);*/ - evt->type = CHARDATA; - evt->data = p; - evt->len = l; - evtlist->n++; -} - -int testxmlparser(const char * xml, int size) -{ - int r; - struct eventlist evtlist; - struct eventlist evtlistref; - struct xmlparser parser; - evtlist.n = 0; - evtlist.events = malloc(sizeof(struct event)*100); - if(evtlist.events == NULL) - { - fprintf(stderr, "Memory allocation error.\n"); - return -1; - } - memset(&parser, 0, sizeof(parser)); - parser.xmlstart = xml; - parser.xmlsize = size; - parser.data = &evtlist; - parser.starteltfunc = startelt; - parser.endeltfunc = endelt; - parser.datafunc = chardata; - parsexml(&parser); - printf("%d events\n", evtlist.n); - /* compare */ - evtlistref.n = sizeof(evtref)/sizeof(struct event); - evtlistref.events = (struct event *)evtref; - r = evtlistcmp(&evtlistref, &evtlist); - free(evtlist.events); - return r; -} - -int main(int argc, char * * argv) -{ - int r; - (void)argc; (void)argv; - - r = testxmlparser(xmldata, sizeof(xmldata)-1); - if(r) - printf("minixml validation test failed\n"); - return r; -} - diff --git a/ext/miniupnpc/portlistingparse.c b/ext/miniupnpc/portlistingparse.c deleted file mode 100644 index d1954f59f..000000000 --- a/ext/miniupnpc/portlistingparse.c +++ /dev/null @@ -1,172 +0,0 @@ -/* $Id: portlistingparse.c,v 1.10 2016/12/16 08:53:21 nanard Exp $ */ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2011-2016 Thomas Bernard - * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ -#include -#include -#ifdef DEBUG -#include -#endif /* DEBUG */ -#include "portlistingparse.h" -#include "minixml.h" - -/* list of the elements */ -static const struct { - const portMappingElt code; - const char * const str; -} elements[] = { - { PortMappingEntry, "PortMappingEntry"}, - { NewRemoteHost, "NewRemoteHost"}, - { NewExternalPort, "NewExternalPort"}, - { NewProtocol, "NewProtocol"}, - { NewInternalPort, "NewInternalPort"}, - { NewInternalClient, "NewInternalClient"}, - { NewEnabled, "NewEnabled"}, - { NewDescription, "NewDescription"}, - { NewLeaseTime, "NewLeaseTime"}, - { PortMappingEltNone, NULL} -}; - -/* Helper function */ -static UNSIGNED_INTEGER -atoui(const char * p, int l) -{ - UNSIGNED_INTEGER r = 0; - while(l > 0 && *p) - { - if(*p >= '0' && *p <= '9') - r = r*10 + (*p - '0'); - else - break; - p++; - l--; - } - return r; -} - -/* Start element handler */ -static void -startelt(void * d, const char * name, int l) -{ - int i; - struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; - pdata->curelt = PortMappingEltNone; - for(i = 0; elements[i].str; i++) - { - if(strlen(elements[i].str) == (size_t)l && memcmp(name, elements[i].str, l) == 0) - { - pdata->curelt = elements[i].code; - break; - } - } - if(pdata->curelt == PortMappingEntry) - { - struct PortMapping * pm; - pm = calloc(1, sizeof(struct PortMapping)); - if(pm == NULL) - { - /* malloc error */ -#ifdef DEBUG - fprintf(stderr, "%s: error allocating memory", - "startelt"); -#endif /* DEBUG */ - return; - } - pm->l_next = pdata->l_head; /* insert in list */ - pdata->l_head = pm; - } -} - -/* End element handler */ -static void -endelt(void * d, const char * name, int l) -{ - struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; - (void)name; - (void)l; - pdata->curelt = PortMappingEltNone; -} - -/* Data handler */ -static void -data(void * d, const char * data, int l) -{ - struct PortMapping * pm; - struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; - pm = pdata->l_head; - if(!pm) - return; - if(l > 63) - l = 63; - switch(pdata->curelt) - { - case NewRemoteHost: - memcpy(pm->remoteHost, data, l); - pm->remoteHost[l] = '\0'; - break; - case NewExternalPort: - pm->externalPort = (unsigned short)atoui(data, l); - break; - case NewProtocol: - if(l > 3) - l = 3; - memcpy(pm->protocol, data, l); - pm->protocol[l] = '\0'; - break; - case NewInternalPort: - pm->internalPort = (unsigned short)atoui(data, l); - break; - case NewInternalClient: - memcpy(pm->internalClient, data, l); - pm->internalClient[l] = '\0'; - break; - case NewEnabled: - pm->enabled = (unsigned char)atoui(data, l); - break; - case NewDescription: - memcpy(pm->description, data, l); - pm->description[l] = '\0'; - break; - case NewLeaseTime: - pm->leaseTime = atoui(data, l); - break; - default: - break; - } -} - - -/* Parse the PortMappingList XML document for IGD version 2 - */ -void -ParsePortListing(const char * buffer, int bufsize, - struct PortMappingParserData * pdata) -{ - struct xmlparser parser; - - memset(pdata, 0, sizeof(struct PortMappingParserData)); - /* init xmlparser */ - parser.xmlstart = buffer; - parser.xmlsize = bufsize; - parser.data = pdata; - parser.starteltfunc = startelt; - parser.endeltfunc = endelt; - parser.datafunc = data; - parser.attfunc = 0; - parsexml(&parser); -} - -void -FreePortListing(struct PortMappingParserData * pdata) -{ - struct PortMapping * pm; - while((pm = pdata->l_head) != NULL) - { - /* remove from list */ - pdata->l_head = pm->l_next; - free(pm); - } -} - diff --git a/ext/miniupnpc/receivedata.c b/ext/miniupnpc/receivedata.c deleted file mode 100644 index 5dbd227b2..000000000 --- a/ext/miniupnpc/receivedata.c +++ /dev/null @@ -1,105 +0,0 @@ -/* $Id: receivedata.c,v 1.8 2017/04/21 10:16:45 nanard Exp $ */ -/* Project : miniupnp - * Website : http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2011-2014 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include -#include -#ifdef _WIN32 -#include -#include -#else /* _WIN32 */ -#include -#if defined(__amigaos__) && !defined(__amigaos4__) -#define socklen_t int -#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */ -#include -#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */ -#include -#include -#if !defined(__amigaos__) && !defined(__amigaos4__) -#include -#endif /* !defined(__amigaos__) && !defined(__amigaos4__) */ -#include -#define MINIUPNPC_IGNORE_EINTR -#endif /* _WIN32 */ - -#ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); -#else -#define PRINT_SOCKET_ERROR(x) perror(x) -#endif - -#include "receivedata.h" - -int -receivedata(int socket, - char * data, int length, - int timeout, unsigned int * scope_id) -{ -#ifdef MINIUPNPC_GET_SRC_ADDR - struct sockaddr_storage src_addr; - socklen_t src_addr_len = sizeof(src_addr); -#endif /* MINIUPNPC_GET_SRC_ADDR */ - int n; -#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) - /* using poll */ - struct pollfd fds[1]; /* for the poll */ -#ifdef MINIUPNPC_IGNORE_EINTR - do { -#endif /* MINIUPNPC_IGNORE_EINTR */ - fds[0].fd = socket; - fds[0].events = POLLIN; - n = poll(fds, 1, timeout); -#ifdef MINIUPNPC_IGNORE_EINTR - } while(n < 0 && errno == EINTR); -#endif /* MINIUPNPC_IGNORE_EINTR */ - if(n < 0) { - PRINT_SOCKET_ERROR("poll"); - return -1; - } else if(n == 0) { - /* timeout */ - return 0; - } -#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ - /* using select under _WIN32 and amigaos */ - fd_set socketSet; - TIMEVAL timeval; - FD_ZERO(&socketSet); - FD_SET(socket, &socketSet); - timeval.tv_sec = timeout / 1000; - timeval.tv_usec = (timeout % 1000) * 1000; - n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval); - if(n < 0) { - PRINT_SOCKET_ERROR("select"); - return -1; - } else if(n == 0) { - return 0; - } -#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ -#ifdef MINIUPNPC_GET_SRC_ADDR - memset(&src_addr, 0, sizeof(src_addr)); - n = recvfrom(socket, data, length, 0, - (struct sockaddr *)&src_addr, &src_addr_len); -#else /* MINIUPNPC_GET_SRC_ADDR */ - n = recv(socket, data, length, 0); -#endif /* MINIUPNPC_GET_SRC_ADDR */ - if(n<0) { - PRINT_SOCKET_ERROR("recv"); - } -#ifdef MINIUPNPC_GET_SRC_ADDR - if (src_addr.ss_family == AF_INET6) { - const struct sockaddr_in6 * src_addr6 = (struct sockaddr_in6 *)&src_addr; -#ifdef DEBUG - printf("scope_id=%u\n", src_addr6->sin6_scope_id); -#endif /* DEBUG */ - if(scope_id) - *scope_id = src_addr6->sin6_scope_id; - } -#endif /* MINIUPNPC_GET_SRC_ADDR */ - return n; -} - diff --git a/ext/miniupnpc/updateminiupnpcstrings.sh b/ext/miniupnpc/updateminiupnpcstrings.sh deleted file mode 100755 index dde4354a8..000000000 --- a/ext/miniupnpc/updateminiupnpcstrings.sh +++ /dev/null @@ -1,53 +0,0 @@ -#! /bin/sh -# $Id: updateminiupnpcstrings.sh,v 1.7 2011/01/04 11:41:53 nanard Exp $ -# project miniupnp : http://miniupnp.free.fr/ -# (c) 2009 Thomas Bernard - -FILE=miniupnpcstrings.h -TMPFILE=miniupnpcstrings.h.tmp -TEMPLATE_FILE=${FILE}.in - -# detecting the OS name and version -OS_NAME=`uname -s` -OS_VERSION=`uname -r` -if [ -f /etc/debian_version ]; then - OS_NAME=Debian - OS_VERSION=`cat /etc/debian_version` -fi -# use lsb_release (Linux Standard Base) when available -LSB_RELEASE=`which lsb_release` -if [ 0 -eq $? -a -x "${LSB_RELEASE}" ]; then - OS_NAME=`${LSB_RELEASE} -i -s` - OS_VERSION=`${LSB_RELEASE} -r -s` - case $OS_NAME in - Debian) - #OS_VERSION=`${LSB_RELEASE} -c -s` - ;; - Ubuntu) - #OS_VERSION=`${LSB_RELEASE} -c -s` - ;; - esac -fi - -# on AmigaOS 3, uname -r returns "unknown", so we use uname -v -if [ "$OS_NAME" = "AmigaOS" ]; then - if [ "$OS_VERSION" = "unknown" ]; then - OS_VERSION=`uname -v` - fi -fi - -echo "Detected OS [$OS_NAME] version [$OS_VERSION]" -MINIUPNPC_VERSION=`cat VERSION` -echo "MiniUPnPc version [${MINIUPNPC_VERSION}]" - -EXPR="s|OS_STRING \".*\"|OS_STRING \"${OS_NAME}/${OS_VERSION}\"|" -#echo $EXPR -test -f ${FILE}.in -echo "setting OS_STRING macro value to ${OS_NAME}/${OS_VERSION} in $FILE." -sed -e "$EXPR" < $TEMPLATE_FILE > $TMPFILE - -EXPR="s|MINIUPNPC_VERSION_STRING \".*\"|MINIUPNPC_VERSION_STRING \"${MINIUPNPC_VERSION}\"|" -echo "setting MINIUPNPC_VERSION_STRING macro value to ${MINIUPNPC_VERSION} in $FILE." -sed -e "$EXPR" < $TMPFILE > $FILE -rm $TMPFILE - diff --git a/ext/miniupnpc/upnpc.c b/ext/miniupnpc/upnpc.c deleted file mode 100644 index e719ecec5..000000000 --- a/ext/miniupnpc/upnpc.c +++ /dev/null @@ -1,857 +0,0 @@ -/* $Id: upnpc.c,v 1.117 2017/05/26 15:26:55 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005-2017 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include -#include -#include -#include -#ifdef _WIN32 -#include -#define snprintf _snprintf -#else -/* for IPPROTO_TCP / IPPROTO_UDP */ -#include -#endif -#include -#include "miniwget.h" -#include "miniupnpc.h" -#include "upnpcommands.h" -#include "upnperrors.h" -#include "miniupnpcstrings.h" - -/* protofix() checks if protocol is "UDP" or "TCP" - * returns NULL if not */ -const char * protofix(const char * proto) -{ - static const char proto_tcp[4] = { 'T', 'C', 'P', 0}; - static const char proto_udp[4] = { 'U', 'D', 'P', 0}; - int i, b; - for(i=0, b=1; i<4; i++) - b = b && ( (proto[i] == proto_tcp[i]) - || (proto[i] == (proto_tcp[i] | 32)) ); - if(b) - return proto_tcp; - for(i=0, b=1; i<4; i++) - b = b && ( (proto[i] == proto_udp[i]) - || (proto[i] == (proto_udp[i] | 32)) ); - if(b) - return proto_udp; - return 0; -} - -/* is_int() checks if parameter is an integer or not - * 1 for integer - * 0 for not an integer */ -int is_int(char const* s) -{ - if(s == NULL) - return 0; - while(*s) { - /* #define isdigit(c) ((c) >= '0' && (c) <= '9') */ - if(!isdigit(*s)) - return 0; - s++; - } - return 1; -} - -static void DisplayInfos(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - char externalIPAddress[40]; - char connectionType[64]; - char status[64]; - char lastconnerr[64]; - unsigned int uptime = 0; - unsigned int brUp, brDown; - time_t timenow, timestarted; - int r; - if(UPNP_GetConnectionTypeInfo(urls->controlURL, - data->first.servicetype, - connectionType) != UPNPCOMMAND_SUCCESS) - printf("GetConnectionTypeInfo failed.\n"); - else - printf("Connection Type : %s\n", connectionType); - if(UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, - status, &uptime, lastconnerr) != UPNPCOMMAND_SUCCESS) - printf("GetStatusInfo failed.\n"); - else - printf("Status : %s, uptime=%us, LastConnectionError : %s\n", - status, uptime, lastconnerr); - if(uptime > 0) { - timenow = time(NULL); - timestarted = timenow - uptime; - printf(" Time started : %s", ctime(×tarted)); - } - if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype, - &brDown, &brUp) != UPNPCOMMAND_SUCCESS) { - printf("GetLinkLayerMaxBitRates failed.\n"); - } else { - printf("MaxBitRateDown : %u bps", brDown); - if(brDown >= 1000000) { - printf(" (%u.%u Mbps)", brDown / 1000000, (brDown / 100000) % 10); - } else if(brDown >= 1000) { - printf(" (%u Kbps)", brDown / 1000); - } - printf(" MaxBitRateUp %u bps", brUp); - if(brUp >= 1000000) { - printf(" (%u.%u Mbps)", brUp / 1000000, (brUp / 100000) % 10); - } else if(brUp >= 1000) { - printf(" (%u Kbps)", brUp / 1000); - } - printf("\n"); - } - r = UPNP_GetExternalIPAddress(urls->controlURL, - data->first.servicetype, - externalIPAddress); - if(r != UPNPCOMMAND_SUCCESS) { - printf("GetExternalIPAddress failed. (errorcode=%d)\n", r); - } else { - printf("ExternalIPAddress = %s\n", externalIPAddress); - } -} - -static void GetConnectionStatus(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - unsigned int bytessent, bytesreceived, packetsreceived, packetssent; - DisplayInfos(urls, data); - bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype); - bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype); - packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype); - packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype); - printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived); - printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived); -} - -static void ListRedirections(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - int r; - int i = 0; - char index[6]; - char intClient[40]; - char intPort[6]; - char extPort[6]; - char protocol[4]; - char desc[80]; - char enabled[6]; - char rHost[64]; - char duration[16]; - /*unsigned int num=0; - UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num); - printf("PortMappingNumberOfEntries : %u\n", num);*/ - printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n"); - do { - snprintf(index, 6, "%d", i); - rHost[0] = '\0'; enabled[0] = '\0'; - duration[0] = '\0'; desc[0] = '\0'; - extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; - r = UPNP_GetGenericPortMappingEntry(urls->controlURL, - data->first.servicetype, - index, - extPort, intClient, intPort, - protocol, desc, enabled, - rHost, duration); - if(r==0) - /* - printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n" - " desc='%s' rHost='%s'\n", - i, protocol, extPort, intClient, intPort, - enabled, duration, - desc, rHost); - */ - printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n", - i, protocol, extPort, intClient, intPort, - desc, rHost, duration); - else - printf("GetGenericPortMappingEntry() returned %d (%s)\n", - r, strupnperror(r)); - i++; - } while(r==0); -} - -static void NewListRedirections(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - int r; - int i = 0; - struct PortMappingParserData pdata; - struct PortMapping * pm; - - memset(&pdata, 0, sizeof(struct PortMappingParserData)); - r = UPNP_GetListOfPortMappings(urls->controlURL, - data->first.servicetype, - "0", - "65535", - "TCP", - "1000", - &pdata); - if(r == UPNPCOMMAND_SUCCESS) - { - printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n"); - for(pm = pdata.l_head; pm != NULL; pm = pm->l_next) - { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost, - (unsigned)pm->leaseTime); - i++; - } - FreePortListing(&pdata); - } - else - { - printf("GetListOfPortMappings() returned %d (%s)\n", - r, strupnperror(r)); - } - r = UPNP_GetListOfPortMappings(urls->controlURL, - data->first.servicetype, - "0", - "65535", - "UDP", - "1000", - &pdata); - if(r == UPNPCOMMAND_SUCCESS) - { - for(pm = pdata.l_head; pm != NULL; pm = pm->l_next) - { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost, - (unsigned)pm->leaseTime); - i++; - } - FreePortListing(&pdata); - } - else - { - printf("GetListOfPortMappings() returned %d (%s)\n", - r, strupnperror(r)); - } -} - -/* Test function - * 1 - get connection type - * 2 - get extenal ip address - * 3 - Add port mapping - * 4 - get this port mapping from the IGD */ -static int SetRedirectAndTest(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * iaddr, - const char * iport, - const char * eport, - const char * proto, - const char * leaseDuration, - const char * description, - int addAny) -{ - char externalIPAddress[40]; - char intClient[40]; - char intPort[6]; - char reservedPort[6]; - char duration[16]; - int r; - - if(!iaddr || !iport || !eport || !proto) - { - fprintf(stderr, "Wrong arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "invalid protocol\n"); - return -1; - } - - r = UPNP_GetExternalIPAddress(urls->controlURL, - data->first.servicetype, - externalIPAddress); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetExternalIPAddress failed.\n"); - else - printf("ExternalIPAddress = %s\n", externalIPAddress); - - if (addAny) { - r = UPNP_AddAnyPortMapping(urls->controlURL, data->first.servicetype, - eport, iport, iaddr, description, - proto, 0, leaseDuration, reservedPort); - if(r==UPNPCOMMAND_SUCCESS) - eport = reservedPort; - else - printf("AddAnyPortMapping(%s, %s, %s) failed with code %d (%s)\n", - eport, iport, iaddr, r, strupnperror(r)); - } else { - r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, - eport, iport, iaddr, description, - proto, 0, leaseDuration); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - eport, iport, iaddr, r, strupnperror(r)); - return -2; - } - } - - r = UPNP_GetSpecificPortMappingEntry(urls->controlURL, - data->first.servicetype, - eport, proto, NULL/*remoteHost*/, - intClient, intPort, NULL/*desc*/, - NULL/*enabled*/, duration); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n", - r, strupnperror(r)); - return -2; - } else { - printf("InternalIP:Port = %s:%s\n", intClient, intPort); - printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n", - externalIPAddress, eport, proto, intClient, intPort, duration); - } - return 0; -} - -static int -RemoveRedirect(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * eport, - const char * proto, - const char * remoteHost) -{ - int r; - if(!proto || !eport) - { - fprintf(stderr, "invalid arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "protocol invalid\n"); - return -1; - } - r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, remoteHost); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("UPNP_DeletePortMapping() failed with code : %d\n", r); - return -2; - }else { - printf("UPNP_DeletePortMapping() returned : %d\n", r); - } - return 0; -} - -static int -RemoveRedirectRange(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * ePortStart, char const * ePortEnd, - const char * proto, const char * manage) -{ - int r; - - if (!manage) - manage = "0"; - - if(!proto || !ePortStart || !ePortEnd) - { - fprintf(stderr, "invalid arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "protocol invalid\n"); - return -1; - } - r = UPNP_DeletePortMappingRange(urls->controlURL, data->first.servicetype, ePortStart, ePortEnd, proto, manage); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("UPNP_DeletePortMappingRange() failed with code : %d\n", r); - return -2; - }else { - printf("UPNP_DeletePortMappingRange() returned : %d\n", r); - } - return 0; -} - -/* IGD:2, functions for service WANIPv6FirewallControl:1 */ -static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data) -{ - unsigned int bytessent, bytesreceived, packetsreceived, packetssent; - int firewallEnabled = 0, inboundPinholeAllowed = 0; - - UPNP_GetFirewallStatus(urls->controlURL_6FC, data->IPv6FC.servicetype, &firewallEnabled, &inboundPinholeAllowed); - printf("FirewallEnabled: %d & Inbound Pinhole Allowed: %d\n", firewallEnabled, inboundPinholeAllowed); - printf("GetFirewallStatus:\n Firewall Enabled: %s\n Inbound Pinhole Allowed: %s\n", (firewallEnabled)? "Yes":"No", (inboundPinholeAllowed)? "Yes":"No"); - - bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype); - bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype); - packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype); - packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype); - printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived); - printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived); -} - -/* Test function - * 1 - Add pinhole - * 2 - Check if pinhole is working from the IGD side */ -static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data, - const char * remoteaddr, const char * eport, - const char * intaddr, const char * iport, - const char * proto, const char * lease_time) -{ - char uniqueID[8]; - /*int isWorking = 0;*/ - int r; - char proto_tmp[8]; - - if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - if(atoi(proto) == 0) - { - const char * protocol; - protocol = protofix(proto); - if(protocol && (strcmp("TCP", protocol) == 0)) - { - snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_TCP); - proto = proto_tmp; - } - else if(protocol && (strcmp("UDP", protocol) == 0)) - { - snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_UDP); - proto = proto_tmp; - } - else - { - fprintf(stderr, "invalid protocol\n"); - return; - } - } - r = UPNP_AddPinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, lease_time, uniqueID); - if(r!=UPNPCOMMAND_SUCCESS) - printf("AddPinhole([%s]:%s -> [%s]:%s) failed with code %d (%s)\n", - remoteaddr, eport, intaddr, iport, r, strupnperror(r)); - else - { - printf("AddPinhole: ([%s]:%s -> [%s]:%s) / Pinhole ID = %s\n", - remoteaddr, eport, intaddr, iport, uniqueID); - /*r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->servicetype_6FC, uniqueID, &isWorking); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");*/ - } -} - -/* Test function - * 1 - Check if pinhole is working from the IGD side - * 2 - Update pinhole */ -static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data, - const char * uniqueID, const char * lease_time) -{ - int isWorking = 0; - int r; - - if(!uniqueID || !lease_time) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking); - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - if(isWorking || r==709) - { - r = UPNP_UpdatePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, lease_time); - printf("UpdatePinhole: Pinhole ID = %s with Lease Time: %s\n", uniqueID, lease_time); - if(r!=UPNPCOMMAND_SUCCESS) - printf("UpdatePinhole: ID (%s) failed with code %d (%s)\n", uniqueID, r, strupnperror(r)); - } -} - -/* Test function - * Get pinhole timeout - */ -static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data, - const char * remoteaddr, const char * eport, - const char * intaddr, const char * iport, - const char * proto) -{ - int timeout = 0; - int r; - - if(!intaddr || !remoteaddr || !iport || !eport || !proto) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - - r = UPNP_GetOutboundPinholeTimeout(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, &timeout); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetOutboundPinholeTimeout([%s]:%s -> [%s]:%s) failed with code %d (%s)\n", - intaddr, iport, remoteaddr, eport, r, strupnperror(r)); - else - printf("GetOutboundPinholeTimeout: ([%s]:%s -> [%s]:%s) / Timeout = %d\n", intaddr, iport, remoteaddr, eport, timeout); -} - -static void -GetPinholePackets(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r, pinholePackets = 0; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_GetPinholePackets(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &pinholePackets); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetPinholePackets() failed with code %d (%s)\n", r, strupnperror(r)); - else - printf("GetPinholePackets: Pinhole ID = %s / PinholePackets = %d\n", uniqueID, pinholePackets); -} - -static void -CheckPinhole(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r, isWorking = 0; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - else - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); -} - -static void -RemovePinhole(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_DeletePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID); - printf("UPNP_DeletePinhole() returned : %d\n", r); -} - - -/* sample upnp client program */ -int main(int argc, char ** argv) -{ - char command = 0; - char ** commandargv = 0; - int commandargc = 0; - struct UPNPDev * devlist = 0; - char lanaddr[64] = "unset"; /* my ip address on the LAN */ - int i; - const char * rootdescurl = 0; - const char * multicastif = 0; - const char * minissdpdpath = 0; - int localport = UPNP_LOCAL_PORT_ANY; - int retcode = 0; - int error = 0; - int ipv6 = 0; - unsigned char ttl = 2; /* defaulting to 2 */ - const char * description = 0; - -#ifdef _WIN32 - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if(nResult != NO_ERROR) - { - fprintf(stderr, "WSAStartup() failed.\n"); - return -1; - } -#endif - printf("upnpc : miniupnpc library test client, version %s.\n", MINIUPNPC_VERSION_STRING); - printf(" (c) 2005-2017 Thomas Bernard.\n"); - printf("Go to http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/\n" - "for more information.\n"); - /* command line processing */ - for(i=1; i65535 || - (localport >1 && localport < 1024)) - { - fprintf(stderr, "Invalid localport '%s'\n", argv[i]); - localport = UPNP_LOCAL_PORT_ANY; - break; - } - } - else if(argv[i][1] == 'p') - minissdpdpath = argv[++i]; - else if(argv[i][1] == '6') - ipv6 = 1; - else if(argv[i][1] == 'e') - description = argv[++i]; - else if(argv[i][1] == 't') - ttl = (unsigned char)atoi(argv[++i]); - else - { - command = argv[i][1]; - i++; - commandargv = argv + i; - commandargc = argc - i; - break; - } - } - else - { - fprintf(stderr, "option '%s' invalid\n", argv[i]); - } - } - - if(!command - || (command == 'a' && commandargc<4) - || (command == 'd' && argc<2) - || (command == 'r' && argc<2) - || (command == 'A' && commandargc<6) - || (command == 'U' && commandargc<2) - || (command == 'D' && commandargc<1)) - { - fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol [duration]\n\t\tAdd port redirection\n", argv[0]); - fprintf(stderr, " \t%s [options] -d external_port protocol \n\t\tDelete port redirection\n", argv[0]); - fprintf(stderr, " \t%s [options] -s\n\t\tGet Connection status\n", argv[0]); - fprintf(stderr, " \t%s [options] -l\n\t\tList redirections\n", argv[0]); - fprintf(stderr, " \t%s [options] -L\n\t\tList redirections (using GetListOfPortMappings (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -n ip port external_port protocol [duration]\n\t\tAdd (any) port redirection allowing IGD to use alternative external_port (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -N external_port_start external_port_end protocol [manage]\n\t\tDelete range of port redirections (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -r port1 [external_port1] protocol1 [port2 [external_port2] protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]); - fprintf(stderr, " \t%s [options] -A remote_ip remote_port internal_ip internal_port protocol lease_time\n\t\tAdd Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -U uniqueID new_lease_time\n\t\tUpdate Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -C uniqueID\n\t\tCheck if Pinhole is Working (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -K uniqueID\n\t\tGet Number of packets going through the rule (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -D uniqueID\n\t\tDelete Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -S\n\t\tGet Firewall status (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -G remote_ip remote_port internal_ip internal_port protocol\n\t\tGet Outbound Pinhole Timeout (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -P\n\t\tGet Presentation url\n", argv[0]); - fprintf(stderr, "\nprotocol is UDP or TCP\n"); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -e description : set description for port mapping.\n"); - fprintf(stderr, " -6 : use ip v6 instead of ip v4.\n"); - fprintf(stderr, " -u url : bypass discovery process by providing the XML root description url.\n"); - fprintf(stderr, " -m address/interface : provide ip address (ip v4) or interface name (ip v4 or v6) to use for sending SSDP multicast packets.\n"); - fprintf(stderr, " -z localport : SSDP packets local (source) port (1024-65535).\n"); - fprintf(stderr, " -p path : use this path for MiniSSDPd socket.\n"); - fprintf(stderr, " -t ttl : set multicast TTL. Default value is 2.\n"); - return 1; - } - - if( rootdescurl - || (devlist = upnpDiscover(2000, multicastif, minissdpdpath, - localport, ipv6, ttl, &error))) - { - struct UPNPDev * device; - struct UPNPUrls urls; - struct IGDdatas data; - if(devlist) - { - printf("List of UPNP devices found on the network :\n"); - for(device = devlist; device; device = device->pNext) - { - printf(" desc: %s\n st: %s\n\n", - device->descURL, device->st); - } - } - else if(!rootdescurl) - { - printf("upnpDiscover() error code=%d\n", error); - } - i = 1; - if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr))) - || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)))) - { - switch(i) { - case 1: - printf("Found valid IGD : %s\n", urls.controlURL); - break; - case 2: - printf("Found a (not connected?) IGD : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - break; - case 3: - printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - break; - default: - printf("Found device (igd ?) : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - } - printf("Local LAN ip address : %s\n", lanaddr); - #if 0 - printf("getting \"%s\"\n", urls.ipcondescURL); - descXML = miniwget(urls.ipcondescURL, &descXMLsize); - if(descXML) - { - /*fwrite(descXML, 1, descXMLsize, stdout);*/ - free(descXML); descXML = NULL; - } - #endif - - switch(command) - { - case 'l': - DisplayInfos(&urls, &data); - ListRedirections(&urls, &data); - break; - case 'L': - NewListRedirections(&urls, &data); - break; - case 'a': - if (SetRedirectAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - (commandargc > 4)?commandargv[4]:"0", - description, 0) < 0) - retcode = 2; - break; - case 'd': - if (RemoveRedirect(&urls, &data, commandargv[0], commandargv[1], - commandargc > 2 ? commandargv[2] : NULL) < 0) - retcode = 2; - break; - case 'n': /* aNy */ - if (SetRedirectAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - (commandargc > 4)?commandargv[4]:"0", - description, 1) < 0) - retcode = 2; - break; - case 'N': - if (commandargc < 3) - fprintf(stderr, "too few arguments\n"); - - if (RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2], - commandargc > 3 ? commandargv[3] : NULL) < 0) - retcode = 2; - break; - case 's': - GetConnectionStatus(&urls, &data); - break; - case 'r': - i = 0; - while(i */ - if (SetRedirectAndTest(&urls, &data, - lanaddr, commandargv[i], - commandargv[i+1], commandargv[i+2], "0", - description, 0) < 0) - retcode = 2; - i+=3; /* 3 parameters parsed */ - } else { - /* 2nd parameter not an integer : */ - if (SetRedirectAndTest(&urls, &data, - lanaddr, commandargv[i], - commandargv[i], commandargv[i+1], "0", - description, 0) < 0) - retcode = 2; - i+=2; /* 2 parameters parsed */ - } - } - break; - case 'A': - SetPinholeAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - commandargv[4], commandargv[5]); - break; - case 'U': - GetPinholeAndUpdate(&urls, &data, - commandargv[0], commandargv[1]); - break; - case 'C': - for(i=0; i -#include -#include -#include "upnpcommands.h" -#include "miniupnpc.h" -#include "portlistingparse.h" - -static UNSIGNED_INTEGER -my_atoui(const char * s) -{ - return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0; -} - -/* - * */ -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalBytesSent(const char * controlURL, - const char * servicetype) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - unsigned int r = 0; - char * p; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetTotalBytesSent", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent"); - r = my_atoui(p); - ClearNameValueList(&pdata); - return r; -} - -/* - * */ -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalBytesReceived(const char * controlURL, - const char * servicetype) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - unsigned int r = 0; - char * p; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetTotalBytesReceived", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived"); - r = my_atoui(p); - ClearNameValueList(&pdata); - return r; -} - -/* - * */ -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalPacketsSent(const char * controlURL, - const char * servicetype) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - unsigned int r = 0; - char * p; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetTotalPacketsSent", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent"); - r = my_atoui(p); - ClearNameValueList(&pdata); - return r; -} - -/* - * */ -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalPacketsReceived(const char * controlURL, - const char * servicetype) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - unsigned int r = 0; - char * p; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetTotalPacketsReceived", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived"); - r = my_atoui(p); - ClearNameValueList(&pdata); - return r; -} - -/* UPNP_GetStatusInfo() call the corresponding UPNP method - * returns the current status and uptime */ -MINIUPNP_LIBSPEC int -UPNP_GetStatusInfo(const char * controlURL, - const char * servicetype, - char * status, - unsigned int * uptime, - char * lastconnerror) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char * p; - char * up; - char * err; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!status && !uptime) - return UPNPCOMMAND_INVALID_ARGS; - - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetStatusInfo", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - up = GetValueFromNameValueList(&pdata, "NewUptime"); - p = GetValueFromNameValueList(&pdata, "NewConnectionStatus"); - err = GetValueFromNameValueList(&pdata, "NewLastConnectionError"); - if(p && up) - ret = UPNPCOMMAND_SUCCESS; - - if(status) { - if(p){ - strncpy(status, p, 64 ); - status[63] = '\0'; - }else - status[0]= '\0'; - } - - if(uptime) { - if(up) - sscanf(up,"%u",uptime); - else - *uptime = 0; - } - - if(lastconnerror) { - if(err) { - strncpy(lastconnerror, err, 64 ); - lastconnerror[63] = '\0'; - } else - lastconnerror[0] = '\0'; - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - return ret; -} - -/* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method - * returns the connection type */ -MINIUPNP_LIBSPEC int -UPNP_GetConnectionTypeInfo(const char * controlURL, - const char * servicetype, - char * connectionType) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!connectionType) - return UPNPCOMMAND_INVALID_ARGS; - - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetConnectionTypeInfo", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewConnectionType"); - /*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/ - /* PossibleConnectionTypes will have several values.... */ - if(p) { - strncpy(connectionType, p, 64 ); - connectionType[63] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } else - connectionType[0] = '\0'; - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - return ret; -} - -/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method. - * Returns 2 values: Downloadlink bandwidth and Uplink bandwidth. - * One of the values can be null - * Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only - * We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */ -MINIUPNP_LIBSPEC int -UPNP_GetLinkLayerMaxBitRates(const char * controlURL, - const char * servicetype, - unsigned int * bitrateDown, - unsigned int * bitrateUp) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - char * down; - char * up; - char * p; - - if(!bitrateDown && !bitrateUp) - return UPNPCOMMAND_INVALID_ARGS; - - /* shouldn't we use GetCommonLinkProperties ? */ - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetCommonLinkProperties", 0, &bufsize))) { - /*"GetLinkLayerMaxBitRates", 0, &bufsize);*/ - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - /*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/ - /*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/ - down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate"); - up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate"); - /*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/ - /*GetValueFromNameValueList(&pdata, "NewPhysicalLinkStatus");*/ - if(down && up) - ret = UPNPCOMMAND_SUCCESS; - - if(bitrateDown) { - if(down) - sscanf(down,"%u",bitrateDown); - else - *bitrateDown = 0; - } - - if(bitrateUp) { - if(up) - sscanf(up,"%u",bitrateUp); - else - *bitrateUp = 0; - } - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - return ret; -} - - -/* UPNP_GetExternalIPAddress() call the corresponding UPNP method. - * if the third arg is not null the value is copied to it. - * at least 16 bytes must be available - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR Either an UPnP error code or an unknown error. - * - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. - */ -MINIUPNP_LIBSPEC int -UPNP_GetExternalIPAddress(const char * controlURL, - const char * servicetype, - char * extIpAdd) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!extIpAdd || !controlURL || !servicetype) - return UPNPCOMMAND_INVALID_ARGS; - - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetExternalIPAddress", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - /*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/ - p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress"); - if(p) { - strncpy(extIpAdd, p, 16 ); - extIpAdd[15] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } else - extIpAdd[0] = '\0'; - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_AddPortMapping(const char * controlURL, const char * servicetype, - const char * extPort, - const char * inPort, - const char * inClient, - const char * desc, - const char * proto, - const char * remoteHost, - const char * leaseDuration) -{ - struct UPNParg * AddPortMappingArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!inPort || !inClient || !proto || !extPort) - return UPNPCOMMAND_INVALID_ARGS; - - AddPortMappingArgs = calloc(9, sizeof(struct UPNParg)); - if(AddPortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - AddPortMappingArgs[0].elt = "NewRemoteHost"; - AddPortMappingArgs[0].val = remoteHost; - AddPortMappingArgs[1].elt = "NewExternalPort"; - AddPortMappingArgs[1].val = extPort; - AddPortMappingArgs[2].elt = "NewProtocol"; - AddPortMappingArgs[2].val = proto; - AddPortMappingArgs[3].elt = "NewInternalPort"; - AddPortMappingArgs[3].val = inPort; - AddPortMappingArgs[4].elt = "NewInternalClient"; - AddPortMappingArgs[4].val = inClient; - AddPortMappingArgs[5].elt = "NewEnabled"; - AddPortMappingArgs[5].val = "1"; - AddPortMappingArgs[6].elt = "NewPortMappingDescription"; - AddPortMappingArgs[6].val = desc?desc:"libminiupnpc"; - AddPortMappingArgs[7].elt = "NewLeaseDuration"; - AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0"; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "AddPortMapping", AddPortMappingArgs, - &bufsize); - free(AddPortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - /*buffer[bufsize] = '\0';*/ - /*puts(buffer);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) { - /*printf("AddPortMapping errorCode = '%s'\n", resVal); */ - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } else { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype, - const char * extPort, - const char * inPort, - const char * inClient, - const char * desc, - const char * proto, - const char * remoteHost, - const char * leaseDuration, - char * reservedPort) -{ - struct UPNParg * AddPortMappingArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!inPort || !inClient || !proto || !extPort) - return UPNPCOMMAND_INVALID_ARGS; - - AddPortMappingArgs = calloc(9, sizeof(struct UPNParg)); - if(AddPortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - AddPortMappingArgs[0].elt = "NewRemoteHost"; - AddPortMappingArgs[0].val = remoteHost; - AddPortMappingArgs[1].elt = "NewExternalPort"; - AddPortMappingArgs[1].val = extPort; - AddPortMappingArgs[2].elt = "NewProtocol"; - AddPortMappingArgs[2].val = proto; - AddPortMappingArgs[3].elt = "NewInternalPort"; - AddPortMappingArgs[3].val = inPort; - AddPortMappingArgs[4].elt = "NewInternalClient"; - AddPortMappingArgs[4].val = inClient; - AddPortMappingArgs[5].elt = "NewEnabled"; - AddPortMappingArgs[5].val = "1"; - AddPortMappingArgs[6].elt = "NewPortMappingDescription"; - AddPortMappingArgs[6].val = desc?desc:"libminiupnpc"; - AddPortMappingArgs[7].elt = "NewLeaseDuration"; - AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0"; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "AddAnyPortMapping", AddPortMappingArgs, - &bufsize); - free(AddPortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } else { - char *p; - - p = GetValueFromNameValueList(&pdata, "NewReservedPort"); - if(p) { - strncpy(reservedPort, p, 6); - reservedPort[5] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } else { - ret = UPNPCOMMAND_INVALID_RESPONSE; - } - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, - const char * extPort, const char * proto, - const char * remoteHost) -{ - /*struct NameValueParserData pdata;*/ - struct UPNParg * DeletePortMappingArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!extPort || !proto) - return UPNPCOMMAND_INVALID_ARGS; - - DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg)); - if(DeletePortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - DeletePortMappingArgs[0].elt = "NewRemoteHost"; - DeletePortMappingArgs[0].val = remoteHost; - DeletePortMappingArgs[1].elt = "NewExternalPort"; - DeletePortMappingArgs[1].val = extPort; - DeletePortMappingArgs[2].elt = "NewProtocol"; - DeletePortMappingArgs[2].val = proto; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "DeletePortMapping", - DeletePortMappingArgs, &bufsize); - free(DeletePortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } else { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype, - const char * extPortStart, const char * extPortEnd, - const char * proto, - const char * manage) -{ - struct UPNParg * DeletePortMappingArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!extPortStart || !extPortEnd || !proto || !manage) - return UPNPCOMMAND_INVALID_ARGS; - - DeletePortMappingArgs = calloc(5, sizeof(struct UPNParg)); - if(DeletePortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - DeletePortMappingArgs[0].elt = "NewStartPort"; - DeletePortMappingArgs[0].val = extPortStart; - DeletePortMappingArgs[1].elt = "NewEndPort"; - DeletePortMappingArgs[1].val = extPortEnd; - DeletePortMappingArgs[2].elt = "NewProtocol"; - DeletePortMappingArgs[2].val = proto; - DeletePortMappingArgs[3].elt = "NewManage"; - DeletePortMappingArgs[3].val = manage; - - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "DeletePortMappingRange", - DeletePortMappingArgs, &bufsize); - free(DeletePortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } else { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_GetGenericPortMappingEntry(const char * controlURL, - const char * servicetype, - const char * index, - char * extPort, - char * intClient, - char * intPort, - char * protocol, - char * desc, - char * enabled, - char * rHost, - char * duration) -{ - struct NameValueParserData pdata; - struct UPNParg * GetPortMappingArgs; - char * buffer; - int bufsize; - char * p; - int r = UPNPCOMMAND_UNKNOWN_ERROR; - if(!index) - return UPNPCOMMAND_INVALID_ARGS; - intClient[0] = '\0'; - intPort[0] = '\0'; - GetPortMappingArgs = calloc(2, sizeof(struct UPNParg)); - if(GetPortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetPortMappingArgs[0].elt = "NewPortMappingIndex"; - GetPortMappingArgs[0].val = index; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetGenericPortMappingEntry", - GetPortMappingArgs, &bufsize); - free(GetPortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "NewRemoteHost"); - if(p && rHost) - { - strncpy(rHost, p, 64); - rHost[63] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewExternalPort"); - if(p && extPort) - { - strncpy(extPort, p, 6); - extPort[5] = '\0'; - r = UPNPCOMMAND_SUCCESS; - } - p = GetValueFromNameValueList(&pdata, "NewProtocol"); - if(p && protocol) - { - strncpy(protocol, p, 4); - protocol[3] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewInternalClient"); - if(p) - { - strncpy(intClient, p, 16); - intClient[15] = '\0'; - r = 0; - } - p = GetValueFromNameValueList(&pdata, "NewInternalPort"); - if(p) - { - strncpy(intPort, p, 6); - intPort[5] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewEnabled"); - if(p && enabled) - { - strncpy(enabled, p, 4); - enabled[3] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription"); - if(p && desc) - { - strncpy(desc, p, 80); - desc[79] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewLeaseDuration"); - if(p && duration) - { - strncpy(duration, p, 16); - duration[15] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - r = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &r); - } - ClearNameValueList(&pdata); - return r; -} - -MINIUPNP_LIBSPEC int -UPNP_GetPortMappingNumberOfEntries(const char * controlURL, - const char * servicetype, - unsigned int * numEntries) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char* p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetPortMappingNumberOfEntries", 0, - &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } -#ifdef DEBUG - DisplayNameValueList(buffer, bufsize); -#endif - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries"); - if(numEntries && p) { - *numEntries = 0; - sscanf(p, "%u", numEntries); - ret = UPNPCOMMAND_SUCCESS; - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - -/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping - * the result is returned in the intClient and intPort strings - * please provide 16 and 6 bytes of data */ -MINIUPNP_LIBSPEC int -UPNP_GetSpecificPortMappingEntry(const char * controlURL, - const char * servicetype, - const char * extPort, - const char * proto, - const char * remoteHost, - char * intClient, - char * intPort, - char * desc, - char * enabled, - char * leaseDuration) -{ - struct NameValueParserData pdata; - struct UPNParg * GetPortMappingArgs; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!intPort || !intClient || !extPort || !proto) - return UPNPCOMMAND_INVALID_ARGS; - - GetPortMappingArgs = calloc(4, sizeof(struct UPNParg)); - if(GetPortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetPortMappingArgs[0].elt = "NewRemoteHost"; - GetPortMappingArgs[0].val = remoteHost; - GetPortMappingArgs[1].elt = "NewExternalPort"; - GetPortMappingArgs[1].val = extPort; - GetPortMappingArgs[2].elt = "NewProtocol"; - GetPortMappingArgs[2].val = proto; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetSpecificPortMappingEntry", - GetPortMappingArgs, &bufsize); - free(GetPortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "NewInternalClient"); - if(p) { - strncpy(intClient, p, 16); - intClient[15] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } else - intClient[0] = '\0'; - - p = GetValueFromNameValueList(&pdata, "NewInternalPort"); - if(p) { - strncpy(intPort, p, 6); - intPort[5] = '\0'; - } else - intPort[0] = '\0'; - - p = GetValueFromNameValueList(&pdata, "NewEnabled"); - if(p && enabled) { - strncpy(enabled, p, 4); - enabled[3] = '\0'; - } - - p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription"); - if(p && desc) { - strncpy(desc, p, 80); - desc[79] = '\0'; - } - - p = GetValueFromNameValueList(&pdata, "NewLeaseDuration"); - if(p && leaseDuration) - { - strncpy(leaseDuration, p, 16); - leaseDuration[15] = '\0'; - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - -/* UPNP_GetListOfPortMappings() - * - * Possible UPNP Error codes : - * 606 Action not Authorized - * 730 PortMappingNotFound - no port mapping is found in the specified range. - * 733 InconsistantParameters - NewStartPort and NewEndPort values are not - * consistent. - */ -MINIUPNP_LIBSPEC int -UPNP_GetListOfPortMappings(const char * controlURL, - const char * servicetype, - const char * startPort, - const char * endPort, - const char * protocol, - const char * numberOfPorts, - struct PortMappingParserData * data) -{ - struct NameValueParserData pdata; - struct UPNParg * GetListOfPortMappingsArgs; - const char * p; - char * buffer; - int bufsize; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!startPort || !endPort || !protocol) - return UPNPCOMMAND_INVALID_ARGS; - - GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg)); - if(GetListOfPortMappingsArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetListOfPortMappingsArgs[0].elt = "NewStartPort"; - GetListOfPortMappingsArgs[0].val = startPort; - GetListOfPortMappingsArgs[1].elt = "NewEndPort"; - GetListOfPortMappingsArgs[1].val = endPort; - GetListOfPortMappingsArgs[2].elt = "NewProtocol"; - GetListOfPortMappingsArgs[2].val = protocol; - GetListOfPortMappingsArgs[3].elt = "NewManage"; - GetListOfPortMappingsArgs[3].val = "1"; - GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts"; - GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000"; - - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetListOfPortMappings", - GetListOfPortMappingsArgs, &bufsize); - free(GetListOfPortMappingsArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - /*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/ - /*if(p) { - printf("NewPortListing : %s\n", p); - }*/ - /*printf("NewPortListing(%d chars) : %s\n", - pdata.portListingLength, pdata.portListing);*/ - if(pdata.portListing) - { - /*struct PortMapping * pm; - int i = 0;*/ - ParsePortListing(pdata.portListing, pdata.portListingLength, - data); - ret = UPNPCOMMAND_SUCCESS; - /* - for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next) - { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost); - i++; - } - */ - /*FreePortListing(&data);*/ - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - - /*printf("%.*s", bufsize, buffer);*/ - - return ret; -} - -/* IGD:2, functions for service WANIPv6FirewallControl:1 */ -MINIUPNP_LIBSPEC int -UPNP_GetFirewallStatus(const char * controlURL, - const char * servicetype, - int * firewallEnabled, - int * inboundPinholeAllowed) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char * fe, *ipa, *p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!firewallEnabled || !inboundPinholeAllowed) - return UPNPCOMMAND_INVALID_ARGS; - - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetFirewallStatus", 0, &bufsize); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - fe = GetValueFromNameValueList(&pdata, "FirewallEnabled"); - ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed"); - if(ipa && fe) - ret = UPNPCOMMAND_SUCCESS; - if(fe) - *firewallEnabled = my_atoui(fe); - /*else - *firewallEnabled = 0;*/ - if(ipa) - *inboundPinholeAllowed = my_atoui(ipa); - /*else - *inboundPinholeAllowed = 0;*/ - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - int * opTimeout) -{ - struct UPNParg * GetOutboundPinholeTimeoutArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - char * p; - int ret; - - if(!intPort || !intClient || !proto || !remotePort || !remoteHost) - return UPNPCOMMAND_INVALID_ARGS; - - GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg)); - if(GetOutboundPinholeTimeoutArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost"; - GetOutboundPinholeTimeoutArgs[0].val = remoteHost; - GetOutboundPinholeTimeoutArgs[1].elt = "RemotePort"; - GetOutboundPinholeTimeoutArgs[1].val = remotePort; - GetOutboundPinholeTimeoutArgs[2].elt = "Protocol"; - GetOutboundPinholeTimeoutArgs[2].val = proto; - GetOutboundPinholeTimeoutArgs[3].elt = "InternalPort"; - GetOutboundPinholeTimeoutArgs[3].val = intPort; - GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient"; - GetOutboundPinholeTimeoutArgs[4].val = intClient; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize); - free(GetOutboundPinholeTimeoutArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout"); - if(p) - *opTimeout = my_atoui(p); - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_AddPinhole(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - const char * leaseTime, - char * uniqueID) -{ - struct UPNParg * AddPinholeArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - char * p; - int ret; - - if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime) - return UPNPCOMMAND_INVALID_ARGS; - - AddPinholeArgs = calloc(7, sizeof(struct UPNParg)); - if(AddPinholeArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - /* RemoteHost can be wilcarded */ - if(strncmp(remoteHost, "empty", 5)==0) - { - AddPinholeArgs[0].elt = "RemoteHost"; - AddPinholeArgs[0].val = ""; - } - else - { - AddPinholeArgs[0].elt = "RemoteHost"; - AddPinholeArgs[0].val = remoteHost; - } - AddPinholeArgs[1].elt = "RemotePort"; - AddPinholeArgs[1].val = remotePort; - AddPinholeArgs[2].elt = "Protocol"; - AddPinholeArgs[2].val = proto; - AddPinholeArgs[3].elt = "InternalPort"; - AddPinholeArgs[3].val = intPort; - if(strncmp(intClient, "empty", 5)==0) - { - AddPinholeArgs[4].elt = "InternalClient"; - AddPinholeArgs[4].val = ""; - } - else - { - AddPinholeArgs[4].elt = "InternalClient"; - AddPinholeArgs[4].val = intClient; - } - AddPinholeArgs[5].elt = "LeaseTime"; - AddPinholeArgs[5].val = leaseTime; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "AddPinhole", AddPinholeArgs, &bufsize); - free(AddPinholeArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "UniqueID"); - if(p) - { - strncpy(uniqueID, p, 8); - uniqueID[7] = '\0'; - } - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { - /*printf("AddPortMapping errorCode = '%s'\n", resVal);*/ - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, - const char * uniqueID, - const char * leaseTime) -{ - struct UPNParg * UpdatePinholeArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!uniqueID || !leaseTime) - return UPNPCOMMAND_INVALID_ARGS; - - UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg)); - if(UpdatePinholeArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - UpdatePinholeArgs[0].elt = "UniqueID"; - UpdatePinholeArgs[0].val = uniqueID; - UpdatePinholeArgs[1].elt = "NewLeaseTime"; - UpdatePinholeArgs[1].val = leaseTime; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "UpdatePinhole", UpdatePinholeArgs, &bufsize); - free(UpdatePinholeArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { - /*printf("AddPortMapping errorCode = '%s'\n", resVal); */ - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID) -{ - /*struct NameValueParserData pdata;*/ - struct UPNParg * DeletePinholeArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!uniqueID) - return UPNPCOMMAND_INVALID_ARGS; - - DeletePinholeArgs = calloc(2, sizeof(struct UPNParg)); - if(DeletePinholeArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - DeletePinholeArgs[0].elt = "UniqueID"; - DeletePinholeArgs[0].val = uniqueID; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "DeletePinhole", DeletePinholeArgs, &bufsize); - free(DeletePinholeArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, - const char * uniqueID, int * isWorking) -{ - struct NameValueParserData pdata; - struct UPNParg * CheckPinholeWorkingArgs; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!uniqueID) - return UPNPCOMMAND_INVALID_ARGS; - - CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg)); - if(CheckPinholeWorkingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - CheckPinholeWorkingArgs[0].elt = "UniqueID"; - CheckPinholeWorkingArgs[0].val = uniqueID; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize); - free(CheckPinholeWorkingArgs); - if(!buffer) - { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "IsWorking"); - if(p) - { - *isWorking=my_atoui(p); - ret = UPNPCOMMAND_SUCCESS; - } - else - *isWorking = 0; - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, - const char * uniqueID, int * packets) -{ - struct NameValueParserData pdata; - struct UPNParg * GetPinholePacketsArgs; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!uniqueID) - return UPNPCOMMAND_INVALID_ARGS; - - GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg)); - if(GetPinholePacketsArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetPinholePacketsArgs[0].elt = "UniqueID"; - GetPinholePacketsArgs[0].val = uniqueID; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetPinholePackets", GetPinholePacketsArgs, &bufsize); - free(GetPinholePacketsArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "PinholePackets"); - if(p) - { - *packets=my_atoui(p); - ret = UPNPCOMMAND_SUCCESS; - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - - diff --git a/ext/miniupnpc/upnpdev.c b/ext/miniupnpc/upnpdev.c deleted file mode 100644 index d89a9934c..000000000 --- a/ext/miniupnpc/upnpdev.c +++ /dev/null @@ -1,23 +0,0 @@ -/* $Id: upnpdev.c,v 1.1 2015/08/28 12:14:19 nanard Exp $ */ -/* Project : miniupnp - * Web : http://miniupnp.free.fr/ - * Author : Thomas BERNARD - * copyright (c) 2005-2015 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENSE file. */ -#include -#include "upnpdev.h" - -/* freeUPNPDevlist() should be used to - * free the chained list returned by upnpDiscover() */ -void freeUPNPDevlist(struct UPNPDev * devlist) -{ - struct UPNPDev * next; - while(devlist) - { - next = devlist->pNext; - free(devlist); - devlist = next; - } -} - diff --git a/ext/miniupnpc/upnpdev.h b/ext/miniupnpc/upnpdev.h deleted file mode 100644 index f49fbe17c..000000000 --- a/ext/miniupnpc/upnpdev.h +++ /dev/null @@ -1,36 +0,0 @@ -/* $Id: upnpdev.h,v 1.1 2015/08/28 12:14:19 nanard Exp $ */ -/* Project : miniupnp - * Web : http://miniupnp.free.fr/ - * Author : Thomas BERNARD - * copyright (c) 2005-2015 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENSE file. */ -#ifndef UPNPDEV_H_INCLUDED -#define UPNPDEV_H_INCLUDED - -#include "miniupnpc_declspec.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct UPNPDev { - struct UPNPDev * pNext; - char * descURL; - char * st; - unsigned int scope_id; - char * usn; - char buffer[3]; -}; - -/* freeUPNPDevlist() - * free list returned by upnpDiscover() */ -MINIUPNP_LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist); - - -#ifdef __cplusplus -} -#endif - - -#endif /* UPNPDEV_H_INCLUDED */ diff --git a/ext/miniupnpc/upnperrors.c b/ext/miniupnpc/upnperrors.c deleted file mode 100644 index 7ab8ee96f..000000000 --- a/ext/miniupnpc/upnperrors.c +++ /dev/null @@ -1,107 +0,0 @@ -/* $Id: upnperrors.c,v 1.8 2014/06/10 09:41:48 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas BERNARD - * copyright (c) 2007 Thomas Bernard - * All Right reserved. - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#include -#include "upnperrors.h" -#include "upnpcommands.h" -#include "miniupnpc.h" - -const char * strupnperror(int err) -{ - const char * s = NULL; - switch(err) { - case UPNPCOMMAND_SUCCESS: - s = "Success"; - break; - case UPNPCOMMAND_UNKNOWN_ERROR: - s = "Miniupnpc Unknown Error"; - break; - case UPNPCOMMAND_INVALID_ARGS: - s = "Miniupnpc Invalid Arguments"; - break; - case UPNPCOMMAND_INVALID_RESPONSE: - s = "Miniupnpc Invalid response"; - break; - case UPNPDISCOVER_SOCKET_ERROR: - s = "Miniupnpc Socket error"; - break; - case UPNPDISCOVER_MEMORY_ERROR: - s = "Miniupnpc Memory allocation error"; - break; - case 401: - s = "Invalid Action"; - break; - case 402: - s = "Invalid Args"; - break; - case 501: - s = "Action Failed"; - break; - case 606: - s = "Action not authorized"; - break; - case 701: - s = "PinholeSpaceExhausted"; - break; - case 702: - s = "FirewallDisabled"; - break; - case 703: - s = "InboundPinholeNotAllowed"; - break; - case 704: - s = "NoSuchEntry"; - break; - case 705: - s = "ProtocolNotSupported"; - break; - case 706: - s = "InternalPortWildcardingNotAllowed"; - break; - case 707: - s = "ProtocolWildcardingNotAllowed"; - break; - case 708: - s = "WildcardNotPermittedInSrcIP"; - break; - case 709: - s = "NoPacketSent"; - break; - case 713: - s = "SpecifiedArrayIndexInvalid"; - break; - case 714: - s = "NoSuchEntryInArray"; - break; - case 715: - s = "WildCardNotPermittedInSrcIP"; - break; - case 716: - s = "WildCardNotPermittedInExtPort"; - break; - case 718: - s = "ConflictInMappingEntry"; - break; - case 724: - s = "SamePortValuesRequired"; - break; - case 725: - s = "OnlyPermanentLeasesSupported"; - break; - case 726: - s = "RemoteHostOnlySupportsWildcard"; - break; - case 727: - s = "ExternalPortOnlySupportsWildcard"; - break; - default: - s = "UnknownError"; - break; - } - return s; -} diff --git a/ext/miniupnpc/upnpreplyparse.c b/ext/miniupnpc/upnpreplyparse.c deleted file mode 100644 index 5921349d3..000000000 --- a/ext/miniupnpc/upnpreplyparse.c +++ /dev/null @@ -1,196 +0,0 @@ -/* $Id: upnpreplyparse.c,v 1.20 2017/12/12 11:26:25 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2017 Thomas Bernard - * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ - -#include -#include -#include - -#include "upnpreplyparse.h" -#include "minixml.h" - -static void -NameValueParserStartElt(void * d, const char * name, int l) -{ - struct NameValueParserData * data = (struct NameValueParserData *)d; - data->topelt = 1; - if(l>63) - l = 63; - memcpy(data->curelt, name, l); - data->curelt[l] = '\0'; - data->cdata = NULL; - data->cdatalen = 0; -} - -static void -NameValueParserEndElt(void * d, const char * name, int namelen) -{ - struct NameValueParserData * data = (struct NameValueParserData *)d; - struct NameValue * nv; - (void)name; - (void)namelen; - if(!data->topelt) - return; - if(strcmp(data->curelt, "NewPortListing") != 0) - { - int l; - /* standard case. Limited to n chars strings */ - l = data->cdatalen; - nv = malloc(sizeof(struct NameValue)); - if(nv == NULL) - { - /* malloc error */ -#ifdef DEBUG - fprintf(stderr, "%s: error allocating memory", - "NameValueParserEndElt"); -#endif /* DEBUG */ - return; - } - if(l>=(int)sizeof(nv->value)) - l = sizeof(nv->value) - 1; - strncpy(nv->name, data->curelt, 64); - nv->name[63] = '\0'; - if(data->cdata != NULL) - { - memcpy(nv->value, data->cdata, l); - nv->value[l] = '\0'; - } - else - { - nv->value[0] = '\0'; - } - nv->l_next = data->l_head; /* insert in list */ - data->l_head = nv; - } - data->cdata = NULL; - data->cdatalen = 0; - data->topelt = 0; -} - -static void -NameValueParserGetData(void * d, const char * datas, int l) -{ - struct NameValueParserData * data = (struct NameValueParserData *)d; - if(strcmp(data->curelt, "NewPortListing") == 0) - { - /* specific case for NewPortListing which is a XML Document */ - data->portListing = malloc(l + 1); - if(!data->portListing) - { - /* malloc error */ -#ifdef DEBUG - fprintf(stderr, "%s: error allocating memory", - "NameValueParserGetData"); -#endif /* DEBUG */ - return; - } - memcpy(data->portListing, datas, l); - data->portListing[l] = '\0'; - data->portListingLength = l; - } - else - { - /* standard case. */ - data->cdata = datas; - data->cdatalen = l; - } -} - -void -ParseNameValue(const char * buffer, int bufsize, - struct NameValueParserData * data) -{ - struct xmlparser parser; - memset(data, 0, sizeof(struct NameValueParserData)); - /* init xmlparser object */ - parser.xmlstart = buffer; - parser.xmlsize = bufsize; - parser.data = data; - parser.starteltfunc = NameValueParserStartElt; - parser.endeltfunc = NameValueParserEndElt; - parser.datafunc = NameValueParserGetData; - parser.attfunc = 0; - parsexml(&parser); -} - -void -ClearNameValueList(struct NameValueParserData * pdata) -{ - struct NameValue * nv; - if(pdata->portListing) - { - free(pdata->portListing); - pdata->portListing = NULL; - pdata->portListingLength = 0; - } - while((nv = pdata->l_head) != NULL) - { - pdata->l_head = nv->l_next; - free(nv); - } -} - -char * -GetValueFromNameValueList(struct NameValueParserData * pdata, - const char * Name) -{ - struct NameValue * nv; - char * p = NULL; - for(nv = pdata->l_head; - (nv != NULL) && (p == NULL); - nv = nv->l_next) - { - if(strcmp(nv->name, Name) == 0) - p = nv->value; - } - return p; -} - -#if 0 -/* useless now that minixml ignores namespaces by itself */ -char * -GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, - const char * Name) -{ - struct NameValue * nv; - char * p = NULL; - char * pname; - for(nv = pdata->head.lh_first; - (nv != NULL) && (p == NULL); - nv = nv->entries.le_next) - { - pname = strrchr(nv->name, ':'); - if(pname) - pname++; - else - pname = nv->name; - if(strcmp(pname, Name)==0) - p = nv->value; - } - return p; -} -#endif - -/* debug all-in-one function - * do parsing then display to stdout */ -#ifdef DEBUG -void -DisplayNameValueList(char * buffer, int bufsize) -{ - struct NameValueParserData pdata; - struct NameValue * nv; - ParseNameValue(buffer, bufsize, &pdata); - for(nv = pdata.l_head; - nv != NULL; - nv = nv->l_next) - { - printf("%s = %s\n", nv->name, nv->value); - } - ClearNameValueList(&pdata); -} -#endif /* DEBUG */ - diff --git a/ext/miniupnpc/wingenminiupnpcstrings.c b/ext/miniupnpc/wingenminiupnpcstrings.c deleted file mode 100644 index 50df06a76..000000000 --- a/ext/miniupnpc/wingenminiupnpcstrings.c +++ /dev/null @@ -1,83 +0,0 @@ -/* $Id: wingenminiupnpcstrings.c,v 1.4 2015/02/08 08:46:06 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author: Thomas Bernard - * Copyright (c) 2005-2015 Thomas Bernard - * This software is subjects to the conditions detailed - * in the LICENSE file provided within this distribution */ -#include -#include - -/* This program display the Windows version and is used to - * generate the miniupnpcstrings.h - * wingenminiupnpcstrings miniupnpcstrings.h.in miniupnpcstrings.h - */ -int main(int argc, char * * argv) { - char buffer[256]; - OSVERSIONINFO osvi; - FILE * fin; - FILE * fout; - int n; - char miniupnpcVersion[32]; - /* dwMajorVersion : - The major version number of the operating system. For more information, see Remarks. - dwMinorVersion : - The minor version number of the operating system. For more information, see Remarks. - dwBuildNumber : - The build number of the operating system. - dwPlatformId - The operating system platform. This member can be the following value. - szCSDVersion - A null-terminated string, such as "Service Pack 3", that indicates the - latest Service Pack installed on the system. If no Service Pack has - been installed, the string is empty. - */ - ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - GetVersionEx(&osvi); - - printf("Windows %lu.%lu Build %lu %s\n", - osvi.dwMajorVersion, osvi.dwMinorVersion, - osvi.dwBuildNumber, (const char *)&(osvi.szCSDVersion)); - - fin = fopen("VERSION", "r"); - fgets(miniupnpcVersion, sizeof(miniupnpcVersion), fin); - fclose(fin); - for(n = 0; n < sizeof(miniupnpcVersion); n++) { - if(miniupnpcVersion[n] < ' ') - miniupnpcVersion[n] = '\0'; - } - printf("MiniUPnPc version %s\n", miniupnpcVersion); - - if(argc >= 3) { - fin = fopen(argv[1], "r"); - if(!fin) { - fprintf(stderr, "Cannot open %s for reading.\n", argv[1]); - return 1; - } - fout = fopen(argv[2], "w"); - if(!fout) { - fprintf(stderr, "Cannot open %s for writing.\n", argv[2]); - fclose(fin); - return 1; - } - n = 0; - while(fgets(buffer, sizeof(buffer), fin)) { - if(0 == memcmp(buffer, "#define OS_STRING \"OS/version\"", 30)) { - sprintf(buffer, "#define OS_STRING \"MSWindows/%ld.%ld.%ld\"\n", - osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber); - } else if(0 == memcmp(buffer, "#define MINIUPNPC_VERSION_STRING \"version\"", 42)) { - sprintf(buffer, "#define MINIUPNPC_VERSION_STRING \"%s\"\n", - miniupnpcVersion); - } - /*fputs(buffer, stdout);*/ - fputs(buffer, fout); - n++; - } - fclose(fin); - fclose(fout); - printf("%d lines written to %s.\n", n, argv[2]); - } - return 0; -} diff --git a/ext/misc/linux-old-glibc-compat.c b/ext/misc/linux-old-glibc-compat.c deleted file mode 100644 index 6d793a2d0..000000000 --- a/ext/misc/linux-old-glibc-compat.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include -#include - -__asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); - -#ifdef __cplusplus -extern "C" { -#endif - -extern void *__wrap_memcpy(void *dest,const void *src,size_t n) -{ - return memcpy(dest,src,n); -} - -#ifdef __cplusplus -} -#endif diff --git a/ext/nlohmann/LICENSE.MIT b/ext/nlohmann/LICENSE.MIT deleted file mode 100644 index 00599afe6..000000000 --- a/ext/nlohmann/LICENSE.MIT +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013-2017 Niels Lohmann - -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/nlohmann/README.md b/ext/nlohmann/README.md deleted file mode 100644 index f3bbf847c..000000000 --- a/ext/nlohmann/README.md +++ /dev/null @@ -1,1123 +0,0 @@ -[![JSON for Modern C++](https://raw.githubusercontent.com/nlohmann/json/master/doc/json.gif)](https://github.com/nlohmann/json/releases) - -[![Build Status](https://travis-ci.org/nlohmann/json.svg?branch=master)](https://travis-ci.org/nlohmann/json) -[![Build Status](https://ci.appveyor.com/api/projects/status/1acb366xfyg3qybk/branch/develop?svg=true)](https://ci.appveyor.com/project/nlohmann/json) -[![Coverage Status](https://img.shields.io/coveralls/nlohmann/json.svg)](https://coveralls.io/r/nlohmann/json) -[![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json) -[![Codacy Badge](https://api.codacy.com/project/badge/Grade/f3732b3327e34358a0e9d1fe9f661f08)](https://www.codacy.com/app/nlohmann/json?utm_source=github.com&utm_medium=referral&utm_content=nlohmann/json&utm_campaign=Badge_Grade) -[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/TarF5pPn9NtHQjhf) -[![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](http://nlohmann.github.io/json) -[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT) -[![GitHub Releases](https://img.shields.io/github/release/nlohmann/json.svg)](https://github.com/nlohmann/json/releases) -[![GitHub Issues](https://img.shields.io/github/issues/nlohmann/json.svg)](http://github.com/nlohmann/json/issues) -[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/nlohmann/json.svg)](http://isitmaintained.com/project/nlohmann/json "Average time to resolve an issue") -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/289/badge)](https://bestpractices.coreinfrastructure.org/projects/289) - -- [Design goals](#design-goals) -- [Integration](#integration) -- [Examples](#examples) - - [JSON as first-class data type](#json-as-first-class-data-type) - - [Serialization / Deserialization](#serialization--deserialization) - - [STL-like access](#stl-like-access) - - [Conversion from STL containers](#conversion-from-stl-containers) - - [JSON Pointer and JSON Patch](#json-pointer-and-json-patch) - - [JSON Merge Patch](#json-merge-patch) - - [Implicit conversions](#implicit-conversions) - - [Conversions to/from arbitrary types](#arbitrary-types-conversions) - - [Binary formats (CBOR, MessagePack, and UBJSON)](#binary-formats-cbor-messagepack-and-ubjson) -- [Supported compilers](#supported-compilers) -- [License](#license) -- [Contact](#contact) -- [Thanks](#thanks) -- [Used third-party tools](#used-third-party-tools) -- [Projects using JSON for Modern C++](#projects-using-json-for-modern-c) -- [Notes](#notes) -- [Execute unit tests](#execute-unit-tests) - -## Design goals - -There are myriads of [JSON](http://json.org) libraries out there, and each may even have its reason to exist. Our class had these design goals: - -- **Intuitive syntax**. In languages such as Python, JSON feels like a first class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code. Check out the [examples below](#examples) and you'll know what I mean. - -- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings. - -- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/test/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests agains all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289). - -Other aspects were not so important to us: - -- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs. - -- **Speed**. There are certainly [faster JSON libraries](https://github.com/miloyip/nativejson-benchmark#parsing-time) out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a `std::vector` or `std::map`, you are already set. - -See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.github/CONTRIBUTING.md#please-dont) for more information. - - -## Integration - -[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add - -```cpp -#include - -// for convenience -using json = nlohmann::json; -``` - -to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang). - -You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of json_fwd.hpp (as part of cmake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`. - -### Package Managers - -:beer: If you are using OS X and [Homebrew](http://brew.sh), just type `brew tap nlohmann/json` and `brew install nlohmann_json` and you're set. If you want the bleeding edge rather than the latest release, use `brew install nlohmann_json --HEAD`. - -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://www.conan.io/) to manage your dependencies, merely add `jsonformoderncpp/x.y.z@vthiery/stable` to your `conanfile.py`'s requires, where `x.y.z` is the release version you want to use. Please file issues [here](https://github.com/vthiery/conan-jsonformoderncpp/issues) if you experience problems with the packages. - -If you are using [Spack](https://www.spack.io/) to manage your dependencies, you can use the `nlohmann_json` package. Please see the [spack project](https://github.com/spack/spack) for any issues regarding the packaging. - -If you are using [hunter](https://github.com/ruslo/hunter/) on your project for external dependencies, then you can use the [nlohmann_json package](https://docs.hunter.sh/en/latest/packages/pkg/nlohmann_json.html). Please see the hunter project for any issues regarding the packaging. - -If you are using [Buckaroo](https://buckaroo.pm), you can install this library's module with `buckaroo install nlohmann/json`. Please file issues [here](https://github.com/LoopPerfect/buckaroo-recipes/issues/new?title=nlohmann/nlohmann/json). - -If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project for external dependencies, then you can use the [nlohmann-json package](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json). Please see the vcpkg project for any issues regarding the packaging. - -If you are using [cget](http://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install nlohmann/json`. A specific version can be installed with `cget install nlohmann/json@v3.1.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`). - -If you are using [CocoaPods](https://cocoapods.org), you can use the library by adding pod `"nlohmann_json", '~>3.1.2'` to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues [here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open). - -## Examples - -Beside the examples below, you may want to check the [documentation](https://nlohmann.github.io/json/) where each function contains a separate code example (e.g., check out [`emplace()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a5338e282d1d02bed389d852dd670d98d.html#a5338e282d1d02bed389d852dd670d98d)). All [example files](https://github.com/nlohmann/json/tree/develop/doc/examples) can be compiled and executed on their own (e.g., file [emplace.cpp](https://github.com/nlohmann/json/blob/develop/doc/examples/emplace.cpp)). - -### JSON as first-class data type - -Here are some examples to give you an idea how to use the class. - -Assume you want to create the JSON object - -```json -{ - "pi": 3.141, - "happy": true, - "name": "Niels", - "nothing": null, - "answer": { - "everything": 42 - }, - "list": [1, 0, 2], - "object": { - "currency": "USD", - "value": 42.99 - } -} -``` - -With this library, you could write: - -```cpp -// create an empty structure (null) -json j; - -// add a number that is stored as double (note the implicit conversion of j to an object) -j["pi"] = 3.141; - -// add a Boolean that is stored as bool -j["happy"] = true; - -// add a string that is stored as std::string -j["name"] = "Niels"; - -// add another null object by passing nullptr -j["nothing"] = nullptr; - -// add an object inside the object -j["answer"]["everything"] = 42; - -// add an array that is stored as std::vector (using an initializer list) -j["list"] = { 1, 0, 2 }; - -// add another object (using an initializer list of pairs) -j["object"] = { {"currency", "USD"}, {"value", 42.99} }; - -// instead, you could also write (which looks very similar to the JSON above) -json j2 = { - {"pi", 3.141}, - {"happy", true}, - {"name", "Niels"}, - {"nothing", nullptr}, - {"answer", { - {"everything", 42} - }}, - {"list", {1, 0, 2}}, - {"object", { - {"currency", "USD"}, - {"value", 42.99} - }} -}; -``` - -Note that in all these cases, you never need to "tell" the compiler which JSON value type you want to use. If you want to be explicit or express some edge cases, the functions [`json::array`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_aa80485befaffcadaa39965494e0b4d2e.html#aa80485befaffcadaa39965494e0b4d2e) and [`json::object`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_aa13f7c0615867542ce80337cbcf13ada.html#aa13f7c0615867542ce80337cbcf13ada) will help: - -```cpp -// a way to express the empty array [] -json empty_array_explicit = json::array(); - -// ways to express the empty object {} -json empty_object_implicit = json({}); -json empty_object_explicit = json::object(); - -// a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]] -json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} }); -``` - -### Serialization / Deserialization - -#### To/from strings - -You can create a JSON value (deserialization) by appending `_json` to a string literal: - -```cpp -// create object from string literal -json j = "{ \"happy\": true, \"pi\": 3.141 }"_json; - -// or even nicer with a raw string literal -auto j2 = R"( - { - "happy": true, - "pi": 3.141 - } -)"_json; -``` - -Note that without appending the `_json` suffix, the passed string literal is not parsed, but just used as JSON string value. That is, `json j = "{ \"happy\": true, \"pi\": 3.141 }"` would just store the string `"{ "happy": true, "pi": 3.141 }"` rather than parsing the actual object. - -The above example can also be expressed explicitly using [`json::parse()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_aa9676414f2e36383c4b181fe856aa3c0.html#aa9676414f2e36383c4b181fe856aa3c0): - -```cpp -// parse explicitly -auto j3 = json::parse("{ \"happy\": true, \"pi\": 3.141 }"); -``` - -You can also get a string representation of a JSON value (serialize): - -```cpp -// explicit conversion to string -std::string s = j.dump(); // {\"happy\":true,\"pi\":3.141} - -// serialization with pretty printing -// pass in the amount of spaces to indent -std::cout << j.dump(4) << std::endl; -// { -// "happy": true, -// "pi": 3.141 -// } -``` - -Note the difference between serialization and assignment: - -```cpp -// store a string in a JSON value -json j_string = "this is a string"; - -// retrieve the string value (implicit JSON to std::string conversion) -std::string cpp_string = j_string; -// retrieve the string value (explicit JSON to std::string conversion) -auto cpp_string2 = j_string.get(); - -// retrieve the serialized value (explicit JSON serialization) -std::string serialized_string = j_string.dump(); - -// output of original string -std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get() << '\n'; -// output of serialized value -std::cout << j_string << " == " << serialized_string << std::endl; -``` - -[`.dump()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a5adea76fedba9898d404fef8598aa663.html#a5adea76fedba9898d404fef8598aa663) always returns the serialized value, and [`.get()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a16f9445f7629f634221a42b967cdcd43.html#a16f9445f7629f634221a42b967cdcd43) returns the originally stored string value. - -Note the library only supports UTF-8. When you store strings with different encodings in the library, calling [`dump()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a5adea76fedba9898d404fef8598aa663.html#a5adea76fedba9898d404fef8598aa663) may throw an exception. - -#### To/from streams (e.g. files, string streams) - -You can also use streams to serialize and deserialize: - -```cpp -// deserialize from standard input -json j; -std::cin >> j; - -// serialize to standard output -std::cout << j; - -// the setw manipulator was overloaded to set the indentation for pretty printing -std::cout << std::setw(4) << j << std::endl; -``` - -These operators work for any subclasses of `std::istream` or `std::ostream`. Here is the same example with files: - -```cpp -// read a JSON file -std::ifstream i("file.json"); -json j; -i >> j; - -// write prettified JSON to another file -std::ofstream o("pretty.json"); -o << std::setw(4) << j << std::endl; -``` - -Please note that setting the exception bit for `failbit` is inappropriate for this use case. It will result in program termination due to the `noexcept` specifier in use. - -#### Read from iterator range - -You can also parse JSON from an iterator range; that is, from any container accessible by iterators whose content is stored as contiguous byte sequence, for instance a `std::vector`: - -```cpp -std::vector v = {'t', 'r', 'u', 'e'}; -json j = json::parse(v.begin(), v.end()); -``` - -You may leave the iterators for the range [begin, end): - -```cpp -std::vector v = {'t', 'r', 'u', 'e'}; -json j = json::parse(v); -``` - -#### SAX interface - -The library uses a SAX-like interface with the following functions: - -```cpp -// called when null is parsed -bool null(); - -// called when a boolean is parsed; value is passed -bool boolean(bool val); - -// called when a signed or unsigned integer number is parsed; value is passed -bool number_integer(number_integer_t val); -bool number_unsigned(number_unsigned_t val); - -// called when a floating-point number is parsed; value and original string is passed -bool number_float(number_float_t val, const string_t& s); - -// called when a string is parsed; value is passed and can be safely moved away -bool string(string_t& val); - -// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known) -bool start_object(std::size_t elements); -bool end_object(); -bool start_array(std::size_t elements); -bool end_array(); -// called when an object key is parsed; value is passed and can be safely moved away -bool key(string_t& val); - -// called when a parse error occurs; byte position, the last token, and an exception is passed -bool parse_error(std::size_t position, const std::string& last_token, const detail::exception& ex); -``` - -The return value of each function determines whether parsing should proceed. - -To implement your own SAX handler, proceed as follows: - -1. Implement the SAX interface in a class. You can use class `nlohmann::json_sax` as base class, but you can also use any class where the functions described above are implemented and public. -2. Create an object of your SAX interface class, e.g. `my_sax`. -3. Call `bool json::sax_parse(input, &my_sax)`; where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface. - -Note the `sax_parse` function only returns a `bool` indicating the result of the last executed SAX event. It does not return a `json` value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your `parse_error` implementation. Internally, the SAX interface is used for the DOM parser (class `json_sax_dom_parser`) as well as the acceptor (`json_sax_acceptor`), see file [`json_sax.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/json_sax.hpp). - - -### STL-like access - -We designed the JSON class to behave just like an STL container. In fact, it satisfies the [**ReversibleContainer**](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) requirement. - -```cpp -// create an array using push_back -json j; -j.push_back("foo"); -j.push_back(1); -j.push_back(true); - -// also use emplace_back -j.emplace_back(1.78); - -// iterate the array -for (json::iterator it = j.begin(); it != j.end(); ++it) { - std::cout << *it << '\n'; -} - -// range-based for -for (auto& element : j) { - std::cout << element << '\n'; -} - -// getter/setter -const std::string tmp = j[0]; -j[1] = 42; -bool foo = j.at(2); - -// comparison -j == "[\"foo\", 1, true]"_json; // true - -// other stuff -j.size(); // 3 entries -j.empty(); // false -j.type(); // json::value_t::array -j.clear(); // the array is empty again - -// convenience type checkers -j.is_null(); -j.is_boolean(); -j.is_number(); -j.is_object(); -j.is_array(); -j.is_string(); - -// create an object -json o; -o["foo"] = 23; -o["bar"] = false; -o["baz"] = 3.141; - -// also use emplace -o.emplace("weather", "sunny"); - -// special iterator member functions for objects -for (json::iterator it = o.begin(); it != o.end(); ++it) { - std::cout << it.key() << " : " << it.value() << "\n"; -} - -// find an entry -if (o.find("foo") != o.end()) { - // there is an entry with key "foo" -} - -// or simpler using count() -int foo_present = o.count("foo"); // 1 -int fob_present = o.count("fob"); // 0 - -// delete an entry -o.erase("foo"); -``` - - -### Conversion from STL containers - -Any sequence container (`std::array`, `std::vector`, `std::deque`, `std::forward_list`, `std::list`) whose values can be used to construct JSON values (e.g., integers, floating point numbers, Booleans, string types, or again STL containers described in this section) can be used to create a JSON array. The same holds for similar associative containers (`std::set`, `std::multiset`, `std::unordered_set`, `std::unordered_multiset`), but in these cases the order of the elements of the array depends on how the elements are ordered in the respective STL container. - -```cpp -std::vector c_vector {1, 2, 3, 4}; -json j_vec(c_vector); -// [1, 2, 3, 4] - -std::deque c_deque {1.2, 2.3, 3.4, 5.6}; -json j_deque(c_deque); -// [1.2, 2.3, 3.4, 5.6] - -std::list c_list {true, true, false, true}; -json j_list(c_list); -// [true, true, false, true] - -std::forward_list c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543}; -json j_flist(c_flist); -// [12345678909876, 23456789098765, 34567890987654, 45678909876543] - -std::array c_array {{1, 2, 3, 4}}; -json j_array(c_array); -// [1, 2, 3, 4] - -std::set c_set {"one", "two", "three", "four", "one"}; -json j_set(c_set); // only one entry for "one" is used -// ["four", "one", "three", "two"] - -std::unordered_set c_uset {"one", "two", "three", "four", "one"}; -json j_uset(c_uset); // only one entry for "one" is used -// maybe ["two", "three", "four", "one"] - -std::multiset c_mset {"one", "two", "one", "four"}; -json j_mset(c_mset); // both entries for "one" are used -// maybe ["one", "two", "one", "four"] - -std::unordered_multiset c_umset {"one", "two", "one", "four"}; -json j_umset(c_umset); // both entries for "one" are used -// maybe ["one", "two", "one", "four"] -``` - -Likewise, any associative key-value containers (`std::map`, `std::multimap`, `std::unordered_map`, `std::unordered_multimap`) whose keys can construct an `std::string` and whose values can be used to construct JSON values (see examples above) can be used to create a JSON object. Note that in case of multimaps only one key is used in the JSON object and the value depends on the internal order of the STL container. - -```cpp -std::map c_map { {"one", 1}, {"two", 2}, {"three", 3} }; -json j_map(c_map); -// {"one": 1, "three": 3, "two": 2 } - -std::unordered_map c_umap { {"one", 1.2}, {"two", 2.3}, {"three", 3.4} }; -json j_umap(c_umap); -// {"one": 1.2, "two": 2.3, "three": 3.4} - -std::multimap c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} }; -json j_mmap(c_mmap); // only one entry for key "three" is used -// maybe {"one": true, "two": true, "three": true} - -std::unordered_multimap c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} }; -json j_ummap(c_ummap); // only one entry for key "three" is used -// maybe {"one": true, "two": true, "three": true} -``` - -### JSON Pointer and JSON Patch - -The library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as alternative means to address structured values. On top of this, **JSON Patch** ([RFC 6902](https://tools.ietf.org/html/rfc6902)) allows to describe differences between two JSON values - effectively allowing patch and diff operations known from Unix. - -```cpp -// a JSON value -json j_original = R"({ - "baz": ["one", "two", "three"], - "foo": "bar" -})"_json; - -// access members with a JSON pointer (RFC 6901) -j_original["/baz/1"_json_pointer]; -// "two" - -// a JSON patch (RFC 6902) -json j_patch = R"([ - { "op": "replace", "path": "/baz", "value": "boo" }, - { "op": "add", "path": "/hello", "value": ["world"] }, - { "op": "remove", "path": "/foo"} -])"_json; - -// apply the patch -json j_result = j_original.patch(j_patch); -// { -// "baz": "boo", -// "hello": ["world"] -// } - -// calculate a JSON patch from two JSON values -json::diff(j_result, j_original); -// [ -// { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] }, -// { "op": "remove","path": "/hello" }, -// { "op": "add", "path": "/foo", "value": "bar" } -// ] -``` - -### JSON Merge Patch - -The library supports **JSON Merge Patch** ([RFC 7386](https://tools.ietf.org/html/rfc7386)) as a patch format. Instead of using JSON Pointer (see above) to specify values to be manipulated, it describes the changes using a syntax that closely mimics the document being modified. - -```cpp -// a JSON value -json j_document = R"({ - "a": "b", - "c": { - "d": "e", - "f": "g" - } -})"_json; - -// a patch -json j_patch = R"({ - "a":"z", - "c": { - "f": null - } -})"_json; - -// apply the patch -j_original.merge_patch(j_patch); -// { -// "a": "z", -// "c": { -// "d": "e" -// } -// } -``` - -### Implicit conversions - -The type of the JSON object is determined automatically by the expression to store. Likewise, the stored value is implicitly converted. - -```cpp -// strings -std::string s1 = "Hello, world!"; -json js = s1; -std::string s2 = js; - -// Booleans -bool b1 = true; -json jb = b1; -bool b2 = jb; - -// numbers -int i = 42; -json jn = i; -double f = jn; - -// etc. -``` - -You can also explicitly ask for the value: - -```cpp -std::string vs = js.get(); -bool vb = jb.get(); -int vi = jn.get(); - -// etc. -``` - -Note that `char` types are not automatically converted to JSON strings, but to integer numbers. A conversion to a string must be specified explicitly: - -```cpp -char ch = 'A'; // ASCII value 65 -json j_default = ch; // stores integer number 65 -json j_string = std::string(1, ch); // stores string "A" -``` - -### Arbitrary types conversions - -Every type can be serialized in JSON, not just STL containers and scalar types. Usually, you would do something along those lines: - -```cpp -namespace ns { - // a simple struct to model a person - struct person { - std::string name; - std::string address; - int age; - }; -} - -ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; - -// convert to JSON: copy each value into the JSON object -json j; -j["name"] = p.name; -j["address"] = p.address; -j["age"] = p.age; - -// ... - -// convert from JSON: copy each value from the JSON object -ns::person p { - j["name"].get(), - j["address"].get(), - j["age"].get() -}; -``` - -It works, but that's quite a lot of boilerplate... Fortunately, there's a better way: - -```cpp -// create a person -ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60}; - -// conversion: person -> json -json j = p; - -std::cout << j << std::endl; -// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} - -// conversion: json -> person -ns::person p2 = j; - -// that's it -assert(p == p2); -``` - -#### Basic usage - -To make this work with one of your types, you only need to provide two functions: - -```cpp -using nlohmann::json; - -namespace ns { - void to_json(json& j, const person& p) { - j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}}; - } - - void from_json(const json& j, person& p) { - p.name = j.at("name").get(); - p.address = j.at("address").get(); - p.age = j.at("age").get(); - } -} // namespace ns -``` - -That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called. -Likewise, when calling `get()`, the `from_json` method will be called. - -Some important things: - -* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined). -* Those methods **MUST** be available (e.g., properly headers must be included) everywhere you use the implicit conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise. -* When using `get()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.) -* In function `from_json`, use function [`at()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a93403e803947b86f4da2d1fb3345cf2c.html#a93403e803947b86f4da2d1fb3345cf2c) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior. -* In case your type contains several `operator=` definitions, code like `your_variable = your_json;` [may not compile](https://github.com/nlohmann/json/issues/667). You need to write `your_variable = your_json.get();` instead. -* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these. -* Be careful with the definition order of the `from_json`/`to_json` functions: If a type `B` has a member of type `A`, you **MUST** define `to_json(A)` before `to_json(B)`. Look at [issue 561](https://github.com/nlohmann/json/issues/561) for more details. - - -#### How do I convert third-party types? - -This requires a bit more advanced technique. But first, let's see how this conversion mechanism works: - -The library uses **JSON Serializers** to convert types to json. -The default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)). - -It is implemented like this (simplified): - -```cpp -template -struct adl_serializer { - static void to_json(json& j, const T& value) { - // calls the "to_json" method in T's namespace - } - - static void from_json(const json& j, T& value) { - // same thing, but with the "from_json" method - } -}; -``` - -This serializer works fine when you have control over the type's namespace. However, what about `boost::optional` or `std::filesystem::path` (C++17)? Hijacking the `boost` namespace is pretty bad, and it's illegal to add something other than template specializations to `std`... - -To solve this, you need to add a specialization of `adl_serializer` to the `nlohmann` namespace, here's an example: - -```cpp -// partial specialization (full specialization works too) -namespace nlohmann { - template - struct adl_serializer> { - static void to_json(json& j, const boost::optional& opt) { - if (opt == boost::none) { - j = nullptr; - } else { - j = *opt; // this will call adl_serializer::to_json which will - // find the free function to_json in T's namespace! - } - } - - static void from_json(const json& j, boost::optional& opt) { - if (j.is_null()) { - opt = boost::none; - } else { - opt = j.get(); // same as above, but with - // adl_serializer::from_json - } - } - }; -} -``` - -#### How can I use `get()` for non-default constructible/non-copyable types? - -There is a way, if your type is [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload: - -```cpp -struct move_only_type { - move_only_type() = delete; - move_only_type(int ii): i(ii) {} - move_only_type(const move_only_type&) = delete; - move_only_type(move_only_type&&) = default; - - int i; -}; - -namespace nlohmann { - template <> - struct adl_serializer { - // note: the return type is no longer 'void', and the method only takes - // one argument - static move_only_type from_json(const json& j) { - return {j.get()}; - } - - // Here's the catch! You must provide a to_json method! Otherwise you - // will not be able to convert move_only_type to json, since you fully - // specialized adl_serializer on that type - static void to_json(json& j, move_only_type t) { - j = t.i; - } - }; -} -``` - -#### Can I write my own serializer? (Advanced use) - -Yes. You might want to take a look at [`unit-udt.cpp`](https://github.com/nlohmann/json/blob/develop/test/src/unit-udt.cpp) in the test suite, to see a few examples. - -If you write your own serializer, you'll need to do a few things: - -- use a different `basic_json` alias than `nlohmann::json` (the last template parameter of `basic_json` is the `JSONSerializer`) -- use your `basic_json` alias (or a template parameter) in all your `to_json`/`from_json` methods -- use `nlohmann::to_json` and `nlohmann::from_json` when you need ADL - -Here is an example, without simplifications, that only accepts types with a size <= 32, and uses ADL. - -```cpp -// You should use void as a second template argument -// if you don't need compile-time checks on T -template::type> -struct less_than_32_serializer { - template - static void to_json(BasicJsonType& j, T value) { - // we want to use ADL, and call the correct to_json overload - using nlohmann::to_json; // this method is called by adl_serializer, - // this is where the magic happens - to_json(j, value); - } - - template - static void from_json(const BasicJsonType& j, T& value) { - // same thing here - using nlohmann::from_json; - from_json(j, value); - } -}; -``` - -Be **very** careful when reimplementing your serializer, you can stack overflow if you don't pay attention: - -```cpp -template -struct bad_serializer -{ - template - static void to_json(BasicJsonType& j, const T& value) { - // this calls BasicJsonType::json_serializer::to_json(j, value); - // if BasicJsonType::json_serializer == bad_serializer ... oops! - j = value; - } - - template - static void to_json(const BasicJsonType& j, T& value) { - // this calls BasicJsonType::json_serializer::from_json(j, value); - // if BasicJsonType::json_serializer == bad_serializer ... oops! - value = j.template get(); // oops! - } -}; -``` - -### Binary formats (CBOR, MessagePack, and UBJSON) - -Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports [CBOR](http://cbor.io) (Concise Binary Object Representation), [MessagePack](http://msgpack.org), and [UBJSON](http://ubjson.org) (Universal Binary JSON Specification) to efficiently encode JSON values to byte vectors and to decode such vectors. - -```cpp -// create a JSON value -json j = R"({"compact": true, "schema": 0})"_json; - -// serialize to CBOR -std::vector v_cbor = json::to_cbor(j); - -// 0xA2, 0x67, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0xF5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00 - -// roundtrip -json j_from_cbor = json::from_cbor(v_cbor); - -// serialize to MessagePack -std::vector v_msgpack = json::to_msgpack(j); - -// 0x82, 0xA7, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0xC3, 0xA6, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00 - -// roundtrip -json j_from_msgpack = json::from_msgpack(v_msgpack); - -// serialize to UBJSON -std::vector v_ubjson = json::to_ubjson(j); - -// 0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D - -// roundtrip -json j_from_ubjson = json::from_ubjson(v_ubjson); -``` - - -## Supported compilers - -Though it's 2018 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work: - -- GCC 4.9 - 8.2 (and possibly later) -- Clang 3.4 - 6.1 (and possibly later) -- Intel C++ Compiler 17.0.2 (and possibly later) -- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later) -- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later) - -I would be happy to learn about other compilers/versions. - -Please note: - -- GCC 4.8 does not work because of two bugs ([55817](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55817) and [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824)) in the C++11 support. Note there is a [pull request](https://github.com/nlohmann/json/pull/212) to fix some of the issues. -- Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default. - - ``` - APP_STL := c++_shared - NDK_TOOLCHAIN_VERSION := clang3.6 - APP_CPPFLAGS += -frtti -fexceptions - ``` - - The code compiles successfully with [Android NDK](https://developer.android.com/ndk/index.html?hl=ml), Revision 9 - 11 (and possibly later) and [CrystaX's Android NDK](https://www.crystax.net/en/android/ndk) version 10. - -- For GCC running on MinGW or Android SDK, the error `'to_string' is not a member of 'std'` (or similarly, for `strtod`) may occur. Note this is not an issue with the code, but rather with the compiler itself. On Android, see above to build with a newer environment. For MinGW, please refer to [this site](http://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219). - -- Unsupported versions of GCC and Clang are rejected by `#error` directives. This can be switched off by defining `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`. Note that you can expect no support in this case. - -The following compilers are currently used in continuous integration at [Travis](https://travis-ci.org/nlohmann/json) and [AppVeyor](https://ci.appveyor.com/project/nlohmann/json): - -| Compiler | Operating System | Version String | -|-----------------|------------------------------|----------------| -| GCC 4.9.4 | Ubuntu 14.04.1 LTS | g++-4.9 (Ubuntu 4.9.4-2ubuntu1~14.04.1) 4.9.4 | -| GCC 5.5.0 | Ubuntu 14.04.1 LTS | g++-5 (Ubuntu 5.5.0-12ubuntu1~14.04) 5.5.0 20171010 | -| GCC 6.4.0 | Ubuntu 14.04.1 LTS | g++-6 (Ubuntu 6.4.0-17ubuntu1~14.04) 6.4.0 20180424 | -| GCC 7.3.0 | Ubuntu 14.04.1 LTS | g++-7 (Ubuntu 7.3.0-21ubuntu1~14.04) 7.3.0 | -| GCC 7.3.0 | Windows Server 2012 R2 (x64) | g++ (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 7.3.0 | -| GCC 8.1.0 | Ubuntu 14.04.1 LTS | g++-8 (Ubuntu 8.1.0-5ubuntu1~14.04) 8.1.0 | -| Clang 3.5.0 | Ubuntu 14.04.1 LTS | clang version 3.5.0-4ubuntu2~trusty2 (tags/RELEASE_350/final) (based on LLVM 3.5.0) | -| Clang 3.6.2 | Ubuntu 14.04.1 LTS | clang version 3.6.2-svn240577-1~exp1 (branches/release_36) (based on LLVM 3.6.2) | -| Clang 3.7.1 | Ubuntu 14.04.1 LTS | clang version 3.7.1-svn253571-1~exp1 (branches/release_37) (based on LLVM 3.7.1) | -| Clang 3.8.0 | Ubuntu 14.04.1 LTS | clang version 3.8.0-2ubuntu3~trusty5 (tags/RELEASE_380/final) | -| Clang 3.9.1 | Ubuntu 14.04.1 LTS | clang version 3.9.1-4ubuntu3~14.04.3 (tags/RELEASE_391/rc2) | -| Clang 4.0.1 | Ubuntu 14.04.1 LTS | clang version 4.0.1-svn305264-1~exp1 (branches/release_40) | -| Clang 5.0.2 | Ubuntu 14.04.1 LTS | clang version 5.0.2-svn328729-1~exp1~20180509123505.100 (branches/release_50) | -| Clang 6.0.1 | Ubuntu 14.04.1 LTS | clang version 6.0.1-svn334776-1~exp1~20180726133705.85 (branches/release_60) | -| Clang Xcode 6.4 | OSX 10.10.5 | Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn) | -| Clang Xcode 7.3 | OSX 10.11.6 | Apple LLVM version 7.3.0 (clang-703.0.31) | -| Clang Xcode 8.0 | OSX 10.11.6 | Apple LLVM version 8.0.0 (clang-800.0.38) | -| Clang Xcode 8.1 | OSX 10.12.6 | Apple LLVM version 8.0.0 (clang-800.0.42.1) | -| Clang Xcode 8.2 | OSX 10.12.6 | Apple LLVM version 8.0.0 (clang-800.0.42.1) | -| Clang Xcode 8.3 | OSX 10.11.6 | Apple LLVM version 8.1.0 (clang-802.0.38) | -| Clang Xcode 9.0 | OSX 10.12.6 | Apple LLVM version 9.0.0 (clang-900.0.37) | -| Clang Xcode 9.1 | OSX 10.12.6 | Apple LLVM version 9.0.0 (clang-900.0.38) | -| Clang Xcode 9.2 | OSX 10.13.3 | Apple LLVM version 9.1.0 (clang-902.0.39.1) | -| Clang Xcode 9.3 | OSX 10.13.3 | Apple LLVM version 9.1.0 (clang-902.0.39.2) | -| Visual Studio 14 2015 | Windows Server 2012 R2 (x64) | Microsoft (R) Build Engine version 14.0.25420.1, MSVC 19.0.24215.1 | -| Visual Studio 2017 | Windows Server 2016 | Microsoft (R) Build Engine version 15.7.180.61344, MSVC 19.14.26433.0 | - -## License - - - -The class is licensed under the [MIT License](http://opensource.org/licenses/MIT): - -Copyright © 2013-2018 [Niels Lohmann](http://nlohmann.me) - -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. - -* * * - -The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the [MIT License](http://opensource.org/licenses/MIT) (see above). Copyright © 2008-2009 [Björn Hoehrmann](http://bjoern.hoehrmann.de/) - -The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](http://opensource.org/licenses/MIT) (see above). Copyright © 2009 [Florian Loitsch](http://florian.loitsch.com/) - -## Contact - -If you have questions regarding the library, I would like to invite you to [open an issue at GitHub](https://github.com/nlohmann/json/issues/new). Please describe your request, problem, or question as detailed as possible, and also mention the version of the library you are using as well as the version of your compiler and operating system. Opening an issue at GitHub allows other users and contributors to this library to collaborate. For instance, I have little experience with MSVC, and most issues in this regard have been solved by a growing community. If you have a look at the [closed issues](https://github.com/nlohmann/json/issues?q=is%3Aissue+is%3Aclosed), you will see that we react quite timely in most cases. - -Only if your request would contain confidential information, please [send me an email](mailto:mail@nlohmann.me). For encrypted messages, please use [this key](https://keybase.io/nlohmann/pgp_keys.asc). - -## Security - -[Commits by Niels Lohmann](https://github.com/nlohmann/json/commits) and [releases](https://github.com/nlohmann/json/releases) are signed with this [PGP Key](https://keybase.io/nlohmann/pgp_keys.asc?fingerprint=797167ae41c0a6d9232e48457f3cea63ae251b69). - -## Thanks - -I deeply appreciate the help of the following people. - -![Contributors](https://raw.githubusercontent.com/nlohmann/json/develop/doc/avatars.png) - -- [Teemperor](https://github.com/Teemperor) implemented CMake support and lcov integration, realized escape and Unicode handling in the string parser, and fixed the JSON serialization. -- [elliotgoodrich](https://github.com/elliotgoodrich) fixed an issue with double deletion in the iterator classes. -- [kirkshoop](https://github.com/kirkshoop) made the iterators of the class composable to other libraries. -- [wancw](https://github.com/wanwc) fixed a bug that hindered the class to compile with Clang. -- Tomas Åblad found a bug in the iterator implementation. -- [Joshua C. Randall](https://github.com/jrandall) fixed a bug in the floating-point serialization. -- [Aaron Burghardt](https://github.com/aburgh) implemented code to parse streams incrementally. Furthermore, he greatly improved the parser class by allowing the definition of a filter function to discard undesired elements while parsing. -- [Daniel Kopeček](https://github.com/dkopecek) fixed a bug in the compilation with GCC 5.0. -- [Florian Weber](https://github.com/Florianjw) fixed a bug in and improved the performance of the comparison operators. -- [Eric Cornelius](https://github.com/EricMCornelius) pointed out a bug in the handling with NaN and infinity values. He also improved the performance of the string escaping. -- [易思龙](https://github.com/likebeta) implemented a conversion from anonymous enums. -- [kepkin](https://github.com/kepkin) patiently pushed forward the support for Microsoft Visual studio. -- [gregmarr](https://github.com/gregmarr) simplified the implementation of reverse iterators and helped with numerous hints and improvements. In particular, he pushed forward the implementation of user-defined types. -- [Caio Luppi](https://github.com/caiovlp) fixed a bug in the Unicode handling. -- [dariomt](https://github.com/dariomt) fixed some typos in the examples. -- [Daniel Frey](https://github.com/d-frey) cleaned up some pointers and implemented exception-safe memory allocation. -- [Colin Hirsch](https://github.com/ColinH) took care of a small namespace issue. -- [Huu Nguyen](https://github.com/whoshuu) correct a variable name in the documentation. -- [Silverweed](https://github.com/silverweed) overloaded `parse()` to accept an rvalue reference. -- [dariomt](https://github.com/dariomt) fixed a subtlety in MSVC type support and implemented the `get_ref()` function to get a reference to stored values. -- [ZahlGraf](https://github.com/ZahlGraf) added a workaround that allows compilation using Android NDK. -- [whackashoe](https://github.com/whackashoe) replaced a function that was marked as unsafe by Visual Studio. -- [406345](https://github.com/406345) fixed two small warnings. -- [Glen Fernandes](https://github.com/glenfe) noted a potential portability problem in the `has_mapped_type` function. -- [Corbin Hughes](https://github.com/nibroc) fixed some typos in the contribution guidelines. -- [twelsby](https://github.com/twelsby) fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. He further added support for unsigned integer numbers and implemented better roundtrip support for parsed numbers. -- [Volker Diels-Grabsch](https://github.com/vog) fixed a link in the README file. -- [msm-](https://github.com/msm-) added support for American Fuzzy Lop. -- [Annihil](https://github.com/Annihil) fixed an example in the README file. -- [Themercee](https://github.com/Themercee) noted a wrong URL in the README file. -- [Lv Zheng](https://github.com/lv-zheng) fixed a namespace issue with `int64_t` and `uint64_t`. -- [abc100m](https://github.com/abc100m) analyzed the issues with GCC 4.8 and proposed a [partial solution](https://github.com/nlohmann/json/pull/212). -- [zewt](https://github.com/zewt) added useful notes to the README file about Android. -- [Róbert Márki](https://github.com/robertmrk) added a fix to use move iterators and improved the integration via CMake. -- [Chris Kitching](https://github.com/ChrisKitching) cleaned up the CMake files. -- [Tom Needham](https://github.com/06needhamt) fixed a subtle bug with MSVC 2015 which was also proposed by [Michael K.](https://github.com/Epidal). -- [Mário Feroldi](https://github.com/thelostt) fixed a small typo. -- [duncanwerner](https://github.com/duncanwerner) found a really embarrassing performance regression in the 2.0.0 release. -- [Damien](https://github.com/dtoma) fixed one of the last conversion warnings. -- [Thomas Braun](https://github.com/t-b) fixed a warning in a test case. -- [Théo DELRIEU](https://github.com/theodelrieu) patiently and constructively oversaw the long way toward [iterator-range parsing](https://github.com/nlohmann/json/issues/290). He also implemented the magic behind the serialization/deserialization of user-defined types and split the single header file into smaller chunks. -- [Stefan](https://github.com/5tefan) fixed a minor issue in the documentation. -- [Vasil Dimov](https://github.com/vasild) fixed the documentation regarding conversions from `std::multiset`. -- [ChristophJud](https://github.com/ChristophJud) overworked the CMake files to ease project inclusion. -- [Vladimir Petrigo](https://github.com/vpetrigo) made a SFINAE hack more readable and added Visual Studio 17 to the build matrix. -- [Denis Andrejew](https://github.com/seeekr) fixed a grammar issue in the README file. -- [Pierre-Antoine Lacaze](https://github.com/palacaze) found a subtle bug in the `dump()` function. -- [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](https://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling, found some nice performance improvements in the parser, improved the benchmarking code, and realized locale-independent number parsing and printing. -- [cgzones](https://github.com/cgzones) had an idea how to fix the Coverity scan. -- [Jared Grubb](https://github.com/jaredgrubb) silenced a nasty documentation warning. -- [Yixin Zhang](https://github.com/qwename) fixed an integer overflow check. -- [Bosswestfalen](https://github.com/Bosswestfalen) merged two iterator classes into a smaller one. -- [Daniel599](https://github.com/Daniel599) helped to get Travis execute the tests with Clang's sanitizers. -- [Jonathan Lee](https://github.com/vjon) fixed an example in the README file. -- [gnzlbg](https://github.com/gnzlbg) supported the implementation of user-defined types. -- [Alexej Harm](https://github.com/qis) helped to get the user-defined types working with Visual Studio. -- [Jared Grubb](https://github.com/jaredgrubb) supported the implementation of user-defined types. -- [EnricoBilla](https://github.com/EnricoBilla) noted a typo in an example. -- [Martin Hořeňovský](https://github.com/horenmar) found a way for a 2x speedup for the compilation time of the test suite. -- [ukhegg](https://github.com/ukhegg) found proposed an improvement for the examples section. -- [rswanson-ihi](https://github.com/rswanson-ihi) noted a typo in the README. -- [Mihai Stan](https://github.com/stanmihai4) fixed a bug in the comparison with `nullptr`s. -- [Tushar Maheshwari](https://github.com/tusharpm) added [cotire](https://github.com/sakra/cotire) support to speed up the compilation. -- [TedLyngmo](https://github.com/TedLyngmo) noted a typo in the README, removed unnecessary bit arithmetic, and fixed some `-Weffc++` warnings. -- [Krzysztof Woś](https://github.com/krzysztofwos) made exceptions more visible. -- [ftillier](https://github.com/ftillier) fixed a compiler warning. -- [tinloaf](https://github.com/tinloaf) made sure all pushed warnings are properly popped. -- [Fytch](https://github.com/Fytch) found a bug in the documentation. -- [Jay Sistar](https://github.com/Type1J) implemented a Meson build description. -- [Henry Lee](https://github.com/HenryRLee) fixed a warning in ICC and improved the iterator implementation. -- [Vincent Thiery](https://github.com/vthiery) maintains a package for the Conan package manager. -- [Steffen](https://github.com/koemeet) fixed a potential issue with MSVC and `std::min`. -- [Mike Tzou](https://github.com/Chocobo1) fixed some typos. -- [amrcode](https://github.com/amrcode) noted a misleading documentation about comparison of floats. -- [Oleg Endo](https://github.com/olegendo) reduced the memory consumption by replacing `` with ``. -- [dan-42](https://github.com/dan-42) cleaned up the CMake files to simplify including/reusing of the library. -- [Nikita Ofitserov](https://github.com/himikof) allowed for moving values from initializer lists. -- [Greg Hurrell](https://github.com/wincent) fixed a typo. -- [Dmitry Kukovinets](https://github.com/DmitryKuk) fixed a typo. -- [kbthomp1](https://github.com/kbthomp1) fixed an issue related to the Intel OSX compiler. -- [Markus Werle](https://github.com/daixtrose) fixed a typo. -- [WebProdPP](https://github.com/WebProdPP) fixed a subtle error in a precondition check. -- [Alex](https://github.com/leha-bot) noted an error in a code sample. -- [Tom de Geus](https://github.com/tdegeus) reported some warnings with ICC and helped fixing them. -- [Perry Kundert](https://github.com/pjkundert) simplified reading from input streams. -- [Sonu Lohani](https://github.com/sonulohani) fixed a small compilation error. -- [Jamie Seward](https://github.com/jseward) fixed all MSVC warnings. -- [Nate Vargas](https://github.com/eld00d) added a Doxygen tag file. -- [pvleuven](https://github.com/pvleuven) helped fixing a warning in ICC. -- [Pavel](https://github.com/crea7or) helped fixing some warnings in MSVC. -- [Jamie Seward](https://github.com/jseward) avoided unnecessary string copies in `find()` and `count()`. -- [Mitja](https://github.com/Itja) fixed some typos. -- [Jorrit Wronski](https://github.com/jowr) updated the Hunter package links. -- [Matthias Möller](https://github.com/TinyTinni) added a `.natvis` for the MSVC debug view. -- [bogemic](https://github.com/bogemic) fixed some C++17 deprecation warnings. -- [Eren Okka](https://github.com/erengy) fixed some MSVC warnings. -- [abolz](https://github.com/abolz) integrated the Grisu2 algorithm for proper floating-point formatting, allowing more roundtrip checks to succeed. -- [Vadim Evard](https://github.com/Pipeliner) fixed a Markdown issue in the README. -- [zerodefect](https://github.com/zerodefect) fixed a compiler warning. -- [Kert](https://github.com/kaidokert) allowed to template the string type in the serialization and added the possibility to override the exceptional behavior. -- [mark-99](https://github.com/mark-99) helped fixing an ICC error. -- [Patrik Huber](https://github.com/patrikhuber) fixed links in the README file. -- [johnfb](https://github.com/johnfb) found a bug in the implementation of CBOR's indefinite length strings. -- [Paul Fultz II](https://github.com/pfultz2) added a note on the cget package manager. -- [Wilson Lin](https://github.com/wla80) made the integration section of the README more concise. -- [RalfBielig](https://github.com/ralfbielig) detected and fixed a memory leak in the parser callback. -- [agrianius](https://github.com/agrianius) allowed to dump JSON to an alternative string type. -- [Kevin Tonon](https://github.com/ktonon) overworked the C++11 compiler checks in CMake. -- [Axel Huebl](https://github.com/ax3l) simplified a CMake check and added support for the [Spack package manager](https://spack.io). -- [Carlos O'Ryan](https://github.com/coryan) fixed a typo. -- [James Upjohn](https://github.com/jammehcow) fixed a version number in the compilers section. -- [Chuck Atkins](https://github.com/chuckatkins) adjusted the CMake files to the CMake packaging guidelines -- [Jan Schöppach](https://github.com/dns13) fixed a typo. -- [martin-mfg](https://github.com/martin-mfg) fixed a typo. -- [Matthias Möller](https://github.com/TinyTinni) removed the dependency from `std::stringstream`. -- [agrianius](https://github.com/agrianius) added code to use alternative string implementations. -- [Daniel599](https://github.com/Daniel599) allowed to use more algorithms with the `items()` function. -- [Julius Rakow](https://github.com/jrakow) fixed the Meson include directory and fixed the links to [cppreference.com](cppreference.com). -- [Sonu Lohani](https://github.com/sonulohani) fixed the compilation with MSVC 2015 in debug mode. -- [grembo](https://github.com/grembo) fixed the test suite and re-enabled several test cases. -- [Hyeon Kim](https://github.com/simnalamburt) introduced the macro `JSON_INTERNAL_CATCH` to control the exception handling inside the library. -- [thyu](https://github.com/thyu) fixed a compiler warning. - -Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone. - - -## Used third-party tools - -The library itself consists of a single header file licensed under the MIT license. However, it is built, tested, documented, and whatnot using a lot of third-party tools and services. Thanks a lot! - -- [**amalgamate.py - Amalgamate C source and header files**](https://github.com/edlund/amalgamate) to create a single header file -- [**American fuzzy lop**](http://lcamtuf.coredump.cx/afl/) for fuzz testing -- [**AppVeyor**](https://www.appveyor.com) for [continuous integration](https://ci.appveyor.com/project/nlohmann/json) on Windows -- [**Artistic Style**](http://astyle.sourceforge.net) for automatic source code identation -- [**Catch**](https://github.com/philsquared/Catch) for the unit tests -- [**Clang**](http://clang.llvm.org) for compilation with code sanitizers -- [**Cmake**](https://cmake.org) for build automation -- [**Codacity**](https://www.codacy.com) for further [code analysis](https://www.codacy.com/app/nlohmann/json) -- [**Coveralls**](https://coveralls.io) to measure [code coverage](https://coveralls.io/github/nlohmann/json) -- [**Coverity Scan**](https://scan.coverity.com) for [static analysis](https://scan.coverity.com/projects/nlohmann-json) -- [**cppcheck**](http://cppcheck.sourceforge.net) for static analysis -- [**Doxygen**](http://www.stack.nl/~dimitri/doxygen/) to generate [documentation](https://nlohmann.github.io/json/) -- [**git-update-ghpages**](https://github.com/rstacruz/git-update-ghpages) to upload the documentation to gh-pages -- [**GitHub Changelog Generator**](https://github.com/skywinder/github-changelog-generator) to generate the [ChangeLog](https://github.com/nlohmann/json/blob/develop/ChangeLog.md) -- [**Google Benchmark**](https://github.com/google/benchmark) to implement the benchmarks -- [**libFuzzer**](http://llvm.org/docs/LibFuzzer.html) to implement fuzz testing for OSS-Fuzz -- [**OSS-Fuzz**](https://github.com/google/oss-fuzz) for continuous fuzz testing of the library ([project repository](https://github.com/google/oss-fuzz/tree/master/projects/json)) -- [**Probot**](https://probot.github.io) for automating maintainer tasks such as closing stale issues, requesting missing information, or detecting toxic comments. -- [**send_to_wandbox**](https://github.com/nlohmann/json/blob/develop/doc/scripts/send_to_wandbox.py) to send code examples to [Wandbox](http://melpon.org/wandbox) -- [**Travis**](https://travis-ci.org) for [continuous integration](https://travis-ci.org/nlohmann/json) on Linux and macOS -- [**Valgrind**](http://valgrind.org) to check for correct memory management -- [**Wandbox**](http://melpon.org/wandbox) for [online examples](https://wandbox.org/permlink/TarF5pPn9NtHQjhf) - - -## Projects using JSON for Modern C++ - -The library is currently used in Apple macOS Sierra and iOS 10. I am not sure what they are using the library for, but I am happy that it runs on so many devices. - - -## Notes - -- The code contains numerous debug **assertions** which can be switched off by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](https://en.cppreference.com/w/cpp/error/assert). In particular, note [`operator[]`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a2e26bd0b0168abb61f67ad5bcd5b9fa1.html#a2e26bd0b0168abb61f67ad5bcd5b9fa1) implements **unchecked access** for const objects: If the given key is not present, the behavior is undefined (think of a dereferenced null pointer) and yields an [assertion failure](https://github.com/nlohmann/json/issues/289) if assertions are switched on. If you are not sure whether an element in an object exists, use checked access with the [`at()` function](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a674de1ee73e6bf4843fc5dc1351fb726.html#a674de1ee73e6bf4843fc5dc1351fb726). -- As the exact type of a number is not defined in the [JSON specification](http://rfc7159.net/rfc7159), this library tries to choose the best fitting C++ number type automatically. As a result, the type `double` may be used to store numbers which may yield [**floating-point exceptions**](https://github.com/nlohmann/json/issues/181) in certain rare situations if floating-point exceptions have been unmasked in the calling code. These exceptions are not caused by the library and need to be fixed in the calling code, such as by re-masking the exceptions prior to calling library functions. -- The library supports **Unicode input** as follows: - - Only **UTF-8** encoded input is supported which is the default encoding for JSON according to [RFC 7159](http://rfc7159.net/rfc7159#rfc.section.8.1). - - Other encodings such as Latin-1, UTF-16, or UTF-32 are not supported and will yield parse or serialization errors. - - [Unicode noncharacters](http://www.unicode.org/faq/private_use.html#nonchar1) will not be replaced by the library. - - Invalid surrogates (e.g., incomplete pairs such as `\uDEAD`) will yield parse errors. - - The strings stored in the library are UTF-8 encoded. When using the default string type (`std::string`), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs. -- The code can be compiled without C++ **runtime type identification** features; that is, you can use the `-fno-rtti` compiler flag. -- **Exceptions** are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION`. In this case, exceptions are replaced by an `abort()` call. -- By default, the library does not preserve the **insertion order of object elements**. This is standards-compliant, as the [JSON standard](https://tools.ietf.org/html/rfc7159.html) defines objects as "an unordered collection of zero or more name/value pairs". If you do want to preserve the insertion order, you can specialize the object type with containers like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)). - - -## Execute unit tests - -To compile and run the tests, you need to execute - -```sh -$ mkdir build -$ cd build -$ cmake .. -$ cmake --build . -$ ctest --output-on-failure -``` - -For more information, have a look at the file [.travis.yml](https://github.com/nlohmann/json/blob/master/.travis.yml). diff --git a/ext/nlohmann/json.hpp b/ext/nlohmann/json.hpp deleted file mode 100644 index 8959265da..000000000 --- a/ext/nlohmann/json.hpp +++ /dev/null @@ -1,26640 +0,0 @@ -/* - __ _____ _____ _____ - __| | __| | | | JSON for Modern C++ -| | |__ | | | | | | version 3.10.2 -|_____|_____|_____|_|___| https://github.com/nlohmann/json - -Licensed under the MIT License . -SPDX-License-Identifier: MIT -Copyright (c) 2013-2019 Niels Lohmann . - -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_NLOHMANN_JSON_HPP_ -#define INCLUDE_NLOHMANN_JSON_HPP_ - -#define NLOHMANN_JSON_VERSION_MAJOR 3 -#define NLOHMANN_JSON_VERSION_MINOR 10 -#define NLOHMANN_JSON_VERSION_PATCH 2 - -#include // all_of, find, for_each -#include // nullptr_t, ptrdiff_t, size_t -#include // hash, less -#include // initializer_list -#ifndef JSON_NO_IO - #include // istream, ostream -#endif // JSON_NO_IO -#include // random_access_iterator_tag -#include // unique_ptr -#include // accumulate -#include // string, stoi, to_string -#include // declval, forward, move, pair, swap -#include // vector - -// #include - - -#include -#include - -// #include - - -#include // transform -#include // array -#include // forward_list -#include // inserter, front_inserter, end -#include // map -#include // string -#include // tuple, make_tuple -#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible -#include // unordered_map -#include // pair, declval -#include // valarray - -// #include - - -#include // exception -#include // runtime_error -#include // to_string -#include // vector - -// #include - - -#include // array -#include // size_t -#include // uint8_t -#include // string - -namespace nlohmann -{ -namespace detail -{ -/////////////////////////// -// JSON type enumeration // -/////////////////////////// - -/*! -@brief the JSON type enumeration - -This enumeration collects the different JSON types. It is internally used to -distinguish the stored values, and the functions @ref basic_json::is_null(), -@ref basic_json::is_object(), @ref basic_json::is_array(), -@ref basic_json::is_string(), @ref basic_json::is_boolean(), -@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), -@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), -@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and -@ref basic_json::is_structured() rely on it. - -@note There are three enumeration entries (number_integer, number_unsigned, and -number_float), because the library distinguishes these three types for numbers: -@ref basic_json::number_unsigned_t is used for unsigned integers, -@ref basic_json::number_integer_t is used for signed integers, and -@ref basic_json::number_float_t is used for floating-point numbers or to -approximate integers which do not fit in the limits of their respective type. - -@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON -value with the default value for a given type - -@since version 1.0.0 -*/ -enum class value_t : std::uint8_t -{ - null, ///< null value - object, ///< object (unordered set of name/value pairs) - array, ///< array (ordered collection of values) - string, ///< string value - boolean, ///< boolean value - number_integer, ///< number value (signed integer) - number_unsigned, ///< number value (unsigned integer) - number_float, ///< number value (floating-point) - binary, ///< binary array (ordered collection of bytes) - discarded ///< discarded by the parser callback function -}; - -/*! -@brief comparison operator for JSON types - -Returns an ordering that is similar to Python: -- order: null < boolean < number < object < array < string < binary -- furthermore, each type is not smaller than itself -- discarded values are not comparable -- binary is represented as a b"" string in python and directly comparable to a - string; however, making a binary array directly comparable with a string would - be surprising behavior in a JSON file. - -@since version 1.0.0 -*/ -inline bool operator<(const value_t lhs, const value_t rhs) noexcept -{ - static constexpr std::array order = {{ - 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, - 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, - 6 /* binary */ - } - }; - - const auto l_index = static_cast(lhs); - const auto r_index = static_cast(rhs); - return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; -} -} // namespace detail -} // namespace nlohmann - -// #include - - -#include -// #include - - -#include // pair -// #include - - -/* Hedley - https://nemequ.github.io/hedley - * Created by Evan Nemerson - * - * To the extent possible under law, the author(s) have dedicated all - * copyright and related and neighboring rights to this software to - * the public domain worldwide. This software is distributed without - * any warranty. - * - * For details, see . - * SPDX-License-Identifier: CC0-1.0 - */ - -#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) -#if defined(JSON_HEDLEY_VERSION) - #undef JSON_HEDLEY_VERSION -#endif -#define JSON_HEDLEY_VERSION 15 - -#if defined(JSON_HEDLEY_STRINGIFY_EX) - #undef JSON_HEDLEY_STRINGIFY_EX -#endif -#define JSON_HEDLEY_STRINGIFY_EX(x) #x - -#if defined(JSON_HEDLEY_STRINGIFY) - #undef JSON_HEDLEY_STRINGIFY -#endif -#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) - -#if defined(JSON_HEDLEY_CONCAT_EX) - #undef JSON_HEDLEY_CONCAT_EX -#endif -#define JSON_HEDLEY_CONCAT_EX(a,b) a##b - -#if defined(JSON_HEDLEY_CONCAT) - #undef JSON_HEDLEY_CONCAT -#endif -#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) - -#if defined(JSON_HEDLEY_CONCAT3_EX) - #undef JSON_HEDLEY_CONCAT3_EX -#endif -#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c - -#if defined(JSON_HEDLEY_CONCAT3) - #undef JSON_HEDLEY_CONCAT3 -#endif -#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) - -#if defined(JSON_HEDLEY_VERSION_ENCODE) - #undef JSON_HEDLEY_VERSION_ENCODE -#endif -#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) - #undef JSON_HEDLEY_VERSION_DECODE_MAJOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) - #undef JSON_HEDLEY_VERSION_DECODE_MINOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) - #undef JSON_HEDLEY_VERSION_DECODE_REVISION -#endif -#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) - -#if defined(JSON_HEDLEY_GNUC_VERSION) - #undef JSON_HEDLEY_GNUC_VERSION -#endif -#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#elif defined(__GNUC__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) -#endif - -#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) - #undef JSON_HEDLEY_GNUC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GNUC_VERSION) - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION) - #undef JSON_HEDLEY_MSVC_VERSION -#endif -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) -#elif defined(_MSC_FULL_VER) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) -#elif defined(_MSC_VER) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) - #undef JSON_HEDLEY_MSVC_VERSION_CHECK -#endif -#if !defined(JSON_HEDLEY_MSVC_VERSION) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) -#elif defined(_MSC_VER) && (_MSC_VER >= 1200) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) -#else - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION) - #undef JSON_HEDLEY_INTEL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) -#elif defined(__INTEL_COMPILER) && !defined(__ICL) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) - #undef JSON_HEDLEY_INTEL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_VERSION) - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) - #undef JSON_HEDLEY_INTEL_CL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) - #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) - #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) - #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION) - #undef JSON_HEDLEY_PGI_VERSION -#endif -#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) - #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) - #undef JSON_HEDLEY_PGI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PGI_VERSION) - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #undef JSON_HEDLEY_SUNPRO_VERSION -#endif -#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) -#elif defined(__SUNPRO_C) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) -#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) -#elif defined(__SUNPRO_CC) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) - #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION -#endif -#if defined(__EMSCRIPTEN__) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION) - #undef JSON_HEDLEY_ARM_VERSION -#endif -#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) -#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) - #undef JSON_HEDLEY_ARM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_ARM_VERSION) - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION) - #undef JSON_HEDLEY_IBM_VERSION -#endif -#if defined(__ibmxl__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) -#elif defined(__xlC__) && defined(__xlC_ver__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) -#elif defined(__xlC__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) - #undef JSON_HEDLEY_IBM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IBM_VERSION) - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_VERSION) - #undef JSON_HEDLEY_TI_VERSION -#endif -#if \ - defined(__TI_COMPILER_VERSION__) && \ - ( \ - defined(__TMS470__) || defined(__TI_ARM__) || \ - defined(__MSP430__) || \ - defined(__TMS320C2000__) \ - ) -#if (__TI_COMPILER_VERSION__ >= 16000000) - #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif -#endif - -#if defined(JSON_HEDLEY_TI_VERSION_CHECK) - #undef JSON_HEDLEY_TI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_VERSION) - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #undef JSON_HEDLEY_TI_CL2000_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) - #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #undef JSON_HEDLEY_TI_CL430_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) - #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #undef JSON_HEDLEY_TI_ARMCL_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) - #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) - #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #undef JSON_HEDLEY_TI_CL6X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) - #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #undef JSON_HEDLEY_TI_CL7X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) - #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #undef JSON_HEDLEY_TI_CLPRU_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) - #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION) - #undef JSON_HEDLEY_CRAY_VERSION -#endif -#if defined(_CRAYC) - #if defined(_RELEASE_PATCHLEVEL) - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) - #else - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) - #undef JSON_HEDLEY_CRAY_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_CRAY_VERSION) - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION) - #undef JSON_HEDLEY_IAR_VERSION -#endif -#if defined(__IAR_SYSTEMS_ICC__) - #if __VER__ > 1000 - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) - #else - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) - #undef JSON_HEDLEY_IAR_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IAR_VERSION) - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION) - #undef JSON_HEDLEY_TINYC_VERSION -#endif -#if defined(__TINYC__) - #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) - #undef JSON_HEDLEY_TINYC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION) - #undef JSON_HEDLEY_DMC_VERSION -#endif -#if defined(__DMC__) - #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) - #undef JSON_HEDLEY_DMC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_DMC_VERSION) - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #undef JSON_HEDLEY_COMPCERT_VERSION -#endif -#if defined(__COMPCERT_VERSION__) - #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) - #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION) - #undef JSON_HEDLEY_PELLES_VERSION -#endif -#if defined(__POCC__) - #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) - #undef JSON_HEDLEY_PELLES_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PELLES_VERSION) - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) - #undef JSON_HEDLEY_MCST_LCC_VERSION -#endif -#if defined(__LCC__) && defined(__LCC_MINOR__) - #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) - #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) - #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION) - #undef JSON_HEDLEY_GCC_VERSION -#endif -#if \ - defined(JSON_HEDLEY_GNUC_VERSION) && \ - !defined(__clang__) && \ - !defined(JSON_HEDLEY_INTEL_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_ARM_VERSION) && \ - !defined(JSON_HEDLEY_CRAY_VERSION) && \ - !defined(JSON_HEDLEY_TI_VERSION) && \ - !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ - !defined(__COMPCERT__) && \ - !defined(JSON_HEDLEY_MCST_LCC_VERSION) - #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GCC_VERSION) - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_ATTRIBUTE -#endif -#if \ - defined(__has_attribute) && \ - ( \ - (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ - ) -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) -#else -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE -#endif -#if \ - defined(__has_cpp_attribute) && \ - defined(__cplusplus) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS -#endif -#if !defined(__cplusplus) || !defined(__has_cpp_attribute) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#elif \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ - (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_BUILTIN) - #undef JSON_HEDLEY_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) -#else - #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) - #undef JSON_HEDLEY_GNUC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) - #undef JSON_HEDLEY_GCC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_FEATURE) - #undef JSON_HEDLEY_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) -#else - #define JSON_HEDLEY_HAS_FEATURE(feature) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) - #undef JSON_HEDLEY_GNUC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) - #undef JSON_HEDLEY_GCC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_EXTENSION) - #undef JSON_HEDLEY_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) -#else - #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) - #undef JSON_HEDLEY_GNUC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) - #undef JSON_HEDLEY_GCC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_WARNING) - #undef JSON_HEDLEY_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) -#else - #define JSON_HEDLEY_HAS_WARNING(warning) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) - #undef JSON_HEDLEY_GNUC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_WARNING) - #undef JSON_HEDLEY_GCC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - defined(__clang__) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) - #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_PRAGMA(value) __pragma(value) -#else - #define JSON_HEDLEY_PRAGMA(value) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) - #undef JSON_HEDLEY_DIAGNOSTIC_PUSH -#endif -#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) - #undef JSON_HEDLEY_DIAGNOSTIC_POP -#endif -#if defined(__clang__) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) - #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) -#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_PUSH - #define JSON_HEDLEY_DIAGNOSTIC_POP -#endif - -/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") -# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") -# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# endif -#endif -#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x -#endif - -#if defined(JSON_HEDLEY_CONST_CAST) - #undef JSON_HEDLEY_CONST_CAST -#endif -#if defined(__cplusplus) -# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) -#elif \ - JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_REINTERPRET_CAST) - #undef JSON_HEDLEY_REINTERPRET_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) -#else - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_STATIC_CAST) - #undef JSON_HEDLEY_STATIC_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) -#else - #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_CPP_CAST) - #undef JSON_HEDLEY_CPP_CAST -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ - ((T) (expr)) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("diag_suppress=Pe137") \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) -# endif -#else -# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunused-function") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif - -#if defined(JSON_HEDLEY_DEPRECATED) - #undef JSON_HEDLEY_DEPRECATED -#endif -#if defined(JSON_HEDLEY_DEPRECATED_FOR) - #undef JSON_HEDLEY_DEPRECATED_FOR -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) -#elif \ - (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) -#elif defined(__cplusplus) && (__cplusplus >= 201402L) - #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") -#else - #define JSON_HEDLEY_DEPRECATED(since) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) -#endif - -#if defined(JSON_HEDLEY_UNAVAILABLE) - #undef JSON_HEDLEY_UNAVAILABLE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) -#else - #define JSON_HEDLEY_UNAVAILABLE(available_since) -#endif - -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT -#endif -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) -#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) -#elif defined(_Check_return_) /* SAL */ - #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ -#else - #define JSON_HEDLEY_WARN_UNUSED_RESULT - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) -#endif - -#if defined(JSON_HEDLEY_SENTINEL) - #undef JSON_HEDLEY_SENTINEL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) -#else - #define JSON_HEDLEY_SENTINEL(position) -#endif - -#if defined(JSON_HEDLEY_NO_RETURN) - #undef JSON_HEDLEY_NO_RETURN -#endif -#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NO_RETURN __noreturn -#elif \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L - #define JSON_HEDLEY_NO_RETURN _Noreturn -#elif defined(__cplusplus) && (__cplusplus >= 201103L) - #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#else - #define JSON_HEDLEY_NO_RETURN -#endif - -#if defined(JSON_HEDLEY_NO_ESCAPE) - #undef JSON_HEDLEY_NO_ESCAPE -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) - #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) -#else - #define JSON_HEDLEY_NO_ESCAPE -#endif - -#if defined(JSON_HEDLEY_UNREACHABLE) - #undef JSON_HEDLEY_UNREACHABLE -#endif -#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) - #undef JSON_HEDLEY_UNREACHABLE_RETURN -#endif -#if defined(JSON_HEDLEY_ASSUME) - #undef JSON_HEDLEY_ASSUME -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_ASSUME(expr) __assume(expr) -#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) - #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) -#elif \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #if defined(__cplusplus) - #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) - #else - #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) - #endif -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() -#elif defined(JSON_HEDLEY_ASSUME) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif -#if !defined(JSON_HEDLEY_ASSUME) - #if defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) - #else - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) - #endif -#endif -#if defined(JSON_HEDLEY_UNREACHABLE) - #if \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) - #else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() - #endif -#else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) -#endif -#if !defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif - -JSON_HEDLEY_DIAGNOSTIC_PUSH -#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") - #pragma clang diagnostic ignored "-Wpedantic" -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) - #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" -#endif -#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) - #if defined(__clang__) - #pragma clang diagnostic ignored "-Wvariadic-macros" - #elif defined(JSON_HEDLEY_GCC_VERSION) - #pragma GCC diagnostic ignored "-Wvariadic-macros" - #endif -#endif -#if defined(JSON_HEDLEY_NON_NULL) - #undef JSON_HEDLEY_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) -#else - #define JSON_HEDLEY_NON_NULL(...) -#endif -JSON_HEDLEY_DIAGNOSTIC_POP - -#if defined(JSON_HEDLEY_PRINTF_FORMAT) - #undef JSON_HEDLEY_PRINTF_FORMAT -#endif -#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) -#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) -#else - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) -#endif - -#if defined(JSON_HEDLEY_CONSTEXPR) - #undef JSON_HEDLEY_CONSTEXPR -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) - #endif -#endif -#if !defined(JSON_HEDLEY_CONSTEXPR) - #define JSON_HEDLEY_CONSTEXPR -#endif - -#if defined(JSON_HEDLEY_PREDICT) - #undef JSON_HEDLEY_PREDICT -#endif -#if defined(JSON_HEDLEY_LIKELY) - #undef JSON_HEDLEY_LIKELY -#endif -#if defined(JSON_HEDLEY_UNLIKELY) - #undef JSON_HEDLEY_UNLIKELY -#endif -#if defined(JSON_HEDLEY_UNPREDICTABLE) - #undef JSON_HEDLEY_UNPREDICTABLE -#endif -#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) - #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) -#elif \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ - (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ - })) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ - })) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) -#else -# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) -# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) -#endif -#if !defined(JSON_HEDLEY_UNPREDICTABLE) - #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) -#endif - -#if defined(JSON_HEDLEY_MALLOC) - #undef JSON_HEDLEY_MALLOC -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_MALLOC __declspec(restrict) -#else - #define JSON_HEDLEY_MALLOC -#endif - -#if defined(JSON_HEDLEY_PURE) - #undef JSON_HEDLEY_PURE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PURE __attribute__((__pure__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) -# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ - ) -# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") -#else -# define JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_CONST) - #undef JSON_HEDLEY_CONST -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_CONST __attribute__((__const__)) -#elif \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_CONST _Pragma("no_side_effect") -#else - #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_RESTRICT) - #undef JSON_HEDLEY_RESTRICT -#endif -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT restrict -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - defined(__clang__) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_RESTRICT __restrict -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT _Restrict -#else - #define JSON_HEDLEY_RESTRICT -#endif - -#if defined(JSON_HEDLEY_INLINE) - #undef JSON_HEDLEY_INLINE -#endif -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - (defined(__cplusplus) && (__cplusplus >= 199711L)) - #define JSON_HEDLEY_INLINE inline -#elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) - #define JSON_HEDLEY_INLINE __inline__ -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_INLINE __inline -#else - #define JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_ALWAYS_INLINE) - #undef JSON_HEDLEY_ALWAYS_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) -# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_ALWAYS_INLINE __forceinline -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ - ) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") -#else -# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_NEVER_INLINE) - #undef JSON_HEDLEY_NEVER_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#else - #define JSON_HEDLEY_NEVER_INLINE -#endif - -#if defined(JSON_HEDLEY_PRIVATE) - #undef JSON_HEDLEY_PRIVATE -#endif -#if defined(JSON_HEDLEY_PUBLIC) - #undef JSON_HEDLEY_PUBLIC -#endif -#if defined(JSON_HEDLEY_IMPORT) - #undef JSON_HEDLEY_IMPORT -#endif -#if defined(_WIN32) || defined(__CYGWIN__) -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC __declspec(dllexport) -# define JSON_HEDLEY_IMPORT __declspec(dllimport) -#else -# if \ - JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - ( \ - defined(__TI_EABI__) && \ - ( \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ - ) \ - ) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) -# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) -# else -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC -# endif -# define JSON_HEDLEY_IMPORT extern -#endif - -#if defined(JSON_HEDLEY_NO_THROW) - #undef JSON_HEDLEY_NO_THROW -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NO_THROW __declspec(nothrow) -#else - #define JSON_HEDLEY_NO_THROW -#endif - -#if defined(JSON_HEDLEY_FALL_THROUGH) - #undef JSON_HEDLEY_FALL_THROUGH -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) -#elif defined(__fallthrough) /* SAL */ - #define JSON_HEDLEY_FALL_THROUGH __fallthrough -#else - #define JSON_HEDLEY_FALL_THROUGH -#endif - -#if defined(JSON_HEDLEY_RETURNS_NON_NULL) - #undef JSON_HEDLEY_RETURNS_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) -#elif defined(_Ret_notnull_) /* SAL */ - #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ -#else - #define JSON_HEDLEY_RETURNS_NON_NULL -#endif - -#if defined(JSON_HEDLEY_ARRAY_PARAM) - #undef JSON_HEDLEY_ARRAY_PARAM -#endif -#if \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(__STDC_NO_VLA__) && \ - !defined(__cplusplus) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_ARRAY_PARAM(name) (name) -#else - #define JSON_HEDLEY_ARRAY_PARAM(name) -#endif - -#if defined(JSON_HEDLEY_IS_CONSTANT) - #undef JSON_HEDLEY_IS_CONSTANT -#endif -#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) - #undef JSON_HEDLEY_REQUIRE_CONSTEXPR -#endif -/* JSON_HEDLEY_IS_CONSTEXPR_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #undef JSON_HEDLEY_IS_CONSTEXPR_ -#endif -#if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) -#endif -#if !defined(__cplusplus) -# if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) -#else - #include - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) -#endif -# elif \ - ( \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ - !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION)) || \ - (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) -#else - #include - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) -#endif -# elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - defined(JSON_HEDLEY_INTEL_VERSION) || \ - defined(JSON_HEDLEY_TINYC_VERSION) || \ - defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ - defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ - defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ - defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ - defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ - defined(__clang__) -# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ - sizeof(void) != \ - sizeof(*( \ - 1 ? \ - ((void*) ((expr) * 0L) ) : \ -((struct { char v[sizeof(void) * 2]; } *) 1) \ - ) \ - ) \ - ) -# endif -#endif -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) -#else - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) (0) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) -#endif - -#if defined(JSON_HEDLEY_BEGIN_C_DECLS) - #undef JSON_HEDLEY_BEGIN_C_DECLS -#endif -#if defined(JSON_HEDLEY_END_C_DECLS) - #undef JSON_HEDLEY_END_C_DECLS -#endif -#if defined(JSON_HEDLEY_C_DECL) - #undef JSON_HEDLEY_C_DECL -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { - #define JSON_HEDLEY_END_C_DECLS } - #define JSON_HEDLEY_C_DECL extern "C" -#else - #define JSON_HEDLEY_BEGIN_C_DECLS - #define JSON_HEDLEY_END_C_DECLS - #define JSON_HEDLEY_C_DECL -#endif - -#if defined(JSON_HEDLEY_STATIC_ASSERT) - #undef JSON_HEDLEY_STATIC_ASSERT -#endif -#if \ - !defined(__cplusplus) && ( \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ - (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - defined(_Static_assert) \ - ) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) -#elif \ - (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) -#else -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) -#endif - -#if defined(JSON_HEDLEY_NULL) - #undef JSON_HEDLEY_NULL -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) - #elif defined(NULL) - #define JSON_HEDLEY_NULL NULL - #else - #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) - #endif -#elif defined(NULL) - #define JSON_HEDLEY_NULL NULL -#else - #define JSON_HEDLEY_NULL ((void*) 0) -#endif - -#if defined(JSON_HEDLEY_MESSAGE) - #undef JSON_HEDLEY_MESSAGE -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_MESSAGE(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(message msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) -#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_WARNING) - #undef JSON_HEDLEY_WARNING -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_WARNING(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(clang warning msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_REQUIRE) - #undef JSON_HEDLEY_REQUIRE -#endif -#if defined(JSON_HEDLEY_REQUIRE_MSG) - #undef JSON_HEDLEY_REQUIRE_MSG -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) -# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") -# define JSON_HEDLEY_REQUIRE(expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), #expr, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), msg, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) -# endif -#else -# define JSON_HEDLEY_REQUIRE(expr) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) -#endif - -#if defined(JSON_HEDLEY_FLAGS) - #undef JSON_HEDLEY_FLAGS -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) - #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) -#else - #define JSON_HEDLEY_FLAGS -#endif - -#if defined(JSON_HEDLEY_FLAGS_CAST) - #undef JSON_HEDLEY_FLAGS_CAST -#endif -#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) -# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("warning(disable:188)") \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) -#endif - -#if defined(JSON_HEDLEY_EMPTY_BASES) - #undef JSON_HEDLEY_EMPTY_BASES -#endif -#if \ - (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) -#else - #define JSON_HEDLEY_EMPTY_BASES -#endif - -/* Remaining macros are deprecated. */ - -#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK -#endif -#if defined(__clang__) - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) -#else - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) - #undef JSON_HEDLEY_CLANG_HAS_BUILTIN -#endif -#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) - -#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) - #undef JSON_HEDLEY_CLANG_HAS_FEATURE -#endif -#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) - -#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) - #undef JSON_HEDLEY_CLANG_HAS_EXTENSION -#endif -#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) - -#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) - #undef JSON_HEDLEY_CLANG_HAS_WARNING -#endif -#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) - -#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ - - -// This file contains all internal macro definitions -// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them - -// exclude unsupported compilers -#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) - #if defined(__clang__) - #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 - #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) - #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 - #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #endif -#endif - -// C++ language standard detection -// if the user manually specified the used c++ version this is skipped -#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) - #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) - #define JSON_HAS_CPP_20 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 - #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 - #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) - #define JSON_HAS_CPP_14 - #endif - // the cpp 11 flag is always specified because it is the minimal required version - #define JSON_HAS_CPP_11 -#endif - -// disable documentation warnings on clang -#if defined(__clang__) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdocumentation" - #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" -#endif - -// allow to disable exceptions -#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) - #define JSON_THROW(exception) throw exception - #define JSON_TRY try - #define JSON_CATCH(exception) catch(exception) - #define JSON_INTERNAL_CATCH(exception) catch(exception) -#else - #include - #define JSON_THROW(exception) std::abort() - #define JSON_TRY if(true) - #define JSON_CATCH(exception) if(false) - #define JSON_INTERNAL_CATCH(exception) if(false) -#endif - -// override exception macros -#if defined(JSON_THROW_USER) - #undef JSON_THROW - #define JSON_THROW JSON_THROW_USER -#endif -#if defined(JSON_TRY_USER) - #undef JSON_TRY - #define JSON_TRY JSON_TRY_USER -#endif -#if defined(JSON_CATCH_USER) - #undef JSON_CATCH - #define JSON_CATCH JSON_CATCH_USER - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_CATCH_USER -#endif -#if defined(JSON_INTERNAL_CATCH_USER) - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER -#endif - -// allow to override assert -#if !defined(JSON_ASSERT) - #include // assert - #define JSON_ASSERT(x) assert(x) -#endif - -// allow to access some private functions (needed by the test suite) -#if defined(JSON_TESTS_PRIVATE) - #define JSON_PRIVATE_UNLESS_TESTED public -#else - #define JSON_PRIVATE_UNLESS_TESTED private -#endif - -/*! -@brief macro to briefly define a mapping between an enum and JSON -@def NLOHMANN_JSON_SERIALIZE_ENUM -@since version 3.4.0 -*/ -#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ - template \ - inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [e](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.first == e; \ - }); \ - j = ((it != std::end(m)) ? it : std::begin(m))->second; \ - } \ - template \ - inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [&j](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.second == j; \ - }); \ - e = ((it != std::end(m)) ? it : std::begin(m))->first; \ - } - -// Ugly macros to avoid uglier copy-paste when specializing basic_json. They -// may be removed in the future once the class is split. - -#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ - template class ObjectType, \ - template class ArrayType, \ - class StringType, class BooleanType, class NumberIntegerType, \ - class NumberUnsignedType, class NumberFloatType, \ - template class AllocatorType, \ - template class JSONSerializer, \ - class BinaryType> - -#define NLOHMANN_BASIC_JSON_TPL \ - basic_json - -// Macros to simplify conversion from/to types - -#define NLOHMANN_JSON_EXPAND( x ) x -#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME -#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ - NLOHMANN_JSON_PASTE64, \ - NLOHMANN_JSON_PASTE63, \ - NLOHMANN_JSON_PASTE62, \ - NLOHMANN_JSON_PASTE61, \ - NLOHMANN_JSON_PASTE60, \ - NLOHMANN_JSON_PASTE59, \ - NLOHMANN_JSON_PASTE58, \ - NLOHMANN_JSON_PASTE57, \ - NLOHMANN_JSON_PASTE56, \ - NLOHMANN_JSON_PASTE55, \ - NLOHMANN_JSON_PASTE54, \ - NLOHMANN_JSON_PASTE53, \ - NLOHMANN_JSON_PASTE52, \ - NLOHMANN_JSON_PASTE51, \ - NLOHMANN_JSON_PASTE50, \ - NLOHMANN_JSON_PASTE49, \ - NLOHMANN_JSON_PASTE48, \ - NLOHMANN_JSON_PASTE47, \ - NLOHMANN_JSON_PASTE46, \ - NLOHMANN_JSON_PASTE45, \ - NLOHMANN_JSON_PASTE44, \ - NLOHMANN_JSON_PASTE43, \ - NLOHMANN_JSON_PASTE42, \ - NLOHMANN_JSON_PASTE41, \ - NLOHMANN_JSON_PASTE40, \ - NLOHMANN_JSON_PASTE39, \ - NLOHMANN_JSON_PASTE38, \ - NLOHMANN_JSON_PASTE37, \ - NLOHMANN_JSON_PASTE36, \ - NLOHMANN_JSON_PASTE35, \ - NLOHMANN_JSON_PASTE34, \ - NLOHMANN_JSON_PASTE33, \ - NLOHMANN_JSON_PASTE32, \ - NLOHMANN_JSON_PASTE31, \ - NLOHMANN_JSON_PASTE30, \ - NLOHMANN_JSON_PASTE29, \ - NLOHMANN_JSON_PASTE28, \ - NLOHMANN_JSON_PASTE27, \ - NLOHMANN_JSON_PASTE26, \ - NLOHMANN_JSON_PASTE25, \ - NLOHMANN_JSON_PASTE24, \ - NLOHMANN_JSON_PASTE23, \ - NLOHMANN_JSON_PASTE22, \ - NLOHMANN_JSON_PASTE21, \ - NLOHMANN_JSON_PASTE20, \ - NLOHMANN_JSON_PASTE19, \ - NLOHMANN_JSON_PASTE18, \ - NLOHMANN_JSON_PASTE17, \ - NLOHMANN_JSON_PASTE16, \ - NLOHMANN_JSON_PASTE15, \ - NLOHMANN_JSON_PASTE14, \ - NLOHMANN_JSON_PASTE13, \ - NLOHMANN_JSON_PASTE12, \ - NLOHMANN_JSON_PASTE11, \ - NLOHMANN_JSON_PASTE10, \ - NLOHMANN_JSON_PASTE9, \ - NLOHMANN_JSON_PASTE8, \ - NLOHMANN_JSON_PASTE7, \ - NLOHMANN_JSON_PASTE6, \ - NLOHMANN_JSON_PASTE5, \ - NLOHMANN_JSON_PASTE4, \ - NLOHMANN_JSON_PASTE3, \ - NLOHMANN_JSON_PASTE2, \ - NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) -#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) -#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) -#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) -#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) -#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) -#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) -#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) -#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) -#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) -#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) -#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) -#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) -#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) -#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) -#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) -#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) -#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) -#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) -#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) -#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) -#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) -#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) -#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) -#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) -#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) -#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) -#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) -#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) -#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) -#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) -#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) -#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) -#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) -#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) -#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) -#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) -#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) -#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) -#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) -#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) -#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) -#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) -#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) -#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) -#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) -#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) -#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) -#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) -#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) -#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) -#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) -#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) -#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) -#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) -#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) -#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) -#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) -#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) - -#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; -#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -#ifndef JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_USE_IMPLICIT_CONVERSIONS 1 -#endif - -#if JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_EXPLICIT -#else - #define JSON_EXPLICIT explicit -#endif - -#ifndef JSON_DIAGNOSTICS - #define JSON_DIAGNOSTICS 0 -#endif - - -namespace nlohmann -{ -namespace detail -{ - -/*! -@brief replace all occurrences of a substring by another string - -@param[in,out] s the string to manipulate; changed so that all - occurrences of @a f are replaced with @a t -@param[in] f the substring to replace with @a t -@param[in] t the string to replace @a f - -@pre The search string @a f must not be empty. **This precondition is -enforced with an assertion.** - -@since version 2.0.0 -*/ -inline void replace_substring(std::string& s, const std::string& f, - const std::string& t) -{ - JSON_ASSERT(!f.empty()); - 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 - {} -} - -/*! - * @brief string escaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to escape - * @return escaped string - * - * Note the order of escaping "~" to "~0" and "/" to "~1" is important. - */ -inline std::string escape(std::string s) -{ - replace_substring(s, "~", "~0"); - replace_substring(s, "/", "~1"); - return s; -} - -/*! - * @brief string unescaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to unescape - * @return unescaped string - * - * Note the order of escaping "~1" to "/" and "~0" to "~" is important. - */ -static void unescape(std::string& s) -{ - replace_substring(s, "~1", "/"); - replace_substring(s, "~0", "~"); -} - -} // namespace detail -} // namespace nlohmann - -// #include - - -#include // size_t - -namespace nlohmann -{ -namespace detail -{ -/// struct to capture the start position of the current token -struct position_t -{ - /// the total number of characters read - std::size_t chars_read_total = 0; - /// the number of characters read in the current line - std::size_t chars_read_current_line = 0; - /// the number of lines read - std::size_t lines_read = 0; - - /// conversion to size_t to preserve SAX interface - constexpr operator size_t() const - { - return chars_read_total; - } -}; - -} // namespace detail -} // namespace nlohmann - -// #include - - -namespace nlohmann -{ -namespace detail -{ -//////////////// -// exceptions // -//////////////// - -/*! -@brief general exception of the @ref basic_json class - -This class is an extension of `std::exception` objects with a member @a id for -exception ids. It is used as the base class for all exceptions thrown by the -@ref basic_json class. This class can hence be used as "wildcard" to catch -exceptions. - -Subclasses: -- @ref parse_error for exceptions indicating a parse error -- @ref invalid_iterator for exceptions indicating errors with iterators -- @ref type_error for exceptions indicating executing a member function with - a wrong type -- @ref out_of_range for exceptions indicating access out of the defined range -- @ref other_error for exceptions indicating other library errors - -@internal -@note To have nothrow-copy-constructible exceptions, we internally use - `std::runtime_error` which can cope with arbitrary-length error messages. - Intermediate strings are built with static functions and then passed to - the actual constructor. -@endinternal - -@liveexample{The following code shows how arbitrary library exceptions can be -caught.,exception} - -@since version 3.0.0 -*/ -class exception : public std::exception -{ - public: - /// returns the explanatory string - const char* what() const noexcept override - { - return m.what(); - } - - /// the id of the exception - const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes) - - protected: - JSON_HEDLEY_NON_NULL(3) - exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} - - static std::string name(const std::string& ename, int id_) - { - return "[json.exception." + ename + "." + std::to_string(id_) + "] "; - } - - template - static std::string diagnostics(const BasicJsonType& leaf_element) - { -#if JSON_DIAGNOSTICS - std::vector tokens; - for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent) - { - switch (current->m_parent->type()) - { - case value_t::array: - { - for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i) - { - if (¤t->m_parent->m_value.array->operator[](i) == current) - { - tokens.emplace_back(std::to_string(i)); - break; - } - } - break; - } - - case value_t::object: - { - for (const auto& element : *current->m_parent->m_value.object) - { - if (&element.second == current) - { - tokens.emplace_back(element.first.c_str()); - break; - } - } - break; - } - - case value_t::null: // LCOV_EXCL_LINE - case value_t::string: // LCOV_EXCL_LINE - case value_t::boolean: // LCOV_EXCL_LINE - case value_t::number_integer: // LCOV_EXCL_LINE - case value_t::number_unsigned: // LCOV_EXCL_LINE - case value_t::number_float: // LCOV_EXCL_LINE - case value_t::binary: // LCOV_EXCL_LINE - case value_t::discarded: // LCOV_EXCL_LINE - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE - } - } - - if (tokens.empty()) - { - return ""; - } - - return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{}, - [](const std::string & a, const std::string & b) - { - return a + "/" + detail::escape(b); - }) + ") "; -#else - static_cast(leaf_element); - return ""; -#endif - } - - private: - /// an exception object as storage for error messages - std::runtime_error m; -}; - -/*! -@brief exception indicating a parse error - -This exception is thrown by the library when a parse error occurs. Parse errors -can occur during the deserialization of JSON text, CBOR, MessagePack, as well -as when using JSON Patch. - -Member @a byte holds the byte index of the last read character in the input -file. - -Exceptions have ids 1xx. - -name / id | example message | description ------------------------------- | --------------- | ------------------------- -json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position. -json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point. -json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid. -json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects. -json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors. -json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`. -json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character. -json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences. -json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number. -json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read. -json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read. -json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read. -json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet). -json.exception.parse_error.115 | parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A | A UBJSON high-precision number could not be parsed. - -@note For an input with n bytes, 1 is the index of the first character and n+1 - is the index of the terminating null byte or the end of file. This also - holds true when reading a byte vector (CBOR or MessagePack). - -@liveexample{The following code shows how a `parse_error` exception can be -caught.,parse_error} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class parse_error : public exception -{ - public: - /*! - @brief create a parse error exception - @param[in] id_ the id of the exception - @param[in] pos the position where the error occurred (or with - chars_read_total=0 if the position cannot be - determined) - @param[in] what_arg the explanatory string - @return parse_error object - */ - template - static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context) - { - std::string w = exception::name("parse_error", id_) + "parse error" + - position_string(pos) + ": " + exception::diagnostics(context) + what_arg; - return parse_error(id_, pos.chars_read_total, w.c_str()); - } - - template - static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context) - { - std::string w = exception::name("parse_error", id_) + "parse error" + - (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") + - ": " + exception::diagnostics(context) + what_arg; - return parse_error(id_, byte_, w.c_str()); - } - - /*! - @brief byte index of the parse error - - The byte index of the last read character in the input file. - - @note For an input with n bytes, 1 is the index of the first character and - n+1 is the index of the terminating null byte or the end of file. - This also holds true when reading a byte vector (CBOR or MessagePack). - */ - const std::size_t byte; - - private: - parse_error(int id_, std::size_t byte_, const char* what_arg) - : exception(id_, what_arg), byte(byte_) {} - - static std::string position_string(const position_t& pos) - { - return " at line " + std::to_string(pos.lines_read + 1) + - ", column " + std::to_string(pos.chars_read_current_line); - } -}; - -/*! -@brief exception indicating errors with iterators - -This exception is thrown if iterators passed to a library function do not match -the expected semantics. - -Exceptions have ids 2xx. - -name / id | example message | description ------------------------------------ | --------------- | ------------------------- -json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid. -json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion. -json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from. -json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid. -json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid. -json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range. -json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key. -json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. -json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. -json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid. -json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to. -json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container. -json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered. -json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin(). - -@liveexample{The following code shows how an `invalid_iterator` exception can be -caught.,invalid_iterator} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class invalid_iterator : public exception -{ - public: - template - static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context) - { - std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg; - return invalid_iterator(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - invalid_iterator(int id_, const char* what_arg) - : exception(id_, what_arg) {} -}; - -/*! -@brief exception indicating executing a member function with a wrong type - -This exception is thrown in case of a type error; that is, a library function is -executed on a JSON value whose type does not match the expected semantics. - -Exceptions have ids 3xx. - -name / id | example message | description ------------------------------ | --------------- | ------------------------- -json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead. -json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types. -json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &. -json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types. -json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types. -json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types. -json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types. -json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types. -json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types. -json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types. -json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types. -json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types. -json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined. -json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers. -json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive. -json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. | -json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) | - -@liveexample{The following code shows how a `type_error` exception can be -caught.,type_error} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class type_error : public exception -{ - public: - template - static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context) - { - std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg; - return type_error(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - type_error(int id_, const char* what_arg) : exception(id_, what_arg) {} -}; - -/*! -@brief exception indicating access out of the defined range - -This exception is thrown in case a library function is called on an input -parameter that exceeds the expected range, for instance in case of array -indices or nonexisting object keys. - -Exceptions have ids 4xx. - -name / id | example message | description -------------------------------- | --------------- | ------------------------- -json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1. -json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it. -json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object. -json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved. -json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value. -json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF. -json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. (until version 3.8.0) | -json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. | -json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string | - -@liveexample{The following code shows how an `out_of_range` exception can be -caught.,out_of_range} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class out_of_range : public exception -{ - public: - template - static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context) - { - std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg; - return out_of_range(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {} -}; - -/*! -@brief exception indicating other library errors - -This exception is thrown in case of errors that cannot be classified with the -other exception types. - -Exceptions have ids 5xx. - -name / id | example message | description ------------------------------- | --------------- | ------------------------- -json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed. - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range - -@liveexample{The following code shows how an `other_error` exception can be -caught.,other_error} - -@since version 3.0.0 -*/ -class other_error : public exception -{ - public: - template - static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context) - { - std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg; - return other_error(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - other_error(int id_, const char* what_arg) : exception(id_, what_arg) {} -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - - -#include // size_t -#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type -#include // index_sequence, make_index_sequence, index_sequence_for - -// #include - - -namespace nlohmann -{ -namespace detail -{ - -template -using uncvref_t = typename std::remove_cv::type>::type; - -#ifdef JSON_HAS_CPP_14 - -// the following utilities are natively available in C++14 -using std::enable_if_t; -using std::index_sequence; -using std::make_index_sequence; -using std::index_sequence_for; - -#else - -// alias templates to reduce boilerplate -template -using enable_if_t = typename std::enable_if::type; - -// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h -// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. - -//// START OF CODE FROM GOOGLE ABSEIL - -// integer_sequence -// -// Class template representing a compile-time integer sequence. An instantiation -// of `integer_sequence` has a sequence of integers encoded in its -// type through its template arguments (which is a common need when -// working with C++11 variadic templates). `absl::integer_sequence` is designed -// to be a drop-in replacement for C++14's `std::integer_sequence`. -// -// Example: -// -// template< class T, T... Ints > -// void user_function(integer_sequence); -// -// int main() -// { -// // user_function's `T` will be deduced to `int` and `Ints...` -// // will be deduced to `0, 1, 2, 3, 4`. -// user_function(make_integer_sequence()); -// } -template -struct integer_sequence -{ - using value_type = T; - static constexpr std::size_t size() noexcept - { - return sizeof...(Ints); - } -}; - -// index_sequence -// -// A helper template for an `integer_sequence` of `size_t`, -// `absl::index_sequence` is designed to be a drop-in replacement for C++14's -// `std::index_sequence`. -template -using index_sequence = integer_sequence; - -namespace utility_internal -{ - -template -struct Extend; - -// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. -template -struct Extend, SeqSize, 0> -{ - using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; -}; - -template -struct Extend, SeqSize, 1> -{ - using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; -}; - -// Recursion helper for 'make_integer_sequence'. -// 'Gen::type' is an alias for 'integer_sequence'. -template -struct Gen -{ - using type = - typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; -}; - -template -struct Gen -{ - using type = integer_sequence; -}; - -} // namespace utility_internal - -// Compile-time sequences of integers - -// make_integer_sequence -// -// This template alias is equivalent to -// `integer_sequence`, and is designed to be a drop-in -// replacement for C++14's `std::make_integer_sequence`. -template -using make_integer_sequence = typename utility_internal::Gen::type; - -// make_index_sequence -// -// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, -// and is designed to be a drop-in replacement for C++14's -// `std::make_index_sequence`. -template -using make_index_sequence = make_integer_sequence; - -// index_sequence_for -// -// Converts a typename pack into an index sequence of the same length, and -// is designed to be a drop-in replacement for C++14's -// `std::index_sequence_for()` -template -using index_sequence_for = make_index_sequence; - -//// END OF CODE FROM GOOGLE ABSEIL - -#endif - -// dispatch utility (taken from ranges-v3) -template struct priority_tag : priority_tag < N - 1 > {}; -template<> struct priority_tag<0> {}; - -// taken from ranges-v3 -template -struct static_const -{ - static constexpr T value{}; -}; - -template -constexpr T static_const::value; - -} // namespace detail -} // namespace nlohmann - -// #include - - -namespace nlohmann -{ -namespace detail -{ -// dispatching helper struct -template struct identity_tag {}; -} // namespace detail -} // namespace nlohmann - -// #include - - -#include // numeric_limits -#include // false_type, is_constructible, is_integral, is_same, true_type -#include // declval -#include // tuple - -// #include - - -#include // random_access_iterator_tag - -// #include - - -namespace nlohmann -{ -namespace detail -{ -template struct make_void -{ - using type = void; -}; -template using void_t = typename make_void::type; -} // namespace detail -} // namespace nlohmann - -// #include - - -namespace nlohmann -{ -namespace detail -{ -template -struct iterator_types {}; - -template -struct iterator_types < - It, - void_t> -{ - using difference_type = typename It::difference_type; - using value_type = typename It::value_type; - using pointer = typename It::pointer; - using reference = typename It::reference; - using iterator_category = typename It::iterator_category; -}; - -// This is required as some compilers implement std::iterator_traits in a way that -// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. -template -struct iterator_traits -{ -}; - -template -struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> - : iterator_types -{ -}; - -template -struct iterator_traits::value>> -{ - using iterator_category = std::random_access_iterator_tag; - using value_type = T; - using difference_type = ptrdiff_t; - using pointer = T*; - using reference = T&; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - -// #include - - -#include - -// #include - - -// https://en.cppreference.com/w/cpp/experimental/is_detected -namespace nlohmann -{ -namespace detail -{ -struct nonesuch -{ - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - nonesuch(nonesuch const&&) = delete; - void operator=(nonesuch const&) = delete; - void operator=(nonesuch&&) = delete; -}; - -template class Op, - class... Args> -struct detector -{ - using value_t = std::false_type; - using type = Default; -}; - -template class Op, class... Args> -struct detector>, Op, Args...> -{ - using value_t = std::true_type; - using type = Op; -}; - -template class Op, class... Args> -using is_detected = typename detector::value_t; - -template class Op, class... Args> -struct is_detected_lazy : is_detected { }; - -template class Op, class... Args> -using detected_t = typename detector::type; - -template class Op, class... Args> -using detected_or = detector; - -template class Op, class... Args> -using detected_or_t = typename detected_or::type; - -template class Op, class... Args> -using is_detected_exact = std::is_same>; - -template class Op, class... Args> -using is_detected_convertible = - std::is_convertible, To>; -} // namespace detail -} // namespace nlohmann - -// #include -#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ -#define INCLUDE_NLOHMANN_JSON_FWD_HPP_ - -#include // int64_t, uint64_t -#include // map -#include // allocator -#include // string -#include // vector - -/*! -@brief namespace for Niels Lohmann -@see https://github.com/nlohmann -@since version 1.0.0 -*/ -namespace nlohmann -{ -/*! -@brief default JSONSerializer template argument - -This serializer ignores the template arguments and uses ADL -([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) -for serialization. -*/ -template -struct adl_serializer; - -template class ObjectType = - std::map, - template class ArrayType = std::vector, - class StringType = std::string, class BooleanType = bool, - class NumberIntegerType = std::int64_t, - class NumberUnsignedType = std::uint64_t, - class NumberFloatType = double, - template class AllocatorType = std::allocator, - template class JSONSerializer = - adl_serializer, - class BinaryType = std::vector> -class basic_json; - -/*! -@brief JSON Pointer - -A JSON pointer defines a string syntax for identifying a specific value -within a JSON document. It can be used with functions `at` and -`operator[]`. Furthermore, JSON pointers are the base for JSON patches. - -@sa [RFC 6901](https://tools.ietf.org/html/rfc6901) - -@since version 2.0.0 -*/ -template -class json_pointer; - -/*! -@brief default JSON class - -This type is the default specialization of the @ref basic_json class which -uses the standard template types. - -@since version 1.0.0 -*/ -using json = basic_json<>; - -template -struct ordered_map; - -/*! -@brief ordered JSON class - -This type preserves the insertion order of object keys. - -@since version 3.9.0 -*/ -using ordered_json = basic_json; - -} // namespace nlohmann - -#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ - - -namespace nlohmann -{ -/*! -@brief detail namespace with internal helper functions - -This namespace collects functions that should not be exposed, -implementations of some @ref basic_json methods, and meta-programming helpers. - -@since version 2.1.0 -*/ -namespace detail -{ -///////////// -// helpers // -///////////// - -// Note to maintainers: -// -// Every trait in this file expects a non CV-qualified type. -// The only exceptions are in the 'aliases for detected' section -// (i.e. those of the form: decltype(T::member_function(std::declval()))) -// -// In this case, T has to be properly CV-qualified to constraint the function arguments -// (e.g. to_json(BasicJsonType&, const T&)) - -template struct is_basic_json : std::false_type {}; - -NLOHMANN_BASIC_JSON_TPL_DECLARATION -struct is_basic_json : std::true_type {}; - -////////////////////// -// json_ref helpers // -////////////////////// - -template -class json_ref; - -template -struct is_json_ref : std::false_type {}; - -template -struct is_json_ref> : std::true_type {}; - -////////////////////////// -// aliases for detected // -////////////////////////// - -template -using mapped_type_t = typename T::mapped_type; - -template -using key_type_t = typename T::key_type; - -template -using value_type_t = typename T::value_type; - -template -using difference_type_t = typename T::difference_type; - -template -using pointer_t = typename T::pointer; - -template -using reference_t = typename T::reference; - -template -using iterator_category_t = typename T::iterator_category; - -template -using iterator_t = typename T::iterator; - -template -using to_json_function = decltype(T::to_json(std::declval()...)); - -template -using from_json_function = decltype(T::from_json(std::declval()...)); - -template -using get_template_function = decltype(std::declval().template get()); - -// trait checking if JSONSerializer::from_json(json const&, udt&) exists -template -struct has_from_json : std::false_type {}; - -// trait checking if j.get is valid -// use this trait instead of std::is_constructible or std::is_convertible, -// both rely on, or make use of implicit conversions, and thus fail when T -// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) -template -struct is_getable -{ - static constexpr bool value = is_detected::value; -}; - -template -struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -// This trait checks if JSONSerializer::from_json(json const&) exists -// this overload is used for non-default-constructible user-defined-types -template -struct has_non_default_from_json : std::false_type {}; - -template -struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -// This trait checks if BasicJsonType::json_serializer::to_json exists -// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. -template -struct has_to_json : std::false_type {}; - -template -struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - - -/////////////////// -// is_ functions // -/////////////////// - -// https://en.cppreference.com/w/cpp/types/conjunction -template struct conjunction : std::true_type { }; -template struct conjunction : B1 { }; -template -struct conjunction -: std::conditional, B1>::type {}; - -// https://en.cppreference.com/w/cpp/types/negation -template struct negation : std::integral_constant < bool, !B::value > { }; - -// Reimplementation of is_constructible and is_default_constructible, due to them being broken for -// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). -// This causes compile errors in e.g. clang 3.5 or gcc 4.9. -template -struct is_default_constructible : std::is_default_constructible {}; - -template -struct is_default_constructible> - : conjunction, is_default_constructible> {}; - -template -struct is_default_constructible> - : conjunction, is_default_constructible> {}; - -template -struct is_default_constructible> - : conjunction...> {}; - -template -struct is_default_constructible> - : conjunction...> {}; - - -template -struct is_constructible : std::is_constructible {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - - -template -struct is_iterator_traits : std::false_type {}; - -template -struct is_iterator_traits> -{ - private: - using traits = iterator_traits; - - public: - static constexpr auto value = - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value; -}; - -// The following implementation of is_complete_type is taken from -// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ -// and is written by Xiang Fan who agreed to using it in this library. - -template -struct is_complete_type : std::false_type {}; - -template -struct is_complete_type : std::true_type {}; - -template -struct is_compatible_object_type_impl : std::false_type {}; - -template -struct is_compatible_object_type_impl < - BasicJsonType, CompatibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> -{ - using object_t = typename BasicJsonType::object_t; - - // macOS's is_constructible does not play well with nonesuch... - static constexpr bool value = - is_constructible::value && - is_constructible::value; -}; - -template -struct is_compatible_object_type - : is_compatible_object_type_impl {}; - -template -struct is_constructible_object_type_impl : std::false_type {}; - -template -struct is_constructible_object_type_impl < - BasicJsonType, ConstructibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> -{ - using object_t = typename BasicJsonType::object_t; - - static constexpr bool value = - (is_default_constructible::value && - (std::is_move_assignable::value || - std::is_copy_assignable::value) && - (is_constructible::value && - std::is_same < - typename object_t::mapped_type, - typename ConstructibleObjectType::mapped_type >::value)) || - (has_from_json::value || - has_non_default_from_json < - BasicJsonType, - typename ConstructibleObjectType::mapped_type >::value); -}; - -template -struct is_constructible_object_type - : is_constructible_object_type_impl {}; - -template -struct is_compatible_string_type_impl : std::false_type {}; - -template -struct is_compatible_string_type_impl < - BasicJsonType, CompatibleStringType, - enable_if_t::value >> -{ - static constexpr auto value = - is_constructible::value; -}; - -template -struct is_compatible_string_type - : is_compatible_string_type_impl {}; - -template -struct is_constructible_string_type_impl : std::false_type {}; - -template -struct is_constructible_string_type_impl < - BasicJsonType, ConstructibleStringType, - enable_if_t::value >> -{ - static constexpr auto value = - is_constructible::value; -}; - -template -struct is_constructible_string_type - : is_constructible_string_type_impl {}; - -template -struct is_compatible_array_type_impl : std::false_type {}; - -template -struct is_compatible_array_type_impl < - BasicJsonType, CompatibleArrayType, - enable_if_t < is_detected::value&& - is_detected::value&& -// This is needed because json_reverse_iterator has a ::iterator type... -// Therefore it is detected as a CompatibleArrayType. -// The real fix would be to have an Iterable concept. - !is_iterator_traits < - iterator_traits>::value >> -{ - static constexpr bool value = - is_constructible::value; -}; - -template -struct is_compatible_array_type - : is_compatible_array_type_impl {}; - -template -struct is_constructible_array_type_impl : std::false_type {}; - -template -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t::value >> - : std::true_type {}; - -template -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t < !std::is_same::value&& - is_default_constructible::value&& -(std::is_move_assignable::value || - std::is_copy_assignable::value)&& -is_detected::value&& -is_detected::value&& -is_complete_type < -detected_t>::value >> -{ - static constexpr bool value = - // This is needed because json_reverse_iterator has a ::iterator type, - // furthermore, std::back_insert_iterator (and other iterators) have a - // base class `iterator`... Therefore it is detected as a - // ConstructibleArrayType. The real fix would be to have an Iterable - // concept. - !is_iterator_traits>::value && - - (std::is_same::value || - has_from_json::value || - has_non_default_from_json < - BasicJsonType, typename ConstructibleArrayType::value_type >::value); -}; - -template -struct is_constructible_array_type - : is_constructible_array_type_impl {}; - -template -struct is_compatible_integer_type_impl : std::false_type {}; - -template -struct is_compatible_integer_type_impl < - RealIntegerType, CompatibleNumberIntegerType, - enable_if_t < std::is_integral::value&& - std::is_integral::value&& - !std::is_same::value >> -{ - // is there an assert somewhere on overflows? - using RealLimits = std::numeric_limits; - using CompatibleLimits = std::numeric_limits; - - static constexpr auto value = - is_constructible::value && - CompatibleLimits::is_integer && - RealLimits::is_signed == CompatibleLimits::is_signed; -}; - -template -struct is_compatible_integer_type - : is_compatible_integer_type_impl {}; - -template -struct is_compatible_type_impl: std::false_type {}; - -template -struct is_compatible_type_impl < - BasicJsonType, CompatibleType, - enable_if_t::value >> -{ - static constexpr bool value = - has_to_json::value; -}; - -template -struct is_compatible_type - : is_compatible_type_impl {}; - -template -struct is_constructible_tuple : std::false_type {}; - -template -struct is_constructible_tuple> : conjunction...> {}; - -// a naive helper to check if a type is an ordered_map (exploits the fact that -// ordered_map inherits capacity() from std::vector) -template -struct is_ordered_map -{ - using one = char; - - struct two - { - char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - }; - - template static one test( decltype(&C::capacity) ) ; - template static two test(...); - - enum { value = sizeof(test(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) -}; - -// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324) -template < typename T, typename U, enable_if_t < !std::is_same::value, int > = 0 > -T conditional_static_cast(U value) -{ - return static_cast(value); -} - -template::value, int> = 0> -T conditional_static_cast(U value) -{ - return value; -} - -} // namespace detail -} // namespace nlohmann - -// #include - - -namespace nlohmann -{ -namespace detail -{ -template -void from_json(const BasicJsonType& j, typename std::nullptr_t& n) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_null())) - { - JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j)); - } - n = nullptr; -} - -// overloads for basic_json template parameters -template < typename BasicJsonType, typename ArithmeticType, - enable_if_t < std::is_arithmetic::value&& - !std::is_same::value, - int > = 0 > -void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) -{ - switch (static_cast(j)) - { - case value_t::number_unsigned: - { - val = static_cast(*j.template get_ptr()); - break; - } - case value_t::number_integer: - { - val = static_cast(*j.template get_ptr()); - break; - } - case value_t::number_float: - { - val = static_cast(*j.template get_ptr()); - break; - } - - case value_t::null: - case value_t::object: - case value_t::array: - case value_t::string: - case value_t::boolean: - case value_t::binary: - case value_t::discarded: - default: - JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j)); - } -} - -template -void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_boolean())) - { - JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j)); - } - b = *j.template get_ptr(); -} - -template -void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_string())) - { - JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j)); - } - s = *j.template get_ptr(); -} - -template < - typename BasicJsonType, typename ConstructibleStringType, - enable_if_t < - is_constructible_string_type::value&& - !std::is_same::value, - int > = 0 > -void from_json(const BasicJsonType& j, ConstructibleStringType& s) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_string())) - { - JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j)); - } - - s = *j.template get_ptr(); -} - -template -void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val) -{ - get_arithmetic_value(j, val); -} - -template -void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val) -{ - get_arithmetic_value(j, val); -} - -template -void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val) -{ - get_arithmetic_value(j, val); -} - -template::value, int> = 0> -void from_json(const BasicJsonType& j, EnumType& e) -{ - typename std::underlying_type::type val; - get_arithmetic_value(j, val); - e = static_cast(val); -} - -// forward_list doesn't have an insert method -template::value, int> = 0> -void from_json(const BasicJsonType& j, std::forward_list& l) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - l.clear(); - std::transform(j.rbegin(), j.rend(), - std::front_inserter(l), [](const BasicJsonType & i) - { - return i.template get(); - }); -} - -// valarray doesn't have an insert method -template::value, int> = 0> -void from_json(const BasicJsonType& j, std::valarray& l) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - l.resize(j.size()); - std::transform(j.begin(), j.end(), std::begin(l), - [](const BasicJsonType & elem) - { - return elem.template get(); - }); -} - -template -auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) --> decltype(j.template get(), void()) -{ - for (std::size_t i = 0; i < N; ++i) - { - arr[i] = j.at(i).template get(); - } -} - -template -void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/) -{ - arr = *j.template get_ptr(); -} - -template -auto from_json_array_impl(const BasicJsonType& j, std::array& arr, - priority_tag<2> /*unused*/) --> decltype(j.template get(), void()) -{ - for (std::size_t i = 0; i < N; ++i) - { - arr[i] = j.at(i).template get(); - } -} - -template::value, - int> = 0> -auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/) --> decltype( - arr.reserve(std::declval()), - j.template get(), - void()) -{ - using std::end; - - ConstructibleArrayType ret; - ret.reserve(j.size()); - std::transform(j.begin(), j.end(), - std::inserter(ret, end(ret)), [](const BasicJsonType & i) - { - // get() returns *this, this won't call a from_json - // method when value_type is BasicJsonType - return i.template get(); - }); - arr = std::move(ret); -} - -template::value, - int> = 0> -void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, - priority_tag<0> /*unused*/) -{ - using std::end; - - ConstructibleArrayType ret; - std::transform( - j.begin(), j.end(), std::inserter(ret, end(ret)), - [](const BasicJsonType & i) - { - // get() returns *this, this won't call a from_json - // method when value_type is BasicJsonType - return i.template get(); - }); - arr = std::move(ret); -} - -template < typename BasicJsonType, typename ConstructibleArrayType, - enable_if_t < - is_constructible_array_type::value&& - !is_constructible_object_type::value&& - !is_constructible_string_type::value&& - !std::is_same::value&& - !is_basic_json::value, - int > = 0 > -auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr) --> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), -j.template get(), -void()) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - - from_json_array_impl(j, arr, priority_tag<3> {}); -} - -template < typename BasicJsonType, typename T, std::size_t... Idx > -std::array from_json_inplace_array_impl(BasicJsonType&& j, - identity_tag> /*unused*/, index_sequence /*unused*/) -{ - return { { std::forward(j).at(Idx).template get()... } }; -} - -template < typename BasicJsonType, typename T, std::size_t N > -auto from_json(BasicJsonType&& j, identity_tag> tag) --> decltype(from_json_inplace_array_impl(std::forward(j), tag, make_index_sequence {})) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - - return from_json_inplace_array_impl(std::forward(j), tag, make_index_sequence {}); -} - -template -void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_binary())) - { - JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j)); - } - - bin = *j.template get_ptr(); -} - -template::value, int> = 0> -void from_json(const BasicJsonType& j, ConstructibleObjectType& obj) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_object())) - { - JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j)); - } - - ConstructibleObjectType ret; - const auto* inner_object = j.template get_ptr(); - using value_type = typename ConstructibleObjectType::value_type; - std::transform( - inner_object->begin(), inner_object->end(), - std::inserter(ret, ret.begin()), - [](typename BasicJsonType::object_t::value_type const & p) - { - return value_type(p.first, p.second.template get()); - }); - obj = std::move(ret); -} - -// overload for arithmetic types, not chosen for basic_json template arguments -// (BooleanType, etc..); note: Is it really necessary to provide explicit -// overloads for boolean_t etc. in case of a custom BooleanType which is not -// an arithmetic type? -template < typename BasicJsonType, typename ArithmeticType, - enable_if_t < - std::is_arithmetic::value&& - !std::is_same::value&& - !std::is_same::value&& - !std::is_same::value&& - !std::is_same::value, - int > = 0 > -void from_json(const BasicJsonType& j, ArithmeticType& val) -{ - switch (static_cast(j)) - { - case value_t::number_unsigned: - { - val = static_cast(*j.template get_ptr()); - break; - } - case value_t::number_integer: - { - val = static_cast(*j.template get_ptr()); - break; - } - case value_t::number_float: - { - val = static_cast(*j.template get_ptr()); - break; - } - case value_t::boolean: - { - val = static_cast(*j.template get_ptr()); - break; - } - - case value_t::null: - case value_t::object: - case value_t::array: - case value_t::string: - case value_t::binary: - case value_t::discarded: - default: - JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j)); - } -} - -template -std::tuple from_json_tuple_impl_base(BasicJsonType&& j, index_sequence /*unused*/) -{ - return std::make_tuple(std::forward(j).at(Idx).template get()...); -} - -template < typename BasicJsonType, class A1, class A2 > -std::pair from_json_tuple_impl(BasicJsonType&& j, identity_tag> /*unused*/, priority_tag<0> /*unused*/) -{ - return {std::forward(j).at(0).template get(), - std::forward(j).at(1).template get()}; -} - -template -void from_json_tuple_impl(BasicJsonType&& j, std::pair& p, priority_tag<1> /*unused*/) -{ - p = from_json_tuple_impl(std::forward(j), identity_tag> {}, priority_tag<0> {}); -} - -template -std::tuple from_json_tuple_impl(BasicJsonType&& j, identity_tag> /*unused*/, priority_tag<2> /*unused*/) -{ - return from_json_tuple_impl_base(std::forward(j), index_sequence_for {}); -} - -template -void from_json_tuple_impl(BasicJsonType&& j, std::tuple& t, priority_tag<3> /*unused*/) -{ - t = from_json_tuple_impl_base(std::forward(j), index_sequence_for {}); -} - -template -auto from_json(BasicJsonType&& j, TupleRelated&& t) --> decltype(from_json_tuple_impl(std::forward(j), std::forward(t), priority_tag<3> {})) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - - return from_json_tuple_impl(std::forward(j), std::forward(t), priority_tag<3> {}); -} - -template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator, - typename = enable_if_t < !std::is_constructible < - typename BasicJsonType::string_t, Key >::value >> -void from_json(const BasicJsonType& j, std::map& m) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - m.clear(); - for (const auto& p : j) - { - if (JSON_HEDLEY_UNLIKELY(!p.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j)); - } - m.emplace(p.at(0).template get(), p.at(1).template get()); - } -} - -template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator, - typename = enable_if_t < !std::is_constructible < - typename BasicJsonType::string_t, Key >::value >> -void from_json(const BasicJsonType& j, std::unordered_map& m) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - m.clear(); - for (const auto& p : j) - { - if (JSON_HEDLEY_UNLIKELY(!p.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j)); - } - m.emplace(p.at(0).template get(), p.at(1).template get()); - } -} - -struct from_json_fn -{ - template - auto operator()(const BasicJsonType& j, T&& val) const - noexcept(noexcept(from_json(j, std::forward(val)))) - -> decltype(from_json(j, std::forward(val))) - { - return from_json(j, std::forward(val)); - } -}; -} // namespace detail - -/// namespace to hold default `from_json` function -/// to see why this is required: -/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html -namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces) -{ -constexpr const auto& from_json = detail::static_const::value; // NOLINT(misc-definitions-in-headers) -} // namespace -} // namespace nlohmann - -// #include - - -#include // copy -#include // begin, end -#include // string -#include // tuple, get -#include // is_same, is_constructible, is_floating_point, is_enum, underlying_type -#include // move, forward, declval, pair -#include // valarray -#include // vector - -// #include - - -#include // size_t -#include // input_iterator_tag -#include // string, to_string -#include // tuple_size, get, tuple_element -#include // move - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -template -void int_to_string( string_type& target, std::size_t value ) -{ - // For ADL - using std::to_string; - target = to_string(value); -} -template class iteration_proxy_value -{ - public: - using difference_type = std::ptrdiff_t; - using value_type = iteration_proxy_value; - using pointer = value_type * ; - using reference = value_type & ; - using iterator_category = std::input_iterator_tag; - using string_type = typename std::remove_cv< typename std::remove_reference().key() ) >::type >::type; - - private: - /// the iterator - IteratorType anchor; - /// an index for arrays (used to create key names) - std::size_t array_index = 0; - /// last stringified array index - mutable std::size_t array_index_last = 0; - /// a string representation of the array index - mutable string_type array_index_str = "0"; - /// an empty string (to return a reference for primitive values) - const string_type empty_str{}; - - public: - explicit iteration_proxy_value(IteratorType it) noexcept - : anchor(std::move(it)) - {} - - /// dereference operator (needed for range-based for) - iteration_proxy_value& operator*() - { - return *this; - } - - /// increment operator (needed for range-based for) - iteration_proxy_value& operator++() - { - ++anchor; - ++array_index; - - return *this; - } - - /// equality operator (needed for InputIterator) - bool operator==(const iteration_proxy_value& o) const - { - return anchor == o.anchor; - } - - /// inequality operator (needed for range-based for) - bool operator!=(const iteration_proxy_value& o) const - { - return anchor != o.anchor; - } - - /// return key of the iterator - const string_type& key() const - { - JSON_ASSERT(anchor.m_object != nullptr); - - switch (anchor.m_object->type()) - { - // use integer array index as key - case value_t::array: - { - if (array_index != array_index_last) - { - int_to_string( array_index_str, array_index ); - array_index_last = array_index; - } - return array_index_str; - } - - // use key from the object - case value_t::object: - return anchor.key(); - - // use an empty key for all primitive types - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - return empty_str; - } - } - - /// return value of the iterator - typename IteratorType::reference value() const - { - return anchor.value(); - } -}; - -/// proxy class for the items() function -template class iteration_proxy -{ - private: - /// the container to iterate - typename IteratorType::reference container; - - public: - /// construct iteration proxy from a container - explicit iteration_proxy(typename IteratorType::reference cont) noexcept - : container(cont) {} - - /// return iterator begin (needed for range-based for) - iteration_proxy_value begin() noexcept - { - return iteration_proxy_value(container.begin()); - } - - /// return iterator end (needed for range-based for) - iteration_proxy_value end() noexcept - { - return iteration_proxy_value(container.end()); - } -}; -// Structured Bindings Support -// For further reference see https://blog.tartanllama.xyz/structured-bindings/ -// And see https://github.com/nlohmann/json/pull/1391 -template = 0> -auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.key()) -{ - return i.key(); -} -// Structured Bindings Support -// For further reference see https://blog.tartanllama.xyz/structured-bindings/ -// And see https://github.com/nlohmann/json/pull/1391 -template = 0> -auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.value()) -{ - return i.value(); -} -} // namespace detail -} // namespace nlohmann - -// The Addition to the STD Namespace is required to add -// Structured Bindings Support to the iteration_proxy_value class -// For further reference see https://blog.tartanllama.xyz/structured-bindings/ -// And see https://github.com/nlohmann/json/pull/1391 -namespace std -{ -#if defined(__clang__) - // Fix: https://github.com/nlohmann/json/issues/1401 - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wmismatched-tags" -#endif -template -class tuple_size<::nlohmann::detail::iteration_proxy_value> - : public std::integral_constant {}; - -template -class tuple_element> -{ - public: - using type = decltype( - get(std::declval < - ::nlohmann::detail::iteration_proxy_value> ())); -}; -#if defined(__clang__) - #pragma clang diagnostic pop -#endif -} // namespace std - -// #include - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -////////////////// -// constructors // -////////////////// - -/* - * Note all external_constructor<>::construct functions need to call - * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an - * allocated value (e.g., a string). See bug issue - * https://github.com/nlohmann/json/issues/2865 for more information. - */ - -template struct external_constructor; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::boolean; - j.m_value = b; - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::string; - j.m_value = s; - j.assert_invariant(); - } - - template - static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::string; - j.m_value = std::move(s); - j.assert_invariant(); - } - - template < typename BasicJsonType, typename CompatibleStringType, - enable_if_t < !std::is_same::value, - int > = 0 > - static void construct(BasicJsonType& j, const CompatibleStringType& str) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::string; - j.m_value.string = j.template create(str); - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::binary; - j.m_value = typename BasicJsonType::binary_t(b); - j.assert_invariant(); - } - - template - static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::binary; - j.m_value = typename BasicJsonType::binary_t(std::move(b)); - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::number_float; - j.m_value = val; - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::number_unsigned; - j.m_value = val; - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::number_integer; - j.m_value = val; - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::array; - j.m_value = arr; - j.set_parents(); - j.assert_invariant(); - } - - template - static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::array; - j.m_value = std::move(arr); - j.set_parents(); - j.assert_invariant(); - } - - template < typename BasicJsonType, typename CompatibleArrayType, - enable_if_t < !std::is_same::value, - int > = 0 > - static void construct(BasicJsonType& j, const CompatibleArrayType& arr) - { - using std::begin; - using std::end; - - j.m_value.destroy(j.m_type); - j.m_type = value_t::array; - j.m_value.array = j.template create(begin(arr), end(arr)); - j.set_parents(); - j.assert_invariant(); - } - - template - static void construct(BasicJsonType& j, const std::vector& arr) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::array; - j.m_value = value_t::array; - j.m_value.array->reserve(arr.size()); - for (const bool x : arr) - { - j.m_value.array->push_back(x); - j.set_parent(j.m_value.array->back()); - } - j.assert_invariant(); - } - - template::value, int> = 0> - static void construct(BasicJsonType& j, const std::valarray& arr) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::array; - j.m_value = value_t::array; - j.m_value.array->resize(arr.size()); - if (arr.size() > 0) - { - std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin()); - } - j.set_parents(); - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::object; - j.m_value = obj; - j.set_parents(); - j.assert_invariant(); - } - - template - static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::object; - j.m_value = std::move(obj); - j.set_parents(); - j.assert_invariant(); - } - - template < typename BasicJsonType, typename CompatibleObjectType, - enable_if_t < !std::is_same::value, int > = 0 > - static void construct(BasicJsonType& j, const CompatibleObjectType& obj) - { - using std::begin; - using std::end; - - j.m_value.destroy(j.m_type); - j.m_type = value_t::object; - j.m_value.object = j.template create(begin(obj), end(obj)); - j.set_parents(); - j.assert_invariant(); - } -}; - -///////////// -// to_json // -///////////// - -template::value, int> = 0> -void to_json(BasicJsonType& j, T b) noexcept -{ - external_constructor::construct(j, b); -} - -template::value, int> = 0> -void to_json(BasicJsonType& j, const CompatibleString& s) -{ - external_constructor::construct(j, s); -} - -template -void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s) -{ - external_constructor::construct(j, std::move(s)); -} - -template::value, int> = 0> -void to_json(BasicJsonType& j, FloatType val) noexcept -{ - external_constructor::construct(j, static_cast(val)); -} - -template::value, int> = 0> -void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept -{ - external_constructor::construct(j, static_cast(val)); -} - -template::value, int> = 0> -void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept -{ - external_constructor::construct(j, static_cast(val)); -} - -template::value, int> = 0> -void to_json(BasicJsonType& j, EnumType e) noexcept -{ - using underlying_type = typename std::underlying_type::type; - external_constructor::construct(j, static_cast(e)); -} - -template -void to_json(BasicJsonType& j, const std::vector& e) -{ - external_constructor::construct(j, e); -} - -template < typename BasicJsonType, typename CompatibleArrayType, - enable_if_t < is_compatible_array_type::value&& - !is_compatible_object_type::value&& - !is_compatible_string_type::value&& - !std::is_same::value&& - !is_basic_json::value, - int > = 0 > -void to_json(BasicJsonType& j, const CompatibleArrayType& arr) -{ - external_constructor::construct(j, arr); -} - -template -void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin) -{ - external_constructor::construct(j, bin); -} - -template::value, int> = 0> -void to_json(BasicJsonType& j, const std::valarray& arr) -{ - external_constructor::construct(j, std::move(arr)); -} - -template -void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr) -{ - external_constructor::construct(j, std::move(arr)); -} - -template < typename BasicJsonType, typename CompatibleObjectType, - enable_if_t < is_compatible_object_type::value&& !is_basic_json::value, int > = 0 > -void to_json(BasicJsonType& j, const CompatibleObjectType& obj) -{ - external_constructor::construct(j, obj); -} - -template -void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) -{ - external_constructor::construct(j, std::move(obj)); -} - -template < - typename BasicJsonType, typename T, std::size_t N, - enable_if_t < !std::is_constructible::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - int > = 0 > -void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) -{ - external_constructor::construct(j, arr); -} - -template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible::value&& std::is_constructible::value, int > = 0 > -void to_json(BasicJsonType& j, const std::pair& p) -{ - j = { p.first, p.second }; -} - -// for https://github.com/nlohmann/json/pull/1134 -template>::value, int> = 0> -void to_json(BasicJsonType& j, const T& b) -{ - j = { {b.key(), b.value()} }; -} - -template -void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence /*unused*/) -{ - j = { std::get(t)... }; -} - -template::value, int > = 0> -void to_json(BasicJsonType& j, const T& t) -{ - to_json_tuple_impl(j, t, make_index_sequence::value> {}); -} - -struct to_json_fn -{ - template - auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward(val)))) - -> decltype(to_json(j, std::forward(val)), void()) - { - return to_json(j, std::forward(val)); - } -}; -} // namespace detail - -/// namespace to hold default `to_json` function -/// to see why this is required: -/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html -namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces) -{ -constexpr const auto& to_json = detail::static_const::value; // NOLINT(misc-definitions-in-headers) -} // namespace -} // namespace nlohmann - -// #include - -// #include - - -namespace nlohmann -{ - -template -struct adl_serializer -{ - /*! - @brief convert a JSON value to any value type - - This function is usually called by the `get()` function of the - @ref basic_json class (either explicit or via conversion operators). - - @note This function is chosen for default-constructible value types. - - @param[in] j JSON value to read from - @param[in,out] val value to write to - */ - template - static auto from_json(BasicJsonType && j, TargetType& val) noexcept( - noexcept(::nlohmann::from_json(std::forward(j), val))) - -> decltype(::nlohmann::from_json(std::forward(j), val), void()) - { - ::nlohmann::from_json(std::forward(j), val); - } - - /*! - @brief convert a JSON value to any value type - - This function is usually called by the `get()` function of the - @ref basic_json class (either explicit or via conversion operators). - - @note This function is chosen for value types which are not default-constructible. - - @param[in] j JSON value to read from - - @return copy of the JSON value, converted to @a ValueType - */ - template - static auto from_json(BasicJsonType && j) noexcept( - noexcept(::nlohmann::from_json(std::forward(j), detail::identity_tag {}))) - -> decltype(::nlohmann::from_json(std::forward(j), detail::identity_tag {})) - { - return ::nlohmann::from_json(std::forward(j), detail::identity_tag {}); - } - - /*! - @brief convert any value type to a JSON value - - This function is usually called by the constructors of the @ref basic_json - class. - - @param[in,out] j JSON value to write to - @param[in] val value to read from - */ - template - static auto to_json(BasicJsonType& j, TargetType && val) noexcept( - noexcept(::nlohmann::to_json(j, std::forward(val)))) - -> decltype(::nlohmann::to_json(j, std::forward(val)), void()) - { - ::nlohmann::to_json(j, std::forward(val)); - } -}; -} // namespace nlohmann - -// #include - - -#include // uint8_t, uint64_t -#include // tie -#include // move - -namespace nlohmann -{ - -/*! -@brief an internal type for a backed binary type - -This type extends the template parameter @a BinaryType provided to `basic_json` -with a subtype used by BSON and MessagePack. This type exists so that the user -does not have to specify a type themselves with a specific naming scheme in -order to override the binary type. - -@tparam BinaryType container to store bytes (`std::vector` by - default) - -@since version 3.8.0; changed type of subtypes to std::uint64_t in 3.10.0. -*/ -template -class byte_container_with_subtype : public BinaryType -{ - public: - /// the type of the underlying container - using container_type = BinaryType; - /// the type of the subtype - using subtype_type = std::uint64_t; - - byte_container_with_subtype() noexcept(noexcept(container_type())) - : container_type() - {} - - byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b))) - : container_type(b) - {} - - byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b)))) - : container_type(std::move(b)) - {} - - byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b))) - : container_type(b) - , m_subtype(subtype_) - , m_has_subtype(true) - {} - - byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b)))) - : container_type(std::move(b)) - , m_subtype(subtype_) - , m_has_subtype(true) - {} - - bool operator==(const byte_container_with_subtype& rhs) const - { - return std::tie(static_cast(*this), m_subtype, m_has_subtype) == - std::tie(static_cast(rhs), rhs.m_subtype, rhs.m_has_subtype); - } - - bool operator!=(const byte_container_with_subtype& rhs) const - { - return !(rhs == *this); - } - - /*! - @brief sets the binary subtype - - Sets the binary subtype of the value, also flags a binary JSON value as - having a subtype, which has implications for serialization. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa see @ref subtype() -- return the binary subtype - @sa see @ref clear_subtype() -- clears the binary subtype - @sa see @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ - void set_subtype(subtype_type subtype_) noexcept - { - m_subtype = subtype_; - m_has_subtype = true; - } - - /*! - @brief return the binary subtype - - Returns the numerical subtype of the value if it has a subtype. If it does - not have a subtype, this function will return subtype_type(-1) as a sentinel - value. - - @return the numerical subtype of the binary value - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa see @ref set_subtype() -- sets the binary subtype - @sa see @ref clear_subtype() -- clears the binary subtype - @sa see @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0; fixed return value to properly return - subtype_type(-1) as documented in version 3.10.0 - */ - constexpr subtype_type subtype() const noexcept - { - return m_has_subtype ? m_subtype : subtype_type(-1); - } - - /*! - @brief return whether the value has a subtype - - @return whether the value has a subtype - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa see @ref subtype() -- return the binary subtype - @sa see @ref set_subtype() -- sets the binary subtype - @sa see @ref clear_subtype() -- clears the binary subtype - - @since version 3.8.0 - */ - constexpr bool has_subtype() const noexcept - { - return m_has_subtype; - } - - /*! - @brief clears the binary subtype - - Clears the binary subtype and flags the value as not having a subtype, which - has implications for serialization; for instance MessagePack will prefer the - bin family over the ext family. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa see @ref subtype() -- return the binary subtype - @sa see @ref set_subtype() -- sets the binary subtype - @sa see @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ - void clear_subtype() noexcept - { - m_subtype = 0; - m_has_subtype = false; - } - - private: - subtype_type m_subtype = 0; - bool m_has_subtype = false; -}; - -} // namespace nlohmann - -// #include - -// #include - -// #include - -// #include - - -#include // uint8_t -#include // size_t -#include // hash - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ - -// boost::hash_combine -inline std::size_t combine(std::size_t seed, std::size_t h) noexcept -{ - seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); - return seed; -} - -/*! -@brief hash a JSON value - -The hash function tries to rely on std::hash where possible. Furthermore, the -type of the JSON value is taken into account to have different hash values for -null, 0, 0U, and false, etc. - -@tparam BasicJsonType basic_json specialization -@param j JSON value to hash -@return hash value of j -*/ -template -std::size_t hash(const BasicJsonType& j) -{ - using string_t = typename BasicJsonType::string_t; - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - - const auto type = static_cast(j.type()); - switch (j.type()) - { - case BasicJsonType::value_t::null: - case BasicJsonType::value_t::discarded: - { - return combine(type, 0); - } - - case BasicJsonType::value_t::object: - { - auto seed = combine(type, j.size()); - for (const auto& element : j.items()) - { - const auto h = std::hash {}(element.key()); - seed = combine(seed, h); - seed = combine(seed, hash(element.value())); - } - return seed; - } - - case BasicJsonType::value_t::array: - { - auto seed = combine(type, j.size()); - for (const auto& element : j) - { - seed = combine(seed, hash(element)); - } - return seed; - } - - case BasicJsonType::value_t::string: - { - const auto h = std::hash {}(j.template get_ref()); - return combine(type, h); - } - - case BasicJsonType::value_t::boolean: - { - const auto h = std::hash {}(j.template get()); - return combine(type, h); - } - - case BasicJsonType::value_t::number_integer: - { - const auto h = std::hash {}(j.template get()); - return combine(type, h); - } - - case BasicJsonType::value_t::number_unsigned: - { - const auto h = std::hash {}(j.template get()); - return combine(type, h); - } - - case BasicJsonType::value_t::number_float: - { - const auto h = std::hash {}(j.template get()); - return combine(type, h); - } - - case BasicJsonType::value_t::binary: - { - auto seed = combine(type, j.get_binary().size()); - const auto h = std::hash {}(j.get_binary().has_subtype()); - seed = combine(seed, h); - seed = combine(seed, static_cast(j.get_binary().subtype())); - for (const auto byte : j.get_binary()) - { - seed = combine(seed, std::hash {}(byte)); - } - return seed; - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - return 0; // LCOV_EXCL_LINE - } -} - -} // namespace detail -} // namespace nlohmann - -// #include - - -#include // generate_n -#include // array -#include // ldexp -#include // size_t -#include // uint8_t, uint16_t, uint32_t, uint64_t -#include // snprintf -#include // memcpy -#include // back_inserter -#include // numeric_limits -#include // char_traits, string -#include // make_pair, move -#include // vector - -// #include - -// #include - - -#include // array -#include // size_t -#include // strlen -#include // begin, end, iterator_traits, random_access_iterator_tag, distance, next -#include // shared_ptr, make_shared, addressof -#include // accumulate -#include // string, char_traits -#include // enable_if, is_base_of, is_pointer, is_integral, remove_pointer -#include // pair, declval - -#ifndef JSON_NO_IO - #include // FILE * - #include // istream -#endif // JSON_NO_IO - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -/// the supported input formats -enum class input_format_t { json, cbor, msgpack, ubjson, bson }; - -//////////////////// -// input adapters // -//////////////////// - -#ifndef JSON_NO_IO -/*! -Input adapter for stdio file access. This adapter read only 1 byte and do not use any - buffer. This adapter is a very low level adapter. -*/ -class file_input_adapter -{ - public: - using char_type = char; - - JSON_HEDLEY_NON_NULL(2) - explicit file_input_adapter(std::FILE* f) noexcept - : m_file(f) - {} - - // make class move-only - file_input_adapter(const file_input_adapter&) = delete; - file_input_adapter(file_input_adapter&&) noexcept = default; - file_input_adapter& operator=(const file_input_adapter&) = delete; - file_input_adapter& operator=(file_input_adapter&&) = delete; - ~file_input_adapter() = default; - - std::char_traits::int_type get_character() noexcept - { - return std::fgetc(m_file); - } - - private: - /// the file pointer to read from - std::FILE* m_file; -}; - - -/*! -Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at -beginning of input. Does not support changing the underlying std::streambuf -in mid-input. Maintains underlying std::istream and std::streambuf to support -subsequent use of standard std::istream operations to process any input -characters following those used in parsing the JSON input. Clears the -std::istream flags; any input errors (e.g., EOF) will be detected by the first -subsequent call for input from the std::istream. -*/ -class input_stream_adapter -{ - public: - using char_type = char; - - ~input_stream_adapter() - { - // clear stream flags; we use underlying streambuf I/O, do not - // maintain ifstream flags, except eof - if (is != nullptr) - { - is->clear(is->rdstate() & std::ios::eofbit); - } - } - - explicit input_stream_adapter(std::istream& i) - : is(&i), sb(i.rdbuf()) - {} - - // delete because of pointer members - input_stream_adapter(const input_stream_adapter&) = delete; - input_stream_adapter& operator=(input_stream_adapter&) = delete; - input_stream_adapter& operator=(input_stream_adapter&&) = delete; - - input_stream_adapter(input_stream_adapter&& rhs) noexcept - : is(rhs.is), sb(rhs.sb) - { - rhs.is = nullptr; - rhs.sb = nullptr; - } - - // std::istream/std::streambuf use std::char_traits::to_int_type, to - // ensure that std::char_traits::eof() and the character 0xFF do not - // end up as the same value, eg. 0xFFFFFFFF. - std::char_traits::int_type get_character() - { - auto res = sb->sbumpc(); - // set eof manually, as we don't use the istream interface. - if (JSON_HEDLEY_UNLIKELY(res == std::char_traits::eof())) - { - is->clear(is->rdstate() | std::ios::eofbit); - } - return res; - } - - private: - /// the associated input stream - std::istream* is = nullptr; - std::streambuf* sb = nullptr; -}; -#endif // JSON_NO_IO - -// General-purpose iterator-based adapter. It might not be as fast as -// theoretically possible for some containers, but it is extremely versatile. -template -class iterator_input_adapter -{ - public: - using char_type = typename std::iterator_traits::value_type; - - iterator_input_adapter(IteratorType first, IteratorType last) - : current(std::move(first)), end(std::move(last)) - {} - - typename std::char_traits::int_type get_character() - { - if (JSON_HEDLEY_LIKELY(current != end)) - { - auto result = std::char_traits::to_int_type(*current); - std::advance(current, 1); - return result; - } - - return std::char_traits::eof(); - } - - private: - IteratorType current; - IteratorType end; - - template - friend struct wide_string_input_helper; - - bool empty() const - { - return current == end; - } -}; - - -template -struct wide_string_input_helper; - -template -struct wide_string_input_helper -{ - // UTF-32 - static void fill_buffer(BaseInputAdapter& input, - std::array::int_type, 4>& utf8_bytes, - size_t& utf8_bytes_index, - size_t& utf8_bytes_filled) - { - utf8_bytes_index = 0; - - if (JSON_HEDLEY_UNLIKELY(input.empty())) - { - utf8_bytes[0] = std::char_traits::eof(); - utf8_bytes_filled = 1; - } - else - { - // get the current character - const auto wc = input.get_character(); - - // UTF-32 to UTF-8 encoding - if (wc < 0x80) - { - utf8_bytes[0] = static_cast::int_type>(wc); - utf8_bytes_filled = 1; - } - else if (wc <= 0x7FF) - { - utf8_bytes[0] = static_cast::int_type>(0xC0u | ((static_cast(wc) >> 6u) & 0x1Fu)); - utf8_bytes[1] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); - utf8_bytes_filled = 2; - } - else if (wc <= 0xFFFF) - { - utf8_bytes[0] = static_cast::int_type>(0xE0u | ((static_cast(wc) >> 12u) & 0x0Fu)); - utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); - utf8_bytes[2] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); - utf8_bytes_filled = 3; - } - else if (wc <= 0x10FFFF) - { - utf8_bytes[0] = static_cast::int_type>(0xF0u | ((static_cast(wc) >> 18u) & 0x07u)); - utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 12u) & 0x3Fu)); - utf8_bytes[2] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); - utf8_bytes[3] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); - utf8_bytes_filled = 4; - } - else - { - // unknown character - utf8_bytes[0] = static_cast::int_type>(wc); - utf8_bytes_filled = 1; - } - } - } -}; - -template -struct wide_string_input_helper -{ - // UTF-16 - static void fill_buffer(BaseInputAdapter& input, - std::array::int_type, 4>& utf8_bytes, - size_t& utf8_bytes_index, - size_t& utf8_bytes_filled) - { - utf8_bytes_index = 0; - - if (JSON_HEDLEY_UNLIKELY(input.empty())) - { - utf8_bytes[0] = std::char_traits::eof(); - utf8_bytes_filled = 1; - } - else - { - // get the current character - const auto wc = input.get_character(); - - // UTF-16 to UTF-8 encoding - if (wc < 0x80) - { - utf8_bytes[0] = static_cast::int_type>(wc); - utf8_bytes_filled = 1; - } - else if (wc <= 0x7FF) - { - utf8_bytes[0] = static_cast::int_type>(0xC0u | ((static_cast(wc) >> 6u))); - utf8_bytes[1] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); - utf8_bytes_filled = 2; - } - else if (0xD800 > wc || wc >= 0xE000) - { - utf8_bytes[0] = static_cast::int_type>(0xE0u | ((static_cast(wc) >> 12u))); - utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); - utf8_bytes[2] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); - utf8_bytes_filled = 3; - } - else - { - if (JSON_HEDLEY_UNLIKELY(!input.empty())) - { - const auto wc2 = static_cast(input.get_character()); - const auto charcode = 0x10000u + (((static_cast(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu)); - utf8_bytes[0] = static_cast::int_type>(0xF0u | (charcode >> 18u)); - utf8_bytes[1] = static_cast::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu)); - utf8_bytes[2] = static_cast::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu)); - utf8_bytes[3] = static_cast::int_type>(0x80u | (charcode & 0x3Fu)); - utf8_bytes_filled = 4; - } - else - { - utf8_bytes[0] = static_cast::int_type>(wc); - utf8_bytes_filled = 1; - } - } - } - } -}; - -// Wraps another input apdater to convert wide character types into individual bytes. -template -class wide_string_input_adapter -{ - public: - using char_type = char; - - wide_string_input_adapter(BaseInputAdapter base) - : base_adapter(base) {} - - typename std::char_traits::int_type get_character() noexcept - { - // check if buffer needs to be filled - if (utf8_bytes_index == utf8_bytes_filled) - { - fill_buffer(); - - JSON_ASSERT(utf8_bytes_filled > 0); - JSON_ASSERT(utf8_bytes_index == 0); - } - - // use buffer - JSON_ASSERT(utf8_bytes_filled > 0); - JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled); - return utf8_bytes[utf8_bytes_index++]; - } - - private: - BaseInputAdapter base_adapter; - - template - void fill_buffer() - { - wide_string_input_helper::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled); - } - - /// a buffer for UTF-8 bytes - std::array::int_type, 4> utf8_bytes = {{0, 0, 0, 0}}; - - /// index to the utf8_codes array for the next valid byte - std::size_t utf8_bytes_index = 0; - /// number of valid bytes in the utf8_codes array - std::size_t utf8_bytes_filled = 0; -}; - - -template -struct iterator_input_adapter_factory -{ - using iterator_type = IteratorType; - using char_type = typename std::iterator_traits::value_type; - using adapter_type = iterator_input_adapter; - - static adapter_type create(IteratorType first, IteratorType last) - { - return adapter_type(std::move(first), std::move(last)); - } -}; - -template -struct is_iterator_of_multibyte -{ - using value_type = typename std::iterator_traits::value_type; - enum - { - value = sizeof(value_type) > 1 - }; -}; - -template -struct iterator_input_adapter_factory::value>> -{ - using iterator_type = IteratorType; - using char_type = typename std::iterator_traits::value_type; - using base_adapter_type = iterator_input_adapter; - using adapter_type = wide_string_input_adapter; - - static adapter_type create(IteratorType first, IteratorType last) - { - return adapter_type(base_adapter_type(std::move(first), std::move(last))); - } -}; - -// General purpose iterator-based input -template -typename iterator_input_adapter_factory::adapter_type input_adapter(IteratorType first, IteratorType last) -{ - using factory_type = iterator_input_adapter_factory; - return factory_type::create(first, last); -} - -// Convenience shorthand from container to iterator -// Enables ADL on begin(container) and end(container) -// Encloses the using declarations in namespace for not to leak them to outside scope - -namespace container_input_adapter_factory_impl -{ - -using std::begin; -using std::end; - -template -struct container_input_adapter_factory {}; - -template -struct container_input_adapter_factory< ContainerType, - void_t()), end(std::declval()))>> - { - using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); - - static adapter_type create(const ContainerType& container) -{ - return input_adapter(begin(container), end(container)); -} - }; - -} // namespace container_input_adapter_factory_impl - -template -typename container_input_adapter_factory_impl::container_input_adapter_factory::adapter_type input_adapter(const ContainerType& container) -{ - return container_input_adapter_factory_impl::container_input_adapter_factory::create(container); -} - -#ifndef JSON_NO_IO -// Special cases with fast paths -inline file_input_adapter input_adapter(std::FILE* file) -{ - return file_input_adapter(file); -} - -inline input_stream_adapter input_adapter(std::istream& stream) -{ - return input_stream_adapter(stream); -} - -inline input_stream_adapter input_adapter(std::istream&& stream) -{ - return input_stream_adapter(stream); -} -#endif // JSON_NO_IO - -using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval(), std::declval())); - -// Null-delimited strings, and the like. -template < typename CharT, - typename std::enable_if < - std::is_pointer::value&& - !std::is_array::value&& - std::is_integral::type>::value&& - sizeof(typename std::remove_pointer::type) == 1, - int >::type = 0 > -contiguous_bytes_input_adapter input_adapter(CharT b) -{ - auto length = std::strlen(reinterpret_cast(b)); - const auto* ptr = reinterpret_cast(b); - return input_adapter(ptr, ptr + length); -} - -template -auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) -{ - return input_adapter(array, array + N); -} - -// This class only handles inputs of input_buffer_adapter type. -// It's required so that expressions like {ptr, len} can be implicitely casted -// to the correct adapter. -class span_input_adapter -{ - public: - template < typename CharT, - typename std::enable_if < - std::is_pointer::value&& - std::is_integral::type>::value&& - sizeof(typename std::remove_pointer::type) == 1, - int >::type = 0 > - span_input_adapter(CharT b, std::size_t l) - : ia(reinterpret_cast(b), reinterpret_cast(b) + l) {} - - template::iterator_category, std::random_access_iterator_tag>::value, - int>::type = 0> - span_input_adapter(IteratorType first, IteratorType last) - : ia(input_adapter(first, last)) {} - - contiguous_bytes_input_adapter&& get() - { - return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg) - } - - private: - contiguous_bytes_input_adapter ia; -}; -} // namespace detail -} // namespace nlohmann - -// #include - - -#include -#include // string -#include // move -#include // vector - -// #include - -// #include - - -namespace nlohmann -{ - -/*! -@brief SAX interface - -This class describes the SAX interface used by @ref nlohmann::json::sax_parse. -Each function is called in different situations while the input is parsed. The -boolean return value informs the parser whether to continue processing the -input. -*/ -template -struct json_sax -{ - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - - /*! - @brief a null value was read - @return whether parsing should proceed - */ - virtual bool null() = 0; - - /*! - @brief a boolean value was read - @param[in] val boolean value - @return whether parsing should proceed - */ - virtual bool boolean(bool val) = 0; - - /*! - @brief an integer number was read - @param[in] val integer value - @return whether parsing should proceed - */ - virtual bool number_integer(number_integer_t val) = 0; - - /*! - @brief an unsigned integer number was read - @param[in] val unsigned integer value - @return whether parsing should proceed - */ - virtual bool number_unsigned(number_unsigned_t val) = 0; - - /*! - @brief an floating-point number was read - @param[in] val floating-point value - @param[in] s raw token value - @return whether parsing should proceed - */ - virtual bool number_float(number_float_t val, const string_t& s) = 0; - - /*! - @brief a string was read - @param[in] val string value - @return whether parsing should proceed - @note It is safe to move the passed string. - */ - virtual bool string(string_t& val) = 0; - - /*! - @brief a binary string was read - @param[in] val binary value - @return whether parsing should proceed - @note It is safe to move the passed binary. - */ - virtual bool binary(binary_t& val) = 0; - - /*! - @brief the beginning of an object was read - @param[in] elements number of object elements or -1 if unknown - @return whether parsing should proceed - @note binary formats may report the number of elements - */ - virtual bool start_object(std::size_t elements) = 0; - - /*! - @brief an object key was read - @param[in] val object key - @return whether parsing should proceed - @note It is safe to move the passed string. - */ - virtual bool key(string_t& val) = 0; - - /*! - @brief the end of an object was read - @return whether parsing should proceed - */ - virtual bool end_object() = 0; - - /*! - @brief the beginning of an array was read - @param[in] elements number of array elements or -1 if unknown - @return whether parsing should proceed - @note binary formats may report the number of elements - */ - virtual bool start_array(std::size_t elements) = 0; - - /*! - @brief the end of an array was read - @return whether parsing should proceed - */ - virtual bool end_array() = 0; - - /*! - @brief a parse error occurred - @param[in] position the position in the input where the error occurs - @param[in] last_token the last read token - @param[in] ex an exception object describing the error - @return whether parsing should proceed (must return false) - */ - virtual bool parse_error(std::size_t position, - const std::string& last_token, - const detail::exception& ex) = 0; - - json_sax() = default; - json_sax(const json_sax&) = default; - json_sax(json_sax&&) noexcept = default; - json_sax& operator=(const json_sax&) = default; - json_sax& operator=(json_sax&&) noexcept = default; - virtual ~json_sax() = default; -}; - - -namespace detail -{ -/*! -@brief SAX implementation to create a JSON value from SAX events - -This class implements the @ref json_sax interface and processes the SAX events -to create a JSON value which makes it basically a DOM parser. The structure or -hierarchy of the JSON value is managed by the stack `ref_stack` which contains -a pointer to the respective array or object for each recursion depth. - -After successful parsing, the value that is passed by reference to the -constructor contains the parsed value. - -@tparam BasicJsonType the JSON type -*/ -template -class json_sax_dom_parser -{ - public: - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - - /*! - @param[in,out] r reference to a JSON value that is manipulated while - parsing - @param[in] allow_exceptions_ whether parse errors yield exceptions - */ - explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true) - : root(r), allow_exceptions(allow_exceptions_) - {} - - // make class move-only - json_sax_dom_parser(const json_sax_dom_parser&) = delete; - json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete; - json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - ~json_sax_dom_parser() = default; - - bool null() - { - handle_value(nullptr); - return true; - } - - bool boolean(bool val) - { - handle_value(val); - return true; - } - - bool number_integer(number_integer_t val) - { - handle_value(val); - return true; - } - - bool number_unsigned(number_unsigned_t val) - { - handle_value(val); - return true; - } - - bool number_float(number_float_t val, const string_t& /*unused*/) - { - handle_value(val); - return true; - } - - bool string(string_t& val) - { - handle_value(val); - return true; - } - - bool binary(binary_t& val) - { - handle_value(std::move(val)); - return true; - } - - bool start_object(std::size_t len) - { - ref_stack.push_back(handle_value(BasicJsonType::value_t::object)); - - if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) - { - JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back())); - } - - return true; - } - - bool key(string_t& val) - { - // add null at given key and store the reference for later - object_element = &(ref_stack.back()->m_value.object->operator[](val)); - return true; - } - - bool end_object() - { - ref_stack.back()->set_parents(); - ref_stack.pop_back(); - return true; - } - - bool start_array(std::size_t len) - { - ref_stack.push_back(handle_value(BasicJsonType::value_t::array)); - - if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) - { - JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back())); - } - - return true; - } - - bool end_array() - { - ref_stack.back()->set_parents(); - ref_stack.pop_back(); - return true; - } - - template - bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, - const Exception& ex) - { - errored = true; - static_cast(ex); - if (allow_exceptions) - { - JSON_THROW(ex); - } - return false; - } - - constexpr bool is_errored() const - { - return errored; - } - - private: - /*! - @invariant If the ref stack is empty, then the passed value will be the new - root. - @invariant If the ref stack contains a value, then it is an array or an - object to which we can add elements - */ - template - JSON_HEDLEY_RETURNS_NON_NULL - BasicJsonType* handle_value(Value&& v) - { - if (ref_stack.empty()) - { - root = BasicJsonType(std::forward(v)); - return &root; - } - - JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); - - if (ref_stack.back()->is_array()) - { - ref_stack.back()->m_value.array->emplace_back(std::forward(v)); - return &(ref_stack.back()->m_value.array->back()); - } - - JSON_ASSERT(ref_stack.back()->is_object()); - JSON_ASSERT(object_element); - *object_element = BasicJsonType(std::forward(v)); - return object_element; - } - - /// the parsed JSON value - BasicJsonType& root; - /// stack to model hierarchy of values - std::vector ref_stack {}; - /// helper to hold the reference for the next object element - BasicJsonType* object_element = nullptr; - /// whether a syntax error occurred - bool errored = false; - /// whether to throw exceptions in case of errors - const bool allow_exceptions = true; -}; - -template -class json_sax_dom_callback_parser -{ - public: - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using parser_callback_t = typename BasicJsonType::parser_callback_t; - using parse_event_t = typename BasicJsonType::parse_event_t; - - json_sax_dom_callback_parser(BasicJsonType& r, - const parser_callback_t cb, - const bool allow_exceptions_ = true) - : root(r), callback(cb), allow_exceptions(allow_exceptions_) - { - keep_stack.push_back(true); - } - - // make class move-only - json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete; - json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete; - json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - ~json_sax_dom_callback_parser() = default; - - bool null() - { - handle_value(nullptr); - return true; - } - - bool boolean(bool val) - { - handle_value(val); - return true; - } - - bool number_integer(number_integer_t val) - { - handle_value(val); - return true; - } - - bool number_unsigned(number_unsigned_t val) - { - handle_value(val); - return true; - } - - bool number_float(number_float_t val, const string_t& /*unused*/) - { - handle_value(val); - return true; - } - - bool string(string_t& val) - { - handle_value(val); - return true; - } - - bool binary(binary_t& val) - { - handle_value(std::move(val)); - return true; - } - - bool start_object(std::size_t len) - { - // check callback for object start - const bool keep = callback(static_cast(ref_stack.size()), parse_event_t::object_start, discarded); - keep_stack.push_back(keep); - - auto val = handle_value(BasicJsonType::value_t::object, true); - ref_stack.push_back(val.second); - - // check object limit - if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) - { - JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back())); - } - - return true; - } - - bool key(string_t& val) - { - BasicJsonType k = BasicJsonType(val); - - // check callback for key - const bool keep = callback(static_cast(ref_stack.size()), parse_event_t::key, k); - key_keep_stack.push_back(keep); - - // add discarded value at given key and store the reference for later - if (keep && ref_stack.back()) - { - object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded); - } - - return true; - } - - bool end_object() - { - if (ref_stack.back()) - { - if (!callback(static_cast(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back())) - { - // discard object - *ref_stack.back() = discarded; - } - else - { - ref_stack.back()->set_parents(); - } - } - - JSON_ASSERT(!ref_stack.empty()); - JSON_ASSERT(!keep_stack.empty()); - ref_stack.pop_back(); - keep_stack.pop_back(); - - if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured()) - { - // remove discarded value - for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it) - { - if (it->is_discarded()) - { - ref_stack.back()->erase(it); - break; - } - } - } - - return true; - } - - bool start_array(std::size_t len) - { - const bool keep = callback(static_cast(ref_stack.size()), parse_event_t::array_start, discarded); - keep_stack.push_back(keep); - - auto val = handle_value(BasicJsonType::value_t::array, true); - ref_stack.push_back(val.second); - - // check array limit - if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) - { - JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back())); - } - - return true; - } - - bool end_array() - { - bool keep = true; - - if (ref_stack.back()) - { - keep = callback(static_cast(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back()); - if (keep) - { - ref_stack.back()->set_parents(); - } - else - { - // discard array - *ref_stack.back() = discarded; - } - } - - JSON_ASSERT(!ref_stack.empty()); - JSON_ASSERT(!keep_stack.empty()); - ref_stack.pop_back(); - keep_stack.pop_back(); - - // remove discarded value - if (!keep && !ref_stack.empty() && ref_stack.back()->is_array()) - { - ref_stack.back()->m_value.array->pop_back(); - } - - return true; - } - - template - bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, - const Exception& ex) - { - errored = true; - static_cast(ex); - if (allow_exceptions) - { - JSON_THROW(ex); - } - return false; - } - - constexpr bool is_errored() const - { - return errored; - } - - private: - /*! - @param[in] v value to add to the JSON value we build during parsing - @param[in] skip_callback whether we should skip calling the callback - function; this is required after start_array() and - start_object() SAX events, because otherwise we would call the - callback function with an empty array or object, respectively. - - @invariant If the ref stack is empty, then the passed value will be the new - root. - @invariant If the ref stack contains a value, then it is an array or an - object to which we can add elements - - @return pair of boolean (whether value should be kept) and pointer (to the - passed value in the ref_stack hierarchy; nullptr if not kept) - */ - template - std::pair handle_value(Value&& v, const bool skip_callback = false) - { - JSON_ASSERT(!keep_stack.empty()); - - // do not handle this value if we know it would be added to a discarded - // container - if (!keep_stack.back()) - { - return {false, nullptr}; - } - - // create value - auto value = BasicJsonType(std::forward(v)); - - // check callback - const bool keep = skip_callback || callback(static_cast(ref_stack.size()), parse_event_t::value, value); - - // do not handle this value if we just learnt it shall be discarded - if (!keep) - { - return {false, nullptr}; - } - - if (ref_stack.empty()) - { - root = std::move(value); - return {true, &root}; - } - - // skip this value if we already decided to skip the parent - // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360) - if (!ref_stack.back()) - { - return {false, nullptr}; - } - - // we now only expect arrays and objects - JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); - - // array - if (ref_stack.back()->is_array()) - { - ref_stack.back()->m_value.array->emplace_back(std::move(value)); - return {true, &(ref_stack.back()->m_value.array->back())}; - } - - // object - JSON_ASSERT(ref_stack.back()->is_object()); - // check if we should store an element for the current key - JSON_ASSERT(!key_keep_stack.empty()); - const bool store_element = key_keep_stack.back(); - key_keep_stack.pop_back(); - - if (!store_element) - { - return {false, nullptr}; - } - - JSON_ASSERT(object_element); - *object_element = std::move(value); - return {true, object_element}; - } - - /// the parsed JSON value - BasicJsonType& root; - /// stack to model hierarchy of values - std::vector ref_stack {}; - /// stack to manage which values to keep - std::vector keep_stack {}; - /// stack to manage which object keys to keep - std::vector key_keep_stack {}; - /// helper to hold the reference for the next object element - BasicJsonType* object_element = nullptr; - /// whether a syntax error occurred - bool errored = false; - /// callback function - const parser_callback_t callback = nullptr; - /// whether to throw exceptions in case of errors - const bool allow_exceptions = true; - /// a discarded value for the callback - BasicJsonType discarded = BasicJsonType::value_t::discarded; -}; - -template -class json_sax_acceptor -{ - public: - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - - bool null() - { - return true; - } - - bool boolean(bool /*unused*/) - { - return true; - } - - bool number_integer(number_integer_t /*unused*/) - { - return true; - } - - bool number_unsigned(number_unsigned_t /*unused*/) - { - return true; - } - - bool number_float(number_float_t /*unused*/, const string_t& /*unused*/) - { - return true; - } - - bool string(string_t& /*unused*/) - { - return true; - } - - bool binary(binary_t& /*unused*/) - { - return true; - } - - bool start_object(std::size_t /*unused*/ = std::size_t(-1)) - { - return true; - } - - bool key(string_t& /*unused*/) - { - return true; - } - - bool end_object() - { - return true; - } - - bool start_array(std::size_t /*unused*/ = std::size_t(-1)) - { - return true; - } - - bool end_array() - { - return true; - } - - bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/) - { - return false; - } -}; -} // namespace detail - -} // namespace nlohmann - -// #include - - -#include // array -#include // localeconv -#include // size_t -#include // snprintf -#include // strtof, strtod, strtold, strtoll, strtoull -#include // initializer_list -#include // char_traits, string -#include // move -#include // vector - -// #include - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -/////////// -// lexer // -/////////// - -template -class lexer_base -{ - public: - /// token types for the parser - enum class token_type - { - uninitialized, ///< indicating the scanner is uninitialized - literal_true, ///< the `true` literal - literal_false, ///< the `false` literal - literal_null, ///< the `null` literal - value_string, ///< a string -- use get_string() for actual value - value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value - value_integer, ///< a signed integer -- use get_number_integer() for actual value - value_float, ///< an floating point number -- use get_number_float() for actual value - begin_array, ///< the character for array begin `[` - begin_object, ///< the character for object begin `{` - end_array, ///< the character for array end `]` - end_object, ///< the character for object end `}` - name_separator, ///< the name separator `:` - value_separator, ///< the value separator `,` - parse_error, ///< indicating a parse error - end_of_input, ///< indicating the end of the input buffer - literal_or_value ///< a literal or the begin of a value (only for diagnostics) - }; - - /// return name of values of type token_type (only used for errors) - JSON_HEDLEY_RETURNS_NON_NULL - JSON_HEDLEY_CONST - static const char* token_type_name(const token_type t) noexcept - { - switch (t) - { - case token_type::uninitialized: - return ""; - case token_type::literal_true: - return "true literal"; - case token_type::literal_false: - return "false literal"; - case token_type::literal_null: - return "null literal"; - case token_type::value_string: - return "string literal"; - case token_type::value_unsigned: - case token_type::value_integer: - case token_type::value_float: - return "number literal"; - case token_type::begin_array: - return "'['"; - case token_type::begin_object: - return "'{'"; - case token_type::end_array: - return "']'"; - case token_type::end_object: - return "'}'"; - case token_type::name_separator: - return "':'"; - case token_type::value_separator: - return "','"; - case token_type::parse_error: - return ""; - case token_type::end_of_input: - return "end of input"; - case token_type::literal_or_value: - return "'[', '{', or a literal"; - // LCOV_EXCL_START - default: // catch non-enum values - return "unknown token"; - // LCOV_EXCL_STOP - } - } -}; -/*! -@brief lexical analysis - -This class organizes the lexical analysis during JSON deserialization. -*/ -template -class lexer : public lexer_base -{ - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using char_type = typename InputAdapterType::char_type; - using char_int_type = typename std::char_traits::int_type; - - public: - using token_type = typename lexer_base::token_type; - - explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept - : ia(std::move(adapter)) - , ignore_comments(ignore_comments_) - , decimal_point_char(static_cast(get_decimal_point())) - {} - - // delete because of pointer members - lexer(const lexer&) = delete; - lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - lexer& operator=(lexer&) = delete; - lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - ~lexer() = default; - - private: - ///////////////////// - // locales - ///////////////////// - - /// return the locale-dependent decimal point - JSON_HEDLEY_PURE - static char get_decimal_point() noexcept - { - const auto* loc = localeconv(); - JSON_ASSERT(loc != nullptr); - return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point); - } - - ///////////////////// - // scan functions - ///////////////////// - - /*! - @brief get codepoint from 4 hex characters following `\u` - - For input "\u c1 c2 c3 c4" the codepoint is: - (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4 - = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0) - - Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f' - must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The - conversion is done by subtracting the offset (0x30, 0x37, and 0x57) - between the ASCII value of the character and the desired integer value. - - @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or - non-hex character) - */ - int get_codepoint() - { - // this function only makes sense after reading `\u` - JSON_ASSERT(current == 'u'); - int codepoint = 0; - - const auto factors = { 12u, 8u, 4u, 0u }; - for (const auto factor : factors) - { - get(); - - if (current >= '0' && current <= '9') - { - codepoint += static_cast((static_cast(current) - 0x30u) << factor); - } - else if (current >= 'A' && current <= 'F') - { - codepoint += static_cast((static_cast(current) - 0x37u) << factor); - } - else if (current >= 'a' && current <= 'f') - { - codepoint += static_cast((static_cast(current) - 0x57u) << factor); - } - else - { - return -1; - } - } - - JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF); - return codepoint; - } - - /*! - @brief check if the next byte(s) are inside a given range - - Adds the current byte and, for each passed range, reads a new byte and - checks if it is inside the range. If a violation was detected, set up an - error message and return false. Otherwise, return true. - - @param[in] ranges list of integers; interpreted as list of pairs of - inclusive lower and upper bound, respectively - - @pre The passed list @a ranges must have 2, 4, or 6 elements; that is, - 1, 2, or 3 pairs. This precondition is enforced by an assertion. - - @return true if and only if no range violation was detected - */ - bool next_byte_in_range(std::initializer_list ranges) - { - JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6); - add(current); - - for (auto range = ranges.begin(); range != ranges.end(); ++range) - { - get(); - if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) - { - add(current); - } - else - { - error_message = "invalid string: ill-formed UTF-8 byte"; - return false; - } - } - - return true; - } - - /*! - @brief scan a string literal - - This function scans a string according to Sect. 7 of RFC 8259. While - scanning, bytes are escaped and copied into buffer token_buffer. Then the - function returns successfully, token_buffer is *not* null-terminated (as it - may contain \0 bytes), and token_buffer.size() is the number of bytes in the - string. - - @return token_type::value_string if string could be successfully scanned, - token_type::parse_error otherwise - - @note In case of errors, variable error_message contains a textual - description. - */ - token_type scan_string() - { - // reset token_buffer (ignore opening quote) - reset(); - - // we entered the function by reading an open quote - JSON_ASSERT(current == '\"'); - - while (true) - { - // get next character - switch (get()) - { - // end of file while parsing string - case std::char_traits::eof(): - { - error_message = "invalid string: missing closing quote"; - return token_type::parse_error; - } - - // closing quote - case '\"': - { - return token_type::value_string; - } - - // escapes - case '\\': - { - switch (get()) - { - // quotation mark - case '\"': - add('\"'); - break; - // reverse solidus - case '\\': - add('\\'); - break; - // solidus - case '/': - add('/'); - break; - // backspace - case 'b': - add('\b'); - break; - // form feed - case 'f': - add('\f'); - break; - // line feed - case 'n': - add('\n'); - break; - // carriage return - case 'r': - add('\r'); - break; - // tab - case 't': - add('\t'); - break; - - // unicode escapes - case 'u': - { - const int codepoint1 = get_codepoint(); - int codepoint = codepoint1; // start with codepoint1 - - if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1)) - { - error_message = "invalid string: '\\u' must be followed by 4 hex digits"; - return token_type::parse_error; - } - - // check if code point is a high surrogate - if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF) - { - // expect next \uxxxx entry - if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u')) - { - const int codepoint2 = get_codepoint(); - - if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1)) - { - error_message = "invalid string: '\\u' must be followed by 4 hex digits"; - return token_type::parse_error; - } - - // check if codepoint2 is a low surrogate - if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF)) - { - // overwrite codepoint - codepoint = static_cast( - // high surrogate occupies the most significant 22 bits - (static_cast(codepoint1) << 10u) - // low surrogate occupies the least significant 15 bits - + static_cast(codepoint2) - // there is still the 0xD800, 0xDC00 and 0x10000 noise - // in the result so we have to subtract with: - // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00 - - 0x35FDC00u); - } - else - { - error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF"; - return token_type::parse_error; - } - } - else - { - error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF"; - return token_type::parse_error; - } - } - else - { - if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF)) - { - error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF"; - return token_type::parse_error; - } - } - - // result of the above calculation yields a proper codepoint - JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF); - - // translate codepoint into bytes - if (codepoint < 0x80) - { - // 1-byte characters: 0xxxxxxx (ASCII) - add(static_cast(codepoint)); - } - else if (codepoint <= 0x7FF) - { - // 2-byte characters: 110xxxxx 10xxxxxx - add(static_cast(0xC0u | (static_cast(codepoint) >> 6u))); - add(static_cast(0x80u | (static_cast(codepoint) & 0x3Fu))); - } - else if (codepoint <= 0xFFFF) - { - // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx - add(static_cast(0xE0u | (static_cast(codepoint) >> 12u))); - add(static_cast(0x80u | ((static_cast(codepoint) >> 6u) & 0x3Fu))); - add(static_cast(0x80u | (static_cast(codepoint) & 0x3Fu))); - } - else - { - // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - add(static_cast(0xF0u | (static_cast(codepoint) >> 18u))); - add(static_cast(0x80u | ((static_cast(codepoint) >> 12u) & 0x3Fu))); - add(static_cast(0x80u | ((static_cast(codepoint) >> 6u) & 0x3Fu))); - add(static_cast(0x80u | (static_cast(codepoint) & 0x3Fu))); - } - - break; - } - - // other characters after escape - default: - error_message = "invalid string: forbidden character after backslash"; - return token_type::parse_error; - } - - break; - } - - // invalid control characters - case 0x00: - { - error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000"; - return token_type::parse_error; - } - - case 0x01: - { - error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001"; - return token_type::parse_error; - } - - case 0x02: - { - error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002"; - return token_type::parse_error; - } - - case 0x03: - { - error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003"; - return token_type::parse_error; - } - - case 0x04: - { - error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004"; - return token_type::parse_error; - } - - case 0x05: - { - error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005"; - return token_type::parse_error; - } - - case 0x06: - { - error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006"; - return token_type::parse_error; - } - - case 0x07: - { - error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007"; - return token_type::parse_error; - } - - case 0x08: - { - error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b"; - return token_type::parse_error; - } - - case 0x09: - { - error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t"; - return token_type::parse_error; - } - - case 0x0A: - { - error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n"; - return token_type::parse_error; - } - - case 0x0B: - { - error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B"; - return token_type::parse_error; - } - - case 0x0C: - { - error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f"; - return token_type::parse_error; - } - - case 0x0D: - { - error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r"; - return token_type::parse_error; - } - - case 0x0E: - { - error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E"; - return token_type::parse_error; - } - - case 0x0F: - { - error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F"; - return token_type::parse_error; - } - - case 0x10: - { - error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010"; - return token_type::parse_error; - } - - case 0x11: - { - error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011"; - return token_type::parse_error; - } - - case 0x12: - { - error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012"; - return token_type::parse_error; - } - - case 0x13: - { - error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013"; - return token_type::parse_error; - } - - case 0x14: - { - error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014"; - return token_type::parse_error; - } - - case 0x15: - { - error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015"; - return token_type::parse_error; - } - - case 0x16: - { - error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016"; - return token_type::parse_error; - } - - case 0x17: - { - error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017"; - return token_type::parse_error; - } - - case 0x18: - { - error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018"; - return token_type::parse_error; - } - - case 0x19: - { - error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019"; - return token_type::parse_error; - } - - case 0x1A: - { - error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A"; - return token_type::parse_error; - } - - case 0x1B: - { - error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B"; - return token_type::parse_error; - } - - case 0x1C: - { - error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C"; - return token_type::parse_error; - } - - case 0x1D: - { - error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D"; - return token_type::parse_error; - } - - case 0x1E: - { - error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E"; - return token_type::parse_error; - } - - case 0x1F: - { - error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F"; - return token_type::parse_error; - } - - // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace)) - case 0x20: - case 0x21: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - case 0x29: - case 0x2A: - case 0x2B: - case 0x2C: - case 0x2D: - case 0x2E: - case 0x2F: - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3A: - case 0x3B: - case 0x3C: - case 0x3D: - case 0x3E: - case 0x3F: - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4A: - case 0x4B: - case 0x4C: - case 0x4D: - case 0x4E: - case 0x4F: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5A: - case 0x5B: - case 0x5D: - case 0x5E: - case 0x5F: - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6A: - case 0x6B: - case 0x6C: - case 0x6D: - case 0x6E: - case 0x6F: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - case 0x78: - case 0x79: - case 0x7A: - case 0x7B: - case 0x7C: - case 0x7D: - case 0x7E: - case 0x7F: - { - add(current); - break; - } - - // U+0080..U+07FF: bytes C2..DF 80..BF - case 0xC2: - case 0xC3: - case 0xC4: - case 0xC5: - case 0xC6: - case 0xC7: - case 0xC8: - case 0xC9: - case 0xCA: - case 0xCB: - case 0xCC: - case 0xCD: - case 0xCE: - case 0xCF: - case 0xD0: - case 0xD1: - case 0xD2: - case 0xD3: - case 0xD4: - case 0xD5: - case 0xD6: - case 0xD7: - case 0xD8: - case 0xD9: - case 0xDA: - case 0xDB: - case 0xDC: - case 0xDD: - case 0xDE: - case 0xDF: - { - if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF}))) - { - return token_type::parse_error; - } - break; - } - - // U+0800..U+0FFF: bytes E0 A0..BF 80..BF - case 0xE0: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF - // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF - case 0xE1: - case 0xE2: - case 0xE3: - case 0xE4: - case 0xE5: - case 0xE6: - case 0xE7: - case 0xE8: - case 0xE9: - case 0xEA: - case 0xEB: - case 0xEC: - case 0xEE: - case 0xEF: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+D000..U+D7FF: bytes ED 80..9F 80..BF - case 0xED: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF - case 0xF0: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF - case 0xF1: - case 0xF2: - case 0xF3: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF - case 0xF4: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // remaining bytes (80..C1 and F5..FF) are ill-formed - default: - { - error_message = "invalid string: ill-formed UTF-8 byte"; - return token_type::parse_error; - } - } - } - } - - /*! - * @brief scan a comment - * @return whether comment could be scanned successfully - */ - bool scan_comment() - { - switch (get()) - { - // single-line comments skip input until a newline or EOF is read - case '/': - { - while (true) - { - switch (get()) - { - case '\n': - case '\r': - case std::char_traits::eof(): - case '\0': - return true; - - default: - break; - } - } - } - - // multi-line comments skip input until */ is read - case '*': - { - while (true) - { - switch (get()) - { - case std::char_traits::eof(): - case '\0': - { - error_message = "invalid comment; missing closing '*/'"; - return false; - } - - case '*': - { - switch (get()) - { - case '/': - return true; - - default: - { - unget(); - continue; - } - } - } - - default: - continue; - } - } - } - - // unexpected character after reading '/' - default: - { - error_message = "invalid comment; expecting '/' or '*' after '/'"; - return false; - } - } - } - - JSON_HEDLEY_NON_NULL(2) - static void strtof(float& f, const char* str, char** endptr) noexcept - { - f = std::strtof(str, endptr); - } - - JSON_HEDLEY_NON_NULL(2) - static void strtof(double& f, const char* str, char** endptr) noexcept - { - f = std::strtod(str, endptr); - } - - JSON_HEDLEY_NON_NULL(2) - static void strtof(long double& f, const char* str, char** endptr) noexcept - { - f = std::strtold(str, endptr); - } - - /*! - @brief scan a number literal - - This function scans a string according to Sect. 6 of RFC 8259. - - The function is realized with a deterministic finite state machine derived - from the grammar described in RFC 8259. Starting in state "init", the - input is read and used to determined the next state. Only state "done" - accepts the number. State "error" is a trap state to model errors. In the - table below, "anything" means any character but the ones listed before. - - state | 0 | 1-9 | e E | + | - | . | anything - ---------|----------|----------|----------|---------|---------|----------|----------- - init | zero | any1 | [error] | [error] | minus | [error] | [error] - minus | zero | any1 | [error] | [error] | [error] | [error] | [error] - zero | done | done | exponent | done | done | decimal1 | done - any1 | any1 | any1 | exponent | done | done | decimal1 | done - decimal1 | decimal2 | decimal2 | [error] | [error] | [error] | [error] | [error] - decimal2 | decimal2 | decimal2 | exponent | done | done | done | done - exponent | any2 | any2 | [error] | sign | sign | [error] | [error] - sign | any2 | any2 | [error] | [error] | [error] | [error] | [error] - any2 | any2 | any2 | done | done | done | done | done - - The state machine is realized with one label per state (prefixed with - "scan_number_") and `goto` statements between them. The state machine - contains cycles, but any cycle can be left when EOF is read. Therefore, - the function is guaranteed to terminate. - - During scanning, the read bytes are stored in token_buffer. This string is - then converted to a signed integer, an unsigned integer, or a - floating-point number. - - @return token_type::value_unsigned, token_type::value_integer, or - token_type::value_float if number could be successfully scanned, - token_type::parse_error otherwise - - @note The scanner is independent of the current locale. Internally, the - locale's decimal point is used instead of `.` to work with the - locale-dependent converters. - */ - token_type scan_number() // lgtm [cpp/use-of-goto] - { - // reset token_buffer to store the number's bytes - reset(); - - // the type of the parsed number; initially set to unsigned; will be - // changed if minus sign, decimal point or exponent is read - token_type number_type = token_type::value_unsigned; - - // state (init): we just found out we need to scan a number - switch (current) - { - case '-': - { - add(current); - goto scan_number_minus; - } - - case '0': - { - add(current); - goto scan_number_zero; - } - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any1; - } - - // all other characters are rejected outside scan_number() - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - -scan_number_minus: - // state: we just parsed a leading minus sign - number_type = token_type::value_integer; - switch (get()) - { - case '0': - { - add(current); - goto scan_number_zero; - } - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any1; - } - - default: - { - error_message = "invalid number; expected digit after '-'"; - return token_type::parse_error; - } - } - -scan_number_zero: - // state: we just parse a zero (maybe with a leading minus sign) - switch (get()) - { - case '.': - { - add(decimal_point_char); - goto scan_number_decimal1; - } - - case 'e': - case 'E': - { - add(current); - goto scan_number_exponent; - } - - default: - goto scan_number_done; - } - -scan_number_any1: - // state: we just parsed a number 0-9 (maybe with a leading minus sign) - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any1; - } - - case '.': - { - add(decimal_point_char); - goto scan_number_decimal1; - } - - case 'e': - case 'E': - { - add(current); - goto scan_number_exponent; - } - - default: - goto scan_number_done; - } - -scan_number_decimal1: - // state: we just parsed a decimal point - number_type = token_type::value_float; - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_decimal2; - } - - default: - { - error_message = "invalid number; expected digit after '.'"; - return token_type::parse_error; - } - } - -scan_number_decimal2: - // we just parsed at least one number after a decimal point - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_decimal2; - } - - case 'e': - case 'E': - { - add(current); - goto scan_number_exponent; - } - - default: - goto scan_number_done; - } - -scan_number_exponent: - // we just parsed an exponent - number_type = token_type::value_float; - switch (get()) - { - case '+': - case '-': - { - add(current); - goto scan_number_sign; - } - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any2; - } - - default: - { - error_message = - "invalid number; expected '+', '-', or digit after exponent"; - return token_type::parse_error; - } - } - -scan_number_sign: - // we just parsed an exponent sign - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any2; - } - - default: - { - error_message = "invalid number; expected digit after exponent sign"; - return token_type::parse_error; - } - } - -scan_number_any2: - // we just parsed a number after the exponent or exponent sign - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any2; - } - - default: - goto scan_number_done; - } - -scan_number_done: - // unget the character after the number (we only read it to know that - // we are done scanning a number) - unget(); - - char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - errno = 0; - - // try to parse integers first and fall back to floats - if (number_type == token_type::value_unsigned) - { - const auto x = std::strtoull(token_buffer.data(), &endptr, 10); - - // we checked the number format before - JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); - - if (errno == 0) - { - value_unsigned = static_cast(x); - if (value_unsigned == x) - { - return token_type::value_unsigned; - } - } - } - else if (number_type == token_type::value_integer) - { - const auto x = std::strtoll(token_buffer.data(), &endptr, 10); - - // we checked the number format before - JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); - - if (errno == 0) - { - value_integer = static_cast(x); - if (value_integer == x) - { - return token_type::value_integer; - } - } - } - - // this code is reached if we parse a floating-point number or if an - // integer conversion above failed - strtof(value_float, token_buffer.data(), &endptr); - - // we checked the number format before - JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); - - return token_type::value_float; - } - - /*! - @param[in] literal_text the literal text to expect - @param[in] length the length of the passed literal text - @param[in] return_type the token type to return on success - */ - JSON_HEDLEY_NON_NULL(2) - token_type scan_literal(const char_type* literal_text, const std::size_t length, - token_type return_type) - { - JSON_ASSERT(std::char_traits::to_char_type(current) == literal_text[0]); - for (std::size_t i = 1; i < length; ++i) - { - if (JSON_HEDLEY_UNLIKELY(std::char_traits::to_char_type(get()) != literal_text[i])) - { - error_message = "invalid literal"; - return token_type::parse_error; - } - } - return return_type; - } - - ///////////////////// - // input management - ///////////////////// - - /// reset token_buffer; current character is beginning of token - void reset() noexcept - { - token_buffer.clear(); - token_string.clear(); - token_string.push_back(std::char_traits::to_char_type(current)); - } - - /* - @brief get next character from the input - - This function provides the interface to the used input adapter. It does - not throw in case the input reached EOF, but returns a - `std::char_traits::eof()` in that case. Stores the scanned characters - for use in error messages. - - @return character read from the input - */ - char_int_type get() - { - ++position.chars_read_total; - ++position.chars_read_current_line; - - if (next_unget) - { - // just reset the next_unget variable and work with current - next_unget = false; - } - else - { - current = ia.get_character(); - } - - if (JSON_HEDLEY_LIKELY(current != std::char_traits::eof())) - { - token_string.push_back(std::char_traits::to_char_type(current)); - } - - if (current == '\n') - { - ++position.lines_read; - position.chars_read_current_line = 0; - } - - return current; - } - - /*! - @brief unget current character (read it again on next get) - - We implement unget by setting variable next_unget to true. The input is not - changed - we just simulate ungetting by modifying chars_read_total, - chars_read_current_line, and token_string. The next call to get() will - behave as if the unget character is read again. - */ - void unget() - { - next_unget = true; - - --position.chars_read_total; - - // in case we "unget" a newline, we have to also decrement the lines_read - if (position.chars_read_current_line == 0) - { - if (position.lines_read > 0) - { - --position.lines_read; - } - } - else - { - --position.chars_read_current_line; - } - - if (JSON_HEDLEY_LIKELY(current != std::char_traits::eof())) - { - JSON_ASSERT(!token_string.empty()); - token_string.pop_back(); - } - } - - /// add a character to token_buffer - void add(char_int_type c) - { - token_buffer.push_back(static_cast(c)); - } - - public: - ///////////////////// - // value getters - ///////////////////// - - /// return integer value - constexpr number_integer_t get_number_integer() const noexcept - { - return value_integer; - } - - /// return unsigned integer value - constexpr number_unsigned_t get_number_unsigned() const noexcept - { - return value_unsigned; - } - - /// return floating-point value - constexpr number_float_t get_number_float() const noexcept - { - return value_float; - } - - /// return current string value (implicitly resets the token; useful only once) - string_t& get_string() - { - return token_buffer; - } - - ///////////////////// - // diagnostics - ///////////////////// - - /// return position of last read token - constexpr position_t get_position() const noexcept - { - return position; - } - - /// return the last read token (for errors only). Will never contain EOF - /// (an arbitrary value that is not a valid char value, often -1), because - /// 255 may legitimately occur. May contain NUL, which should be escaped. - std::string get_token_string() const - { - // escape control characters - std::string result; - for (const auto c : token_string) - { - if (static_cast(c) <= '\x1F') - { - // escape control characters - std::array cs{{}}; - (std::snprintf)(cs.data(), cs.size(), "", static_cast(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - result += cs.data(); - } - else - { - // add character as is - result.push_back(static_cast(c)); - } - } - - return result; - } - - /// return syntax error message - JSON_HEDLEY_RETURNS_NON_NULL - constexpr const char* get_error_message() const noexcept - { - return error_message; - } - - ///////////////////// - // actual scanner - ///////////////////// - - /*! - @brief skip the UTF-8 byte order mark - @return true iff there is no BOM or the correct BOM has been skipped - */ - bool skip_bom() - { - if (get() == 0xEF) - { - // check if we completely parse the BOM - return get() == 0xBB && get() == 0xBF; - } - - // the first character is not the beginning of the BOM; unget it to - // process is later - unget(); - return true; - } - - void skip_whitespace() - { - do - { - get(); - } - while (current == ' ' || current == '\t' || current == '\n' || current == '\r'); - } - - token_type scan() - { - // initially, skip the BOM - if (position.chars_read_total == 0 && !skip_bom()) - { - error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given"; - return token_type::parse_error; - } - - // read next character and ignore whitespace - skip_whitespace(); - - // ignore comments - while (ignore_comments && current == '/') - { - if (!scan_comment()) - { - return token_type::parse_error; - } - - // skip following whitespace - skip_whitespace(); - } - - switch (current) - { - // structural characters - case '[': - return token_type::begin_array; - case ']': - return token_type::end_array; - case '{': - return token_type::begin_object; - case '}': - return token_type::end_object; - case ':': - return token_type::name_separator; - case ',': - return token_type::value_separator; - - // literals - case 't': - { - std::array true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}}; - return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true); - } - case 'f': - { - std::array false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}}; - return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false); - } - case 'n': - { - std::array null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}}; - return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null); - } - - // string - case '\"': - return scan_string(); - - // number - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return scan_number(); - - // end of input (the null byte is needed when parsing from - // string literals) - case '\0': - case std::char_traits::eof(): - return token_type::end_of_input; - - // error - default: - error_message = "invalid literal"; - return token_type::parse_error; - } - } - - private: - /// input adapter - InputAdapterType ia; - - /// whether comments should be ignored (true) or signaled as errors (false) - const bool ignore_comments = false; - - /// the current character - char_int_type current = std::char_traits::eof(); - - /// whether the next get() call should just return current - bool next_unget = false; - - /// the start position of the current token - position_t position {}; - - /// raw input token string (for error messages) - std::vector token_string {}; - - /// buffer for variable-length tokens (numbers, strings) - string_t token_buffer {}; - - /// a description of occurred lexer errors - const char* error_message = ""; - - // number values - number_integer_t value_integer = 0; - number_unsigned_t value_unsigned = 0; - number_float_t value_float = 0; - - /// the decimal point - const char_int_type decimal_point_char = '.'; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - - -#include // size_t -#include // declval -#include // string - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -template -using null_function_t = decltype(std::declval().null()); - -template -using boolean_function_t = - decltype(std::declval().boolean(std::declval())); - -template -using number_integer_function_t = - decltype(std::declval().number_integer(std::declval())); - -template -using number_unsigned_function_t = - decltype(std::declval().number_unsigned(std::declval())); - -template -using number_float_function_t = decltype(std::declval().number_float( - std::declval(), std::declval())); - -template -using string_function_t = - decltype(std::declval().string(std::declval())); - -template -using binary_function_t = - decltype(std::declval().binary(std::declval())); - -template -using start_object_function_t = - decltype(std::declval().start_object(std::declval())); - -template -using key_function_t = - decltype(std::declval().key(std::declval())); - -template -using end_object_function_t = decltype(std::declval().end_object()); - -template -using start_array_function_t = - decltype(std::declval().start_array(std::declval())); - -template -using end_array_function_t = decltype(std::declval().end_array()); - -template -using parse_error_function_t = decltype(std::declval().parse_error( - std::declval(), std::declval(), - std::declval())); - -template -struct is_sax -{ - private: - static_assert(is_basic_json::value, - "BasicJsonType must be of type basic_json<...>"); - - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using exception_t = typename BasicJsonType::exception; - - public: - static constexpr bool value = - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value; -}; - -template -struct is_sax_static_asserts -{ - private: - static_assert(is_basic_json::value, - "BasicJsonType must be of type basic_json<...>"); - - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using exception_t = typename BasicJsonType::exception; - - public: - static_assert(is_detected_exact::value, - "Missing/invalid function: bool null()"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool boolean(bool)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool boolean(bool)"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool number_integer(number_integer_t)"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool number_unsigned(number_unsigned_t)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool number_float(number_float_t, const string_t&)"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool string(string_t&)"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool binary(binary_t&)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool start_object(std::size_t)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool key(string_t&)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool end_object()"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool start_array(std::size_t)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool end_array()"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool parse_error(std::size_t, const " - "std::string&, const exception&)"); -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ - -/// how to treat CBOR tags -enum class cbor_tag_handler_t -{ - error, ///< throw a parse_error exception in case of a tag - ignore, ///< ignore tags - store ///< store tags as binary type -}; - -/*! -@brief determine system byte order - -@return true if and only if system's byte order is little endian - -@note from https://stackoverflow.com/a/1001328/266378 -*/ -static inline bool little_endianess(int num = 1) noexcept -{ - return *reinterpret_cast(&num) == 1; -} - - -/////////////////// -// binary reader // -/////////////////// - -/*! -@brief deserialization of CBOR, MessagePack, and UBJSON values -*/ -template> -class binary_reader -{ - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using json_sax_t = SAX; - using char_type = typename InputAdapterType::char_type; - using char_int_type = typename std::char_traits::int_type; - - public: - /*! - @brief create a binary reader - - @param[in] adapter input adapter to read from - */ - explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter)) - { - (void)detail::is_sax_static_asserts {}; - } - - // make class move-only - binary_reader(const binary_reader&) = delete; - binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - binary_reader& operator=(const binary_reader&) = delete; - binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - ~binary_reader() = default; - - /*! - @param[in] format the binary format to parse - @param[in] sax_ a SAX event processor - @param[in] strict whether to expect the input to be consumed completed - @param[in] tag_handler how to treat CBOR tags - - @return whether parsing was successful - */ - JSON_HEDLEY_NON_NULL(3) - bool sax_parse(const input_format_t format, - json_sax_t* sax_, - const bool strict = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - sax = sax_; - bool result = false; - - switch (format) - { - case input_format_t::bson: - result = parse_bson_internal(); - break; - - case input_format_t::cbor: - result = parse_cbor_internal(true, tag_handler); - break; - - case input_format_t::msgpack: - result = parse_msgpack_internal(); - break; - - case input_format_t::ubjson: - result = parse_ubjson_internal(); - break; - - case input_format_t::json: // LCOV_EXCL_LINE - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - - // strict mode: next byte must be EOF - if (result && strict) - { - if (format == input_format_t::ubjson) - { - get_ignore_noop(); - } - else - { - get(); - } - - if (JSON_HEDLEY_UNLIKELY(current != std::char_traits::eof())) - { - return sax->parse_error(chars_read, get_token_string(), - parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType())); - } - } - - return result; - } - - private: - ////////// - // BSON // - ////////// - - /*! - @brief Reads in a BSON-object and passes it to the SAX-parser. - @return whether a valid BSON-value was passed to the SAX parser - */ - bool parse_bson_internal() - { - std::int32_t document_size{}; - get_number(input_format_t::bson, document_size); - - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false))) - { - return false; - } - - return sax->end_object(); - } - - /*! - @brief Parses a C-style string from the BSON input. - @param[in,out] result A reference to the string variable where the read - string is to be stored. - @return `true` if the \x00-byte indicating the end of the string was - encountered before the EOF; false` indicates an unexpected EOF. - */ - bool get_bson_cstr(string_t& result) - { - auto out = std::back_inserter(result); - while (true) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring"))) - { - return false; - } - if (current == 0x00) - { - return true; - } - *out++ = static_cast(current); - } - } - - /*! - @brief Parses a zero-terminated string of length @a len from the BSON - input. - @param[in] len The length (including the zero-byte at the end) of the - string to be read. - @param[in,out] result A reference to the string variable where the read - string is to be stored. - @tparam NumberType The type of the length @a len - @pre len >= 1 - @return `true` if the string was successfully parsed - */ - template - bool get_bson_string(const NumberType len, string_t& result) - { - if (JSON_HEDLEY_UNLIKELY(len < 1)) - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string"), BasicJsonType())); - } - - return get_string(input_format_t::bson, len - static_cast(1), result) && get() != std::char_traits::eof(); - } - - /*! - @brief Parses a byte array input of length @a len from the BSON input. - @param[in] len The length of the byte array to be read. - @param[in,out] result A reference to the binary variable where the read - array is to be stored. - @tparam NumberType The type of the length @a len - @pre len >= 0 - @return `true` if the byte array was successfully parsed - */ - template - bool get_bson_binary(const NumberType len, binary_t& result) - { - if (JSON_HEDLEY_UNLIKELY(len < 0)) - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary"), BasicJsonType())); - } - - // All BSON binary values have a subtype - std::uint8_t subtype{}; - get_number(input_format_t::bson, subtype); - result.set_subtype(subtype); - - return get_binary(input_format_t::bson, len, result); - } - - /*! - @brief Read a BSON document element of the given @a element_type. - @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html - @param[in] element_type_parse_position The position in the input stream, - where the `element_type` was read. - @warning Not all BSON element types are supported yet. An unsupported - @a element_type will give rise to a parse_error.114: - Unsupported BSON record type 0x... - @return whether a valid BSON-object/array was passed to the SAX parser - */ - bool parse_bson_element_internal(const char_int_type element_type, - const std::size_t element_type_parse_position) - { - switch (element_type) - { - case 0x01: // double - { - double number{}; - return get_number(input_format_t::bson, number) && sax->number_float(static_cast(number), ""); - } - - case 0x02: // string - { - std::int32_t len{}; - string_t value; - return get_number(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value); - } - - case 0x03: // object - { - return parse_bson_internal(); - } - - case 0x04: // array - { - return parse_bson_array(); - } - - case 0x05: // binary - { - std::int32_t len{}; - binary_t value; - return get_number(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value); - } - - case 0x08: // boolean - { - return sax->boolean(get() != 0); - } - - case 0x0A: // null - { - return sax->null(); - } - - case 0x10: // int32 - { - std::int32_t value{}; - return get_number(input_format_t::bson, value) && sax->number_integer(value); - } - - case 0x12: // int64 - { - std::int64_t value{}; - return get_number(input_format_t::bson, value) && sax->number_integer(value); - } - - default: // anything else not supported (yet) - { - std::array cr{{}}; - (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()), BasicJsonType())); - } - } - } - - /*! - @brief Read a BSON element list (as specified in the BSON-spec) - - The same binary layout is used for objects and arrays, hence it must be - indicated with the argument @a is_array which one is expected - (true --> array, false --> object). - - @param[in] is_array Determines if the element list being read is to be - treated as an object (@a is_array == false), or as an - array (@a is_array == true). - @return whether a valid BSON-object/array was passed to the SAX parser - */ - bool parse_bson_element_list(const bool is_array) - { - string_t key; - - while (auto element_type = get()) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list"))) - { - return false; - } - - const std::size_t element_type_parse_position = chars_read; - if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key))) - { - return false; - } - - if (!is_array && !sax->key(key)) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position))) - { - return false; - } - - // get_bson_cstr only appends - key.clear(); - } - - return true; - } - - /*! - @brief Reads an array from the BSON input and passes it to the SAX-parser. - @return whether a valid BSON-array was passed to the SAX parser - */ - bool parse_bson_array() - { - std::int32_t document_size{}; - get_number(input_format_t::bson, document_size); - - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true))) - { - return false; - } - - return sax->end_array(); - } - - ////////// - // CBOR // - ////////// - - /*! - @param[in] get_char whether a new character should be retrieved from the - input (true) or whether the last read character should - be considered instead (false) - @param[in] tag_handler how CBOR tags should be treated - - @return whether a valid CBOR value was passed to the SAX parser - */ - bool parse_cbor_internal(const bool get_char, - const cbor_tag_handler_t tag_handler) - { - switch (get_char ? get() : current) - { - // EOF - case std::char_traits::eof(): - return unexpect_eof(input_format_t::cbor, "value"); - - // Integer 0x00..0x17 (0..23) - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x09: - case 0x0A: - case 0x0B: - case 0x0C: - case 0x0D: - case 0x0E: - case 0x0F: - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - return sax->number_unsigned(static_cast(current)); - - case 0x18: // Unsigned integer (one-byte uint8_t follows) - { - std::uint8_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); - } - - case 0x19: // Unsigned integer (two-byte uint16_t follows) - { - std::uint16_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); - } - - case 0x1A: // Unsigned integer (four-byte uint32_t follows) - { - std::uint32_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); - } - - case 0x1B: // Unsigned integer (eight-byte uint64_t follows) - { - std::uint64_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); - } - - // Negative integer -1-0x00..-1-0x17 (-1..-24) - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - case 0x29: - case 0x2A: - case 0x2B: - case 0x2C: - case 0x2D: - case 0x2E: - case 0x2F: - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - return sax->number_integer(static_cast(0x20 - 1 - current)); - - case 0x38: // Negative integer (one-byte uint8_t follows) - { - std::uint8_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); - } - - case 0x39: // Negative integer -1-n (two-byte uint16_t follows) - { - std::uint16_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); - } - - case 0x3A: // Negative integer -1-n (four-byte uint32_t follows) - { - std::uint32_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); - } - - case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows) - { - std::uint64_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - - static_cast(number)); - } - - // Binary data (0x00..0x17 bytes follow) - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4A: - case 0x4B: - case 0x4C: - case 0x4D: - case 0x4E: - case 0x4F: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: // Binary data (one-byte uint8_t for n follows) - case 0x59: // Binary data (two-byte uint16_t for n follow) - case 0x5A: // Binary data (four-byte uint32_t for n follow) - case 0x5B: // Binary data (eight-byte uint64_t for n follow) - case 0x5F: // Binary data (indefinite length) - { - binary_t b; - return get_cbor_binary(b) && sax->binary(b); - } - - // UTF-8 string (0x00..0x17 bytes follow) - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6A: - case 0x6B: - case 0x6C: - case 0x6D: - case 0x6E: - case 0x6F: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - case 0x78: // UTF-8 string (one-byte uint8_t for n follows) - case 0x79: // UTF-8 string (two-byte uint16_t for n follow) - case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) - case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) - case 0x7F: // UTF-8 string (indefinite length) - { - string_t s; - return get_cbor_string(s) && sax->string(s); - } - - // array (0x00..0x17 data items follow) - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - case 0x86: - case 0x87: - case 0x88: - case 0x89: - case 0x8A: - case 0x8B: - case 0x8C: - case 0x8D: - case 0x8E: - case 0x8F: - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - return get_cbor_array(static_cast(static_cast(current) & 0x1Fu), tag_handler); - - case 0x98: // array (one-byte uint8_t for n follows) - { - std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); - } - - case 0x99: // array (two-byte uint16_t for n follow) - { - std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); - } - - case 0x9A: // array (four-byte uint32_t for n follow) - { - std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); - } - - case 0x9B: // array (eight-byte uint64_t for n follow) - { - std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast(len), tag_handler); - } - - case 0x9F: // array (indefinite length) - return get_cbor_array(std::size_t(-1), tag_handler); - - // map (0x00..0x17 pairs of data items follow) - case 0xA0: - case 0xA1: - case 0xA2: - case 0xA3: - case 0xA4: - case 0xA5: - case 0xA6: - case 0xA7: - case 0xA8: - case 0xA9: - case 0xAA: - case 0xAB: - case 0xAC: - case 0xAD: - case 0xAE: - case 0xAF: - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - return get_cbor_object(static_cast(static_cast(current) & 0x1Fu), tag_handler); - - case 0xB8: // map (one-byte uint8_t for n follows) - { - std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); - } - - case 0xB9: // map (two-byte uint16_t for n follow) - { - std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); - } - - case 0xBA: // map (four-byte uint32_t for n follow) - { - std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); - } - - case 0xBB: // map (eight-byte uint64_t for n follow) - { - std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast(len), tag_handler); - } - - case 0xBF: // map (indefinite length) - return get_cbor_object(std::size_t(-1), tag_handler); - - case 0xC6: // tagged item - case 0xC7: - case 0xC8: - case 0xC9: - case 0xCA: - case 0xCB: - case 0xCC: - case 0xCD: - case 0xCE: - case 0xCF: - case 0xD0: - case 0xD1: - case 0xD2: - case 0xD3: - case 0xD4: - case 0xD8: // tagged item (1 bytes follow) - case 0xD9: // tagged item (2 bytes follow) - case 0xDA: // tagged item (4 bytes follow) - case 0xDB: // tagged item (8 bytes follow) - { - switch (tag_handler) - { - case cbor_tag_handler_t::error: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType())); - } - - case cbor_tag_handler_t::ignore: - { - // ignore binary subtype - switch (current) - { - case 0xD8: - { - std::uint8_t subtype_to_ignore{}; - get_number(input_format_t::cbor, subtype_to_ignore); - break; - } - case 0xD9: - { - std::uint16_t subtype_to_ignore{}; - get_number(input_format_t::cbor, subtype_to_ignore); - break; - } - case 0xDA: - { - std::uint32_t subtype_to_ignore{}; - get_number(input_format_t::cbor, subtype_to_ignore); - break; - } - case 0xDB: - { - std::uint64_t subtype_to_ignore{}; - get_number(input_format_t::cbor, subtype_to_ignore); - break; - } - default: - break; - } - return parse_cbor_internal(true, tag_handler); - } - - case cbor_tag_handler_t::store: - { - binary_t b; - // use binary subtype and store in binary container - switch (current) - { - case 0xD8: - { - std::uint8_t subtype{}; - get_number(input_format_t::cbor, subtype); - b.set_subtype(detail::conditional_static_cast(subtype)); - break; - } - case 0xD9: - { - std::uint16_t subtype{}; - get_number(input_format_t::cbor, subtype); - b.set_subtype(detail::conditional_static_cast(subtype)); - break; - } - case 0xDA: - { - std::uint32_t subtype{}; - get_number(input_format_t::cbor, subtype); - b.set_subtype(detail::conditional_static_cast(subtype)); - break; - } - case 0xDB: - { - std::uint64_t subtype{}; - get_number(input_format_t::cbor, subtype); - b.set_subtype(detail::conditional_static_cast(subtype)); - break; - } - default: - return parse_cbor_internal(true, tag_handler); - } - get(); - return get_cbor_binary(b) && sax->binary(b); - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - return false; // LCOV_EXCL_LINE - } - } - - case 0xF4: // false - return sax->boolean(false); - - case 0xF5: // true - return sax->boolean(true); - - case 0xF6: // null - return sax->null(); - - case 0xF9: // Half-Precision Float (two-byte IEEE 754) - { - const auto byte1_raw = get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) - { - return false; - } - const auto byte2_raw = get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) - { - return false; - } - - const auto byte1 = static_cast(byte1_raw); - const auto byte2 = static_cast(byte2_raw); - - // code from RFC 7049, Appendix D, Figure 3: - // As half-precision floating-point numbers were only added - // to IEEE 754 in 2008, today's programming platforms often - // still only have limited support for them. It is very - // easy to include at least decoding support for them even - // without such support. An example of a small decoder for - // half-precision floating-point numbers in the C language - // is shown in Fig. 3. - const auto half = static_cast((byte1 << 8u) + byte2); - const double val = [&half] - { - const int exp = (half >> 10u) & 0x1Fu; - const unsigned int mant = half & 0x3FFu; - JSON_ASSERT(0 <= exp&& exp <= 32); - JSON_ASSERT(mant <= 1024); - switch (exp) - { - case 0: - return std::ldexp(mant, -24); - case 31: - return (mant == 0) - ? std::numeric_limits::infinity() - : std::numeric_limits::quiet_NaN(); - default: - return std::ldexp(mant + 1024, exp - 25); - } - }(); - return sax->number_float((half & 0x8000u) != 0 - ? static_cast(-val) - : static_cast(val), ""); - } - - case 0xFA: // Single-Precision Float (four-byte IEEE 754) - { - float number{}; - return get_number(input_format_t::cbor, number) && sax->number_float(static_cast(number), ""); - } - - case 0xFB: // Double-Precision Float (eight-byte IEEE 754) - { - double number{}; - return get_number(input_format_t::cbor, number) && sax->number_float(static_cast(number), ""); - } - - default: // anything else (0xFF is handled inside the other types) - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType())); - } - } - } - - /*! - @brief reads a CBOR string - - This function first reads starting bytes to determine the expected - string length and then copies this number of bytes into a string. - Additionally, CBOR's strings with indefinite lengths are supported. - - @param[out] result created string - - @return whether string creation completed - */ - bool get_cbor_string(string_t& result) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string"))) - { - return false; - } - - switch (current) - { - // UTF-8 string (0x00..0x17 bytes follow) - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6A: - case 0x6B: - case 0x6C: - case 0x6D: - case 0x6E: - case 0x6F: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - { - return get_string(input_format_t::cbor, static_cast(current) & 0x1Fu, result); - } - - case 0x78: // UTF-8 string (one-byte uint8_t for n follows) - { - std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); - } - - case 0x79: // UTF-8 string (two-byte uint16_t for n follow) - { - std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); - } - - case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) - { - std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); - } - - case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) - { - std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); - } - - case 0x7F: // UTF-8 string (indefinite length) - { - while (get() != 0xFF) - { - string_t chunk; - if (!get_cbor_string(chunk)) - { - return false; - } - result.append(chunk); - } - return true; - } - - default: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string"), BasicJsonType())); - } - } - } - - /*! - @brief reads a CBOR byte array - - This function first reads starting bytes to determine the expected - byte array length and then copies this number of bytes into the byte array. - Additionally, CBOR's byte arrays with indefinite lengths are supported. - - @param[out] result created byte array - - @return whether byte array creation completed - */ - bool get_cbor_binary(binary_t& result) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary"))) - { - return false; - } - - switch (current) - { - // Binary data (0x00..0x17 bytes follow) - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4A: - case 0x4B: - case 0x4C: - case 0x4D: - case 0x4E: - case 0x4F: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - { - return get_binary(input_format_t::cbor, static_cast(current) & 0x1Fu, result); - } - - case 0x58: // Binary data (one-byte uint8_t for n follows) - { - std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && - get_binary(input_format_t::cbor, len, result); - } - - case 0x59: // Binary data (two-byte uint16_t for n follow) - { - std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && - get_binary(input_format_t::cbor, len, result); - } - - case 0x5A: // Binary data (four-byte uint32_t for n follow) - { - std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && - get_binary(input_format_t::cbor, len, result); - } - - case 0x5B: // Binary data (eight-byte uint64_t for n follow) - { - std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && - get_binary(input_format_t::cbor, len, result); - } - - case 0x5F: // Binary data (indefinite length) - { - while (get() != 0xFF) - { - binary_t chunk; - if (!get_cbor_binary(chunk)) - { - return false; - } - result.insert(result.end(), chunk.begin(), chunk.end()); - } - return true; - } - - default: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary"), BasicJsonType())); - } - } - } - - /*! - @param[in] len the length of the array or std::size_t(-1) for an - array of indefinite size - @param[in] tag_handler how CBOR tags should be treated - @return whether array creation completed - */ - bool get_cbor_array(const std::size_t len, - const cbor_tag_handler_t tag_handler) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) - { - return false; - } - - if (len != std::size_t(-1)) - { - for (std::size_t i = 0; i < len; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) - { - return false; - } - } - } - else - { - while (get() != 0xFF) - { - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler))) - { - return false; - } - } - } - - return sax->end_array(); - } - - /*! - @param[in] len the length of the object or std::size_t(-1) for an - object of indefinite size - @param[in] tag_handler how CBOR tags should be treated - @return whether object creation completed - */ - bool get_cbor_object(const std::size_t len, - const cbor_tag_handler_t tag_handler) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) - { - return false; - } - - if (len != 0) - { - string_t key; - if (len != std::size_t(-1)) - { - for (std::size_t i = 0; i < len; ++i) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) - { - return false; - } - key.clear(); - } - } - else - { - while (get() != 0xFF) - { - if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) - { - return false; - } - key.clear(); - } - } - } - - return sax->end_object(); - } - - ///////////// - // MsgPack // - ///////////// - - /*! - @return whether a valid MessagePack value was passed to the SAX parser - */ - bool parse_msgpack_internal() - { - switch (get()) - { - // EOF - case std::char_traits::eof(): - return unexpect_eof(input_format_t::msgpack, "value"); - - // positive fixint - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x09: - case 0x0A: - case 0x0B: - case 0x0C: - case 0x0D: - case 0x0E: - case 0x0F: - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - case 0x18: - case 0x19: - case 0x1A: - case 0x1B: - case 0x1C: - case 0x1D: - case 0x1E: - case 0x1F: - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - case 0x29: - case 0x2A: - case 0x2B: - case 0x2C: - case 0x2D: - case 0x2E: - case 0x2F: - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3A: - case 0x3B: - case 0x3C: - case 0x3D: - case 0x3E: - case 0x3F: - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4A: - case 0x4B: - case 0x4C: - case 0x4D: - case 0x4E: - case 0x4F: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5A: - case 0x5B: - case 0x5C: - case 0x5D: - case 0x5E: - case 0x5F: - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6A: - case 0x6B: - case 0x6C: - case 0x6D: - case 0x6E: - case 0x6F: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - case 0x78: - case 0x79: - case 0x7A: - case 0x7B: - case 0x7C: - case 0x7D: - case 0x7E: - case 0x7F: - return sax->number_unsigned(static_cast(current)); - - // fixmap - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - case 0x86: - case 0x87: - case 0x88: - case 0x89: - case 0x8A: - case 0x8B: - case 0x8C: - case 0x8D: - case 0x8E: - case 0x8F: - return get_msgpack_object(static_cast(static_cast(current) & 0x0Fu)); - - // fixarray - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - case 0x98: - case 0x99: - case 0x9A: - case 0x9B: - case 0x9C: - case 0x9D: - case 0x9E: - case 0x9F: - return get_msgpack_array(static_cast(static_cast(current) & 0x0Fu)); - - // fixstr - case 0xA0: - case 0xA1: - case 0xA2: - case 0xA3: - case 0xA4: - case 0xA5: - case 0xA6: - case 0xA7: - case 0xA8: - case 0xA9: - case 0xAA: - case 0xAB: - case 0xAC: - case 0xAD: - case 0xAE: - case 0xAF: - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - case 0xB8: - case 0xB9: - case 0xBA: - case 0xBB: - case 0xBC: - case 0xBD: - case 0xBE: - case 0xBF: - case 0xD9: // str 8 - case 0xDA: // str 16 - case 0xDB: // str 32 - { - string_t s; - return get_msgpack_string(s) && sax->string(s); - } - - case 0xC0: // nil - return sax->null(); - - case 0xC2: // false - return sax->boolean(false); - - case 0xC3: // true - return sax->boolean(true); - - case 0xC4: // bin 8 - case 0xC5: // bin 16 - case 0xC6: // bin 32 - case 0xC7: // ext 8 - case 0xC8: // ext 16 - case 0xC9: // ext 32 - case 0xD4: // fixext 1 - case 0xD5: // fixext 2 - case 0xD6: // fixext 4 - case 0xD7: // fixext 8 - case 0xD8: // fixext 16 - { - binary_t b; - return get_msgpack_binary(b) && sax->binary(b); - } - - case 0xCA: // float 32 - { - float number{}; - return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast(number), ""); - } - - case 0xCB: // float 64 - { - double number{}; - return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast(number), ""); - } - - case 0xCC: // uint 8 - { - std::uint8_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); - } - - case 0xCD: // uint 16 - { - std::uint16_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); - } - - case 0xCE: // uint 32 - { - std::uint32_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); - } - - case 0xCF: // uint 64 - { - std::uint64_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); - } - - case 0xD0: // int 8 - { - std::int8_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_integer(number); - } - - case 0xD1: // int 16 - { - std::int16_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_integer(number); - } - - case 0xD2: // int 32 - { - std::int32_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_integer(number); - } - - case 0xD3: // int 64 - { - std::int64_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_integer(number); - } - - case 0xDC: // array 16 - { - std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast(len)); - } - - case 0xDD: // array 32 - { - std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast(len)); - } - - case 0xDE: // map 16 - { - std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast(len)); - } - - case 0xDF: // map 32 - { - std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast(len)); - } - - // negative fixint - case 0xE0: - case 0xE1: - case 0xE2: - case 0xE3: - case 0xE4: - case 0xE5: - case 0xE6: - case 0xE7: - case 0xE8: - case 0xE9: - case 0xEA: - case 0xEB: - case 0xEC: - case 0xED: - case 0xEE: - case 0xEF: - case 0xF0: - case 0xF1: - case 0xF2: - case 0xF3: - case 0xF4: - case 0xF5: - case 0xF6: - case 0xF7: - case 0xF8: - case 0xF9: - case 0xFA: - case 0xFB: - case 0xFC: - case 0xFD: - case 0xFE: - case 0xFF: - return sax->number_integer(static_cast(current)); - - default: // anything else - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value"), BasicJsonType())); - } - } - } - - /*! - @brief reads a MessagePack string - - This function first reads starting bytes to determine the expected - string length and then copies this number of bytes into a string. - - @param[out] result created string - - @return whether string creation completed - */ - bool get_msgpack_string(string_t& result) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string"))) - { - return false; - } - - switch (current) - { - // fixstr - case 0xA0: - case 0xA1: - case 0xA2: - case 0xA3: - case 0xA4: - case 0xA5: - case 0xA6: - case 0xA7: - case 0xA8: - case 0xA9: - case 0xAA: - case 0xAB: - case 0xAC: - case 0xAD: - case 0xAE: - case 0xAF: - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - case 0xB8: - case 0xB9: - case 0xBA: - case 0xBB: - case 0xBC: - case 0xBD: - case 0xBE: - case 0xBF: - { - return get_string(input_format_t::msgpack, static_cast(current) & 0x1Fu, result); - } - - case 0xD9: // str 8 - { - std::uint8_t len{}; - return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); - } - - case 0xDA: // str 16 - { - std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); - } - - case 0xDB: // str 32 - { - std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); - } - - default: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string"), BasicJsonType())); - } - } - } - - /*! - @brief reads a MessagePack byte array - - This function first reads starting bytes to determine the expected - byte array length and then copies this number of bytes into a byte array. - - @param[out] result created byte array - - @return whether byte array creation completed - */ - bool get_msgpack_binary(binary_t& result) - { - // helper function to set the subtype - auto assign_and_return_true = [&result](std::int8_t subtype) - { - result.set_subtype(static_cast(subtype)); - return true; - }; - - switch (current) - { - case 0xC4: // bin 8 - { - std::uint8_t len{}; - return get_number(input_format_t::msgpack, len) && - get_binary(input_format_t::msgpack, len, result); - } - - case 0xC5: // bin 16 - { - std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) && - get_binary(input_format_t::msgpack, len, result); - } - - case 0xC6: // bin 32 - { - std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && - get_binary(input_format_t::msgpack, len, result); - } - - case 0xC7: // ext 8 - { - std::uint8_t len{}; - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, len) && - get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, len, result) && - assign_and_return_true(subtype); - } - - case 0xC8: // ext 16 - { - std::uint16_t len{}; - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, len) && - get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, len, result) && - assign_and_return_true(subtype); - } - - case 0xC9: // ext 32 - { - std::uint32_t len{}; - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, len) && - get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, len, result) && - assign_and_return_true(subtype); - } - - case 0xD4: // fixext 1 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 1, result) && - assign_and_return_true(subtype); - } - - case 0xD5: // fixext 2 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 2, result) && - assign_and_return_true(subtype); - } - - case 0xD6: // fixext 4 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 4, result) && - assign_and_return_true(subtype); - } - - case 0xD7: // fixext 8 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 8, result) && - assign_and_return_true(subtype); - } - - case 0xD8: // fixext 16 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 16, result) && - assign_and_return_true(subtype); - } - - default: // LCOV_EXCL_LINE - return false; // LCOV_EXCL_LINE - } - } - - /*! - @param[in] len the length of the array - @return whether array creation completed - */ - bool get_msgpack_array(const std::size_t len) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) - { - return false; - } - - for (std::size_t i = 0; i < len; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) - { - return false; - } - } - - return sax->end_array(); - } - - /*! - @param[in] len the length of the object - @return whether object creation completed - */ - bool get_msgpack_object(const std::size_t len) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) - { - return false; - } - - string_t key; - for (std::size_t i = 0; i < len; ++i) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) - { - return false; - } - key.clear(); - } - - return sax->end_object(); - } - - //////////// - // UBJSON // - //////////// - - /*! - @param[in] get_char whether a new character should be retrieved from the - input (true, default) or whether the last read - character should be considered instead - - @return whether a valid UBJSON value was passed to the SAX parser - */ - bool parse_ubjson_internal(const bool get_char = true) - { - return get_ubjson_value(get_char ? get_ignore_noop() : current); - } - - /*! - @brief reads a UBJSON string - - This function is either called after reading the 'S' byte explicitly - indicating a string, or in case of an object key where the 'S' byte can be - left out. - - @param[out] result created string - @param[in] get_char whether a new character should be retrieved from the - input (true, default) or whether the last read - character should be considered instead - - @return whether string creation completed - */ - bool get_ubjson_string(string_t& result, const bool get_char = true) - { - if (get_char) - { - get(); // TODO(niels): may we ignore N here? - } - - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value"))) - { - return false; - } - - switch (current) - { - case 'U': - { - std::uint8_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - case 'i': - { - std::int8_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - case 'I': - { - std::int16_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - case 'l': - { - std::int32_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - case 'L': - { - std::int64_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - default: - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), BasicJsonType())); - } - } - - /*! - @param[out] result determined size - @return whether size determination completed - */ - bool get_ubjson_size_value(std::size_t& result) - { - switch (get_ignore_noop()) - { - case 'U': - { - std::uint8_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast(number); - return true; - } - - case 'i': - { - std::int8_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char - return true; - } - - case 'I': - { - std::int16_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast(number); - return true; - } - - case 'l': - { - std::int32_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast(number); - return true; - } - - case 'L': - { - std::int64_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast(number); - return true; - } - - default: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), BasicJsonType())); - } - } - } - - /*! - @brief determine the type and size for a container - - In the optimized UBJSON format, a type and a size can be provided to allow - for a more compact representation. - - @param[out] result pair of the size and the type - - @return whether pair creation completed - */ - bool get_ubjson_size_type(std::pair& result) - { - result.first = string_t::npos; // size - result.second = 0; // type - - get_ignore_noop(); - - if (current == '$') - { - result.second = get(); // must not ignore 'N', because 'N' maybe the type - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type"))) - { - return false; - } - - get_ignore_noop(); - if (JSON_HEDLEY_UNLIKELY(current != '#')) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value"))) - { - return false; - } - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size"), BasicJsonType())); - } - - return get_ubjson_size_value(result.first); - } - - if (current == '#') - { - return get_ubjson_size_value(result.first); - } - - return true; - } - - /*! - @param prefix the previously read or set type prefix - @return whether value creation completed - */ - bool get_ubjson_value(const char_int_type prefix) - { - switch (prefix) - { - case std::char_traits::eof(): // EOF - return unexpect_eof(input_format_t::ubjson, "value"); - - case 'T': // true - return sax->boolean(true); - case 'F': // false - return sax->boolean(false); - - case 'Z': // null - return sax->null(); - - case 'U': - { - std::uint8_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number); - } - - case 'i': - { - std::int8_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_integer(number); - } - - case 'I': - { - std::int16_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_integer(number); - } - - case 'l': - { - std::int32_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_integer(number); - } - - case 'L': - { - std::int64_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_integer(number); - } - - case 'd': - { - float number{}; - return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast(number), ""); - } - - case 'D': - { - double number{}; - return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast(number), ""); - } - - case 'H': - { - return get_ubjson_high_precision_number(); - } - - case 'C': // char - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char"))) - { - return false; - } - if (JSON_HEDLEY_UNLIKELY(current > 127)) - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char"), BasicJsonType())); - } - string_t s(1, static_cast(current)); - return sax->string(s); - } - - case 'S': // string - { - string_t s; - return get_ubjson_string(s) && sax->string(s); - } - - case '[': // array - return get_ubjson_array(); - - case '{': // object - return get_ubjson_object(); - - default: // anything else - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value"), BasicJsonType())); - } - } - } - - /*! - @return whether array creation completed - */ - bool get_ubjson_array() - { - std::pair size_and_type; - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) - { - return false; - } - - if (size_and_type.first != string_t::npos) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first))) - { - return false; - } - - if (size_and_type.second != 0) - { - if (size_and_type.second != 'N') - { - for (std::size_t i = 0; i < size_and_type.first; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) - { - return false; - } - } - } - } - else - { - for (std::size_t i = 0; i < size_and_type.first; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) - { - return false; - } - } - } - } - else - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) - { - return false; - } - - while (current != ']') - { - if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false))) - { - return false; - } - get_ignore_noop(); - } - } - - return sax->end_array(); - } - - /*! - @return whether object creation completed - */ - bool get_ubjson_object() - { - std::pair size_and_type; - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) - { - return false; - } - - string_t key; - if (size_and_type.first != string_t::npos) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first))) - { - return false; - } - - if (size_and_type.second != 0) - { - for (std::size_t i = 0; i < size_and_type.first; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) - { - return false; - } - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) - { - return false; - } - key.clear(); - } - } - else - { - for (std::size_t i = 0; i < size_and_type.first; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) - { - return false; - } - if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) - { - return false; - } - key.clear(); - } - } - } - else - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) - { - return false; - } - - while (current != '}') - { - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key))) - { - return false; - } - if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) - { - return false; - } - get_ignore_noop(); - key.clear(); - } - } - - return sax->end_object(); - } - - // Note, no reader for UBJSON binary types is implemented because they do - // not exist - - bool get_ubjson_high_precision_number() - { - // get size of following number string - std::size_t size{}; - auto res = get_ubjson_size_value(size); - if (JSON_HEDLEY_UNLIKELY(!res)) - { - return res; - } - - // get number string - std::vector number_vector; - for (std::size_t i = 0; i < size; ++i) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number"))) - { - return false; - } - number_vector.push_back(static_cast(current)); - } - - // parse number string - using ia_type = decltype(detail::input_adapter(number_vector)); - auto number_lexer = detail::lexer(detail::input_adapter(number_vector), false); - const auto result_number = number_lexer.scan(); - const auto number_string = number_lexer.get_token_string(); - const auto result_remainder = number_lexer.scan(); - - using token_type = typename detail::lexer_base::token_type; - - if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input)) - { - return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType())); - } - - switch (result_number) - { - case token_type::value_integer: - return sax->number_integer(number_lexer.get_number_integer()); - case token_type::value_unsigned: - return sax->number_unsigned(number_lexer.get_number_unsigned()); - case token_type::value_float: - return sax->number_float(number_lexer.get_number_float(), std::move(number_string)); - case token_type::uninitialized: - case token_type::literal_true: - case token_type::literal_false: - case token_type::literal_null: - case token_type::value_string: - case token_type::begin_array: - case token_type::begin_object: - case token_type::end_array: - case token_type::end_object: - case token_type::name_separator: - case token_type::value_separator: - case token_type::parse_error: - case token_type::end_of_input: - case token_type::literal_or_value: - default: - return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType())); - } - } - - /////////////////////// - // Utility functions // - /////////////////////// - - /*! - @brief get next character from the input - - This function provides the interface to the used input adapter. It does - not throw in case the input reached EOF, but returns a -'ve valued - `std::char_traits::eof()` in that case. - - @return character read from the input - */ - char_int_type get() - { - ++chars_read; - return current = ia.get_character(); - } - - /*! - @return character read from the input after ignoring all 'N' entries - */ - char_int_type get_ignore_noop() - { - do - { - get(); - } - while (current == 'N'); - - return current; - } - - /* - @brief read a number from the input - - @tparam NumberType the type of the number - @param[in] format the current format (for diagnostics) - @param[out] result number of type @a NumberType - - @return whether conversion completed - - @note This function needs to respect the system's endianess, because - bytes in CBOR, MessagePack, and UBJSON are stored in network order - (big endian) and therefore need reordering on little endian systems. - */ - template - bool get_number(const input_format_t format, NumberType& result) - { - // step 1: read input into array with system's byte order - std::array vec{}; - for (std::size_t i = 0; i < sizeof(NumberType); ++i) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number"))) - { - return false; - } - - // reverse byte order prior to conversion if necessary - if (is_little_endian != InputIsLittleEndian) - { - vec[sizeof(NumberType) - i - 1] = static_cast(current); - } - else - { - vec[i] = static_cast(current); // LCOV_EXCL_LINE - } - } - - // step 2: convert array into number of type T and return - std::memcpy(&result, vec.data(), sizeof(NumberType)); - return true; - } - - /*! - @brief create a string by reading characters from the input - - @tparam NumberType the type of the number - @param[in] format the current format (for diagnostics) - @param[in] len number of characters to read - @param[out] result string created by reading @a len bytes - - @return whether string creation completed - - @note We can not reserve @a len bytes for the result, because @a len - may be too large. Usually, @ref unexpect_eof() detects the end of - the input before we run out of string memory. - */ - template - bool get_string(const input_format_t format, - const NumberType len, - string_t& result) - { - bool success = true; - for (NumberType i = 0; i < len; i++) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string"))) - { - success = false; - break; - } - result.push_back(static_cast(current)); - } - return success; - } - - /*! - @brief create a byte array by reading bytes from the input - - @tparam NumberType the type of the number - @param[in] format the current format (for diagnostics) - @param[in] len number of bytes to read - @param[out] result byte array created by reading @a len bytes - - @return whether byte array creation completed - - @note We can not reserve @a len bytes for the result, because @a len - may be too large. Usually, @ref unexpect_eof() detects the end of - the input before we run out of memory. - */ - template - bool get_binary(const input_format_t format, - const NumberType len, - binary_t& result) - { - bool success = true; - for (NumberType i = 0; i < len; i++) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary"))) - { - success = false; - break; - } - result.push_back(static_cast(current)); - } - return success; - } - - /*! - @param[in] format the current format (for diagnostics) - @param[in] context further context information (for diagnostics) - @return whether the last read character is not EOF - */ - JSON_HEDLEY_NON_NULL(3) - bool unexpect_eof(const input_format_t format, const char* context) const - { - if (JSON_HEDLEY_UNLIKELY(current == std::char_traits::eof())) - { - return sax->parse_error(chars_read, "", - parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType())); - } - return true; - } - - /*! - @return a string representation of the last read byte - */ - std::string get_token_string() const - { - std::array cr{{}}; - (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - return std::string{cr.data()}; - } - - /*! - @param[in] format the current format - @param[in] detail a detailed error message - @param[in] context further context information - @return a message string to use in the parse_error exceptions - */ - std::string exception_message(const input_format_t format, - const std::string& detail, - const std::string& context) const - { - std::string error_msg = "syntax error while parsing "; - - switch (format) - { - case input_format_t::cbor: - error_msg += "CBOR"; - break; - - case input_format_t::msgpack: - error_msg += "MessagePack"; - break; - - case input_format_t::ubjson: - error_msg += "UBJSON"; - break; - - case input_format_t::bson: - error_msg += "BSON"; - break; - - case input_format_t::json: // LCOV_EXCL_LINE - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - - return error_msg + " " + context + ": " + detail; - } - - private: - /// input adapter - InputAdapterType ia; - - /// the current character - char_int_type current = std::char_traits::eof(); - - /// the number of characters read - std::size_t chars_read = 0; - - /// whether we can assume little endianess - const bool is_little_endian = little_endianess(); - - /// the SAX parser - json_sax_t* sax = nullptr; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - -// #include - - -#include // isfinite -#include // uint8_t -#include // function -#include // string -#include // move -#include // vector - -// #include - -// #include - -// #include - -// #include - -// #include - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -//////////// -// parser // -//////////// - -enum class parse_event_t : std::uint8_t -{ - /// the parser read `{` and started to process a JSON object - object_start, - /// the parser read `}` and finished processing a JSON object - object_end, - /// the parser read `[` and started to process a JSON array - array_start, - /// the parser read `]` and finished processing a JSON array - array_end, - /// the parser read a key of a value in an object - key, - /// the parser finished reading a JSON value - value -}; - -template -using parser_callback_t = - std::function; - -/*! -@brief syntax analysis - -This class implements a recursive descent parser. -*/ -template -class parser -{ - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using lexer_t = lexer; - using token_type = typename lexer_t::token_type; - - public: - /// a parser reading from an input adapter - explicit parser(InputAdapterType&& adapter, - const parser_callback_t cb = nullptr, - const bool allow_exceptions_ = true, - const bool skip_comments = false) - : callback(cb) - , m_lexer(std::move(adapter), skip_comments) - , allow_exceptions(allow_exceptions_) - { - // read first token - get_token(); - } - - /*! - @brief public parser interface - - @param[in] strict whether to expect the last token to be EOF - @param[in,out] result parsed JSON value - - @throw parse_error.101 in case of an unexpected token - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - */ - void parse(const bool strict, BasicJsonType& result) - { - if (callback) - { - json_sax_dom_callback_parser sdp(result, callback, allow_exceptions); - sax_parse_internal(&sdp); - - // in strict mode, input must be completely read - if (strict && (get_token() != token_type::end_of_input)) - { - sdp.parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), - exception_message(token_type::end_of_input, "value"), BasicJsonType())); - } - - // in case of an error, return discarded value - if (sdp.is_errored()) - { - result = value_t::discarded; - return; - } - - // set top-level value to null if it was discarded by the callback - // function - if (result.is_discarded()) - { - result = nullptr; - } - } - else - { - json_sax_dom_parser sdp(result, allow_exceptions); - sax_parse_internal(&sdp); - - // in strict mode, input must be completely read - if (strict && (get_token() != token_type::end_of_input)) - { - sdp.parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType())); - } - - // in case of an error, return discarded value - if (sdp.is_errored()) - { - result = value_t::discarded; - return; - } - } - - result.assert_invariant(); - } - - /*! - @brief public accept interface - - @param[in] strict whether to expect the last token to be EOF - @return whether the input is a proper JSON text - */ - bool accept(const bool strict = true) - { - json_sax_acceptor sax_acceptor; - return sax_parse(&sax_acceptor, strict); - } - - template - JSON_HEDLEY_NON_NULL(2) - bool sax_parse(SAX* sax, const bool strict = true) - { - (void)detail::is_sax_static_asserts {}; - const bool result = sax_parse_internal(sax); - - // strict mode: next byte must be EOF - if (result && strict && (get_token() != token_type::end_of_input)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType())); - } - - return result; - } - - private: - template - JSON_HEDLEY_NON_NULL(2) - bool sax_parse_internal(SAX* sax) - { - // stack to remember the hierarchy of structured values we are parsing - // true = array; false = object - std::vector states; - // value to avoid a goto (see comment where set to true) - bool skip_to_state_evaluation = false; - - while (true) - { - if (!skip_to_state_evaluation) - { - // invariant: get_token() was called before each iteration - switch (last_token) - { - case token_type::begin_object: - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) - { - return false; - } - - // closing } -> we are done - if (get_token() == token_type::end_object) - { - if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) - { - return false; - } - break; - } - - // parse key - if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType())); - } - if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) - { - return false; - } - - // parse separator (:) - if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType())); - } - - // remember we are now inside an object - states.push_back(false); - - // parse values - get_token(); - continue; - } - - case token_type::begin_array: - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) - { - return false; - } - - // closing ] -> we are done - if (get_token() == token_type::end_array) - { - if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) - { - return false; - } - break; - } - - // remember we are now inside an array - states.push_back(true); - - // parse values (no need to call get_token) - continue; - } - - case token_type::value_float: - { - const auto res = m_lexer.get_number_float(); - - if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res))) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType())); - } - - if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string()))) - { - return false; - } - - break; - } - - case token_type::literal_false: - { - if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false))) - { - return false; - } - break; - } - - case token_type::literal_null: - { - if (JSON_HEDLEY_UNLIKELY(!sax->null())) - { - return false; - } - break; - } - - case token_type::literal_true: - { - if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true))) - { - return false; - } - break; - } - - case token_type::value_integer: - { - if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer()))) - { - return false; - } - break; - } - - case token_type::value_string: - { - if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string()))) - { - return false; - } - break; - } - - case token_type::value_unsigned: - { - if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned()))) - { - return false; - } - break; - } - - case token_type::parse_error: - { - // using "uninitialized" to avoid "expected" message - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType())); - } - - case token_type::uninitialized: - case token_type::end_array: - case token_type::end_object: - case token_type::name_separator: - case token_type::value_separator: - case token_type::end_of_input: - case token_type::literal_or_value: - default: // the last token was unexpected - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType())); - } - } - } - else - { - skip_to_state_evaluation = false; - } - - // we reached this line after we successfully parsed a value - if (states.empty()) - { - // empty stack: we reached the end of the hierarchy: done - return true; - } - - if (states.back()) // array - { - // comma -> next value - if (get_token() == token_type::value_separator) - { - // parse a new value - get_token(); - continue; - } - - // closing ] - if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array)) - { - if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) - { - return false; - } - - // We are done with this array. Before we can parse a - // new value, we need to evaluate the new state first. - // By setting skip_to_state_evaluation to false, we - // are effectively jumping to the beginning of this if. - JSON_ASSERT(!states.empty()); - states.pop_back(); - skip_to_state_evaluation = true; - continue; - } - - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType())); - } - - // states.back() is false -> object - - // comma -> next value - if (get_token() == token_type::value_separator) - { - // parse key - if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType())); - } - - if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) - { - return false; - } - - // parse separator (:) - if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType())); - } - - // parse values - get_token(); - continue; - } - - // closing } - if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object)) - { - if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) - { - return false; - } - - // We are done with this object. Before we can parse a - // new value, we need to evaluate the new state first. - // By setting skip_to_state_evaluation to false, we - // are effectively jumping to the beginning of this if. - JSON_ASSERT(!states.empty()); - states.pop_back(); - skip_to_state_evaluation = true; - continue; - } - - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType())); - } - } - - /// get next token from lexer - token_type get_token() - { - return last_token = m_lexer.scan(); - } - - std::string exception_message(const token_type expected, const std::string& context) - { - std::string error_msg = "syntax error "; - - if (!context.empty()) - { - error_msg += "while parsing " + context + " "; - } - - error_msg += "- "; - - if (last_token == token_type::parse_error) - { - error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" + - m_lexer.get_token_string() + "'"; - } - else - { - error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token)); - } - - if (expected != token_type::uninitialized) - { - error_msg += "; expected " + std::string(lexer_t::token_type_name(expected)); - } - - return error_msg; - } - - private: - /// callback function - const parser_callback_t callback = nullptr; - /// the type of the last read token - token_type last_token = token_type::uninitialized; - /// the lexer - lexer_t m_lexer; - /// whether to throw exceptions in case of errors - const bool allow_exceptions = true; -}; - -} // namespace detail -} // namespace nlohmann - -// #include - - -// #include - - -#include // ptrdiff_t -#include // numeric_limits - -// #include - - -namespace nlohmann -{ -namespace detail -{ -/* -@brief an iterator for primitive JSON types - -This class models an iterator for primitive JSON types (boolean, number, -string). It's only purpose is to allow the iterator/const_iterator classes -to "iterate" over primitive values. Internally, the iterator is modeled by -a `difference_type` variable. Value begin_value (`0`) models the begin, -end_value (`1`) models past the end. -*/ -class primitive_iterator_t -{ - private: - using difference_type = std::ptrdiff_t; - static constexpr difference_type begin_value = 0; - static constexpr difference_type end_value = begin_value + 1; - - JSON_PRIVATE_UNLESS_TESTED: - /// iterator as signed integer type - difference_type m_it = (std::numeric_limits::min)(); - - public: - constexpr difference_type get_value() const noexcept - { - return m_it; - } - - /// set iterator to a defined beginning - void set_begin() noexcept - { - m_it = begin_value; - } - - /// set iterator to a defined past the end - void set_end() noexcept - { - m_it = end_value; - } - - /// return whether the iterator can be dereferenced - constexpr bool is_begin() const noexcept - { - return m_it == begin_value; - } - - /// return whether the iterator is at end - constexpr bool is_end() const noexcept - { - return m_it == end_value; - } - - friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept - { - return lhs.m_it == rhs.m_it; - } - - friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept - { - return lhs.m_it < rhs.m_it; - } - - primitive_iterator_t operator+(difference_type n) noexcept - { - auto result = *this; - result += n; - return result; - } - - friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept - { - return lhs.m_it - rhs.m_it; - } - - primitive_iterator_t& operator++() noexcept - { - ++m_it; - return *this; - } - - primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type) - { - auto result = *this; - ++m_it; - return result; - } - - primitive_iterator_t& operator--() noexcept - { - --m_it; - return *this; - } - - primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type) - { - auto result = *this; - --m_it; - return result; - } - - primitive_iterator_t& operator+=(difference_type n) noexcept - { - m_it += n; - return *this; - } - - primitive_iterator_t& operator-=(difference_type n) noexcept - { - m_it -= n; - return *this; - } -}; -} // namespace detail -} // namespace nlohmann - - -namespace nlohmann -{ -namespace detail -{ -/*! -@brief an iterator value - -@note This structure could easily be a union, but MSVC currently does not allow -unions members with complex constructors, see https://github.com/nlohmann/json/pull/105. -*/ -template struct internal_iterator -{ - /// iterator for JSON objects - typename BasicJsonType::object_t::iterator object_iterator {}; - /// iterator for JSON arrays - typename BasicJsonType::array_t::iterator array_iterator {}; - /// generic iterator for all other types - primitive_iterator_t primitive_iterator {}; -}; -} // namespace detail -} // namespace nlohmann - -// #include - - -#include // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next -#include // conditional, is_const, remove_const - -// #include - -// #include - -// #include - -// #include - -// #include - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -// forward declare, to be able to friend it later on -template class iteration_proxy; -template class iteration_proxy_value; - -/*! -@brief a template for a bidirectional iterator for the @ref basic_json class -This class implements a both iterators (iterator and const_iterator) for the -@ref basic_json class. -@note An iterator is called *initialized* when a pointer to a JSON value has - been set (e.g., by a constructor or a copy assignment). If the iterator is - default-constructed, it is *uninitialized* and most methods are undefined. - **The library uses assertions to detect calls on uninitialized iterators.** -@requirement The class satisfies the following concept requirements: -- -[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): - The iterator that can be moved can be moved in both directions (i.e. - incremented and decremented). -@since version 1.0.0, simplified in version 2.0.9, change to bidirectional - iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593) -*/ -template -class iter_impl -{ - /// the iterator with BasicJsonType of different const-ness - using other_iter_impl = iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; - /// allow basic_json to access private members - friend other_iter_impl; - friend BasicJsonType; - friend iteration_proxy; - friend iteration_proxy_value; - - using object_t = typename BasicJsonType::object_t; - using array_t = typename BasicJsonType::array_t; - // make sure BasicJsonType is basic_json or const basic_json - static_assert(is_basic_json::type>::value, - "iter_impl only accepts (const) basic_json"); - - public: - - /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17. - /// The C++ Standard has never required user-defined iterators to derive from std::iterator. - /// A user-defined iterator should provide publicly accessible typedefs named - /// iterator_category, value_type, difference_type, pointer, and reference. - /// Note that value_type is required to be non-const, even for constant iterators. - using iterator_category = std::bidirectional_iterator_tag; - - /// the type of the values when the iterator is dereferenced - using value_type = typename BasicJsonType::value_type; - /// a type to represent differences between iterators - using difference_type = typename BasicJsonType::difference_type; - /// defines a pointer to the type iterated over (value_type) - using pointer = typename std::conditional::value, - typename BasicJsonType::const_pointer, - typename BasicJsonType::pointer>::type; - /// defines a reference to the type iterated over (value_type) - using reference = - typename std::conditional::value, - typename BasicJsonType::const_reference, - typename BasicJsonType::reference>::type; - - iter_impl() = default; - ~iter_impl() = default; - iter_impl(iter_impl&&) noexcept = default; - iter_impl& operator=(iter_impl&&) noexcept = default; - - /*! - @brief constructor for a given JSON instance - @param[in] object pointer to a JSON object for this iterator - @pre object != nullptr - @post The iterator is initialized; i.e. `m_object != nullptr`. - */ - explicit iter_impl(pointer object) noexcept : m_object(object) - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - m_it.object_iterator = typename object_t::iterator(); - break; - } - - case value_t::array: - { - m_it.array_iterator = typename array_t::iterator(); - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - m_it.primitive_iterator = primitive_iterator_t(); - break; - } - } - } - - /*! - @note The conventional copy constructor and copy assignment are implicitly - defined. Combined with the following converting constructor and - assignment, they support: (1) copy from iterator to iterator, (2) - copy from const iterator to const iterator, and (3) conversion from - iterator to const iterator. However conversion from const iterator - to iterator is not defined. - */ - - /*! - @brief const copy constructor - @param[in] other const iterator to copy from - @note This copy constructor had to be defined explicitly to circumvent a bug - occurring on msvc v19.0 compiler (VS 2015) debug build. For more - information refer to: https://github.com/nlohmann/json/issues/1608 - */ - iter_impl(const iter_impl& other) noexcept - : m_object(other.m_object), m_it(other.m_it) - {} - - /*! - @brief converting assignment - @param[in] other const iterator to copy from - @return const/non-const iterator - @note It is not checked whether @a other is initialized. - */ - iter_impl& operator=(const iter_impl& other) noexcept - { - if (&other != this) - { - m_object = other.m_object; - m_it = other.m_it; - } - return *this; - } - - /*! - @brief converting constructor - @param[in] other non-const iterator to copy from - @note It is not checked whether @a other is initialized. - */ - iter_impl(const iter_impl::type>& other) noexcept - : m_object(other.m_object), m_it(other.m_it) - {} - - /*! - @brief converting assignment - @param[in] other non-const iterator to copy from - @return const/non-const iterator - @note It is not checked whether @a other is initialized. - */ - iter_impl& operator=(const iter_impl::type>& other) noexcept // NOLINT(cert-oop54-cpp) - { - m_object = other.m_object; - m_it = other.m_it; - return *this; - } - - JSON_PRIVATE_UNLESS_TESTED: - /*! - @brief set the iterator to the first value - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - void set_begin() noexcept - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - m_it.object_iterator = m_object->m_value.object->begin(); - break; - } - - case value_t::array: - { - m_it.array_iterator = m_object->m_value.array->begin(); - break; - } - - case value_t::null: - { - // set to end so begin()==end() is true: null is empty - m_it.primitive_iterator.set_end(); - break; - } - - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - m_it.primitive_iterator.set_begin(); - break; - } - } - } - - /*! - @brief set the iterator past the last value - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - void set_end() noexcept - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - m_it.object_iterator = m_object->m_value.object->end(); - break; - } - - case value_t::array: - { - m_it.array_iterator = m_object->m_value.array->end(); - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - m_it.primitive_iterator.set_end(); - break; - } - } - } - - public: - /*! - @brief return a reference to the value pointed to by the iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - reference operator*() const - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end()); - return m_it.object_iterator->second; - } - - case value_t::array: - { - JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end()); - return *m_it.array_iterator; - } - - case value_t::null: - JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object)); - - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) - { - return *m_object; - } - - JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object)); - } - } - } - - /*! - @brief dereference the iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - pointer operator->() const - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end()); - return &(m_it.object_iterator->second); - } - - case value_t::array: - { - JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end()); - return &*m_it.array_iterator; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) - { - return m_object; - } - - JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object)); - } - } - } - - /*! - @brief post-increment (it++) - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl const operator++(int) // NOLINT(readability-const-return-type) - { - auto result = *this; - ++(*this); - return result; - } - - /*! - @brief pre-increment (++it) - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl& operator++() - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - std::advance(m_it.object_iterator, 1); - break; - } - - case value_t::array: - { - std::advance(m_it.array_iterator, 1); - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - ++m_it.primitive_iterator; - break; - } - } - - return *this; - } - - /*! - @brief post-decrement (it--) - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl const operator--(int) // NOLINT(readability-const-return-type) - { - auto result = *this; - --(*this); - return result; - } - - /*! - @brief pre-decrement (--it) - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl& operator--() - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - std::advance(m_it.object_iterator, -1); - break; - } - - case value_t::array: - { - std::advance(m_it.array_iterator, -1); - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - --m_it.primitive_iterator; - break; - } - } - - return *this; - } - - /*! - @brief comparison: equal - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > - bool operator==(const IterImpl& other) const - { - // if objects are not the same, the comparison is undefined - if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) - { - JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object)); - } - - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - return (m_it.object_iterator == other.m_it.object_iterator); - - case value_t::array: - return (m_it.array_iterator == other.m_it.array_iterator); - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - return (m_it.primitive_iterator == other.m_it.primitive_iterator); - } - } - - /*! - @brief comparison: not equal - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > - bool operator!=(const IterImpl& other) const - { - return !operator==(other); - } - - /*! - @brief comparison: smaller - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator<(const iter_impl& other) const - { - // if objects are not the same, the comparison is undefined - if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) - { - JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object)); - } - - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object)); - - case value_t::array: - return (m_it.array_iterator < other.m_it.array_iterator); - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - return (m_it.primitive_iterator < other.m_it.primitive_iterator); - } - } - - /*! - @brief comparison: less than or equal - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator<=(const iter_impl& other) const - { - return !other.operator < (*this); - } - - /*! - @brief comparison: greater than - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator>(const iter_impl& other) const - { - return !operator<=(other); - } - - /*! - @brief comparison: greater than or equal - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator>=(const iter_impl& other) const - { - return !operator<(other); - } - - /*! - @brief add to iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl& operator+=(difference_type i) - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object)); - - case value_t::array: - { - std::advance(m_it.array_iterator, i); - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - m_it.primitive_iterator += i; - break; - } - } - - return *this; - } - - /*! - @brief subtract from iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl& operator-=(difference_type i) - { - return operator+=(-i); - } - - /*! - @brief add to iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl operator+(difference_type i) const - { - auto result = *this; - result += i; - return result; - } - - /*! - @brief addition of distance and iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - friend iter_impl operator+(difference_type i, const iter_impl& it) - { - auto result = it; - result += i; - return result; - } - - /*! - @brief subtract from iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl operator-(difference_type i) const - { - auto result = *this; - result -= i; - return result; - } - - /*! - @brief return difference - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - difference_type operator-(const iter_impl& other) const - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object)); - - case value_t::array: - return m_it.array_iterator - other.m_it.array_iterator; - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - return m_it.primitive_iterator - other.m_it.primitive_iterator; - } - } - - /*! - @brief access to successor - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - reference operator[](difference_type n) const - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object)); - - case value_t::array: - return *std::next(m_it.array_iterator, n); - - case value_t::null: - JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object)); - - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n)) - { - return *m_object; - } - - JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object)); - } - } - } - - /*! - @brief return the key of an object iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - const typename object_t::key_type& key() const - { - JSON_ASSERT(m_object != nullptr); - - if (JSON_HEDLEY_LIKELY(m_object->is_object())) - { - return m_it.object_iterator->first; - } - - JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object)); - } - - /*! - @brief return the value of an iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - reference value() const - { - return operator*(); - } - - JSON_PRIVATE_UNLESS_TESTED: - /// associated JSON instance - pointer m_object = nullptr; - /// the actual iterator of the associated instance - internal_iterator::type> m_it {}; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - - -#include // ptrdiff_t -#include // reverse_iterator -#include // declval - -namespace nlohmann -{ -namespace detail -{ -////////////////////// -// reverse_iterator // -////////////////////// - -/*! -@brief a template for a reverse iterator class - -@tparam Base the base iterator type to reverse. Valid types are @ref -iterator (to create @ref reverse_iterator) and @ref const_iterator (to -create @ref const_reverse_iterator). - -@requirement The class satisfies the following concept requirements: -- -[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): - The iterator that can be moved can be moved in both directions (i.e. - incremented and decremented). -- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator): - It is possible to write to the pointed-to element (only if @a Base is - @ref iterator). - -@since version 1.0.0 -*/ -template -class json_reverse_iterator : public std::reverse_iterator -{ - public: - using difference_type = std::ptrdiff_t; - /// shortcut to the reverse iterator adapter - using base_iterator = std::reverse_iterator; - /// the reference type for the pointed-to element - using reference = typename Base::reference; - - /// create reverse iterator from iterator - explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept - : base_iterator(it) {} - - /// create reverse iterator from base class - explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {} - - /// post-increment (it++) - json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type) - { - return static_cast(base_iterator::operator++(1)); - } - - /// pre-increment (++it) - json_reverse_iterator& operator++() - { - return static_cast(base_iterator::operator++()); - } - - /// post-decrement (it--) - json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type) - { - return static_cast(base_iterator::operator--(1)); - } - - /// pre-decrement (--it) - json_reverse_iterator& operator--() - { - return static_cast(base_iterator::operator--()); - } - - /// add to iterator - json_reverse_iterator& operator+=(difference_type i) - { - return static_cast(base_iterator::operator+=(i)); - } - - /// add to iterator - json_reverse_iterator operator+(difference_type i) const - { - return static_cast(base_iterator::operator+(i)); - } - - /// subtract from iterator - json_reverse_iterator operator-(difference_type i) const - { - return static_cast(base_iterator::operator-(i)); - } - - /// return difference - difference_type operator-(const json_reverse_iterator& other) const - { - return base_iterator(*this) - base_iterator(other); - } - - /// access to successor - reference operator[](difference_type n) const - { - return *(this->operator+(n)); - } - - /// return the key of an object iterator - auto key() const -> decltype(std::declval().key()) - { - auto it = --this->base(); - return it.key(); - } - - /// return the value of an iterator - reference value() const - { - auto it = --this->base(); - return it.operator * (); - } -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - - -#include // all_of -#include // isdigit -#include // max -#include // accumulate -#include // string -#include // move -#include // vector - -// #include - -// #include - -// #include - -// #include - - -namespace nlohmann -{ -template -class json_pointer -{ - // allow basic_json to access private members - NLOHMANN_BASIC_JSON_TPL_DECLARATION - friend class basic_json; - - public: - /*! - @brief create JSON pointer - - Create a JSON pointer according to the syntax described in - [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3). - - @param[in] s string representing the JSON pointer; if omitted, the empty - string is assumed which references the whole JSON value - - @throw parse_error.107 if the given JSON pointer @a s is nonempty and does - not begin with a slash (`/`); see example below - - @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is - not followed by `0` (representing `~`) or `1` (representing `/`); see - example below - - @liveexample{The example shows the construction several valid JSON pointers - as well as the exceptional behavior.,json_pointer} - - @since version 2.0.0 - */ - explicit json_pointer(const std::string& s = "") - : reference_tokens(split(s)) - {} - - /*! - @brief return a string representation of the JSON pointer - - @invariant For each JSON pointer `ptr`, it holds: - @code {.cpp} - ptr == json_pointer(ptr.to_string()); - @endcode - - @return a string representation of the JSON pointer - - @liveexample{The example shows the result of `to_string`.,json_pointer__to_string} - - @since version 2.0.0 - */ - std::string to_string() const - { - return std::accumulate(reference_tokens.begin(), reference_tokens.end(), - std::string{}, - [](const std::string & a, const std::string & b) - { - return a + "/" + detail::escape(b); - }); - } - - /// @copydoc to_string() - operator std::string() const - { - return to_string(); - } - - /*! - @brief append another JSON pointer at the end of this JSON pointer - - @param[in] ptr JSON pointer to append - @return JSON pointer with @a ptr appended - - @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} - - @complexity Linear in the length of @a ptr. - - @sa see @ref operator/=(std::string) to append a reference token - @sa see @ref operator/=(std::size_t) to append an array index - @sa see @ref operator/(const json_pointer&, const json_pointer&) for a binary operator - - @since version 3.6.0 - */ - json_pointer& operator/=(const json_pointer& ptr) - { - reference_tokens.insert(reference_tokens.end(), - ptr.reference_tokens.begin(), - ptr.reference_tokens.end()); - return *this; - } - - /*! - @brief append an unescaped reference token at the end of this JSON pointer - - @param[in] token reference token to append - @return JSON pointer with @a token appended without escaping @a token - - @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} - - @complexity Amortized constant. - - @sa see @ref operator/=(const json_pointer&) to append a JSON pointer - @sa see @ref operator/=(std::size_t) to append an array index - @sa see @ref operator/(const json_pointer&, std::size_t) for a binary operator - - @since version 3.6.0 - */ - json_pointer& operator/=(std::string token) - { - push_back(std::move(token)); - return *this; - } - - /*! - @brief append an array index at the end of this JSON pointer - - @param[in] array_idx array index to append - @return JSON pointer with @a array_idx appended - - @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} - - @complexity Amortized constant. - - @sa see @ref operator/=(const json_pointer&) to append a JSON pointer - @sa see @ref operator/=(std::string) to append a reference token - @sa see @ref operator/(const json_pointer&, std::string) for a binary operator - - @since version 3.6.0 - */ - json_pointer& operator/=(std::size_t array_idx) - { - return *this /= std::to_string(array_idx); - } - - /*! - @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer - - @param[in] lhs JSON pointer - @param[in] rhs JSON pointer - @return a new JSON pointer with @a rhs appended to @a lhs - - @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} - - @complexity Linear in the length of @a lhs and @a rhs. - - @sa see @ref operator/=(const json_pointer&) to append a JSON pointer - - @since version 3.6.0 - */ - friend json_pointer operator/(const json_pointer& lhs, - const json_pointer& rhs) - { - return json_pointer(lhs) /= rhs; - } - - /*! - @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer - - @param[in] ptr JSON pointer - @param[in] token reference token - @return a new JSON pointer with unescaped @a token appended to @a ptr - - @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} - - @complexity Linear in the length of @a ptr. - - @sa see @ref operator/=(std::string) to append a reference token - - @since version 3.6.0 - */ - friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param) - { - return json_pointer(ptr) /= std::move(token); - } - - /*! - @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer - - @param[in] ptr JSON pointer - @param[in] array_idx array index - @return a new JSON pointer with @a array_idx appended to @a ptr - - @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} - - @complexity Linear in the length of @a ptr. - - @sa see @ref operator/=(std::size_t) to append an array index - - @since version 3.6.0 - */ - friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx) - { - return json_pointer(ptr) /= array_idx; - } - - /*! - @brief returns the parent of this JSON pointer - - @return parent of this JSON pointer; in case this JSON pointer is the root, - the root itself is returned - - @complexity Linear in the length of the JSON pointer. - - @liveexample{The example shows the result of `parent_pointer` for different - JSON Pointers.,json_pointer__parent_pointer} - - @since version 3.6.0 - */ - json_pointer parent_pointer() const - { - if (empty()) - { - return *this; - } - - json_pointer res = *this; - res.pop_back(); - return res; - } - - /*! - @brief remove last reference token - - @pre not `empty()` - - @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back} - - @complexity Constant. - - @throw out_of_range.405 if JSON pointer has no parent - - @since version 3.6.0 - */ - void pop_back() - { - if (JSON_HEDLEY_UNLIKELY(empty())) - { - JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType())); - } - - reference_tokens.pop_back(); - } - - /*! - @brief return last reference token - - @pre not `empty()` - @return last reference token - - @liveexample{The example shows the usage of `back`.,json_pointer__back} - - @complexity Constant. - - @throw out_of_range.405 if JSON pointer has no parent - - @since version 3.6.0 - */ - const std::string& back() const - { - if (JSON_HEDLEY_UNLIKELY(empty())) - { - JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType())); - } - - return reference_tokens.back(); - } - - /*! - @brief append an unescaped token at the end of the reference pointer - - @param[in] token token to add - - @complexity Amortized constant. - - @liveexample{The example shows the result of `push_back` for different - JSON Pointers.,json_pointer__push_back} - - @since version 3.6.0 - */ - void push_back(const std::string& token) - { - reference_tokens.push_back(token); - } - - /// @copydoc push_back(const std::string&) - void push_back(std::string&& token) - { - reference_tokens.push_back(std::move(token)); - } - - /*! - @brief return whether pointer points to the root document - - @return true iff the JSON pointer points to the root document - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example shows the result of `empty` for different JSON - Pointers.,json_pointer__empty} - - @since version 3.6.0 - */ - bool empty() const noexcept - { - return reference_tokens.empty(); - } - - private: - /*! - @param[in] s reference token to be converted into an array index - - @return integer representation of @a s - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index begins not with a digit - @throw out_of_range.404 if string @a s could not be converted to an integer - @throw out_of_range.410 if an array index exceeds size_type - */ - static typename BasicJsonType::size_type array_index(const std::string& s) - { - using size_type = typename BasicJsonType::size_type; - - // error condition (cf. RFC 6901, Sect. 4) - if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0')) - { - JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType())); - } - - // error condition (cf. RFC 6901, Sect. 4) - if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9'))) - { - JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType())); - } - - std::size_t processed_chars = 0; - unsigned long long res = 0; // NOLINT(runtime/int) - JSON_TRY - { - res = std::stoull(s, &processed_chars); - } - JSON_CATCH(std::out_of_range&) - { - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType())); - } - - // check if the string was completely read - if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size())) - { - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType())); - } - - // only triggered on special platforms (like 32bit), see also - // https://github.com/nlohmann/json/pull/2203 - if (res >= static_cast((std::numeric_limits::max)())) // NOLINT(runtime/int) - { - JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE - } - - return static_cast(res); - } - - JSON_PRIVATE_UNLESS_TESTED: - json_pointer top() const - { - if (JSON_HEDLEY_UNLIKELY(empty())) - { - JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType())); - } - - json_pointer result = *this; - result.reference_tokens = {reference_tokens[0]}; - return result; - } - - private: - /*! - @brief create and return a reference to the pointed to value - - @complexity Linear in the number of reference tokens. - - @throw parse_error.109 if array index is not a number - @throw type_error.313 if value cannot be unflattened - */ - BasicJsonType& get_and_create(BasicJsonType& j) const - { - auto* result = &j; - - // in case no reference tokens exist, return a reference to the JSON value - // j which will be overwritten by a primitive value - for (const auto& reference_token : reference_tokens) - { - switch (result->type()) - { - case detail::value_t::null: - { - if (reference_token == "0") - { - // start a new array if reference token is 0 - result = &result->operator[](0); - } - else - { - // start a new object otherwise - result = &result->operator[](reference_token); - } - break; - } - - case detail::value_t::object: - { - // create an entry in the object - result = &result->operator[](reference_token); - break; - } - - case detail::value_t::array: - { - // create an entry in the array - result = &result->operator[](array_index(reference_token)); - break; - } - - /* - The following code is only reached if there exists a reference - token _and_ the current value is primitive. In this case, we have - an error situation, because primitive values may only occur as - single value; that is, with an empty list of reference tokens. - */ - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j)); - } - } - - return *result; - } - - /*! - @brief return a reference to the pointed to value - - @note This version does not throw if a value is not present, but tries to - create nested values instead. For instance, calling this function - with pointer `"/this/that"` on a null value is equivalent to calling - `operator[]("this").operator[]("that")` on that value, effectively - changing the null value to an object. - - @param[in] ptr a JSON value - - @return reference to the JSON value pointed to by the JSON pointer - - @complexity Linear in the length of the JSON pointer. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.404 if the JSON pointer can not be resolved - */ - BasicJsonType& get_unchecked(BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - // convert null values to arrays or objects before continuing - if (ptr->is_null()) - { - // check if reference token is a number - const bool nums = - std::all_of(reference_token.begin(), reference_token.end(), - [](const unsigned char x) - { - return std::isdigit(x); - }); - - // change value to array for numbers or "-" or to object otherwise - *ptr = (nums || reference_token == "-") - ? detail::value_t::array - : detail::value_t::object; - } - - switch (ptr->type()) - { - case detail::value_t::object: - { - // use unchecked object access - ptr = &ptr->operator[](reference_token); - break; - } - - case detail::value_t::array: - { - if (reference_token == "-") - { - // explicitly treat "-" as index beyond the end - ptr = &ptr->operator[](ptr->m_value.array->size()); - } - else - { - // convert array index to number; unchecked access - ptr = &ptr->operator[](array_index(reference_token)); - } - break; - } - - case detail::value_t::null: - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr)); - } - } - - return *ptr; - } - - /*! - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.402 if the array index '-' is used - @throw out_of_range.404 if the JSON pointer can not be resolved - */ - BasicJsonType& get_checked(BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - switch (ptr->type()) - { - case detail::value_t::object: - { - // note: at performs range check - ptr = &ptr->at(reference_token); - break; - } - - case detail::value_t::array: - { - if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) - { - // "-" always fails the range check - JSON_THROW(detail::out_of_range::create(402, - "array index '-' (" + std::to_string(ptr->m_value.array->size()) + - ") is out of range", *ptr)); - } - - // note: at performs range check - ptr = &ptr->at(array_index(reference_token)); - break; - } - - case detail::value_t::null: - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr)); - } - } - - return *ptr; - } - - /*! - @brief return a const reference to the pointed to value - - @param[in] ptr a JSON value - - @return const reference to the JSON value pointed to by the JSON - pointer - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.402 if the array index '-' is used - @throw out_of_range.404 if the JSON pointer can not be resolved - */ - const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - switch (ptr->type()) - { - case detail::value_t::object: - { - // use unchecked object access - ptr = &ptr->operator[](reference_token); - break; - } - - case detail::value_t::array: - { - if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) - { - // "-" cannot be used for const access - JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr)); - } - - // use unchecked array access - ptr = &ptr->operator[](array_index(reference_token)); - break; - } - - case detail::value_t::null: - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr)); - } - } - - return *ptr; - } - - /*! - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.402 if the array index '-' is used - @throw out_of_range.404 if the JSON pointer can not be resolved - */ - const BasicJsonType& get_checked(const BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - switch (ptr->type()) - { - case detail::value_t::object: - { - // note: at performs range check - ptr = &ptr->at(reference_token); - break; - } - - case detail::value_t::array: - { - if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) - { - // "-" always fails the range check - JSON_THROW(detail::out_of_range::create(402, - "array index '-' (" + std::to_string(ptr->m_value.array->size()) + - ") is out of range", *ptr)); - } - - // note: at performs range check - ptr = &ptr->at(array_index(reference_token)); - break; - } - - case detail::value_t::null: - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr)); - } - } - - return *ptr; - } - - /*! - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - */ - bool contains(const BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - switch (ptr->type()) - { - case detail::value_t::object: - { - if (!ptr->contains(reference_token)) - { - // we did not find the key in the object - return false; - } - - ptr = &ptr->operator[](reference_token); - break; - } - - case detail::value_t::array: - { - if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) - { - // "-" always fails the range check - return false; - } - if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9"))) - { - // invalid char - return false; - } - if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1)) - { - if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9'))) - { - // first char should be between '1' and '9' - return false; - } - for (std::size_t i = 1; i < reference_token.size(); i++) - { - if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9'))) - { - // other char should be between '0' and '9' - return false; - } - } - } - - const auto idx = array_index(reference_token); - if (idx >= ptr->size()) - { - // index out of range - return false; - } - - ptr = &ptr->operator[](idx); - break; - } - - case detail::value_t::null: - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - { - // we do not expect primitive values if there is still a - // reference token to process - return false; - } - } - } - - // no reference token left means we found a primitive value - return true; - } - - /*! - @brief split the string input to reference tokens - - @note This function is only called by the json_pointer constructor. - All exceptions below are documented there. - - @throw parse_error.107 if the pointer is not empty or begins with '/' - @throw parse_error.108 if character '~' is not followed by '0' or '1' - */ - static std::vector split(const std::string& reference_string) - { - std::vector result; - - // special case: empty reference string -> no reference tokens - if (reference_string.empty()) - { - return result; - } - - // check if nonempty reference string begins with slash - if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/')) - { - JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType())); - } - - // extract the reference tokens: - // - slash: position of the last read slash (or end of string) - // - start: position after the previous slash - for ( - // search for the first slash after the first character - std::size_t slash = reference_string.find_first_of('/', 1), - // set the beginning of the first reference token - start = 1; - // we can stop if start == 0 (if slash == std::string::npos) - start != 0; - // set the beginning of the next reference token - // (will eventually be 0 if slash == std::string::npos) - start = (slash == std::string::npos) ? 0 : slash + 1, - // find next slash - slash = reference_string.find_first_of('/', start)) - { - // use the text between the beginning of the reference token - // (start) and the last slash (slash). - auto reference_token = reference_string.substr(start, slash - start); - - // check reference tokens are properly escaped - for (std::size_t pos = reference_token.find_first_of('~'); - pos != std::string::npos; - pos = reference_token.find_first_of('~', pos + 1)) - { - JSON_ASSERT(reference_token[pos] == '~'); - - // ~ must be followed by 0 or 1 - if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 || - (reference_token[pos + 1] != '0' && - reference_token[pos + 1] != '1'))) - { - JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType())); - } - } - - // finally, store the reference token - detail::unescape(reference_token); - result.push_back(reference_token); - } - - return result; - } - - private: - /*! - @param[in] reference_string the reference string to the current value - @param[in] value the value to consider - @param[in,out] result the result object to insert values to - - @note Empty objects or arrays are flattened to `null`. - */ - static void flatten(const std::string& reference_string, - const BasicJsonType& value, - BasicJsonType& result) - { - switch (value.type()) - { - case detail::value_t::array: - { - if (value.m_value.array->empty()) - { - // flatten empty array as null - result[reference_string] = nullptr; - } - else - { - // iterate array and use index as reference string - for (std::size_t i = 0; i < value.m_value.array->size(); ++i) - { - flatten(reference_string + "/" + std::to_string(i), - value.m_value.array->operator[](i), result); - } - } - break; - } - - case detail::value_t::object: - { - if (value.m_value.object->empty()) - { - // flatten empty object as null - result[reference_string] = nullptr; - } - else - { - // iterate object and use keys as reference string - for (const auto& element : *value.m_value.object) - { - flatten(reference_string + "/" + detail::escape(element.first), element.second, result); - } - } - break; - } - - case detail::value_t::null: - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - { - // add primitive value with its reference string - result[reference_string] = value; - break; - } - } - } - - /*! - @param[in] value flattened JSON - - @return unflattened JSON - - @throw parse_error.109 if array index is not a number - @throw type_error.314 if value is not an object - @throw type_error.315 if object values are not primitive - @throw type_error.313 if value cannot be unflattened - */ - static BasicJsonType - unflatten(const BasicJsonType& value) - { - if (JSON_HEDLEY_UNLIKELY(!value.is_object())) - { - JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value)); - } - - BasicJsonType result; - - // iterate the JSON object values - for (const auto& element : *value.m_value.object) - { - if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive())) - { - JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second)); - } - - // assign value to reference pointed to by JSON pointer; Note that if - // the JSON pointer is "" (i.e., points to the whole value), function - // get_and_create returns a reference to result itself. An assignment - // will then create a primitive value. - json_pointer(element.first).get_and_create(result) = element.second; - } - - return result; - } - - /*! - @brief compares two JSON pointers for equality - - @param[in] lhs JSON pointer to compare - @param[in] rhs JSON pointer to compare - @return whether @a lhs is equal to @a rhs - - @complexity Linear in the length of the JSON pointer - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - */ - friend bool operator==(json_pointer const& lhs, - json_pointer const& rhs) noexcept - { - return lhs.reference_tokens == rhs.reference_tokens; - } - - /*! - @brief compares two JSON pointers for inequality - - @param[in] lhs JSON pointer to compare - @param[in] rhs JSON pointer to compare - @return whether @a lhs is not equal @a rhs - - @complexity Linear in the length of the JSON pointer - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - */ - friend bool operator!=(json_pointer const& lhs, - json_pointer const& rhs) noexcept - { - return !(lhs == rhs); - } - - /// the reference tokens - std::vector reference_tokens; -}; -} // namespace nlohmann - -// #include - - -#include -#include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -template -class json_ref -{ - public: - using value_type = BasicJsonType; - - json_ref(value_type&& value) - : owned_value(std::move(value)) - {} - - json_ref(const value_type& value) - : value_ref(&value) - {} - - json_ref(std::initializer_list init) - : owned_value(init) - {} - - template < - class... Args, - enable_if_t::value, int> = 0 > - json_ref(Args && ... args) - : owned_value(std::forward(args)...) - {} - - // class should be movable only - json_ref(json_ref&&) noexcept = default; - json_ref(const json_ref&) = delete; - json_ref& operator=(const json_ref&) = delete; - json_ref& operator=(json_ref&&) = delete; - ~json_ref() = default; - - value_type moved_or_copied() const - { - if (value_ref == nullptr) - { - return std::move(owned_value); - } - return *value_ref; - } - - value_type const& operator*() const - { - return value_ref ? *value_ref : owned_value; - } - - value_type const* operator->() const - { - return &** this; - } - - private: - mutable value_type owned_value = nullptr; - value_type const* value_ref = nullptr; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - -// #include - -// #include - -// #include - - -#include // reverse -#include // array -#include // isnan, isinf -#include // uint8_t, uint16_t, uint32_t, uint64_t -#include // memcpy -#include // numeric_limits -#include // string -#include // move - -// #include - -// #include - -// #include - - -#include // copy -#include // size_t -#include // back_inserter -#include // shared_ptr, make_shared -#include // basic_string -#include // vector - -#ifndef JSON_NO_IO - #include // streamsize - #include // basic_ostream -#endif // JSON_NO_IO - -// #include - - -namespace nlohmann -{ -namespace detail -{ -/// abstract output adapter interface -template struct output_adapter_protocol -{ - virtual void write_character(CharType c) = 0; - virtual void write_characters(const CharType* s, std::size_t length) = 0; - virtual ~output_adapter_protocol() = default; - - output_adapter_protocol() = default; - output_adapter_protocol(const output_adapter_protocol&) = default; - output_adapter_protocol(output_adapter_protocol&&) noexcept = default; - output_adapter_protocol& operator=(const output_adapter_protocol&) = default; - output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default; -}; - -/// a type to simplify interfaces -template -using output_adapter_t = std::shared_ptr>; - -/// output adapter for byte vectors -template -class output_vector_adapter : public output_adapter_protocol -{ - public: - explicit output_vector_adapter(std::vector& vec) noexcept - : v(vec) - {} - - void write_character(CharType c) override - { - v.push_back(c); - } - - JSON_HEDLEY_NON_NULL(2) - void write_characters(const CharType* s, std::size_t length) override - { - std::copy(s, s + length, std::back_inserter(v)); - } - - private: - std::vector& v; -}; - -#ifndef JSON_NO_IO -/// output adapter for output streams -template -class output_stream_adapter : public output_adapter_protocol -{ - public: - explicit output_stream_adapter(std::basic_ostream& s) noexcept - : stream(s) - {} - - void write_character(CharType c) override - { - stream.put(c); - } - - JSON_HEDLEY_NON_NULL(2) - void write_characters(const CharType* s, std::size_t length) override - { - stream.write(s, static_cast(length)); - } - - private: - std::basic_ostream& stream; -}; -#endif // JSON_NO_IO - -/// output adapter for basic_string -template> -class output_string_adapter : public output_adapter_protocol -{ - public: - explicit output_string_adapter(StringType& s) noexcept - : str(s) - {} - - void write_character(CharType c) override - { - str.push_back(c); - } - - JSON_HEDLEY_NON_NULL(2) - void write_characters(const CharType* s, std::size_t length) override - { - str.append(s, length); - } - - private: - StringType& str; -}; - -template> -class output_adapter -{ - public: - output_adapter(std::vector& vec) - : oa(std::make_shared>(vec)) {} - -#ifndef JSON_NO_IO - output_adapter(std::basic_ostream& s) - : oa(std::make_shared>(s)) {} -#endif // JSON_NO_IO - - output_adapter(StringType& s) - : oa(std::make_shared>(s)) {} - - operator output_adapter_t() - { - return oa; - } - - private: - output_adapter_t oa = nullptr; -}; -} // namespace detail -} // namespace nlohmann - - -namespace nlohmann -{ -namespace detail -{ -/////////////////// -// binary writer // -/////////////////// - -/*! -@brief serialization to CBOR and MessagePack values -*/ -template -class binary_writer -{ - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using number_float_t = typename BasicJsonType::number_float_t; - - public: - /*! - @brief create a binary writer - - @param[in] adapter output adapter to write to - */ - explicit binary_writer(output_adapter_t adapter) : oa(std::move(adapter)) - { - JSON_ASSERT(oa); - } - - /*! - @param[in] j JSON value to serialize - @pre j.type() == value_t::object - */ - void write_bson(const BasicJsonType& j) - { - switch (j.type()) - { - case value_t::object: - { - write_bson_object(*j.m_value.object); - break; - } - - case value_t::null: - case value_t::array: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j)); - } - } - } - - /*! - @param[in] j JSON value to serialize - */ - void write_cbor(const BasicJsonType& j) - { - switch (j.type()) - { - case value_t::null: - { - oa->write_character(to_char_type(0xF6)); - break; - } - - case value_t::boolean: - { - oa->write_character(j.m_value.boolean - ? to_char_type(0xF5) - : to_char_type(0xF4)); - break; - } - - case value_t::number_integer: - { - if (j.m_value.number_integer >= 0) - { - // CBOR does not differentiate between positive signed - // integers and unsigned integers. Therefore, we used the - // code from the value_t::number_unsigned case here. - if (j.m_value.number_integer <= 0x17) - { - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x18)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x19)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x1A)); - write_number(static_cast(j.m_value.number_integer)); - } - else - { - oa->write_character(to_char_type(0x1B)); - write_number(static_cast(j.m_value.number_integer)); - } - } - else - { - // The conversions below encode the sign in the first - // byte, and the value is converted to a positive number. - const auto positive_number = -1 - j.m_value.number_integer; - if (j.m_value.number_integer >= -24) - { - write_number(static_cast(0x20 + positive_number)); - } - else if (positive_number <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x38)); - write_number(static_cast(positive_number)); - } - else if (positive_number <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x39)); - write_number(static_cast(positive_number)); - } - else if (positive_number <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x3A)); - write_number(static_cast(positive_number)); - } - else - { - oa->write_character(to_char_type(0x3B)); - write_number(static_cast(positive_number)); - } - } - break; - } - - case value_t::number_unsigned: - { - if (j.m_value.number_unsigned <= 0x17) - { - write_number(static_cast(j.m_value.number_unsigned)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x18)); - write_number(static_cast(j.m_value.number_unsigned)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x19)); - write_number(static_cast(j.m_value.number_unsigned)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x1A)); - write_number(static_cast(j.m_value.number_unsigned)); - } - else - { - oa->write_character(to_char_type(0x1B)); - write_number(static_cast(j.m_value.number_unsigned)); - } - break; - } - - case value_t::number_float: - { - if (std::isnan(j.m_value.number_float)) - { - // NaN is 0xf97e00 in CBOR - oa->write_character(to_char_type(0xF9)); - oa->write_character(to_char_type(0x7E)); - oa->write_character(to_char_type(0x00)); - } - else if (std::isinf(j.m_value.number_float)) - { - // Infinity is 0xf97c00, -Infinity is 0xf9fc00 - oa->write_character(to_char_type(0xf9)); - oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC)); - oa->write_character(to_char_type(0x00)); - } - else - { - write_compact_float(j.m_value.number_float, detail::input_format_t::cbor); - } - break; - } - - case value_t::string: - { - // step 1: write control byte and the string length - const auto N = j.m_value.string->size(); - if (N <= 0x17) - { - write_number(static_cast(0x60 + N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x78)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x79)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x7A)); - write_number(static_cast(N)); - } - // LCOV_EXCL_START - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x7B)); - write_number(static_cast(N)); - } - // LCOV_EXCL_STOP - - // step 2: write the string - oa->write_characters( - reinterpret_cast(j.m_value.string->c_str()), - j.m_value.string->size()); - break; - } - - case value_t::array: - { - // step 1: write control byte and the array size - const auto N = j.m_value.array->size(); - if (N <= 0x17) - { - write_number(static_cast(0x80 + N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x98)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x99)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x9A)); - write_number(static_cast(N)); - } - // LCOV_EXCL_START - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x9B)); - write_number(static_cast(N)); - } - // LCOV_EXCL_STOP - - // step 2: write each element - for (const auto& el : *j.m_value.array) - { - write_cbor(el); - } - break; - } - - case value_t::binary: - { - if (j.m_value.binary->has_subtype()) - { - if (j.m_value.binary->subtype() <= (std::numeric_limits::max)()) - { - write_number(static_cast(0xd8)); - write_number(static_cast(j.m_value.binary->subtype())); - } - else if (j.m_value.binary->subtype() <= (std::numeric_limits::max)()) - { - write_number(static_cast(0xd9)); - write_number(static_cast(j.m_value.binary->subtype())); - } - else if (j.m_value.binary->subtype() <= (std::numeric_limits::max)()) - { - write_number(static_cast(0xda)); - write_number(static_cast(j.m_value.binary->subtype())); - } - else if (j.m_value.binary->subtype() <= (std::numeric_limits::max)()) - { - write_number(static_cast(0xdb)); - write_number(static_cast(j.m_value.binary->subtype())); - } - } - - // step 1: write control byte and the binary array size - const auto N = j.m_value.binary->size(); - if (N <= 0x17) - { - write_number(static_cast(0x40 + N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x58)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x59)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x5A)); - write_number(static_cast(N)); - } - // LCOV_EXCL_START - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x5B)); - write_number(static_cast(N)); - } - // LCOV_EXCL_STOP - - // step 2: write each element - oa->write_characters( - reinterpret_cast(j.m_value.binary->data()), - N); - - break; - } - - case value_t::object: - { - // step 1: write control byte and the object size - const auto N = j.m_value.object->size(); - if (N <= 0x17) - { - write_number(static_cast(0xA0 + N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0xB8)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0xB9)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0xBA)); - write_number(static_cast(N)); - } - // LCOV_EXCL_START - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0xBB)); - write_number(static_cast(N)); - } - // LCOV_EXCL_STOP - - // step 2: write each element - for (const auto& el : *j.m_value.object) - { - write_cbor(el.first); - write_cbor(el.second); - } - break; - } - - case value_t::discarded: - default: - break; - } - } - - /*! - @param[in] j JSON value to serialize - */ - void write_msgpack(const BasicJsonType& j) - { - switch (j.type()) - { - case value_t::null: // nil - { - oa->write_character(to_char_type(0xC0)); - break; - } - - case value_t::boolean: // true and false - { - oa->write_character(j.m_value.boolean - ? to_char_type(0xC3) - : to_char_type(0xC2)); - break; - } - - case value_t::number_integer: - { - if (j.m_value.number_integer >= 0) - { - // MessagePack does not differentiate between positive - // signed integers and unsigned integers. Therefore, we used - // the code from the value_t::number_unsigned case here. - if (j.m_value.number_unsigned < 128) - { - // positive fixnum - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 8 - oa->write_character(to_char_type(0xCC)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 16 - oa->write_character(to_char_type(0xCD)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 32 - oa->write_character(to_char_type(0xCE)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 64 - oa->write_character(to_char_type(0xCF)); - write_number(static_cast(j.m_value.number_integer)); - } - } - else - { - if (j.m_value.number_integer >= -32) - { - // negative fixnum - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer >= (std::numeric_limits::min)() && - j.m_value.number_integer <= (std::numeric_limits::max)()) - { - // int 8 - oa->write_character(to_char_type(0xD0)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer >= (std::numeric_limits::min)() && - j.m_value.number_integer <= (std::numeric_limits::max)()) - { - // int 16 - oa->write_character(to_char_type(0xD1)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer >= (std::numeric_limits::min)() && - j.m_value.number_integer <= (std::numeric_limits::max)()) - { - // int 32 - oa->write_character(to_char_type(0xD2)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer >= (std::numeric_limits::min)() && - j.m_value.number_integer <= (std::numeric_limits::max)()) - { - // int 64 - oa->write_character(to_char_type(0xD3)); - write_number(static_cast(j.m_value.number_integer)); - } - } - break; - } - - case value_t::number_unsigned: - { - if (j.m_value.number_unsigned < 128) - { - // positive fixnum - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 8 - oa->write_character(to_char_type(0xCC)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 16 - oa->write_character(to_char_type(0xCD)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 32 - oa->write_character(to_char_type(0xCE)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 64 - oa->write_character(to_char_type(0xCF)); - write_number(static_cast(j.m_value.number_integer)); - } - break; - } - - case value_t::number_float: - { - write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack); - break; - } - - case value_t::string: - { - // step 1: write control byte and the string length - const auto N = j.m_value.string->size(); - if (N <= 31) - { - // fixstr - write_number(static_cast(0xA0 | N)); - } - else if (N <= (std::numeric_limits::max)()) - { - // str 8 - oa->write_character(to_char_type(0xD9)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - // str 16 - oa->write_character(to_char_type(0xDA)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - // str 32 - oa->write_character(to_char_type(0xDB)); - write_number(static_cast(N)); - } - - // step 2: write the string - oa->write_characters( - reinterpret_cast(j.m_value.string->c_str()), - j.m_value.string->size()); - break; - } - - case value_t::array: - { - // step 1: write control byte and the array size - const auto N = j.m_value.array->size(); - if (N <= 15) - { - // fixarray - write_number(static_cast(0x90 | N)); - } - else if (N <= (std::numeric_limits::max)()) - { - // array 16 - oa->write_character(to_char_type(0xDC)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - // array 32 - oa->write_character(to_char_type(0xDD)); - write_number(static_cast(N)); - } - - // step 2: write each element - for (const auto& el : *j.m_value.array) - { - write_msgpack(el); - } - break; - } - - case value_t::binary: - { - // step 0: determine if the binary type has a set subtype to - // determine whether or not to use the ext or fixext types - const bool use_ext = j.m_value.binary->has_subtype(); - - // step 1: write control byte and the byte string length - const auto N = j.m_value.binary->size(); - if (N <= (std::numeric_limits::max)()) - { - std::uint8_t output_type{}; - bool fixed = true; - if (use_ext) - { - switch (N) - { - case 1: - output_type = 0xD4; // fixext 1 - break; - case 2: - output_type = 0xD5; // fixext 2 - break; - case 4: - output_type = 0xD6; // fixext 4 - break; - case 8: - output_type = 0xD7; // fixext 8 - break; - case 16: - output_type = 0xD8; // fixext 16 - break; - default: - output_type = 0xC7; // ext 8 - fixed = false; - break; - } - - } - else - { - output_type = 0xC4; // bin 8 - fixed = false; - } - - oa->write_character(to_char_type(output_type)); - if (!fixed) - { - write_number(static_cast(N)); - } - } - else if (N <= (std::numeric_limits::max)()) - { - std::uint8_t output_type = use_ext - ? 0xC8 // ext 16 - : 0xC5; // bin 16 - - oa->write_character(to_char_type(output_type)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - std::uint8_t output_type = use_ext - ? 0xC9 // ext 32 - : 0xC6; // bin 32 - - oa->write_character(to_char_type(output_type)); - write_number(static_cast(N)); - } - - // step 1.5: if this is an ext type, write the subtype - if (use_ext) - { - write_number(static_cast(j.m_value.binary->subtype())); - } - - // step 2: write the byte string - oa->write_characters( - reinterpret_cast(j.m_value.binary->data()), - N); - - break; - } - - case value_t::object: - { - // step 1: write control byte and the object size - const auto N = j.m_value.object->size(); - if (N <= 15) - { - // fixmap - write_number(static_cast(0x80 | (N & 0xF))); - } - else if (N <= (std::numeric_limits::max)()) - { - // map 16 - oa->write_character(to_char_type(0xDE)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - // map 32 - oa->write_character(to_char_type(0xDF)); - write_number(static_cast(N)); - } - - // step 2: write each element - for (const auto& el : *j.m_value.object) - { - write_msgpack(el.first); - write_msgpack(el.second); - } - break; - } - - case value_t::discarded: - default: - break; - } - } - - /*! - @param[in] j JSON value to serialize - @param[in] use_count whether to use '#' prefixes (optimized format) - @param[in] use_type whether to use '$' prefixes (optimized format) - @param[in] add_prefix whether prefixes need to be used for this value - */ - void write_ubjson(const BasicJsonType& j, const bool use_count, - const bool use_type, const bool add_prefix = true) - { - switch (j.type()) - { - case value_t::null: - { - if (add_prefix) - { - oa->write_character(to_char_type('Z')); - } - break; - } - - case value_t::boolean: - { - if (add_prefix) - { - oa->write_character(j.m_value.boolean - ? to_char_type('T') - : to_char_type('F')); - } - break; - } - - case value_t::number_integer: - { - write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix); - break; - } - - case value_t::number_unsigned: - { - write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix); - break; - } - - case value_t::number_float: - { - write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix); - break; - } - - case value_t::string: - { - if (add_prefix) - { - oa->write_character(to_char_type('S')); - } - write_number_with_ubjson_prefix(j.m_value.string->size(), true); - oa->write_characters( - reinterpret_cast(j.m_value.string->c_str()), - j.m_value.string->size()); - break; - } - - case value_t::array: - { - if (add_prefix) - { - oa->write_character(to_char_type('[')); - } - - bool prefix_required = true; - if (use_type && !j.m_value.array->empty()) - { - JSON_ASSERT(use_count); - const CharType first_prefix = ubjson_prefix(j.front()); - const bool same_prefix = std::all_of(j.begin() + 1, j.end(), - [this, first_prefix](const BasicJsonType & v) - { - return ubjson_prefix(v) == first_prefix; - }); - - if (same_prefix) - { - prefix_required = false; - oa->write_character(to_char_type('$')); - oa->write_character(first_prefix); - } - } - - if (use_count) - { - oa->write_character(to_char_type('#')); - write_number_with_ubjson_prefix(j.m_value.array->size(), true); - } - - for (const auto& el : *j.m_value.array) - { - write_ubjson(el, use_count, use_type, prefix_required); - } - - if (!use_count) - { - oa->write_character(to_char_type(']')); - } - - break; - } - - case value_t::binary: - { - if (add_prefix) - { - oa->write_character(to_char_type('[')); - } - - if (use_type && !j.m_value.binary->empty()) - { - JSON_ASSERT(use_count); - oa->write_character(to_char_type('$')); - oa->write_character('U'); - } - - if (use_count) - { - oa->write_character(to_char_type('#')); - write_number_with_ubjson_prefix(j.m_value.binary->size(), true); - } - - if (use_type) - { - oa->write_characters( - reinterpret_cast(j.m_value.binary->data()), - j.m_value.binary->size()); - } - else - { - for (size_t i = 0; i < j.m_value.binary->size(); ++i) - { - oa->write_character(to_char_type('U')); - oa->write_character(j.m_value.binary->data()[i]); - } - } - - if (!use_count) - { - oa->write_character(to_char_type(']')); - } - - break; - } - - case value_t::object: - { - if (add_prefix) - { - oa->write_character(to_char_type('{')); - } - - bool prefix_required = true; - if (use_type && !j.m_value.object->empty()) - { - JSON_ASSERT(use_count); - const CharType first_prefix = ubjson_prefix(j.front()); - const bool same_prefix = std::all_of(j.begin(), j.end(), - [this, first_prefix](const BasicJsonType & v) - { - return ubjson_prefix(v) == first_prefix; - }); - - if (same_prefix) - { - prefix_required = false; - oa->write_character(to_char_type('$')); - oa->write_character(first_prefix); - } - } - - if (use_count) - { - oa->write_character(to_char_type('#')); - write_number_with_ubjson_prefix(j.m_value.object->size(), true); - } - - for (const auto& el : *j.m_value.object) - { - write_number_with_ubjson_prefix(el.first.size(), true); - oa->write_characters( - reinterpret_cast(el.first.c_str()), - el.first.size()); - write_ubjson(el.second, use_count, use_type, prefix_required); - } - - if (!use_count) - { - oa->write_character(to_char_type('}')); - } - - break; - } - - case value_t::discarded: - default: - break; - } - } - - private: - ////////// - // BSON // - ////////// - - /*! - @return The size of a BSON document entry header, including the id marker - and the entry name size (and its null-terminator). - */ - static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j) - { - const auto it = name.find(static_cast(0)); - if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos)) - { - JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j)); - static_cast(j); - } - - return /*id*/ 1ul + name.size() + /*zero-terminator*/1u; - } - - /*! - @brief Writes the given @a element_type and @a name to the output adapter - */ - void write_bson_entry_header(const string_t& name, - const std::uint8_t element_type) - { - oa->write_character(to_char_type(element_type)); // boolean - oa->write_characters( - reinterpret_cast(name.c_str()), - name.size() + 1u); - } - - /*! - @brief Writes a BSON element with key @a name and boolean value @a value - */ - void write_bson_boolean(const string_t& name, - const bool value) - { - write_bson_entry_header(name, 0x08); - oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00)); - } - - /*! - @brief Writes a BSON element with key @a name and double value @a value - */ - void write_bson_double(const string_t& name, - const double value) - { - write_bson_entry_header(name, 0x01); - write_number(value); - } - - /*! - @return The size of the BSON-encoded string in @a value - */ - static std::size_t calc_bson_string_size(const string_t& value) - { - return sizeof(std::int32_t) + value.size() + 1ul; - } - - /*! - @brief Writes a BSON element with key @a name and string value @a value - */ - void write_bson_string(const string_t& name, - const string_t& value) - { - write_bson_entry_header(name, 0x02); - - write_number(static_cast(value.size() + 1ul)); - oa->write_characters( - reinterpret_cast(value.c_str()), - value.size() + 1); - } - - /*! - @brief Writes a BSON element with key @a name and null value - */ - void write_bson_null(const string_t& name) - { - write_bson_entry_header(name, 0x0A); - } - - /*! - @return The size of the BSON-encoded integer @a value - */ - static std::size_t calc_bson_integer_size(const std::int64_t value) - { - return (std::numeric_limits::min)() <= value && value <= (std::numeric_limits::max)() - ? sizeof(std::int32_t) - : sizeof(std::int64_t); - } - - /*! - @brief Writes a BSON element with key @a name and integer @a value - */ - void write_bson_integer(const string_t& name, - const std::int64_t value) - { - if ((std::numeric_limits::min)() <= value && value <= (std::numeric_limits::max)()) - { - write_bson_entry_header(name, 0x10); // int32 - write_number(static_cast(value)); - } - else - { - write_bson_entry_header(name, 0x12); // int64 - write_number(static_cast(value)); - } - } - - /*! - @return The size of the BSON-encoded unsigned integer in @a j - */ - static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept - { - return (value <= static_cast((std::numeric_limits::max)())) - ? sizeof(std::int32_t) - : sizeof(std::int64_t); - } - - /*! - @brief Writes a BSON element with key @a name and unsigned @a value - */ - void write_bson_unsigned(const string_t& name, - const BasicJsonType& j) - { - if (j.m_value.number_unsigned <= static_cast((std::numeric_limits::max)())) - { - write_bson_entry_header(name, 0x10 /* int32 */); - write_number(static_cast(j.m_value.number_unsigned)); - } - else if (j.m_value.number_unsigned <= static_cast((std::numeric_limits::max)())) - { - write_bson_entry_header(name, 0x12 /* int64 */); - write_number(static_cast(j.m_value.number_unsigned)); - } - else - { - JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(j.m_value.number_unsigned) + " cannot be represented by BSON as it does not fit int64", j)); - } - } - - /*! - @brief Writes a BSON element with key @a name and object @a value - */ - void write_bson_object_entry(const string_t& name, - const typename BasicJsonType::object_t& value) - { - write_bson_entry_header(name, 0x03); // object - write_bson_object(value); - } - - /*! - @return The size of the BSON-encoded array @a value - */ - static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value) - { - std::size_t array_index = 0ul; - - const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el) - { - return result + calc_bson_element_size(std::to_string(array_index++), el); - }); - - return sizeof(std::int32_t) + embedded_document_size + 1ul; - } - - /*! - @return The size of the BSON-encoded binary array @a value - */ - static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value) - { - return sizeof(std::int32_t) + value.size() + 1ul; - } - - /*! - @brief Writes a BSON element with key @a name and array @a value - */ - void write_bson_array(const string_t& name, - const typename BasicJsonType::array_t& value) - { - write_bson_entry_header(name, 0x04); // array - write_number(static_cast(calc_bson_array_size(value))); - - std::size_t array_index = 0ul; - - for (const auto& el : value) - { - write_bson_element(std::to_string(array_index++), el); - } - - oa->write_character(to_char_type(0x00)); - } - - /*! - @brief Writes a BSON element with key @a name and binary value @a value - */ - void write_bson_binary(const string_t& name, - const binary_t& value) - { - write_bson_entry_header(name, 0x05); - - write_number(static_cast(value.size())); - write_number(value.has_subtype() ? static_cast(value.subtype()) : std::uint8_t(0x00)); - - oa->write_characters(reinterpret_cast(value.data()), value.size()); - } - - /*! - @brief Calculates the size necessary to serialize the JSON value @a j with its @a name - @return The calculated size for the BSON document entry for @a j with the given @a name. - */ - static std::size_t calc_bson_element_size(const string_t& name, - const BasicJsonType& j) - { - const auto header_size = calc_bson_entry_header_size(name, j); - switch (j.type()) - { - case value_t::object: - return header_size + calc_bson_object_size(*j.m_value.object); - - case value_t::array: - return header_size + calc_bson_array_size(*j.m_value.array); - - case value_t::binary: - return header_size + calc_bson_binary_size(*j.m_value.binary); - - case value_t::boolean: - return header_size + 1ul; - - case value_t::number_float: - return header_size + 8ul; - - case value_t::number_integer: - return header_size + calc_bson_integer_size(j.m_value.number_integer); - - case value_t::number_unsigned: - return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned); - - case value_t::string: - return header_size + calc_bson_string_size(*j.m_value.string); - - case value_t::null: - return header_size + 0ul; - - // LCOV_EXCL_START - case value_t::discarded: - default: - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) - return 0ul; - // LCOV_EXCL_STOP - } - } - - /*! - @brief Serializes the JSON value @a j to BSON and associates it with the - key @a name. - @param name The name to associate with the JSON entity @a j within the - current BSON document - */ - void write_bson_element(const string_t& name, - const BasicJsonType& j) - { - switch (j.type()) - { - case value_t::object: - return write_bson_object_entry(name, *j.m_value.object); - - case value_t::array: - return write_bson_array(name, *j.m_value.array); - - case value_t::binary: - return write_bson_binary(name, *j.m_value.binary); - - case value_t::boolean: - return write_bson_boolean(name, j.m_value.boolean); - - case value_t::number_float: - return write_bson_double(name, j.m_value.number_float); - - case value_t::number_integer: - return write_bson_integer(name, j.m_value.number_integer); - - case value_t::number_unsigned: - return write_bson_unsigned(name, j); - - case value_t::string: - return write_bson_string(name, *j.m_value.string); - - case value_t::null: - return write_bson_null(name); - - // LCOV_EXCL_START - case value_t::discarded: - default: - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) - return; - // LCOV_EXCL_STOP - } - } - - /*! - @brief Calculates the size of the BSON serialization of the given - JSON-object @a j. - @param[in] value JSON value to serialize - @pre value.type() == value_t::object - */ - static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value) - { - std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0), - [](size_t result, const typename BasicJsonType::object_t::value_type & el) - { - return result += calc_bson_element_size(el.first, el.second); - }); - - return sizeof(std::int32_t) + document_size + 1ul; - } - - /*! - @param[in] value JSON value to serialize - @pre value.type() == value_t::object - */ - void write_bson_object(const typename BasicJsonType::object_t& value) - { - write_number(static_cast(calc_bson_object_size(value))); - - for (const auto& el : value) - { - write_bson_element(el.first, el.second); - } - - oa->write_character(to_char_type(0x00)); - } - - ////////// - // CBOR // - ////////// - - static constexpr CharType get_cbor_float_prefix(float /*unused*/) - { - return to_char_type(0xFA); // Single-Precision Float - } - - static constexpr CharType get_cbor_float_prefix(double /*unused*/) - { - return to_char_type(0xFB); // Double-Precision Float - } - - ///////////// - // MsgPack // - ///////////// - - static constexpr CharType get_msgpack_float_prefix(float /*unused*/) - { - return to_char_type(0xCA); // float 32 - } - - static constexpr CharType get_msgpack_float_prefix(double /*unused*/) - { - return to_char_type(0xCB); // float 64 - } - - //////////// - // UBJSON // - //////////// - - // UBJSON: write number (floating point) - template::value, int>::type = 0> - void write_number_with_ubjson_prefix(const NumberType n, - const bool add_prefix) - { - if (add_prefix) - { - oa->write_character(get_ubjson_float_prefix(n)); - } - write_number(n); - } - - // UBJSON: write number (unsigned integer) - template::value, int>::type = 0> - void write_number_with_ubjson_prefix(const NumberType n, - const bool add_prefix) - { - if (n <= static_cast((std::numeric_limits::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('i')); // int8 - } - write_number(static_cast(n)); - } - else if (n <= (std::numeric_limits::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('U')); // uint8 - } - write_number(static_cast(n)); - } - else if (n <= static_cast((std::numeric_limits::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('I')); // int16 - } - write_number(static_cast(n)); - } - else if (n <= static_cast((std::numeric_limits::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('l')); // int32 - } - write_number(static_cast(n)); - } - else if (n <= static_cast((std::numeric_limits::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('L')); // int64 - } - write_number(static_cast(n)); - } - else - { - if (add_prefix) - { - oa->write_character(to_char_type('H')); // high-precision number - } - - const auto number = BasicJsonType(n).dump(); - write_number_with_ubjson_prefix(number.size(), true); - for (std::size_t i = 0; i < number.size(); ++i) - { - oa->write_character(to_char_type(static_cast(number[i]))); - } - } - } - - // UBJSON: write number (signed integer) - template < typename NumberType, typename std::enable_if < - std::is_signed::value&& - !std::is_floating_point::value, int >::type = 0 > - void write_number_with_ubjson_prefix(const NumberType n, - const bool add_prefix) - { - if ((std::numeric_limits::min)() <= n && n <= (std::numeric_limits::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('i')); // int8 - } - write_number(static_cast(n)); - } - else if (static_cast((std::numeric_limits::min)()) <= n && n <= static_cast((std::numeric_limits::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('U')); // uint8 - } - write_number(static_cast(n)); - } - else if ((std::numeric_limits::min)() <= n && n <= (std::numeric_limits::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('I')); // int16 - } - write_number(static_cast(n)); - } - else if ((std::numeric_limits::min)() <= n && n <= (std::numeric_limits::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('l')); // int32 - } - write_number(static_cast(n)); - } - else if ((std::numeric_limits::min)() <= n && n <= (std::numeric_limits::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('L')); // int64 - } - write_number(static_cast(n)); - } - // LCOV_EXCL_START - else - { - if (add_prefix) - { - oa->write_character(to_char_type('H')); // high-precision number - } - - const auto number = BasicJsonType(n).dump(); - write_number_with_ubjson_prefix(number.size(), true); - for (std::size_t i = 0; i < number.size(); ++i) - { - oa->write_character(to_char_type(static_cast(number[i]))); - } - } - // LCOV_EXCL_STOP - } - - /*! - @brief determine the type prefix of container values - */ - CharType ubjson_prefix(const BasicJsonType& j) const noexcept - { - switch (j.type()) - { - case value_t::null: - return 'Z'; - - case value_t::boolean: - return j.m_value.boolean ? 'T' : 'F'; - - case value_t::number_integer: - { - if ((std::numeric_limits::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits::max)()) - { - return 'i'; - } - if ((std::numeric_limits::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits::max)()) - { - return 'U'; - } - if ((std::numeric_limits::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits::max)()) - { - return 'I'; - } - if ((std::numeric_limits::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits::max)()) - { - return 'l'; - } - if ((std::numeric_limits::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits::max)()) - { - return 'L'; - } - // anything else is treated as high-precision number - return 'H'; // LCOV_EXCL_LINE - } - - case value_t::number_unsigned: - { - if (j.m_value.number_unsigned <= static_cast((std::numeric_limits::max)())) - { - return 'i'; - } - if (j.m_value.number_unsigned <= static_cast((std::numeric_limits::max)())) - { - return 'U'; - } - if (j.m_value.number_unsigned <= static_cast((std::numeric_limits::max)())) - { - return 'I'; - } - if (j.m_value.number_unsigned <= static_cast((std::numeric_limits::max)())) - { - return 'l'; - } - if (j.m_value.number_unsigned <= static_cast((std::numeric_limits::max)())) - { - return 'L'; - } - // anything else is treated as high-precision number - return 'H'; // LCOV_EXCL_LINE - } - - case value_t::number_float: - return get_ubjson_float_prefix(j.m_value.number_float); - - case value_t::string: - return 'S'; - - case value_t::array: // fallthrough - case value_t::binary: - return '['; - - case value_t::object: - return '{'; - - case value_t::discarded: - default: // discarded values - return 'N'; - } - } - - static constexpr CharType get_ubjson_float_prefix(float /*unused*/) - { - return 'd'; // float 32 - } - - static constexpr CharType get_ubjson_float_prefix(double /*unused*/) - { - return 'D'; // float 64 - } - - /////////////////////// - // Utility functions // - /////////////////////// - - /* - @brief write a number to output input - @param[in] n number of type @a NumberType - @tparam NumberType the type of the number - @tparam OutputIsLittleEndian Set to true if output data is - required to be little endian - - @note This function needs to respect the system's endianess, because bytes - in CBOR, MessagePack, and UBJSON are stored in network order (big - endian) and therefore need reordering on little endian systems. - */ - template - void write_number(const NumberType n) - { - // step 1: write number to array of length NumberType - std::array vec{}; - std::memcpy(vec.data(), &n, sizeof(NumberType)); - - // step 2: write array to output (with possible reordering) - if (is_little_endian != OutputIsLittleEndian) - { - // reverse byte order prior to conversion if necessary - std::reverse(vec.begin(), vec.end()); - } - - oa->write_characters(vec.data(), sizeof(NumberType)); - } - - void write_compact_float(const number_float_t n, detail::input_format_t format) - { -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - if (static_cast(n) >= static_cast(std::numeric_limits::lowest()) && - static_cast(n) <= static_cast((std::numeric_limits::max)()) && - static_cast(static_cast(n)) == static_cast(n)) - { - oa->write_character(format == detail::input_format_t::cbor - ? get_cbor_float_prefix(static_cast(n)) - : get_msgpack_float_prefix(static_cast(n))); - write_number(static_cast(n)); - } - else - { - oa->write_character(format == detail::input_format_t::cbor - ? get_cbor_float_prefix(n) - : get_msgpack_float_prefix(n)); - write_number(n); - } -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - } - - public: - // The following to_char_type functions are implement the conversion - // between uint8_t and CharType. In case CharType is not unsigned, - // such a conversion is required to allow values greater than 128. - // See for a discussion. - template < typename C = CharType, - enable_if_t < std::is_signed::value && std::is_signed::value > * = nullptr > - static constexpr CharType to_char_type(std::uint8_t x) noexcept - { - return *reinterpret_cast(&x); - } - - template < typename C = CharType, - enable_if_t < std::is_signed::value && std::is_unsigned::value > * = nullptr > - static CharType to_char_type(std::uint8_t x) noexcept - { - static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t"); - static_assert(std::is_trivial::value, "CharType must be trivial"); - CharType result; - std::memcpy(&result, &x, sizeof(x)); - return result; - } - - template::value>* = nullptr> - static constexpr CharType to_char_type(std::uint8_t x) noexcept - { - return x; - } - - template < typename InputCharType, typename C = CharType, - enable_if_t < - std::is_signed::value && - std::is_signed::value && - std::is_same::type>::value - > * = nullptr > - static constexpr CharType to_char_type(InputCharType x) noexcept - { - return x; - } - - private: - /// whether we can assume little endianess - const bool is_little_endian = little_endianess(); - - /// the output - output_adapter_t oa = nullptr; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - - -#include // reverse, remove, fill, find, none_of -#include // array -#include // localeconv, lconv -#include // labs, isfinite, isnan, signbit -#include // size_t, ptrdiff_t -#include // uint8_t -#include // snprintf -#include // numeric_limits -#include // string, char_traits -#include // is_same -#include // move - -// #include - - -#include // array -#include // signbit, isfinite -#include // intN_t, uintN_t -#include // memcpy, memmove -#include // numeric_limits -#include // conditional - -// #include - - -namespace nlohmann -{ -namespace detail -{ - -/*! -@brief implements the Grisu2 algorithm for binary to decimal floating-point -conversion. - -This implementation is a slightly modified version of the reference -implementation which may be obtained from -http://florian.loitsch.com/publications (bench.tar.gz). - -The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch. - -For a detailed description of the algorithm see: - -[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with - Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming - Language Design and Implementation, PLDI 2010 -[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately", - Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language - Design and Implementation, PLDI 1996 -*/ -namespace dtoa_impl -{ - -template -Target reinterpret_bits(const Source source) -{ - static_assert(sizeof(Target) == sizeof(Source), "size mismatch"); - - Target target; - std::memcpy(&target, &source, sizeof(Source)); - return target; -} - -struct diyfp // f * 2^e -{ - static constexpr int kPrecision = 64; // = q - - std::uint64_t f = 0; - int e = 0; - - constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {} - - /*! - @brief returns x - y - @pre x.e == y.e and x.f >= y.f - */ - static diyfp sub(const diyfp& x, const diyfp& y) noexcept - { - JSON_ASSERT(x.e == y.e); - JSON_ASSERT(x.f >= y.f); - - return {x.f - y.f, x.e}; - } - - /*! - @brief returns x * y - @note The result is rounded. (Only the upper q bits are returned.) - */ - static diyfp mul(const diyfp& x, const diyfp& y) noexcept - { - static_assert(kPrecision == 64, "internal error"); - - // Computes: - // f = round((x.f * y.f) / 2^q) - // e = x.e + y.e + q - - // Emulate the 64-bit * 64-bit multiplication: - // - // p = u * v - // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi) - // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi ) - // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 ) - // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 ) - // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3) - // = (p0_lo ) + 2^32 (Q ) + 2^64 (H ) - // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H ) - // - // (Since Q might be larger than 2^32 - 1) - // - // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H) - // - // (Q_hi + H does not overflow a 64-bit int) - // - // = p_lo + 2^64 p_hi - - const std::uint64_t u_lo = x.f & 0xFFFFFFFFu; - const std::uint64_t u_hi = x.f >> 32u; - const std::uint64_t v_lo = y.f & 0xFFFFFFFFu; - const std::uint64_t v_hi = y.f >> 32u; - - const std::uint64_t p0 = u_lo * v_lo; - const std::uint64_t p1 = u_lo * v_hi; - const std::uint64_t p2 = u_hi * v_lo; - const std::uint64_t p3 = u_hi * v_hi; - - const std::uint64_t p0_hi = p0 >> 32u; - const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu; - const std::uint64_t p1_hi = p1 >> 32u; - const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu; - const std::uint64_t p2_hi = p2 >> 32u; - - std::uint64_t Q = p0_hi + p1_lo + p2_lo; - - // The full product might now be computed as - // - // p_hi = p3 + p2_hi + p1_hi + (Q >> 32) - // p_lo = p0_lo + (Q << 32) - // - // But in this particular case here, the full p_lo is not required. - // Effectively we only need to add the highest bit in p_lo to p_hi (and - // Q_hi + 1 does not overflow). - - Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up - - const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u); - - return {h, x.e + y.e + 64}; - } - - /*! - @brief normalize x such that the significand is >= 2^(q-1) - @pre x.f != 0 - */ - static diyfp normalize(diyfp x) noexcept - { - JSON_ASSERT(x.f != 0); - - while ((x.f >> 63u) == 0) - { - x.f <<= 1u; - x.e--; - } - - return x; - } - - /*! - @brief normalize x such that the result has the exponent E - @pre e >= x.e and the upper e - x.e bits of x.f must be zero. - */ - static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept - { - const int delta = x.e - target_exponent; - - JSON_ASSERT(delta >= 0); - JSON_ASSERT(((x.f << delta) >> delta) == x.f); - - return {x.f << delta, target_exponent}; - } -}; - -struct boundaries -{ - diyfp w; - diyfp minus; - diyfp plus; -}; - -/*! -Compute the (normalized) diyfp representing the input number 'value' and its -boundaries. - -@pre value must be finite and positive -*/ -template -boundaries compute_boundaries(FloatType value) -{ - JSON_ASSERT(std::isfinite(value)); - JSON_ASSERT(value > 0); - - // Convert the IEEE representation into a diyfp. - // - // If v is denormal: - // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1)) - // If v is normalized: - // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1)) - - static_assert(std::numeric_limits::is_iec559, - "internal error: dtoa_short requires an IEEE-754 floating-point implementation"); - - constexpr int kPrecision = std::numeric_limits::digits; // = p (includes the hidden bit) - constexpr int kBias = std::numeric_limits::max_exponent - 1 + (kPrecision - 1); - constexpr int kMinExp = 1 - kBias; - constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1) - - using bits_type = typename std::conditional::type; - - const auto bits = static_cast(reinterpret_bits(value)); - const std::uint64_t E = bits >> (kPrecision - 1); - const std::uint64_t F = bits & (kHiddenBit - 1); - - const bool is_denormal = E == 0; - const diyfp v = is_denormal - ? diyfp(F, kMinExp) - : diyfp(F + kHiddenBit, static_cast(E) - kBias); - - // Compute the boundaries m- and m+ of the floating-point value - // v = f * 2^e. - // - // Determine v- and v+, the floating-point predecessor and successor if v, - // respectively. - // - // v- = v - 2^e if f != 2^(p-1) or e == e_min (A) - // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B) - // - // v+ = v + 2^e - // - // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_ - // between m- and m+ round to v, regardless of how the input rounding - // algorithm breaks ties. - // - // ---+-------------+-------------+-------------+-------------+--- (A) - // v- m- v m+ v+ - // - // -----------------+------+------+-------------+-------------+--- (B) - // v- m- v m+ v+ - - const bool lower_boundary_is_closer = F == 0 && E > 1; - const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1); - const diyfp m_minus = lower_boundary_is_closer - ? diyfp(4 * v.f - 1, v.e - 2) // (B) - : diyfp(2 * v.f - 1, v.e - 1); // (A) - - // Determine the normalized w+ = m+. - const diyfp w_plus = diyfp::normalize(m_plus); - - // Determine w- = m- such that e_(w-) = e_(w+). - const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e); - - return {diyfp::normalize(v), w_minus, w_plus}; -} - -// Given normalized diyfp w, Grisu needs to find a (normalized) cached -// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies -// within a certain range [alpha, gamma] (Definition 3.2 from [1]) -// -// alpha <= e = e_c + e_w + q <= gamma -// -// or -// -// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q -// <= f_c * f_w * 2^gamma -// -// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies -// -// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma -// -// or -// -// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma) -// -// The choice of (alpha,gamma) determines the size of the table and the form of -// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well -// in practice: -// -// The idea is to cut the number c * w = f * 2^e into two parts, which can be -// processed independently: An integral part p1, and a fractional part p2: -// -// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e -// = (f div 2^-e) + (f mod 2^-e) * 2^e -// = p1 + p2 * 2^e -// -// The conversion of p1 into decimal form requires a series of divisions and -// modulos by (a power of) 10. These operations are faster for 32-bit than for -// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be -// achieved by choosing -// -// -e >= 32 or e <= -32 := gamma -// -// In order to convert the fractional part -// -// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ... -// -// into decimal form, the fraction is repeatedly multiplied by 10 and the digits -// d[-i] are extracted in order: -// -// (10 * p2) div 2^-e = d[-1] -// (10 * p2) mod 2^-e = d[-2] / 10^1 + ... -// -// The multiplication by 10 must not overflow. It is sufficient to choose -// -// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64. -// -// Since p2 = f mod 2^-e < 2^-e, -// -// -e <= 60 or e >= -60 := alpha - -constexpr int kAlpha = -60; -constexpr int kGamma = -32; - -struct cached_power // c = f * 2^e ~= 10^k -{ - std::uint64_t f; - int e; - int k; -}; - -/*! -For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached -power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c -satisfies (Definition 3.2 from [1]) - - alpha <= e_c + e + q <= gamma. -*/ -inline cached_power get_cached_power_for_binary_exponent(int e) -{ - // Now - // - // alpha <= e_c + e + q <= gamma (1) - // ==> f_c * 2^alpha <= c * 2^e * 2^q - // - // and since the c's are normalized, 2^(q-1) <= f_c, - // - // ==> 2^(q - 1 + alpha) <= c * 2^(e + q) - // ==> 2^(alpha - e - 1) <= c - // - // If c were an exact power of ten, i.e. c = 10^k, one may determine k as - // - // k = ceil( log_10( 2^(alpha - e - 1) ) ) - // = ceil( (alpha - e - 1) * log_10(2) ) - // - // From the paper: - // "In theory the result of the procedure could be wrong since c is rounded, - // and the computation itself is approximated [...]. In practice, however, - // this simple function is sufficient." - // - // For IEEE double precision floating-point numbers converted into - // normalized diyfp's w = f * 2^e, with q = 64, - // - // e >= -1022 (min IEEE exponent) - // -52 (p - 1) - // -52 (p - 1, possibly normalize denormal IEEE numbers) - // -11 (normalize the diyfp) - // = -1137 - // - // and - // - // e <= +1023 (max IEEE exponent) - // -52 (p - 1) - // -11 (normalize the diyfp) - // = 960 - // - // This binary exponent range [-1137,960] results in a decimal exponent - // range [-307,324]. One does not need to store a cached power for each - // k in this range. For each such k it suffices to find a cached power - // such that the exponent of the product lies in [alpha,gamma]. - // This implies that the difference of the decimal exponents of adjacent - // table entries must be less than or equal to - // - // floor( (gamma - alpha) * log_10(2) ) = 8. - // - // (A smaller distance gamma-alpha would require a larger table.) - - // NB: - // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34. - - constexpr int kCachedPowersMinDecExp = -300; - constexpr int kCachedPowersDecStep = 8; - - static constexpr std::array kCachedPowers = - { - { - { 0xAB70FE17C79AC6CA, -1060, -300 }, - { 0xFF77B1FCBEBCDC4F, -1034, -292 }, - { 0xBE5691EF416BD60C, -1007, -284 }, - { 0x8DD01FAD907FFC3C, -980, -276 }, - { 0xD3515C2831559A83, -954, -268 }, - { 0x9D71AC8FADA6C9B5, -927, -260 }, - { 0xEA9C227723EE8BCB, -901, -252 }, - { 0xAECC49914078536D, -874, -244 }, - { 0x823C12795DB6CE57, -847, -236 }, - { 0xC21094364DFB5637, -821, -228 }, - { 0x9096EA6F3848984F, -794, -220 }, - { 0xD77485CB25823AC7, -768, -212 }, - { 0xA086CFCD97BF97F4, -741, -204 }, - { 0xEF340A98172AACE5, -715, -196 }, - { 0xB23867FB2A35B28E, -688, -188 }, - { 0x84C8D4DFD2C63F3B, -661, -180 }, - { 0xC5DD44271AD3CDBA, -635, -172 }, - { 0x936B9FCEBB25C996, -608, -164 }, - { 0xDBAC6C247D62A584, -582, -156 }, - { 0xA3AB66580D5FDAF6, -555, -148 }, - { 0xF3E2F893DEC3F126, -529, -140 }, - { 0xB5B5ADA8AAFF80B8, -502, -132 }, - { 0x87625F056C7C4A8B, -475, -124 }, - { 0xC9BCFF6034C13053, -449, -116 }, - { 0x964E858C91BA2655, -422, -108 }, - { 0xDFF9772470297EBD, -396, -100 }, - { 0xA6DFBD9FB8E5B88F, -369, -92 }, - { 0xF8A95FCF88747D94, -343, -84 }, - { 0xB94470938FA89BCF, -316, -76 }, - { 0x8A08F0F8BF0F156B, -289, -68 }, - { 0xCDB02555653131B6, -263, -60 }, - { 0x993FE2C6D07B7FAC, -236, -52 }, - { 0xE45C10C42A2B3B06, -210, -44 }, - { 0xAA242499697392D3, -183, -36 }, - { 0xFD87B5F28300CA0E, -157, -28 }, - { 0xBCE5086492111AEB, -130, -20 }, - { 0x8CBCCC096F5088CC, -103, -12 }, - { 0xD1B71758E219652C, -77, -4 }, - { 0x9C40000000000000, -50, 4 }, - { 0xE8D4A51000000000, -24, 12 }, - { 0xAD78EBC5AC620000, 3, 20 }, - { 0x813F3978F8940984, 30, 28 }, - { 0xC097CE7BC90715B3, 56, 36 }, - { 0x8F7E32CE7BEA5C70, 83, 44 }, - { 0xD5D238A4ABE98068, 109, 52 }, - { 0x9F4F2726179A2245, 136, 60 }, - { 0xED63A231D4C4FB27, 162, 68 }, - { 0xB0DE65388CC8ADA8, 189, 76 }, - { 0x83C7088E1AAB65DB, 216, 84 }, - { 0xC45D1DF942711D9A, 242, 92 }, - { 0x924D692CA61BE758, 269, 100 }, - { 0xDA01EE641A708DEA, 295, 108 }, - { 0xA26DA3999AEF774A, 322, 116 }, - { 0xF209787BB47D6B85, 348, 124 }, - { 0xB454E4A179DD1877, 375, 132 }, - { 0x865B86925B9BC5C2, 402, 140 }, - { 0xC83553C5C8965D3D, 428, 148 }, - { 0x952AB45CFA97A0B3, 455, 156 }, - { 0xDE469FBD99A05FE3, 481, 164 }, - { 0xA59BC234DB398C25, 508, 172 }, - { 0xF6C69A72A3989F5C, 534, 180 }, - { 0xB7DCBF5354E9BECE, 561, 188 }, - { 0x88FCF317F22241E2, 588, 196 }, - { 0xCC20CE9BD35C78A5, 614, 204 }, - { 0x98165AF37B2153DF, 641, 212 }, - { 0xE2A0B5DC971F303A, 667, 220 }, - { 0xA8D9D1535CE3B396, 694, 228 }, - { 0xFB9B7CD9A4A7443C, 720, 236 }, - { 0xBB764C4CA7A44410, 747, 244 }, - { 0x8BAB8EEFB6409C1A, 774, 252 }, - { 0xD01FEF10A657842C, 800, 260 }, - { 0x9B10A4E5E9913129, 827, 268 }, - { 0xE7109BFBA19C0C9D, 853, 276 }, - { 0xAC2820D9623BF429, 880, 284 }, - { 0x80444B5E7AA7CF85, 907, 292 }, - { 0xBF21E44003ACDD2D, 933, 300 }, - { 0x8E679C2F5E44FF8F, 960, 308 }, - { 0xD433179D9C8CB841, 986, 316 }, - { 0x9E19DB92B4E31BA9, 1013, 324 }, - } - }; - - // This computation gives exactly the same results for k as - // k = ceil((kAlpha - e - 1) * 0.30102999566398114) - // for |e| <= 1500, but doesn't require floating-point operations. - // NB: log_10(2) ~= 78913 / 2^18 - JSON_ASSERT(e >= -1500); - JSON_ASSERT(e <= 1500); - const int f = kAlpha - e - 1; - const int k = (f * 78913) / (1 << 18) + static_cast(f > 0); - - const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep; - JSON_ASSERT(index >= 0); - JSON_ASSERT(static_cast(index) < kCachedPowers.size()); - - const cached_power cached = kCachedPowers[static_cast(index)]; - JSON_ASSERT(kAlpha <= cached.e + e + 64); - JSON_ASSERT(kGamma >= cached.e + e + 64); - - return cached; -} - -/*! -For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k. -For n == 0, returns 1 and sets pow10 := 1. -*/ -inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10) -{ - // LCOV_EXCL_START - if (n >= 1000000000) - { - pow10 = 1000000000; - return 10; - } - // LCOV_EXCL_STOP - if (n >= 100000000) - { - pow10 = 100000000; - return 9; - } - if (n >= 10000000) - { - pow10 = 10000000; - return 8; - } - if (n >= 1000000) - { - pow10 = 1000000; - return 7; - } - if (n >= 100000) - { - pow10 = 100000; - return 6; - } - if (n >= 10000) - { - pow10 = 10000; - return 5; - } - if (n >= 1000) - { - pow10 = 1000; - return 4; - } - if (n >= 100) - { - pow10 = 100; - return 3; - } - if (n >= 10) - { - pow10 = 10; - return 2; - } - - pow10 = 1; - return 1; -} - -inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta, - std::uint64_t rest, std::uint64_t ten_k) -{ - JSON_ASSERT(len >= 1); - JSON_ASSERT(dist <= delta); - JSON_ASSERT(rest <= delta); - JSON_ASSERT(ten_k > 0); - - // <--------------------------- delta ----> - // <---- dist ---------> - // --------------[------------------+-------------------]-------------- - // M- w M+ - // - // ten_k - // <------> - // <---- rest ----> - // --------------[------------------+----+--------------]-------------- - // w V - // = buf * 10^k - // - // ten_k represents a unit-in-the-last-place in the decimal representation - // stored in buf. - // Decrement buf by ten_k while this takes buf closer to w. - - // The tests are written in this order to avoid overflow in unsigned - // integer arithmetic. - - while (rest < dist - && delta - rest >= ten_k - && (rest + ten_k < dist || dist - rest > rest + ten_k - dist)) - { - JSON_ASSERT(buf[len - 1] != '0'); - buf[len - 1]--; - rest += ten_k; - } -} - -/*! -Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+. -M- and M+ must be normalized and share the same exponent -60 <= e <= -32. -*/ -inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent, - diyfp M_minus, diyfp w, diyfp M_plus) -{ - static_assert(kAlpha >= -60, "internal error"); - static_assert(kGamma <= -32, "internal error"); - - // Generates the digits (and the exponent) of a decimal floating-point - // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's - // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma. - // - // <--------------------------- delta ----> - // <---- dist ---------> - // --------------[------------------+-------------------]-------------- - // M- w M+ - // - // Grisu2 generates the digits of M+ from left to right and stops as soon as - // V is in [M-,M+]. - - JSON_ASSERT(M_plus.e >= kAlpha); - JSON_ASSERT(M_plus.e <= kGamma); - - std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e) - std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e) - - // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0): - // - // M+ = f * 2^e - // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e - // = ((p1 ) * 2^-e + (p2 )) * 2^e - // = p1 + p2 * 2^e - - const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e); - - auto p1 = static_cast(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.) - std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e - - // 1) - // - // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0] - - JSON_ASSERT(p1 > 0); - - std::uint32_t pow10{}; - const int k = find_largest_pow10(p1, pow10); - - // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1) - // - // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1)) - // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1)) - // - // M+ = p1 + p2 * 2^e - // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e - // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e - // = d[k-1] * 10^(k-1) + ( rest) * 2^e - // - // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0) - // - // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0] - // - // but stop as soon as - // - // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e - - int n = k; - while (n > 0) - { - // Invariants: - // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k) - // pow10 = 10^(n-1) <= p1 < 10^n - // - const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1) - const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1) - // - // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e - // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e) - // - JSON_ASSERT(d <= 9); - buffer[length++] = static_cast('0' + d); // buffer := buffer * 10 + d - // - // M+ = buffer * 10^(n-1) + (r + p2 * 2^e) - // - p1 = r; - n--; - // - // M+ = buffer * 10^n + (p1 + p2 * 2^e) - // pow10 = 10^n - // - - // Now check if enough digits have been generated. - // Compute - // - // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e - // - // Note: - // Since rest and delta share the same exponent e, it suffices to - // compare the significands. - const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2; - if (rest <= delta) - { - // V = buffer * 10^n, with M- <= V <= M+. - - decimal_exponent += n; - - // We may now just stop. But instead look if the buffer could be - // decremented to bring V closer to w. - // - // pow10 = 10^n is now 1 ulp in the decimal representation V. - // The rounding procedure works with diyfp's with an implicit - // exponent of e. - // - // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e - // - const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e; - grisu2_round(buffer, length, dist, delta, rest, ten_n); - - return; - } - - pow10 /= 10; - // - // pow10 = 10^(n-1) <= p1 < 10^n - // Invariants restored. - } - - // 2) - // - // The digits of the integral part have been generated: - // - // M+ = d[k-1]...d[1]d[0] + p2 * 2^e - // = buffer + p2 * 2^e - // - // Now generate the digits of the fractional part p2 * 2^e. - // - // Note: - // No decimal point is generated: the exponent is adjusted instead. - // - // p2 actually represents the fraction - // - // p2 * 2^e - // = p2 / 2^-e - // = d[-1] / 10^1 + d[-2] / 10^2 + ... - // - // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...) - // - // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m - // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...) - // - // using - // - // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e) - // = ( d) * 2^-e + ( r) - // - // or - // 10^m * p2 * 2^e = d + r * 2^e - // - // i.e. - // - // M+ = buffer + p2 * 2^e - // = buffer + 10^-m * (d + r * 2^e) - // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e - // - // and stop as soon as 10^-m * r * 2^e <= delta * 2^e - - JSON_ASSERT(p2 > delta); - - int m = 0; - for (;;) - { - // Invariant: - // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e - // = buffer * 10^-m + 10^-m * (p2 ) * 2^e - // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e - // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e - // - JSON_ASSERT(p2 <= (std::numeric_limits::max)() / 10); - p2 *= 10; - const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e - const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e - // - // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e - // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e)) - // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e - // - JSON_ASSERT(d <= 9); - buffer[length++] = static_cast('0' + d); // buffer := buffer * 10 + d - // - // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e - // - p2 = r; - m++; - // - // M+ = buffer * 10^-m + 10^-m * p2 * 2^e - // Invariant restored. - - // Check if enough digits have been generated. - // - // 10^-m * p2 * 2^e <= delta * 2^e - // p2 * 2^e <= 10^m * delta * 2^e - // p2 <= 10^m * delta - delta *= 10; - dist *= 10; - if (p2 <= delta) - { - break; - } - } - - // V = buffer * 10^-m, with M- <= V <= M+. - - decimal_exponent -= m; - - // 1 ulp in the decimal representation is now 10^-m. - // Since delta and dist are now scaled by 10^m, we need to do the - // same with ulp in order to keep the units in sync. - // - // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e - // - const std::uint64_t ten_m = one.f; - grisu2_round(buffer, length, dist, delta, p2, ten_m); - - // By construction this algorithm generates the shortest possible decimal - // number (Loitsch, Theorem 6.2) which rounds back to w. - // For an input number of precision p, at least - // - // N = 1 + ceil(p * log_10(2)) - // - // decimal digits are sufficient to identify all binary floating-point - // numbers (Matula, "In-and-Out conversions"). - // This implies that the algorithm does not produce more than N decimal - // digits. - // - // N = 17 for p = 53 (IEEE double precision) - // N = 9 for p = 24 (IEEE single precision) -} - -/*! -v = buf * 10^decimal_exponent -len is the length of the buffer (number of decimal digits) -The buffer must be large enough, i.e. >= max_digits10. -*/ -JSON_HEDLEY_NON_NULL(1) -inline void grisu2(char* buf, int& len, int& decimal_exponent, - diyfp m_minus, diyfp v, diyfp m_plus) -{ - JSON_ASSERT(m_plus.e == m_minus.e); - JSON_ASSERT(m_plus.e == v.e); - - // --------(-----------------------+-----------------------)-------- (A) - // m- v m+ - // - // --------------------(-----------+-----------------------)-------- (B) - // m- v m+ - // - // First scale v (and m- and m+) such that the exponent is in the range - // [alpha, gamma]. - - const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e); - - const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k - - // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma] - const diyfp w = diyfp::mul(v, c_minus_k); - const diyfp w_minus = diyfp::mul(m_minus, c_minus_k); - const diyfp w_plus = diyfp::mul(m_plus, c_minus_k); - - // ----(---+---)---------------(---+---)---------------(---+---)---- - // w- w w+ - // = c*m- = c*v = c*m+ - // - // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and - // w+ are now off by a small amount. - // In fact: - // - // w - v * 10^k < 1 ulp - // - // To account for this inaccuracy, add resp. subtract 1 ulp. - // - // --------+---[---------------(---+---)---------------]---+-------- - // w- M- w M+ w+ - // - // Now any number in [M-, M+] (bounds included) will round to w when input, - // regardless of how the input rounding algorithm breaks ties. - // - // And digit_gen generates the shortest possible such number in [M-, M+]. - // Note that this does not mean that Grisu2 always generates the shortest - // possible number in the interval (m-, m+). - const diyfp M_minus(w_minus.f + 1, w_minus.e); - const diyfp M_plus (w_plus.f - 1, w_plus.e ); - - decimal_exponent = -cached.k; // = -(-k) = k - - grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus); -} - -/*! -v = buf * 10^decimal_exponent -len is the length of the buffer (number of decimal digits) -The buffer must be large enough, i.e. >= max_digits10. -*/ -template -JSON_HEDLEY_NON_NULL(1) -void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value) -{ - static_assert(diyfp::kPrecision >= std::numeric_limits::digits + 3, - "internal error: not enough precision"); - - JSON_ASSERT(std::isfinite(value)); - JSON_ASSERT(value > 0); - - // If the neighbors (and boundaries) of 'value' are always computed for double-precision - // numbers, all float's can be recovered using strtod (and strtof). However, the resulting - // decimal representations are not exactly "short". - // - // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars) - // says "value is converted to a string as if by std::sprintf in the default ("C") locale" - // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars' - // does. - // On the other hand, the documentation for 'std::to_chars' requires that "parsing the - // representation using the corresponding std::from_chars function recovers value exactly". That - // indicates that single precision floating-point numbers should be recovered using - // 'std::strtof'. - // - // NB: If the neighbors are computed for single-precision numbers, there is a single float - // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision - // value is off by 1 ulp. -#if 0 - const boundaries w = compute_boundaries(static_cast(value)); -#else - const boundaries w = compute_boundaries(value); -#endif - - grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus); -} - -/*! -@brief appends a decimal representation of e to buf -@return a pointer to the element following the exponent. -@pre -1000 < e < 1000 -*/ -JSON_HEDLEY_NON_NULL(1) -JSON_HEDLEY_RETURNS_NON_NULL -inline char* append_exponent(char* buf, int e) -{ - JSON_ASSERT(e > -1000); - JSON_ASSERT(e < 1000); - - if (e < 0) - { - e = -e; - *buf++ = '-'; - } - else - { - *buf++ = '+'; - } - - auto k = static_cast(e); - if (k < 10) - { - // Always print at least two digits in the exponent. - // This is for compatibility with printf("%g"). - *buf++ = '0'; - *buf++ = static_cast('0' + k); - } - else if (k < 100) - { - *buf++ = static_cast('0' + k / 10); - k %= 10; - *buf++ = static_cast('0' + k); - } - else - { - *buf++ = static_cast('0' + k / 100); - k %= 100; - *buf++ = static_cast('0' + k / 10); - k %= 10; - *buf++ = static_cast('0' + k); - } - - return buf; -} - -/*! -@brief prettify v = buf * 10^decimal_exponent - -If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point -notation. Otherwise it will be printed in exponential notation. - -@pre min_exp < 0 -@pre max_exp > 0 -*/ -JSON_HEDLEY_NON_NULL(1) -JSON_HEDLEY_RETURNS_NON_NULL -inline char* format_buffer(char* buf, int len, int decimal_exponent, - int min_exp, int max_exp) -{ - JSON_ASSERT(min_exp < 0); - JSON_ASSERT(max_exp > 0); - - const int k = len; - const int n = len + decimal_exponent; - - // v = buf * 10^(n-k) - // k is the length of the buffer (number of decimal digits) - // n is the position of the decimal point relative to the start of the buffer. - - if (k <= n && n <= max_exp) - { - // digits[000] - // len <= max_exp + 2 - - std::memset(buf + k, '0', static_cast(n) - static_cast(k)); - // Make it look like a floating-point number (#362, #378) - buf[n + 0] = '.'; - buf[n + 1] = '0'; - return buf + (static_cast(n) + 2); - } - - if (0 < n && n <= max_exp) - { - // dig.its - // len <= max_digits10 + 1 - - JSON_ASSERT(k > n); - - std::memmove(buf + (static_cast(n) + 1), buf + n, static_cast(k) - static_cast(n)); - buf[n] = '.'; - return buf + (static_cast(k) + 1U); - } - - if (min_exp < n && n <= 0) - { - // 0.[000]digits - // len <= 2 + (-min_exp - 1) + max_digits10 - - std::memmove(buf + (2 + static_cast(-n)), buf, static_cast(k)); - buf[0] = '0'; - buf[1] = '.'; - std::memset(buf + 2, '0', static_cast(-n)); - return buf + (2U + static_cast(-n) + static_cast(k)); - } - - if (k == 1) - { - // dE+123 - // len <= 1 + 5 - - buf += 1; - } - else - { - // d.igitsE+123 - // len <= max_digits10 + 1 + 5 - - std::memmove(buf + 2, buf + 1, static_cast(k) - 1); - buf[1] = '.'; - buf += 1 + static_cast(k); - } - - *buf++ = 'e'; - return append_exponent(buf, n - 1); -} - -} // namespace dtoa_impl - -/*! -@brief generates a decimal representation of the floating-point number value in [first, last). - -The format of the resulting decimal representation is similar to printf's %g -format. Returns an iterator pointing past-the-end of the decimal representation. - -@note The input number must be finite, i.e. NaN's and Inf's are not supported. -@note The buffer must be large enough. -@note The result is NOT null-terminated. -*/ -template -JSON_HEDLEY_NON_NULL(1, 2) -JSON_HEDLEY_RETURNS_NON_NULL -char* to_chars(char* first, const char* last, FloatType value) -{ - static_cast(last); // maybe unused - fix warning - JSON_ASSERT(std::isfinite(value)); - - // Use signbit(value) instead of (value < 0) since signbit works for -0. - if (std::signbit(value)) - { - value = -value; - *first++ = '-'; - } - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - if (value == 0) // +-0 - { - *first++ = '0'; - // Make it look like a floating-point number (#362, #378) - *first++ = '.'; - *first++ = '0'; - return first; - } -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - - JSON_ASSERT(last - first >= std::numeric_limits::max_digits10); - - // Compute v = buffer * 10^decimal_exponent. - // The decimal digits are stored in the buffer, which needs to be interpreted - // as an unsigned decimal integer. - // len is the length of the buffer, i.e. the number of decimal digits. - int len = 0; - int decimal_exponent = 0; - dtoa_impl::grisu2(first, len, decimal_exponent, value); - - JSON_ASSERT(len <= std::numeric_limits::max_digits10); - - // Format the buffer like printf("%.*g", prec, value) - constexpr int kMinExp = -4; - // Use digits10 here to increase compatibility with version 2. - constexpr int kMaxExp = std::numeric_limits::digits10; - - JSON_ASSERT(last - first >= kMaxExp + 2); - JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits::max_digits10); - JSON_ASSERT(last - first >= std::numeric_limits::max_digits10 + 6); - - return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp); -} - -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - -// #include - -// #include - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -/////////////////// -// serialization // -/////////////////// - -/// how to treat decoding errors -enum class error_handler_t -{ - strict, ///< throw a type_error exception in case of invalid UTF-8 - replace, ///< replace invalid UTF-8 sequences with U+FFFD - ignore ///< ignore invalid UTF-8 sequences -}; - -template -class serializer -{ - using string_t = typename BasicJsonType::string_t; - using number_float_t = typename BasicJsonType::number_float_t; - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using binary_char_t = typename BasicJsonType::binary_t::value_type; - static constexpr std::uint8_t UTF8_ACCEPT = 0; - static constexpr std::uint8_t UTF8_REJECT = 1; - - public: - /*! - @param[in] s output stream to serialize to - @param[in] ichar indentation character to use - @param[in] error_handler_ how to react on decoding errors - */ - serializer(output_adapter_t s, const char ichar, - error_handler_t error_handler_ = error_handler_t::strict) - : o(std::move(s)) - , loc(std::localeconv()) - , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits::to_char_type(* (loc->thousands_sep))) - , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits::to_char_type(* (loc->decimal_point))) - , indent_char(ichar) - , indent_string(512, indent_char) - , error_handler(error_handler_) - {} - - // delete because of pointer members - serializer(const serializer&) = delete; - serializer& operator=(const serializer&) = delete; - serializer(serializer&&) = delete; - serializer& operator=(serializer&&) = delete; - ~serializer() = default; - - /*! - @brief internal implementation of the serialization function - - This function is called by the public member function dump and organizes - the serialization internally. The indentation level is propagated as - additional parameter. In case of arrays and objects, the function is - called recursively. - - - strings and object keys are escaped using `escape_string()` - - integer numbers are converted implicitly via `operator<<` - - floating-point numbers are converted to a string using `"%g"` format - - binary values are serialized as objects containing the subtype and the - byte array - - @param[in] val value to serialize - @param[in] pretty_print whether the output shall be pretty-printed - @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters - in the output are escaped with `\uXXXX` sequences, and the result consists - of ASCII characters only. - @param[in] indent_step the indent level - @param[in] current_indent the current indent level (only used internally) - */ - void dump(const BasicJsonType& val, - const bool pretty_print, - const bool ensure_ascii, - const unsigned int indent_step, - const unsigned int current_indent = 0) - { - switch (val.m_type) - { - case value_t::object: - { - if (val.m_value.object->empty()) - { - o->write_characters("{}", 2); - return; - } - - if (pretty_print) - { - o->write_characters("{\n", 2); - - // variable to hold indentation for recursive calls - const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize(indent_string.size() * 2, ' '); - } - - // first n-1 elements - auto i = val.m_value.object->cbegin(); - for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) - { - o->write_characters(indent_string.c_str(), new_indent); - o->write_character('\"'); - dump_escaped(i->first, ensure_ascii); - o->write_characters("\": ", 3); - dump(i->second, true, ensure_ascii, indent_step, new_indent); - o->write_characters(",\n", 2); - } - - // last element - JSON_ASSERT(i != val.m_value.object->cend()); - JSON_ASSERT(std::next(i) == val.m_value.object->cend()); - o->write_characters(indent_string.c_str(), new_indent); - o->write_character('\"'); - dump_escaped(i->first, ensure_ascii); - o->write_characters("\": ", 3); - dump(i->second, true, ensure_ascii, indent_step, new_indent); - - o->write_character('\n'); - o->write_characters(indent_string.c_str(), current_indent); - o->write_character('}'); - } - else - { - o->write_character('{'); - - // first n-1 elements - auto i = val.m_value.object->cbegin(); - for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) - { - o->write_character('\"'); - dump_escaped(i->first, ensure_ascii); - o->write_characters("\":", 2); - dump(i->second, false, ensure_ascii, indent_step, current_indent); - o->write_character(','); - } - - // last element - JSON_ASSERT(i != val.m_value.object->cend()); - JSON_ASSERT(std::next(i) == val.m_value.object->cend()); - o->write_character('\"'); - dump_escaped(i->first, ensure_ascii); - o->write_characters("\":", 2); - dump(i->second, false, ensure_ascii, indent_step, current_indent); - - o->write_character('}'); - } - - return; - } - - case value_t::array: - { - if (val.m_value.array->empty()) - { - o->write_characters("[]", 2); - return; - } - - if (pretty_print) - { - o->write_characters("[\n", 2); - - // variable to hold indentation for recursive calls - const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize(indent_string.size() * 2, ' '); - } - - // first n-1 elements - for (auto i = val.m_value.array->cbegin(); - i != val.m_value.array->cend() - 1; ++i) - { - o->write_characters(indent_string.c_str(), new_indent); - dump(*i, true, ensure_ascii, indent_step, new_indent); - o->write_characters(",\n", 2); - } - - // last element - JSON_ASSERT(!val.m_value.array->empty()); - o->write_characters(indent_string.c_str(), new_indent); - dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent); - - o->write_character('\n'); - o->write_characters(indent_string.c_str(), current_indent); - o->write_character(']'); - } - else - { - o->write_character('['); - - // first n-1 elements - for (auto i = val.m_value.array->cbegin(); - i != val.m_value.array->cend() - 1; ++i) - { - dump(*i, false, ensure_ascii, indent_step, current_indent); - o->write_character(','); - } - - // last element - JSON_ASSERT(!val.m_value.array->empty()); - dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent); - - o->write_character(']'); - } - - return; - } - - case value_t::string: - { - o->write_character('\"'); - dump_escaped(*val.m_value.string, ensure_ascii); - o->write_character('\"'); - return; - } - - case value_t::binary: - { - if (pretty_print) - { - o->write_characters("{\n", 2); - - // variable to hold indentation for recursive calls - const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize(indent_string.size() * 2, ' '); - } - - o->write_characters(indent_string.c_str(), new_indent); - - o->write_characters("\"bytes\": [", 10); - - if (!val.m_value.binary->empty()) - { - for (auto i = val.m_value.binary->cbegin(); - i != val.m_value.binary->cend() - 1; ++i) - { - dump_integer(*i); - o->write_characters(", ", 2); - } - dump_integer(val.m_value.binary->back()); - } - - o->write_characters("],\n", 3); - o->write_characters(indent_string.c_str(), new_indent); - - o->write_characters("\"subtype\": ", 11); - if (val.m_value.binary->has_subtype()) - { - dump_integer(val.m_value.binary->subtype()); - } - else - { - o->write_characters("null", 4); - } - o->write_character('\n'); - o->write_characters(indent_string.c_str(), current_indent); - o->write_character('}'); - } - else - { - o->write_characters("{\"bytes\":[", 10); - - if (!val.m_value.binary->empty()) - { - for (auto i = val.m_value.binary->cbegin(); - i != val.m_value.binary->cend() - 1; ++i) - { - dump_integer(*i); - o->write_character(','); - } - dump_integer(val.m_value.binary->back()); - } - - o->write_characters("],\"subtype\":", 12); - if (val.m_value.binary->has_subtype()) - { - dump_integer(val.m_value.binary->subtype()); - o->write_character('}'); - } - else - { - o->write_characters("null}", 5); - } - } - return; - } - - case value_t::boolean: - { - if (val.m_value.boolean) - { - o->write_characters("true", 4); - } - else - { - o->write_characters("false", 5); - } - return; - } - - case value_t::number_integer: - { - dump_integer(val.m_value.number_integer); - return; - } - - case value_t::number_unsigned: - { - dump_integer(val.m_value.number_unsigned); - return; - } - - case value_t::number_float: - { - dump_float(val.m_value.number_float); - return; - } - - case value_t::discarded: - { - o->write_characters("", 11); - return; - } - - case value_t::null: - { - o->write_characters("null", 4); - return; - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - } - - JSON_PRIVATE_UNLESS_TESTED: - /*! - @brief dump escaped string - - Escape a string by replacing certain special characters by a sequence of an - escape character (backslash) and another character and other control - characters by a sequence of "\u" followed by a four-digit hex - representation. The escaped string is written to output stream @a o. - - @param[in] s the string to escape - @param[in] ensure_ascii whether to escape non-ASCII characters with - \uXXXX sequences - - @complexity Linear in the length of string @a s. - */ - void dump_escaped(const string_t& s, const bool ensure_ascii) - { - std::uint32_t codepoint{}; - std::uint8_t state = UTF8_ACCEPT; - std::size_t bytes = 0; // number of bytes written to string_buffer - - // number of bytes written at the point of the last valid byte - std::size_t bytes_after_last_accept = 0; - std::size_t undumped_chars = 0; - - for (std::size_t i = 0; i < s.size(); ++i) - { - const auto byte = static_cast(s[i]); - - switch (decode(state, codepoint, byte)) - { - case UTF8_ACCEPT: // decode found a new code point - { - switch (codepoint) - { - case 0x08: // backspace - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'b'; - break; - } - - case 0x09: // horizontal tab - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 't'; - break; - } - - case 0x0A: // newline - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'n'; - break; - } - - case 0x0C: // formfeed - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'f'; - break; - } - - case 0x0D: // carriage return - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'r'; - break; - } - - case 0x22: // quotation mark - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = '\"'; - break; - } - - case 0x5C: // reverse solidus - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = '\\'; - break; - } - - default: - { - // escape control characters (0x00..0x1F) or, if - // ensure_ascii parameter is used, non-ASCII characters - if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F))) - { - if (codepoint <= 0xFFFF) - { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x", - static_cast(codepoint)); - bytes += 6; - } - else - { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x", - static_cast(0xD7C0u + (codepoint >> 10u)), - static_cast(0xDC00u + (codepoint & 0x3FFu))); - bytes += 12; - } - } - else - { - // copy byte to buffer (all previous bytes - // been copied have in default case above) - string_buffer[bytes++] = s[i]; - } - break; - } - } - - // write buffer and reset index; there must be 13 bytes - // left, as this is the maximal number of bytes to be - // written ("\uxxxx\uxxxx\0") for one code point - if (string_buffer.size() - bytes < 13) - { - o->write_characters(string_buffer.data(), bytes); - bytes = 0; - } - - // remember the byte position of this accept - bytes_after_last_accept = bytes; - undumped_chars = 0; - break; - } - - case UTF8_REJECT: // decode found invalid UTF-8 byte - { - switch (error_handler) - { - case error_handler_t::strict: - { - std::string sn(9, '\0'); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - (std::snprintf)(&sn[0], sn.size(), "%.2X", byte); - JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType())); - } - - case error_handler_t::ignore: - case error_handler_t::replace: - { - // in case we saw this character the first time, we - // would like to read it again, because the byte - // may be OK for itself, but just not OK for the - // previous sequence - if (undumped_chars > 0) - { - --i; - } - - // reset length buffer to the last accepted index; - // thus removing/ignoring the invalid characters - bytes = bytes_after_last_accept; - - if (error_handler == error_handler_t::replace) - { - // add a replacement character - if (ensure_ascii) - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'u'; - string_buffer[bytes++] = 'f'; - string_buffer[bytes++] = 'f'; - string_buffer[bytes++] = 'f'; - string_buffer[bytes++] = 'd'; - } - else - { - string_buffer[bytes++] = detail::binary_writer::to_char_type('\xEF'); - string_buffer[bytes++] = detail::binary_writer::to_char_type('\xBF'); - string_buffer[bytes++] = detail::binary_writer::to_char_type('\xBD'); - } - - // write buffer and reset index; there must be 13 bytes - // left, as this is the maximal number of bytes to be - // written ("\uxxxx\uxxxx\0") for one code point - if (string_buffer.size() - bytes < 13) - { - o->write_characters(string_buffer.data(), bytes); - bytes = 0; - } - - bytes_after_last_accept = bytes; - } - - undumped_chars = 0; - - // continue processing the string - state = UTF8_ACCEPT; - break; - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - break; - } - - default: // decode found yet incomplete multi-byte code point - { - if (!ensure_ascii) - { - // code point will not be escaped - copy byte to buffer - string_buffer[bytes++] = s[i]; - } - ++undumped_chars; - break; - } - } - } - - // we finished processing the string - if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT)) - { - // write buffer - if (bytes > 0) - { - o->write_characters(string_buffer.data(), bytes); - } - } - else - { - // we finish reading, but do not accept: string was incomplete - switch (error_handler) - { - case error_handler_t::strict: - { - std::string sn(9, '\0'); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast(s.back())); - JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType())); - } - - case error_handler_t::ignore: - { - // write all accepted bytes - o->write_characters(string_buffer.data(), bytes_after_last_accept); - break; - } - - case error_handler_t::replace: - { - // write all accepted bytes - o->write_characters(string_buffer.data(), bytes_after_last_accept); - // add a replacement character - if (ensure_ascii) - { - o->write_characters("\\ufffd", 6); - } - else - { - o->write_characters("\xEF\xBF\xBD", 3); - } - break; - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - } - } - - private: - /*! - @brief count digits - - Count the number of decimal (base 10) digits for an input unsigned integer. - - @param[in] x unsigned integer number to count its digits - @return number of decimal digits - */ - inline unsigned int count_digits(number_unsigned_t x) noexcept - { - unsigned int n_digits = 1; - for (;;) - { - if (x < 10) - { - return n_digits; - } - if (x < 100) - { - return n_digits + 1; - } - if (x < 1000) - { - return n_digits + 2; - } - if (x < 10000) - { - return n_digits + 3; - } - x = x / 10000u; - n_digits += 4; - } - } - - /*! - @brief dump an integer - - Dump a given integer to output stream @a o. Works internally with - @a number_buffer. - - @param[in] x integer number (signed or unsigned) to dump - @tparam NumberType either @a number_integer_t or @a number_unsigned_t - */ - template < typename NumberType, detail::enable_if_t < - std::is_integral::value || - std::is_same::value || - std::is_same::value || - std::is_same::value, - int > = 0 > - void dump_integer(NumberType x) - { - static constexpr std::array, 100> digits_to_99 - { - { - {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}}, - {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}}, - {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}}, - {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}}, - {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}}, - {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}}, - {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}}, - {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}}, - {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}}, - {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}}, - } - }; - - // special case for "0" - if (x == 0) - { - o->write_character('0'); - return; - } - - // use a pointer to fill the buffer - auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg) - - const bool is_negative = std::is_signed::value && !(x >= 0); // see issue #755 - number_unsigned_t abs_value; - - unsigned int n_chars{}; - - if (is_negative) - { - *buffer_ptr = '-'; - abs_value = remove_sign(static_cast(x)); - - // account one more byte for the minus sign - n_chars = 1 + count_digits(abs_value); - } - else - { - abs_value = static_cast(x); - n_chars = count_digits(abs_value); - } - - // spare 1 byte for '\0' - JSON_ASSERT(n_chars < number_buffer.size() - 1); - - // jump to the end to generate the string from backward - // so we later avoid reversing the result - buffer_ptr += n_chars; - - // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu - // See: https://www.youtube.com/watch?v=o4-CwDo2zpg - while (abs_value >= 100) - { - const auto digits_index = static_cast((abs_value % 100)); - abs_value /= 100; - *(--buffer_ptr) = digits_to_99[digits_index][1]; - *(--buffer_ptr) = digits_to_99[digits_index][0]; - } - - if (abs_value >= 10) - { - const auto digits_index = static_cast(abs_value); - *(--buffer_ptr) = digits_to_99[digits_index][1]; - *(--buffer_ptr) = digits_to_99[digits_index][0]; - } - else - { - *(--buffer_ptr) = static_cast('0' + abs_value); - } - - o->write_characters(number_buffer.data(), n_chars); - } - - /*! - @brief dump a floating-point number - - Dump a given floating-point number to output stream @a o. Works internally - with @a number_buffer. - - @param[in] x floating-point number to dump - */ - void dump_float(number_float_t x) - { - // NaN / inf - if (!std::isfinite(x)) - { - o->write_characters("null", 4); - return; - } - - // If number_float_t is an IEEE-754 single or double precision number, - // use the Grisu2 algorithm to produce short numbers which are - // guaranteed to round-trip, using strtof and strtod, resp. - // - // NB: The test below works if == . - static constexpr bool is_ieee_single_or_double - = (std::numeric_limits::is_iec559 && std::numeric_limits::digits == 24 && std::numeric_limits::max_exponent == 128) || - (std::numeric_limits::is_iec559 && std::numeric_limits::digits == 53 && std::numeric_limits::max_exponent == 1024); - - dump_float(x, std::integral_constant()); - } - - void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/) - { - auto* begin = number_buffer.data(); - auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x); - - o->write_characters(begin, static_cast(end - begin)); - } - - void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/) - { - // get number of digits for a float -> text -> float round-trip - static constexpr auto d = std::numeric_limits::max_digits10; - - // the actual conversion - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x); - - // negative value indicates an error - JSON_ASSERT(len > 0); - // check if buffer was large enough - JSON_ASSERT(static_cast(len) < number_buffer.size()); - - // erase thousands separator - if (thousands_sep != '\0') - { - auto* const end = std::remove(number_buffer.begin(), - number_buffer.begin() + len, thousands_sep); - std::fill(end, number_buffer.end(), '\0'); - JSON_ASSERT((end - number_buffer.begin()) <= len); - len = (end - number_buffer.begin()); - } - - // convert decimal point to '.' - if (decimal_point != '\0' && decimal_point != '.') - { - auto* const dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point); - if (dec_pos != number_buffer.end()) - { - *dec_pos = '.'; - } - } - - o->write_characters(number_buffer.data(), static_cast(len)); - - // determine if need to append ".0" - const bool value_is_int_like = - std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1, - [](char c) - { - return c == '.' || c == 'e'; - }); - - if (value_is_int_like) - { - o->write_characters(".0", 2); - } - } - - /*! - @brief check whether a string is UTF-8 encoded - - The function checks each byte of a string whether it is UTF-8 encoded. The - result of the check is stored in the @a state parameter. The function must - be called initially with state 0 (accept). State 1 means the string must - be rejected, because the current byte is not allowed. If the string is - completely processed, but the state is non-zero, the string ended - prematurely; that is, the last byte indicated more bytes should have - followed. - - @param[in,out] state the state of the decoding - @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT) - @param[in] byte next byte to decode - @return new state - - @note The function has been edited: a std::array is used. - - @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann - @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ - */ - static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept - { - static const std::array utf8d = - { - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF - 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF - 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF - 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF - 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2 - 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4 - 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6 - 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8 - } - }; - - JSON_ASSERT(byte < utf8d.size()); - const std::uint8_t type = utf8d[byte]; - - codep = (state != UTF8_ACCEPT) - ? (byte & 0x3fu) | (codep << 6u) - : (0xFFu >> type) & (byte); - - std::size_t index = 256u + static_cast(state) * 16u + static_cast(type); - JSON_ASSERT(index < 400); - state = utf8d[index]; - return state; - } - - /* - * Overload to make the compiler happy while it is instantiating - * dump_integer for number_unsigned_t. - * Must never be called. - */ - number_unsigned_t remove_sign(number_unsigned_t x) - { - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - return x; // LCOV_EXCL_LINE - } - - /* - * Helper function for dump_integer - * - * This function takes a negative signed integer and returns its absolute - * value as unsigned integer. The plus/minus shuffling is necessary as we can - * not directly remove the sign of an arbitrary signed integer as the - * absolute values of INT_MIN and INT_MAX are usually not the same. See - * #1708 for details. - */ - inline number_unsigned_t remove_sign(number_integer_t x) noexcept - { - JSON_ASSERT(x < 0 && x < (std::numeric_limits::max)()); // NOLINT(misc-redundant-expression) - return static_cast(-(x + 1)) + 1; - } - - private: - /// the output of the serializer - output_adapter_t o = nullptr; - - /// a (hopefully) large enough character buffer - std::array number_buffer{{}}; - - /// the locale - const std::lconv* loc = nullptr; - /// the locale's thousand separator character - const char thousands_sep = '\0'; - /// the locale's decimal point character - const char decimal_point = '\0'; - - /// string buffer - std::array string_buffer{{}}; - - /// the indentation character - const char indent_char; - /// the indentation string - string_t indent_string; - - /// error_handler how to react on decoding errors - const error_handler_t error_handler; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - -// #include - - -#include // less -#include // initializer_list -#include // input_iterator_tag, iterator_traits -#include // allocator -#include // for out_of_range -#include // enable_if, is_convertible -#include // pair -#include // vector - -// #include - - -namespace nlohmann -{ - -/// ordered_map: a minimal map-like container that preserves insertion order -/// for use within nlohmann::basic_json -template , - class Allocator = std::allocator>> - struct ordered_map : std::vector, Allocator> -{ - using key_type = Key; - using mapped_type = T; - using Container = std::vector, Allocator>; - using typename Container::iterator; - using typename Container::const_iterator; - using typename Container::size_type; - using typename Container::value_type; - - // Explicit constructors instead of `using Container::Container` - // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4) - ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {} - template - ordered_map(It first, It last, const Allocator& alloc = Allocator()) - : Container{first, last, alloc} {} - ordered_map(std::initializer_list init, const Allocator& alloc = Allocator() ) - : Container{init, alloc} {} - - std::pair emplace(const key_type& key, T&& t) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return {it, false}; - } - } - Container::emplace_back(key, t); - return {--this->end(), true}; - } - - T& operator[](const Key& key) - { - return emplace(key, T{}).first->second; - } - - const T& operator[](const Key& key) const - { - return at(key); - } - - T& at(const Key& key) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return it->second; - } - } - - JSON_THROW(std::out_of_range("key not found")); - } - - const T& at(const Key& key) const - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return it->second; - } - } - - JSON_THROW(std::out_of_range("key not found")); - } - - size_type erase(const Key& key) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - // Since we cannot move const Keys, re-construct them in place - for (auto next = it; ++next != this->end(); ++it) - { - it->~value_type(); // Destroy but keep allocation - new (&*it) value_type{std::move(*next)}; - } - Container::pop_back(); - return 1; - } - } - return 0; - } - - iterator erase(iterator pos) - { - auto it = pos; - - // Since we cannot move const Keys, re-construct them in place - for (auto next = it; ++next != this->end(); ++it) - { - it->~value_type(); // Destroy but keep allocation - new (&*it) value_type{std::move(*next)}; - } - Container::pop_back(); - return pos; - } - - size_type count(const Key& key) const - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return 1; - } - } - return 0; - } - - iterator find(const Key& key) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return it; - } - } - return Container::end(); - } - - const_iterator find(const Key& key) const - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return it; - } - } - return Container::end(); - } - - std::pair insert( value_type&& value ) - { - return emplace(value.first, std::move(value.second)); - } - - std::pair insert( const value_type& value ) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == value.first) - { - return {it, false}; - } - } - Container::push_back(value); - return {--this->end(), true}; - } - - template - using require_input_iter = typename std::enable_if::iterator_category, - std::input_iterator_tag>::value>::type; - - template> - void insert(InputIt first, InputIt last) - { - for (auto it = first; it != last; ++it) - { - insert(*it); - } - } -}; - -} // namespace nlohmann - - -#if defined(JSON_HAS_CPP_17) - #include -#endif - -/*! -@brief namespace for Niels Lohmann -@see https://github.com/nlohmann -@since version 1.0.0 -*/ -namespace nlohmann -{ - -/*! -@brief a class to store JSON values - -@tparam ObjectType type for JSON objects (`std::map` by default; will be used -in @ref object_t) -@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used -in @ref array_t) -@tparam StringType type for JSON strings and object keys (`std::string` by -default; will be used in @ref string_t) -@tparam BooleanType type for JSON booleans (`bool` by default; will be used -in @ref boolean_t) -@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by -default; will be used in @ref number_integer_t) -@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c -`uint64_t` by default; will be used in @ref number_unsigned_t) -@tparam NumberFloatType type for JSON floating-point numbers (`double` by -default; will be used in @ref number_float_t) -@tparam BinaryType type for packed binary data for compatibility with binary -serialization formats (`std::vector` by default; will be used in -@ref binary_t) -@tparam AllocatorType type of the allocator to use (`std::allocator` by -default) -@tparam JSONSerializer the serializer to resolve internal calls to `to_json()` -and `from_json()` (@ref adl_serializer by default) - -@requirement The class satisfies the following concept requirements: -- Basic - - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible): - JSON values can be default constructed. The result will be a JSON null - value. - - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible): - A JSON value can be constructed from an rvalue argument. - - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible): - A JSON value can be copy-constructed from an lvalue expression. - - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable): - A JSON value van be assigned from an rvalue argument. - - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable): - A JSON value can be copy-assigned from an lvalue expression. - - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible): - JSON values can be destructed. -- Layout - - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType): - JSON values have - [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout): - All non-static data members are private and standard layout types, the - class has no virtual functions or (virtual) base classes. -- Library-wide - - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable): - JSON values can be compared with `==`, see @ref - operator==(const_reference,const_reference). - - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable): - JSON values can be compared with `<`, see @ref - operator<(const_reference,const_reference). - - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable): - Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of - other compatible types, using unqualified function call @ref swap(). - - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer): - JSON values can be compared against `std::nullptr_t` objects which are used - to model the `null` value. -- Container - - [Container](https://en.cppreference.com/w/cpp/named_req/Container): - JSON values can be used like STL containers and provide iterator access. - - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer); - JSON values can be used like STL containers and provide reverse iterator - access. - -@invariant The member variables @a m_value and @a m_type have the following -relationship: -- If `m_type == value_t::object`, then `m_value.object != nullptr`. -- If `m_type == value_t::array`, then `m_value.array != nullptr`. -- If `m_type == value_t::string`, then `m_value.string != nullptr`. -The invariants are checked by member function assert_invariant(). - -@internal -@note ObjectType trick from https://stackoverflow.com/a/9860911 -@endinternal - -@see [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange -Format](https://tools.ietf.org/html/rfc8259) - -@since version 1.0.0 - -@nosubgrouping -*/ -NLOHMANN_BASIC_JSON_TPL_DECLARATION -class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) -{ - private: - template friend struct detail::external_constructor; - friend ::nlohmann::json_pointer; - - template - friend class ::nlohmann::detail::parser; - friend ::nlohmann::detail::serializer; - template - friend class ::nlohmann::detail::iter_impl; - template - friend class ::nlohmann::detail::binary_writer; - template - friend class ::nlohmann::detail::binary_reader; - template - friend class ::nlohmann::detail::json_sax_dom_parser; - template - friend class ::nlohmann::detail::json_sax_dom_callback_parser; - friend class ::nlohmann::detail::exception; - - /// workaround type for MSVC - using basic_json_t = NLOHMANN_BASIC_JSON_TPL; - - JSON_PRIVATE_UNLESS_TESTED: - // convenience aliases for types residing in namespace detail; - using lexer = ::nlohmann::detail::lexer_base; - - template - static ::nlohmann::detail::parser parser( - InputAdapterType adapter, - detail::parser_callback_tcb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false - ) - { - return ::nlohmann::detail::parser(std::move(adapter), - std::move(cb), allow_exceptions, ignore_comments); - } - - private: - using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t; - template - using internal_iterator = ::nlohmann::detail::internal_iterator; - template - using iter_impl = ::nlohmann::detail::iter_impl; - template - using iteration_proxy = ::nlohmann::detail::iteration_proxy; - template using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator; - - template - using output_adapter_t = ::nlohmann::detail::output_adapter_t; - - template - using binary_reader = ::nlohmann::detail::binary_reader; - template using binary_writer = ::nlohmann::detail::binary_writer; - - JSON_PRIVATE_UNLESS_TESTED: - using serializer = ::nlohmann::detail::serializer; - - public: - using value_t = detail::value_t; - /// JSON Pointer, see @ref nlohmann::json_pointer - using json_pointer = ::nlohmann::json_pointer; - template - using json_serializer = JSONSerializer; - /// how to treat decoding errors - using error_handler_t = detail::error_handler_t; - /// how to treat CBOR tags - using cbor_tag_handler_t = detail::cbor_tag_handler_t; - /// helper type for initializer lists of basic_json values - using initializer_list_t = std::initializer_list>; - - using input_format_t = detail::input_format_t; - /// SAX interface type, see @ref nlohmann::json_sax - using json_sax_t = json_sax; - - //////////////// - // exceptions // - //////////////// - - /// @name exceptions - /// Classes to implement user-defined exceptions. - /// @{ - - /// @copydoc detail::exception - using exception = detail::exception; - /// @copydoc detail::parse_error - using parse_error = detail::parse_error; - /// @copydoc detail::invalid_iterator - using invalid_iterator = detail::invalid_iterator; - /// @copydoc detail::type_error - using type_error = detail::type_error; - /// @copydoc detail::out_of_range - using out_of_range = detail::out_of_range; - /// @copydoc detail::other_error - using other_error = detail::other_error; - - /// @} - - - ///////////////////// - // container types // - ///////////////////// - - /// @name container types - /// The canonic container types to use @ref basic_json like any other STL - /// container. - /// @{ - - /// the type of elements in a basic_json container - using value_type = basic_json; - - /// the type of an element reference - using reference = value_type&; - /// the type of an element const reference - using const_reference = const value_type&; - - /// a type to represent differences between iterators - using difference_type = std::ptrdiff_t; - /// a type to represent container sizes - using size_type = std::size_t; - - /// the allocator type - using allocator_type = AllocatorType; - - /// the type of an element pointer - using pointer = typename std::allocator_traits::pointer; - /// the type of an element const pointer - using const_pointer = typename std::allocator_traits::const_pointer; - - /// an iterator for a basic_json container - using iterator = iter_impl; - /// a const iterator for a basic_json container - using const_iterator = iter_impl; - /// a reverse iterator for a basic_json container - using reverse_iterator = json_reverse_iterator; - /// a const reverse iterator for a basic_json container - using const_reverse_iterator = json_reverse_iterator; - - /// @} - - - /*! - @brief returns the allocator associated with the container - */ - static allocator_type get_allocator() - { - return allocator_type(); - } - - /*! - @brief returns version information on the library - - This function returns a JSON object with information about the library, - including the version number and information on the platform and compiler. - - @return JSON object holding version information - key | description - ----------- | --------------- - `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version). - `copyright` | The copyright line for the library as string. - `name` | The name of the library as string. - `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`. - `url` | The URL of the project as string. - `version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string). - - @liveexample{The following code shows an example output of the `meta()` - function.,meta} - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @complexity Constant. - - @since 2.1.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json meta() - { - basic_json result; - - result["copyright"] = "(C) 2013-2021 Niels Lohmann"; - result["name"] = "JSON for Modern C++"; - result["url"] = "https://github.com/nlohmann/json"; - result["version"]["string"] = - std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." + - std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." + - std::to_string(NLOHMANN_JSON_VERSION_PATCH); - result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR; - result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR; - result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH; - -#ifdef _WIN32 - result["platform"] = "win32"; -#elif defined __linux__ - result["platform"] = "linux"; -#elif defined __APPLE__ - result["platform"] = "apple"; -#elif defined __unix__ - result["platform"] = "unix"; -#else - result["platform"] = "unknown"; -#endif - -#if defined(__ICC) || defined(__INTEL_COMPILER) - result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}}; -#elif defined(__clang__) - result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}}; -#elif defined(__GNUC__) || defined(__GNUG__) - result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}}; -#elif defined(__HP_cc) || defined(__HP_aCC) - result["compiler"] = "hp" -#elif defined(__IBMCPP__) - result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}}; -#elif defined(_MSC_VER) - result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}}; -#elif defined(__PGI) - result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}}; -#elif defined(__SUNPRO_CC) - result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}}; -#else - result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}}; -#endif - -#ifdef __cplusplus - result["compiler"]["c++"] = std::to_string(__cplusplus); -#else - result["compiler"]["c++"] = "unknown"; -#endif - return result; - } - - - /////////////////////////// - // JSON value data types // - /////////////////////////// - - /// @name JSON value data types - /// The data types to store a JSON value. These types are derived from - /// the template arguments passed to class @ref basic_json. - /// @{ - -#if defined(JSON_HAS_CPP_14) - // Use transparent comparator if possible, combined with perfect forwarding - // on find() and count() calls prevents unnecessary string construction. - using object_comparator_t = std::less<>; -#else - using object_comparator_t = std::less; -#endif - - /*! - @brief a type for an object - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows: - > An object is an unordered collection of zero or more name/value pairs, - > where a name is a string and a value is a string, number, boolean, null, - > object, or array. - - To store objects in C++, a type is defined by the template parameters - described below. - - @tparam ObjectType the container to store objects (e.g., `std::map` or - `std::unordered_map`) - @tparam StringType the type of the keys or names (e.g., `std::string`). - The comparison function `std::less` is used to order elements - inside the container. - @tparam AllocatorType the allocator to use for objects (e.g., - `std::allocator`) - - #### Default type - - With the default values for @a ObjectType (`std::map`), @a StringType - (`std::string`), and @a AllocatorType (`std::allocator`), the default - value for @a object_t is: - - @code {.cpp} - std::map< - std::string, // key_type - basic_json, // value_type - std::less, // key_compare - std::allocator> // allocator_type - > - @endcode - - #### Behavior - - The choice of @a object_t influences the behavior of the JSON class. With - the default type, objects have the following behavior: - - - When all names are unique, objects will be interoperable in the sense - that all software implementations receiving that object will agree on - the name-value mappings. - - When the names within an object are not unique, it is unspecified which - one of the values for a given key will be chosen. For instance, - `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or - `{"key": 2}`. - - Internally, name/value pairs are stored in lexicographical order of the - names. Objects will also be serialized (see @ref dump) in this order. - For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored - and serialized as `{"a": 2, "b": 1}`. - - When comparing objects, the order of the name/value pairs is irrelevant. - This makes objects interoperable in the sense that they will not be - affected by these differences. For instance, `{"b": 1, "a": 2}` and - `{"a": 2, "b": 1}` will be treated as equal. - - #### Limits - - [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: - > An implementation may set limits on the maximum depth of nesting. - - In this class, the object's limit of nesting is not explicitly constrained. - However, a maximum depth of nesting may be introduced by the compiler or - runtime environment. A theoretical limit can be queried by calling the - @ref max_size function of a JSON object. - - #### Storage - - Objects are stored as pointers in a @ref basic_json type. That is, for any - access to object values, a pointer of type `object_t*` must be - dereferenced. - - @sa see @ref array_t -- type for an array value - - @since version 1.0.0 - - @note The order name/value pairs are added to the object is *not* - preserved by the library. Therefore, iterating an object may return - name/value pairs in a different order than they were originally stored. In - fact, keys will be traversed in alphabetical order as `std::map` with - `std::less` is used by default. Please note this behavior conforms to [RFC - 8259](https://tools.ietf.org/html/rfc8259), because any order implements the - specified "unordered" nature of JSON objects. - */ - using object_t = ObjectType>>; - - /*! - @brief a type for an array - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows: - > An array is an ordered sequence of zero or more values. - - To store objects in C++, a type is defined by the template parameters - explained below. - - @tparam ArrayType container type to store arrays (e.g., `std::vector` or - `std::list`) - @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`) - - #### Default type - - With the default values for @a ArrayType (`std::vector`) and @a - AllocatorType (`std::allocator`), the default value for @a array_t is: - - @code {.cpp} - std::vector< - basic_json, // value_type - std::allocator // allocator_type - > - @endcode - - #### Limits - - [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: - > An implementation may set limits on the maximum depth of nesting. - - In this class, the array's limit of nesting is not explicitly constrained. - However, a maximum depth of nesting may be introduced by the compiler or - runtime environment. A theoretical limit can be queried by calling the - @ref max_size function of a JSON array. - - #### Storage - - Arrays are stored as pointers in a @ref basic_json type. That is, for any - access to array values, a pointer of type `array_t*` must be dereferenced. - - @sa see @ref object_t -- type for an object value - - @since version 1.0.0 - */ - using array_t = ArrayType>; - - /*! - @brief a type for a string - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows: - > A string is a sequence of zero or more Unicode characters. - - To store objects in C++, a type is defined by the template parameter - described below. Unicode values are split by the JSON class into - byte-sized characters during deserialization. - - @tparam StringType the container to store strings (e.g., `std::string`). - Note this container is used for keys/names in objects, see @ref object_t. - - #### Default type - - With the default values for @a StringType (`std::string`), the default - value for @a string_t is: - - @code {.cpp} - std::string - @endcode - - #### Encoding - - Strings are stored in UTF-8 encoding. Therefore, functions like - `std::string::size()` or `std::string::length()` return the number of - bytes in the string rather than the number of characters or glyphs. - - #### String comparison - - [RFC 8259](https://tools.ietf.org/html/rfc8259) states: - > Software implementations are typically required to test names of object - > members for equality. Implementations that transform the textual - > representation into sequences of Unicode code units and then perform the - > comparison numerically, code unit by code unit, are interoperable in the - > sense that implementations will agree in all cases on equality or - > inequality of two strings. For example, implementations that compare - > strings with escaped characters unconverted may incorrectly find that - > `"a\\b"` and `"a\u005Cb"` are not equal. - - This implementation is interoperable as it does compare strings code unit - by code unit. - - #### Storage - - String values are stored as pointers in a @ref basic_json type. That is, - for any access to string values, a pointer of type `string_t*` must be - dereferenced. - - @since version 1.0.0 - */ - using string_t = StringType; - - /*! - @brief a type for a boolean - - [RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a - type which differentiates the two literals `true` and `false`. - - To store objects in C++, a type is defined by the template parameter @a - BooleanType which chooses the type to use. - - #### Default type - - With the default values for @a BooleanType (`bool`), the default value for - @a boolean_t is: - - @code {.cpp} - bool - @endcode - - #### Storage - - Boolean values are stored directly inside a @ref basic_json type. - - @since version 1.0.0 - */ - using boolean_t = BooleanType; - - /*! - @brief a type for a number (integer) - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: - > The representation of numbers is similar to that used in most - > programming languages. A number is represented in base 10 using decimal - > digits. It contains an integer component that may be prefixed with an - > optional minus sign, which may be followed by a fraction part and/or an - > exponent part. Leading zeros are not allowed. (...) Numeric values that - > cannot be represented in the grammar below (such as Infinity and NaN) - > are not permitted. - - This description includes both integer and floating-point numbers. - However, C++ allows more precise storage if it is known whether the number - is a signed integer, an unsigned integer or a floating-point number. - Therefore, three different types, @ref number_integer_t, @ref - number_unsigned_t and @ref number_float_t are used. - - To store integer numbers in C++, a type is defined by the template - parameter @a NumberIntegerType which chooses the type to use. - - #### Default type - - With the default values for @a NumberIntegerType (`int64_t`), the default - value for @a number_integer_t is: - - @code {.cpp} - int64_t - @endcode - - #### Default behavior - - - The restrictions about leading zeros is not enforced in C++. Instead, - leading zeros in integer literals lead to an interpretation as octal - number. Internally, the value will be stored as decimal number. For - instance, the C++ integer literal `010` will be serialized to `8`. - During deserialization, leading zeros yield an error. - - Not-a-number (NaN) values will be serialized to `null`. - - #### Limits - - [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: - > An implementation may set limits on the range and precision of numbers. - - When the default type is used, the maximal integer number that can be - stored is `9223372036854775807` (INT64_MAX) and the minimal integer number - that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers - that are out of range will yield over/underflow when used in a - constructor. During deserialization, too large or small integer numbers - will be automatically be stored as @ref number_unsigned_t or @ref - number_float_t. - - [RFC 8259](https://tools.ietf.org/html/rfc8259) further states: - > Note that when such software is used, numbers that are integers and are - > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense - > that implementations will agree exactly on their numeric values. - - As this range is a subrange of the exactly supported range [INT64_MIN, - INT64_MAX], this class's integer type is interoperable. - - #### Storage - - Integer number values are stored directly inside a @ref basic_json type. - - @sa see @ref number_float_t -- type for number values (floating-point) - - @sa see @ref number_unsigned_t -- type for number values (unsigned integer) - - @since version 1.0.0 - */ - using number_integer_t = NumberIntegerType; - - /*! - @brief a type for a number (unsigned) - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: - > The representation of numbers is similar to that used in most - > programming languages. A number is represented in base 10 using decimal - > digits. It contains an integer component that may be prefixed with an - > optional minus sign, which may be followed by a fraction part and/or an - > exponent part. Leading zeros are not allowed. (...) Numeric values that - > cannot be represented in the grammar below (such as Infinity and NaN) - > are not permitted. - - This description includes both integer and floating-point numbers. - However, C++ allows more precise storage if it is known whether the number - is a signed integer, an unsigned integer or a floating-point number. - Therefore, three different types, @ref number_integer_t, @ref - number_unsigned_t and @ref number_float_t are used. - - To store unsigned integer numbers in C++, a type is defined by the - template parameter @a NumberUnsignedType which chooses the type to use. - - #### Default type - - With the default values for @a NumberUnsignedType (`uint64_t`), the - default value for @a number_unsigned_t is: - - @code {.cpp} - uint64_t - @endcode - - #### Default behavior - - - The restrictions about leading zeros is not enforced in C++. Instead, - leading zeros in integer literals lead to an interpretation as octal - number. Internally, the value will be stored as decimal number. For - instance, the C++ integer literal `010` will be serialized to `8`. - During deserialization, leading zeros yield an error. - - Not-a-number (NaN) values will be serialized to `null`. - - #### Limits - - [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: - > An implementation may set limits on the range and precision of numbers. - - When the default type is used, the maximal integer number that can be - stored is `18446744073709551615` (UINT64_MAX) and the minimal integer - number that can be stored is `0`. Integer numbers that are out of range - will yield over/underflow when used in a constructor. During - deserialization, too large or small integer numbers will be automatically - be stored as @ref number_integer_t or @ref number_float_t. - - [RFC 8259](https://tools.ietf.org/html/rfc8259) further states: - > Note that when such software is used, numbers that are integers and are - > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense - > that implementations will agree exactly on their numeric values. - - As this range is a subrange (when considered in conjunction with the - number_integer_t type) of the exactly supported range [0, UINT64_MAX], - this class's integer type is interoperable. - - #### Storage - - Integer number values are stored directly inside a @ref basic_json type. - - @sa see @ref number_float_t -- type for number values (floating-point) - @sa see @ref number_integer_t -- type for number values (integer) - - @since version 2.0.0 - */ - using number_unsigned_t = NumberUnsignedType; - - /*! - @brief a type for a number (floating-point) - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: - > The representation of numbers is similar to that used in most - > programming languages. A number is represented in base 10 using decimal - > digits. It contains an integer component that may be prefixed with an - > optional minus sign, which may be followed by a fraction part and/or an - > exponent part. Leading zeros are not allowed. (...) Numeric values that - > cannot be represented in the grammar below (such as Infinity and NaN) - > are not permitted. - - This description includes both integer and floating-point numbers. - However, C++ allows more precise storage if it is known whether the number - is a signed integer, an unsigned integer or a floating-point number. - Therefore, three different types, @ref number_integer_t, @ref - number_unsigned_t and @ref number_float_t are used. - - To store floating-point numbers in C++, a type is defined by the template - parameter @a NumberFloatType which chooses the type to use. - - #### Default type - - With the default values for @a NumberFloatType (`double`), the default - value for @a number_float_t is: - - @code {.cpp} - double - @endcode - - #### Default behavior - - - The restrictions about leading zeros is not enforced in C++. Instead, - leading zeros in floating-point literals will be ignored. Internally, - the value will be stored as decimal number. For instance, the C++ - floating-point literal `01.2` will be serialized to `1.2`. During - deserialization, leading zeros yield an error. - - Not-a-number (NaN) values will be serialized to `null`. - - #### Limits - - [RFC 8259](https://tools.ietf.org/html/rfc8259) states: - > This specification allows implementations to set limits on the range and - > precision of numbers accepted. Since software that implements IEEE - > 754-2008 binary64 (double precision) numbers is generally available and - > widely used, good interoperability can be achieved by implementations - > that expect no more precision or range than these provide, in the sense - > that implementations will approximate JSON numbers within the expected - > precision. - - This implementation does exactly follow this approach, as it uses double - precision floating-point numbers. Note values smaller than - `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` - will be stored as NaN internally and be serialized to `null`. - - #### Storage - - Floating-point number values are stored directly inside a @ref basic_json - type. - - @sa see @ref number_integer_t -- type for number values (integer) - - @sa see @ref number_unsigned_t -- type for number values (unsigned integer) - - @since version 1.0.0 - */ - using number_float_t = NumberFloatType; - - /*! - @brief a type for a packed binary type - - This type is a type designed to carry binary data that appears in various - serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and - BSON's generic binary subtype. This type is NOT a part of standard JSON and - exists solely for compatibility with these binary types. As such, it is - simply defined as an ordered sequence of zero or more byte values. - - Additionally, as an implementation detail, the subtype of the binary data is - carried around as a `std::uint8_t`, which is compatible with both of the - binary data formats that use binary subtyping, (though the specific - numbering is incompatible with each other, and it is up to the user to - translate between them). - - [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type - as: - > Major type 2: a byte string. The string's length in bytes is represented - > following the rules for positive integers (major type 0). - - [MessagePack's documentation on the bin type - family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family) - describes this type as: - > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes - > in addition to the size of the byte array. - - [BSON's specifications](http://bsonspec.org/spec.html) describe several - binary types; however, this type is intended to represent the generic binary - type which has the description: - > Generic binary subtype - This is the most commonly used binary subtype and - > should be the 'default' for drivers and tools. - - None of these impose any limitations on the internal representation other - than the basic unit of storage be some type of array whose parts are - decomposable into bytes. - - The default representation of this binary format is a - `std::vector`, which is a very common way to represent a byte - array in modern C++. - - #### Default type - - The default values for @a BinaryType is `std::vector` - - #### Storage - - Binary Arrays are stored as pointers in a @ref basic_json type. That is, - for any access to array values, a pointer of the type `binary_t*` must be - dereferenced. - - #### Notes on subtypes - - - CBOR - - Binary values are represented as byte strings. Subtypes are serialized - as tagged values. - - MessagePack - - If a subtype is given and the binary array contains exactly 1, 2, 4, 8, - or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8) - is used. For other sizes, the ext family (ext8, ext16, ext32) is used. - The subtype is then added as singed 8-bit integer. - - If no subtype is given, the bin family (bin8, bin16, bin32) is used. - - BSON - - If a subtype is given, it is used and added as unsigned 8-bit integer. - - If no subtype is given, the generic binary subtype 0x00 is used. - - @sa see @ref binary -- create a binary array - - @since version 3.8.0 - */ - using binary_t = nlohmann::byte_container_with_subtype; - /// @} - - private: - - /// helper for exception-safe object creation - template - JSON_HEDLEY_RETURNS_NON_NULL - static T* create(Args&& ... args) - { - AllocatorType alloc; - using AllocatorTraits = std::allocator_traits>; - - auto deleter = [&](T * obj) - { - AllocatorTraits::deallocate(alloc, obj, 1); - }; - std::unique_ptr obj(AllocatorTraits::allocate(alloc, 1), deleter); - AllocatorTraits::construct(alloc, obj.get(), std::forward(args)...); - JSON_ASSERT(obj != nullptr); - return obj.release(); - } - - //////////////////////// - // JSON value storage // - //////////////////////// - - JSON_PRIVATE_UNLESS_TESTED: - /*! - @brief a JSON value - - The actual storage for a JSON value of the @ref basic_json class. This - union combines the different storage types for the JSON value types - defined in @ref value_t. - - JSON type | value_t type | used type - --------- | --------------- | ------------------------ - object | object | pointer to @ref object_t - array | array | pointer to @ref array_t - string | string | pointer to @ref string_t - boolean | boolean | @ref boolean_t - number | number_integer | @ref number_integer_t - number | number_unsigned | @ref number_unsigned_t - number | number_float | @ref number_float_t - binary | binary | pointer to @ref binary_t - null | null | *no value is stored* - - @note Variable-length types (objects, arrays, and strings) are stored as - pointers. The size of the union should not exceed 64 bits if the default - value types are used. - - @since version 1.0.0 - */ - union json_value - { - /// object (stored with pointer to save storage) - object_t* object; - /// array (stored with pointer to save storage) - array_t* array; - /// string (stored with pointer to save storage) - string_t* string; - /// binary (stored with pointer to save storage) - binary_t* binary; - /// boolean - boolean_t boolean; - /// number (integer) - number_integer_t number_integer; - /// number (unsigned integer) - number_unsigned_t number_unsigned; - /// number (floating-point) - number_float_t number_float; - - /// default constructor (for null values) - json_value() = default; - /// constructor for booleans - json_value(boolean_t v) noexcept : boolean(v) {} - /// constructor for numbers (integer) - json_value(number_integer_t v) noexcept : number_integer(v) {} - /// constructor for numbers (unsigned) - json_value(number_unsigned_t v) noexcept : number_unsigned(v) {} - /// constructor for numbers (floating-point) - json_value(number_float_t v) noexcept : number_float(v) {} - /// constructor for empty values of a given type - json_value(value_t t) - { - switch (t) - { - case value_t::object: - { - object = create(); - break; - } - - case value_t::array: - { - array = create(); - break; - } - - case value_t::string: - { - string = create(""); - break; - } - - case value_t::binary: - { - binary = create(); - break; - } - - case value_t::boolean: - { - boolean = boolean_t(false); - break; - } - - case value_t::number_integer: - { - number_integer = number_integer_t(0); - break; - } - - case value_t::number_unsigned: - { - number_unsigned = number_unsigned_t(0); - break; - } - - case value_t::number_float: - { - number_float = number_float_t(0.0); - break; - } - - case value_t::null: - { - object = nullptr; // silence warning, see #821 - break; - } - - case value_t::discarded: - default: - { - object = nullptr; // silence warning, see #821 - if (JSON_HEDLEY_UNLIKELY(t == value_t::null)) - { - JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.2", basic_json())); // LCOV_EXCL_LINE - } - break; - } - } - } - - /// constructor for strings - json_value(const string_t& value) - { - string = create(value); - } - - /// constructor for rvalue strings - json_value(string_t&& value) - { - string = create(std::move(value)); - } - - /// constructor for objects - json_value(const object_t& value) - { - object = create(value); - } - - /// constructor for rvalue objects - json_value(object_t&& value) - { - object = create(std::move(value)); - } - - /// constructor for arrays - json_value(const array_t& value) - { - array = create(value); - } - - /// constructor for rvalue arrays - json_value(array_t&& value) - { - array = create(std::move(value)); - } - - /// constructor for binary arrays - json_value(const typename binary_t::container_type& value) - { - binary = create(value); - } - - /// constructor for rvalue binary arrays - json_value(typename binary_t::container_type&& value) - { - binary = create(std::move(value)); - } - - /// constructor for binary arrays (internal type) - json_value(const binary_t& value) - { - binary = create(value); - } - - /// constructor for rvalue binary arrays (internal type) - json_value(binary_t&& value) - { - binary = create(std::move(value)); - } - - void destroy(value_t t) - { - if (t == value_t::array || t == value_t::object) - { - // flatten the current json_value to a heap-allocated stack - std::vector stack; - - // move the top-level items to stack - if (t == value_t::array) - { - stack.reserve(array->size()); - std::move(array->begin(), array->end(), std::back_inserter(stack)); - } - else - { - stack.reserve(object->size()); - for (auto&& it : *object) - { - stack.push_back(std::move(it.second)); - } - } - - while (!stack.empty()) - { - // move the last item to local variable to be processed - basic_json current_item(std::move(stack.back())); - stack.pop_back(); - - // if current_item is array/object, move - // its children to the stack to be processed later - if (current_item.is_array()) - { - std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack)); - - current_item.m_value.array->clear(); - } - else if (current_item.is_object()) - { - for (auto&& it : *current_item.m_value.object) - { - stack.push_back(std::move(it.second)); - } - - current_item.m_value.object->clear(); - } - - // it's now safe that current_item get destructed - // since it doesn't have any children - } - } - - switch (t) - { - case value_t::object: - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, object); - std::allocator_traits::deallocate(alloc, object, 1); - break; - } - - case value_t::array: - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, array); - std::allocator_traits::deallocate(alloc, array, 1); - break; - } - - case value_t::string: - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, string); - std::allocator_traits::deallocate(alloc, string, 1); - break; - } - - case value_t::binary: - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, binary); - std::allocator_traits::deallocate(alloc, binary, 1); - break; - } - - case value_t::null: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::discarded: - default: - { - break; - } - } - } - }; - - private: - /*! - @brief checks the class invariants - - This function asserts the class invariants. It needs to be called at the - end of every constructor to make sure that created objects respect the - invariant. Furthermore, it has to be called each time the type of a JSON - value is changed, because the invariant expresses a relationship between - @a m_type and @a m_value. - - Furthermore, the parent relation is checked for arrays and objects: If - @a check_parents true and the value is an array or object, then the - container's elements must have the current value as parent. - - @param[in] check_parents whether the parent relation should be checked. - The value is true by default and should only be set to false - during destruction of objects when the invariant does not - need to hold. - */ - void assert_invariant(bool check_parents = true) const noexcept - { - JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr); - JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr); - JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr); - JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr); - -#if JSON_DIAGNOSTICS - JSON_TRY - { - // cppcheck-suppress assertWithSideEffect - JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j) - { - return j.m_parent == this; - })); - } - JSON_CATCH(...) {} // LCOV_EXCL_LINE -#endif - static_cast(check_parents); - } - - void set_parents() - { -#if JSON_DIAGNOSTICS - switch (m_type) - { - case value_t::array: - { - for (auto& element : *m_value.array) - { - element.m_parent = this; - } - break; - } - - case value_t::object: - { - for (auto& element : *m_value.object) - { - element.second.m_parent = this; - } - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - break; - } -#endif - } - - iterator set_parents(iterator it, typename iterator::difference_type count) - { -#if JSON_DIAGNOSTICS - for (typename iterator::difference_type i = 0; i < count; ++i) - { - (it + i)->m_parent = this; - } -#else - static_cast(count); -#endif - return it; - } - - reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1)) - { -#if JSON_DIAGNOSTICS - if (old_capacity != std::size_t(-1)) - { - // see https://github.com/nlohmann/json/issues/2838 - JSON_ASSERT(type() == value_t::array); - if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity)) - { - // capacity has changed: update all parents - set_parents(); - return j; - } - } - - // ordered_json uses a vector internally, so pointers could have - // been invalidated; see https://github.com/nlohmann/json/issues/2962 -#ifdef JSON_HEDLEY_MSVC_VERSION -#pragma warning(push ) -#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr -#endif - if (detail::is_ordered_map::value) - { - set_parents(); - return j; - } -#ifdef JSON_HEDLEY_MSVC_VERSION -#pragma warning( pop ) -#endif - - j.m_parent = this; -#else - static_cast(j); - static_cast(old_capacity); -#endif - return j; - } - - public: - ////////////////////////// - // JSON parser callback // - ////////////////////////// - - /*! - @brief parser event types - - The parser callback distinguishes the following events: - - `object_start`: the parser read `{` and started to process a JSON object - - `key`: the parser read a key of a value in an object - - `object_end`: the parser read `}` and finished processing a JSON object - - `array_start`: the parser read `[` and started to process a JSON array - - `array_end`: the parser read `]` and finished processing a JSON array - - `value`: the parser finished reading a JSON value - - @image html callback_events.png "Example when certain parse events are triggered" - - @sa see @ref parser_callback_t for more information and examples - */ - using parse_event_t = detail::parse_event_t; - - /*! - @brief per-element parser callback type - - With a parser callback function, the result of parsing a JSON text can be - influenced. When passed to @ref parse, it is called on certain events - (passed as @ref parse_event_t via parameter @a event) with a set recursion - depth @a depth and context JSON value @a parsed. The return value of the - callback function is a boolean indicating whether the element that emitted - the callback shall be kept or not. - - We distinguish six scenarios (determined by the event type) in which the - callback function can be called. The following table describes the values - of the parameters @a depth, @a event, and @a parsed. - - parameter @a event | description | parameter @a depth | parameter @a parsed - ------------------ | ----------- | ------------------ | ------------------- - parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded - parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key - parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object - parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded - parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array - parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value - - @image html callback_events.png "Example when certain parse events are triggered" - - Discarding a value (i.e., returning `false`) has different effects - depending on the context in which function was called: - - - Discarded values in structured types are skipped. That is, the parser - will behave as if the discarded value was never read. - - In case a value outside a structured type is skipped, it is replaced - with `null`. This case happens if the top-level element is skipped. - - @param[in] depth the depth of the recursion during parsing - - @param[in] event an event of type parse_event_t indicating the context in - the callback function has been called - - @param[in,out] parsed the current intermediate parse result; note that - writing to this value has no effect for parse_event_t::key events - - @return Whether the JSON value which called the function during parsing - should be kept (`true`) or not (`false`). In the latter case, it is either - skipped completely or replaced by an empty discarded object. - - @sa see @ref parse for examples - - @since version 1.0.0 - */ - using parser_callback_t = detail::parser_callback_t; - - ////////////////// - // constructors // - ////////////////// - - /// @name constructors and destructors - /// Constructors of class @ref basic_json, copy/move constructor, copy - /// assignment, static functions creating objects, and the destructor. - /// @{ - - /*! - @brief create an empty value with a given type - - Create an empty JSON value with a given type. The value will be default - initialized with an empty value which depends on the type: - - Value type | initial value - ----------- | ------------- - null | `null` - boolean | `false` - string | `""` - number | `0` - object | `{}` - array | `[]` - binary | empty array - - @param[in] v the type of the value to create - - @complexity Constant. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows the constructor for different @ref - value_t values,basic_json__value_t} - - @sa see @ref clear() -- restores the postcondition of this constructor - - @since version 1.0.0 - */ - basic_json(const value_t v) - : m_type(v), m_value(v) - { - assert_invariant(); - } - - /*! - @brief create a null object - - Create a `null` JSON value. It either takes a null pointer as parameter - (explicitly creating `null`) or no parameter (implicitly creating `null`). - The passed null pointer itself is not read -- it is only used to choose - the right constructor. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this constructor never throws - exceptions. - - @liveexample{The following code shows the constructor with and without a - null pointer parameter.,basic_json__nullptr_t} - - @since version 1.0.0 - */ - basic_json(std::nullptr_t = nullptr) noexcept - : basic_json(value_t::null) - { - assert_invariant(); - } - - /*! - @brief create a JSON value - - This is a "catch all" constructor for all compatible JSON types; that is, - types for which a `to_json()` method exists. The constructor forwards the - parameter @a val to that method (to `json_serializer::to_json` method - with `U = uncvref_t`, to be exact). - - Template type @a CompatibleType includes, but is not limited to, the - following types: - - **arrays**: @ref array_t and all kinds of compatible containers such as - `std::vector`, `std::deque`, `std::list`, `std::forward_list`, - `std::array`, `std::valarray`, `std::set`, `std::unordered_set`, - `std::multiset`, and `std::unordered_multiset` with a `value_type` from - which a @ref basic_json value can be constructed. - - **objects**: @ref object_t and all kinds of compatible associative - containers such as `std::map`, `std::unordered_map`, `std::multimap`, - and `std::unordered_multimap` with a `key_type` compatible to - @ref string_t and a `value_type` from which a @ref basic_json value can - be constructed. - - **strings**: @ref string_t, string literals, and all compatible string - containers can be used. - - **numbers**: @ref number_integer_t, @ref number_unsigned_t, - @ref number_float_t, and all convertible number types such as `int`, - `size_t`, `int64_t`, `float` or `double` can be used. - - **boolean**: @ref boolean_t / `bool` can be used. - - **binary**: @ref binary_t / `std::vector` may be used, - unfortunately because string literals cannot be distinguished from binary - character arrays by the C++ type system, all types compatible with `const - char*` will be directed to the string constructor instead. This is both - for backwards compatibility, and due to the fact that a binary type is not - a standard JSON type. - - See the examples below. - - @tparam CompatibleType a type such that: - - @a CompatibleType is not derived from `std::istream`, - - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move - constructors), - - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments) - - @a CompatibleType is not a @ref basic_json nested type (e.g., - @ref json_pointer, @ref iterator, etc ...) - - `json_serializer` has a `to_json(basic_json_t&, CompatibleType&&)` method - - @tparam U = `uncvref_t` - - @param[in] val the value to be forwarded to the respective constructor - - @complexity Usually linear in the size of the passed @a val, also - depending on the implementation of the called `to_json()` - method. - - @exceptionsafety Depends on the called constructor. For types directly - supported by the library (i.e., all types for which no `to_json()` function - was provided), strong guarantee holds: if an exception is thrown, there are - no changes to any JSON value. - - @liveexample{The following code shows the constructor with several - compatible types.,basic_json__CompatibleType} - - @since version 2.1.0 - */ - template < typename CompatibleType, - typename U = detail::uncvref_t, - detail::enable_if_t < - !detail::is_basic_json::value && detail::is_compatible_type::value, int > = 0 > - basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape) - JSONSerializer::to_json(std::declval(), - std::forward(val)))) - { - JSONSerializer::to_json(*this, std::forward(val)); - set_parents(); - assert_invariant(); - } - - /*! - @brief create a JSON value from an existing one - - This is a constructor for existing @ref basic_json types. - It does not hijack copy/move constructors, since the parameter has different - template arguments than the current ones. - - The constructor tries to convert the internal @ref m_value of the parameter. - - @tparam BasicJsonType a type such that: - - @a BasicJsonType is a @ref basic_json type. - - @a BasicJsonType has different template arguments than @ref basic_json_t. - - @param[in] val the @ref basic_json value to be converted. - - @complexity Usually linear in the size of the passed @a val, also - depending on the implementation of the called `to_json()` - method. - - @exceptionsafety Depends on the called constructor. For types directly - supported by the library (i.e., all types for which no `to_json()` function - was provided), strong guarantee holds: if an exception is thrown, there are - no changes to any JSON value. - - @since version 3.2.0 - */ - template < typename BasicJsonType, - detail::enable_if_t < - detail::is_basic_json::value&& !std::is_same::value, int > = 0 > - basic_json(const BasicJsonType& val) - { - using other_boolean_t = typename BasicJsonType::boolean_t; - using other_number_float_t = typename BasicJsonType::number_float_t; - using other_number_integer_t = typename BasicJsonType::number_integer_t; - using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using other_string_t = typename BasicJsonType::string_t; - using other_object_t = typename BasicJsonType::object_t; - using other_array_t = typename BasicJsonType::array_t; - using other_binary_t = typename BasicJsonType::binary_t; - - switch (val.type()) - { - case value_t::boolean: - JSONSerializer::to_json(*this, val.template get()); - break; - case value_t::number_float: - JSONSerializer::to_json(*this, val.template get()); - break; - case value_t::number_integer: - JSONSerializer::to_json(*this, val.template get()); - break; - case value_t::number_unsigned: - JSONSerializer::to_json(*this, val.template get()); - break; - case value_t::string: - JSONSerializer::to_json(*this, val.template get_ref()); - break; - case value_t::object: - JSONSerializer::to_json(*this, val.template get_ref()); - break; - case value_t::array: - JSONSerializer::to_json(*this, val.template get_ref()); - break; - case value_t::binary: - JSONSerializer::to_json(*this, val.template get_ref()); - break; - case value_t::null: - *this = nullptr; - break; - case value_t::discarded: - m_type = value_t::discarded; - break; - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - set_parents(); - assert_invariant(); - } - - /*! - @brief create a container (array or object) from an initializer list - - Creates a JSON value of type array or object from the passed initializer - list @a init. In case @a type_deduction is `true` (default), the type of - the JSON value to be created is deducted from the initializer list @a init - according to the following rules: - - 1. If the list is empty, an empty JSON object value `{}` is created. - 2. If the list consists of pairs whose first element is a string, a JSON - object value is created where the first elements of the pairs are - treated as keys and the second elements are as values. - 3. In all other cases, an array is created. - - The rules aim to create the best fit between a C++ initializer list and - JSON values. The rationale is as follows: - - 1. The empty initializer list is written as `{}` which is exactly an empty - JSON object. - 2. C++ has no way of describing mapped types other than to list a list of - pairs. As JSON requires that keys must be of type string, rule 2 is the - weakest constraint one can pose on initializer lists to interpret them - as an object. - 3. In all other cases, the initializer list could not be interpreted as - JSON object type, so interpreting it as JSON array type is safe. - - With the rules described above, the following JSON values cannot be - expressed by an initializer list: - - - the empty array (`[]`): use @ref array(initializer_list_t) - with an empty initializer list in this case - - arrays whose elements satisfy rule 2: use @ref - array(initializer_list_t) with the same initializer list - in this case - - @note When used without parentheses around an empty initializer list, @ref - basic_json() is called instead of this function, yielding the JSON null - value. - - @param[in] init initializer list with JSON values - - @param[in] type_deduction internal parameter; when set to `true`, the type - of the JSON value is deducted from the initializer list @a init; when set - to `false`, the type provided via @a manual_type is forced. This mode is - used by the functions @ref array(initializer_list_t) and - @ref object(initializer_list_t). - - @param[in] manual_type internal parameter; when @a type_deduction is set - to `false`, the created JSON value will use the provided type (only @ref - value_t::array and @ref value_t::object are valid); when @a type_deduction - is set to `true`, this parameter has no effect - - @throw type_error.301 if @a type_deduction is `false`, @a manual_type is - `value_t::object`, but @a init contains an element which is not a pair - whose first element is a string. In this case, the constructor could not - create an object. If @a type_deduction would have be `true`, an array - would have been created. See @ref object(initializer_list_t) - for an example. - - @complexity Linear in the size of the initializer list @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The example below shows how JSON values are created from - initializer lists.,basic_json__list_init_t} - - @sa see @ref array(initializer_list_t) -- create a JSON array - value from an initializer list - @sa see @ref object(initializer_list_t) -- create a JSON object - value from an initializer list - - @since version 1.0.0 - */ - basic_json(initializer_list_t init, - bool type_deduction = true, - value_t manual_type = value_t::array) - { - // check if each element is an array with two elements whose first - // element is a string - bool is_an_object = std::all_of(init.begin(), init.end(), - [](const detail::json_ref& element_ref) - { - return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string(); - }); - - // adjust type if type deduction is not wanted - if (!type_deduction) - { - // if array is wanted, do not create an object though possible - if (manual_type == value_t::array) - { - is_an_object = false; - } - - // if object is wanted but impossible, throw an exception - if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object)) - { - JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json())); - } - } - - if (is_an_object) - { - // the initializer list is a list of pairs -> create object - m_type = value_t::object; - m_value = value_t::object; - - for (auto& element_ref : init) - { - auto element = element_ref.moved_or_copied(); - m_value.object->emplace( - std::move(*((*element.m_value.array)[0].m_value.string)), - std::move((*element.m_value.array)[1])); - } - } - else - { - // the initializer list describes an array -> create array - m_type = value_t::array; - m_value.array = create(init.begin(), init.end()); - } - - set_parents(); - assert_invariant(); - } - - /*! - @brief explicitly create a binary array (without subtype) - - Creates a JSON binary array value from a given binary container. Binary - values are part of various binary formats, such as CBOR, MessagePack, and - BSON. This constructor is used to create a value for serialization to those - formats. - - @note Note, this function exists because of the difficulty in correctly - specifying the correct template overload in the standard value ctor, as both - JSON arrays and JSON binary arrays are backed with some form of a - `std::vector`. Because JSON binary arrays are a non-standard extension it - was decided that it would be best to prevent automatic initialization of a - binary array type, for backwards compatibility and so it does not happen on - accident. - - @param[in] init container containing bytes to use as binary type - - @return JSON binary array value - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @since version 3.8.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary(const typename binary_t::container_type& init) - { - auto res = basic_json(); - res.m_type = value_t::binary; - res.m_value = init; - return res; - } - - /*! - @brief explicitly create a binary array (with subtype) - - Creates a JSON binary array value from a given binary container. Binary - values are part of various binary formats, such as CBOR, MessagePack, and - BSON. This constructor is used to create a value for serialization to those - formats. - - @note Note, this function exists because of the difficulty in correctly - specifying the correct template overload in the standard value ctor, as both - JSON arrays and JSON binary arrays are backed with some form of a - `std::vector`. Because JSON binary arrays are a non-standard extension it - was decided that it would be best to prevent automatic initialization of a - binary array type, for backwards compatibility and so it does not happen on - accident. - - @param[in] init container containing bytes to use as binary type - @param[in] subtype subtype to use in MessagePack and BSON - - @return JSON binary array value - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @since version 3.8.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype) - { - auto res = basic_json(); - res.m_type = value_t::binary; - res.m_value = binary_t(init, subtype); - return res; - } - - /// @copydoc binary(const typename binary_t::container_type&) - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary(typename binary_t::container_type&& init) - { - auto res = basic_json(); - res.m_type = value_t::binary; - res.m_value = std::move(init); - return res; - } - - /// @copydoc binary(const typename binary_t::container_type&, typename binary_t::subtype_type) - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype) - { - auto res = basic_json(); - res.m_type = value_t::binary; - res.m_value = binary_t(std::move(init), subtype); - return res; - } - - /*! - @brief explicitly create an array from an initializer list - - Creates a JSON array value from a given initializer list. That is, given a - list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the - initializer list is empty, the empty array `[]` is created. - - @note This function is only needed to express two edge cases that cannot - be realized with the initializer list constructor (@ref - basic_json(initializer_list_t, bool, value_t)). These cases - are: - 1. creating an array whose elements are all pairs whose first element is a - string -- in this case, the initializer list constructor would create an - object, taking the first elements as keys - 2. creating an empty array -- passing the empty initializer list to the - initializer list constructor yields an empty object - - @param[in] init initializer list with JSON values to create an array from - (optional) - - @return JSON array value - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows an example for the `array` - function.,array} - - @sa see @ref basic_json(initializer_list_t, bool, value_t) -- - create a JSON value from an initializer list - @sa see @ref object(initializer_list_t) -- create a JSON object - value from an initializer list - - @since version 1.0.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json array(initializer_list_t init = {}) - { - return basic_json(init, false, value_t::array); - } - - /*! - @brief explicitly create an object from an initializer list - - Creates a JSON object value from a given initializer list. The initializer - lists elements must be pairs, and their first elements must be strings. If - the initializer list is empty, the empty object `{}` is created. - - @note This function is only added for symmetry reasons. In contrast to the - related function @ref array(initializer_list_t), there are - no cases which can only be expressed by this function. That is, any - initializer list @a init can also be passed to the initializer list - constructor @ref basic_json(initializer_list_t, bool, value_t). - - @param[in] init initializer list to create an object from (optional) - - @return JSON object value - - @throw type_error.301 if @a init is not a list of pairs whose first - elements are strings. In this case, no object can be created. When such a - value is passed to @ref basic_json(initializer_list_t, bool, value_t), - an array would have been created from the passed initializer list @a init. - See example below. - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows an example for the `object` - function.,object} - - @sa see @ref basic_json(initializer_list_t, bool, value_t) -- - create a JSON value from an initializer list - @sa see @ref array(initializer_list_t) -- create a JSON array - value from an initializer list - - @since version 1.0.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json object(initializer_list_t init = {}) - { - return basic_json(init, false, value_t::object); - } - - /*! - @brief construct an array with count copies of given value - - Constructs a JSON array value by creating @a cnt copies of a passed value. - In case @a cnt is `0`, an empty array is created. - - @param[in] cnt the number of JSON copies of @a val to create - @param[in] val the JSON value to copy - - @post `std::distance(begin(),end()) == cnt` holds. - - @complexity Linear in @a cnt. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows examples for the @ref - basic_json(size_type\, const basic_json&) - constructor.,basic_json__size_type_basic_json} - - @since version 1.0.0 - */ - basic_json(size_type cnt, const basic_json& val) - : m_type(value_t::array) - { - m_value.array = create(cnt, val); - set_parents(); - assert_invariant(); - } - - /*! - @brief construct a JSON container given an iterator range - - Constructs the JSON value with the contents of the range `[first, last)`. - The semantics depends on the different types a JSON value can have: - - In case of a null type, invalid_iterator.206 is thrown. - - In case of other primitive types (number, boolean, or string), @a first - must be `begin()` and @a last must be `end()`. In this case, the value is - copied. Otherwise, invalid_iterator.204 is thrown. - - In case of structured types (array, object), the constructor behaves as - similar versions for `std::vector` or `std::map`; that is, a JSON array - or object is constructed from the values in the range. - - @tparam InputIT an input iterator type (@ref iterator or @ref - const_iterator) - - @param[in] first begin of the range to copy from (included) - @param[in] last end of the range to copy from (excluded) - - @pre Iterators @a first and @a last must be initialized. **This - precondition is enforced with an assertion (see warning).** If - assertions are switched off, a violation of this precondition yields - undefined behavior. - - @pre Range `[first, last)` is valid. Usually, this precondition cannot be - checked efficiently. Only certain edge cases are detected; see the - description of the exceptions below. A violation of this precondition - yields undefined behavior. - - @warning A precondition is enforced with a runtime assertion that will - result in calling `std::abort` if this precondition is not met. - Assertions can be disabled by defining `NDEBUG` at compile time. - See https://en.cppreference.com/w/cpp/error/assert for more - information. - - @throw invalid_iterator.201 if iterators @a first and @a last are not - compatible (i.e., do not belong to the same JSON value). In this case, - the range `[first, last)` is undefined. - @throw invalid_iterator.204 if iterators @a first and @a last belong to a - primitive type (number, boolean, or string), but @a first does not point - to the first element any more. In this case, the range `[first, last)` is - undefined. See example code below. - @throw invalid_iterator.206 if iterators @a first and @a last belong to a - null value. In this case, the range `[first, last)` is undefined. - - @complexity Linear in distance between @a first and @a last. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The example below shows several ways to create JSON values by - specifying a subrange with iterators.,basic_json__InputIt_InputIt} - - @since version 1.0.0 - */ - template < class InputIT, typename std::enable_if < - std::is_same::value || - std::is_same::value, int >::type = 0 > - basic_json(InputIT first, InputIT last) - { - JSON_ASSERT(first.m_object != nullptr); - JSON_ASSERT(last.m_object != nullptr); - - // make sure iterator fits the current value - if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) - { - JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json())); - } - - // copy type from first iterator - m_type = first.m_object->m_type; - - // check if iterator range is complete for primitive values - switch (m_type) - { - case value_t::boolean: - case value_t::number_float: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::string: - { - if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin() - || !last.m_it.primitive_iterator.is_end())) - { - JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object)); - } - break; - } - - case value_t::null: - case value_t::object: - case value_t::array: - case value_t::binary: - case value_t::discarded: - default: - break; - } - - switch (m_type) - { - case value_t::number_integer: - { - m_value.number_integer = first.m_object->m_value.number_integer; - break; - } - - case value_t::number_unsigned: - { - m_value.number_unsigned = first.m_object->m_value.number_unsigned; - break; - } - - case value_t::number_float: - { - m_value.number_float = first.m_object->m_value.number_float; - break; - } - - case value_t::boolean: - { - m_value.boolean = first.m_object->m_value.boolean; - break; - } - - case value_t::string: - { - m_value = *first.m_object->m_value.string; - break; - } - - case value_t::object: - { - m_value.object = create(first.m_it.object_iterator, - last.m_it.object_iterator); - break; - } - - case value_t::array: - { - m_value.array = create(first.m_it.array_iterator, - last.m_it.array_iterator); - break; - } - - case value_t::binary: - { - m_value = *first.m_object->m_value.binary; - break; - } - - case value_t::null: - case value_t::discarded: - default: - JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object)); - } - - set_parents(); - assert_invariant(); - } - - - /////////////////////////////////////// - // other constructors and destructor // - /////////////////////////////////////// - - template, - std::is_same>::value, int> = 0 > - basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {} - - /*! - @brief copy constructor - - Creates a copy of a given JSON value. - - @param[in] other the JSON value to copy - - @post `*this == other` - - @complexity Linear in the size of @a other. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is linear. - - As postcondition, it holds: `other == basic_json(other)`. - - @liveexample{The following code shows an example for the copy - constructor.,basic_json__basic_json} - - @since version 1.0.0 - */ - basic_json(const basic_json& other) - : m_type(other.m_type) - { - // check of passed value is valid - other.assert_invariant(); - - switch (m_type) - { - case value_t::object: - { - m_value = *other.m_value.object; - break; - } - - case value_t::array: - { - m_value = *other.m_value.array; - break; - } - - case value_t::string: - { - m_value = *other.m_value.string; - break; - } - - case value_t::boolean: - { - m_value = other.m_value.boolean; - break; - } - - case value_t::number_integer: - { - m_value = other.m_value.number_integer; - break; - } - - case value_t::number_unsigned: - { - m_value = other.m_value.number_unsigned; - break; - } - - case value_t::number_float: - { - m_value = other.m_value.number_float; - break; - } - - case value_t::binary: - { - m_value = *other.m_value.binary; - break; - } - - case value_t::null: - case value_t::discarded: - default: - break; - } - - set_parents(); - assert_invariant(); - } - - /*! - @brief move constructor - - Move constructor. Constructs a JSON value with the contents of the given - value @a other using move semantics. It "steals" the resources from @a - other and leaves it as JSON null value. - - @param[in,out] other value to move to this object - - @post `*this` has the same value as @a other before the call. - @post @a other is a JSON null value. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this constructor never throws - exceptions. - - @requirement This function helps `basic_json` satisfying the - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible) - requirements. - - @liveexample{The code below shows the move constructor explicitly called - via std::move.,basic_json__moveconstructor} - - @since version 1.0.0 - */ - basic_json(basic_json&& other) noexcept - : m_type(std::move(other.m_type)), - m_value(std::move(other.m_value)) - { - // check that passed value is valid - other.assert_invariant(false); - - // invalidate payload - other.m_type = value_t::null; - other.m_value = {}; - - set_parents(); - assert_invariant(); - } - - /*! - @brief copy assignment - - Copy assignment operator. Copies a JSON value via the "copy and swap" - strategy: It is expressed in terms of the copy constructor, destructor, - and the `swap()` member function. - - @param[in] other value to copy from - - @complexity Linear. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is linear. - - @liveexample{The code below shows and example for the copy assignment. It - creates a copy of value `a` which is then swapped with `b`. Finally\, the - copy of `a` (which is the null value after the swap) is - destroyed.,basic_json__copyassignment} - - @since version 1.0.0 - */ - basic_json& operator=(basic_json other) noexcept ( - std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_assignable::value&& - std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_assignable::value - ) - { - // check that passed value is valid - other.assert_invariant(); - - using std::swap; - swap(m_type, other.m_type); - swap(m_value, other.m_value); - - set_parents(); - assert_invariant(); - return *this; - } - - /*! - @brief destructor - - Destroys the JSON value and frees all allocated memory. - - @complexity Linear. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is linear. - - All stored elements are destroyed and all memory is freed. - - @since version 1.0.0 - */ - ~basic_json() noexcept - { - assert_invariant(false); - m_value.destroy(m_type); - } - - /// @} - - public: - /////////////////////// - // object inspection // - /////////////////////// - - /// @name object inspection - /// Functions to inspect the type of a JSON value. - /// @{ - - /*! - @brief serialization - - Serialization function for JSON values. The function tries to mimic - Python's `json.dumps()` function, and currently supports its @a indent - and @a ensure_ascii parameters. - - @param[in] indent If indent is nonnegative, then array elements and object - members will be pretty-printed with that indent level. An indent level of - `0` will only insert newlines. `-1` (the default) selects the most compact - representation. - @param[in] indent_char The character to use for indentation if @a indent is - greater than `0`. The default is ` ` (space). - @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters - in the output are escaped with `\uXXXX` sequences, and the result consists - of ASCII characters only. - @param[in] error_handler how to react on decoding errors; there are three - possible values: `strict` (throws and exception in case a decoding error - occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD), - and `ignore` (ignore invalid UTF-8 sequences during serialization; all - bytes are copied to the output unchanged). - - @return string containing the serialization of the JSON value - - @throw type_error.316 if a string stored inside the JSON value is not - UTF-8 encoded and @a error_handler is set to strict - - @note Binary values are serialized as object containing two keys: - - "bytes": an array of bytes as integers - - "subtype": the subtype as integer or "null" if the binary has no subtype - - @complexity Linear. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @liveexample{The following example shows the effect of different @a indent\, - @a indent_char\, and @a ensure_ascii parameters to the result of the - serialization.,dump} - - @see https://docs.python.org/2/library/json.html#json.dump - - @since version 1.0.0; indentation character @a indent_char, option - @a ensure_ascii and exceptions added in version 3.0.0; error - handlers added in version 3.4.0; serialization of binary values added - in version 3.8.0. - */ - string_t dump(const int indent = -1, - const char indent_char = ' ', - const bool ensure_ascii = false, - const error_handler_t error_handler = error_handler_t::strict) const - { - string_t result; - serializer s(detail::output_adapter(result), indent_char, error_handler); - - if (indent >= 0) - { - s.dump(*this, true, ensure_ascii, static_cast(indent)); - } - else - { - s.dump(*this, false, ensure_ascii, 0); - } - - return result; - } - - /*! - @brief return the type of the JSON value (explicit) - - Return the type of the JSON value as a value from the @ref value_t - enumeration. - - @return the type of the JSON value - Value type | return value - ------------------------- | ------------------------- - null | value_t::null - boolean | value_t::boolean - string | value_t::string - number (integer) | value_t::number_integer - number (unsigned integer) | value_t::number_unsigned - number (floating-point) | value_t::number_float - object | value_t::object - array | value_t::array - binary | value_t::binary - discarded | value_t::discarded - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `type()` for all JSON - types.,type} - - @sa see @ref operator value_t() -- return the type of the JSON value (implicit) - @sa see @ref type_name() -- return the type as string - - @since version 1.0.0 - */ - constexpr value_t type() const noexcept - { - return m_type; - } - - /*! - @brief return whether type is primitive - - This function returns true if and only if the JSON type is primitive - (string, number, boolean, or null). - - @return `true` if type is primitive (string, number, boolean, or null), - `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_primitive()` for all JSON - types.,is_primitive} - - @sa see @ref is_structured() -- returns whether JSON value is structured - @sa see @ref is_null() -- returns whether JSON value is `null` - @sa see @ref is_string() -- returns whether JSON value is a string - @sa see @ref is_boolean() -- returns whether JSON value is a boolean - @sa see @ref is_number() -- returns whether JSON value is a number - @sa see @ref is_binary() -- returns whether JSON value is a binary array - - @since version 1.0.0 - */ - constexpr bool is_primitive() const noexcept - { - return is_null() || is_string() || is_boolean() || is_number() || is_binary(); - } - - /*! - @brief return whether type is structured - - This function returns true if and only if the JSON type is structured - (array or object). - - @return `true` if type is structured (array or object), `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_structured()` for all JSON - types.,is_structured} - - @sa see @ref is_primitive() -- returns whether value is primitive - @sa see @ref is_array() -- returns whether value is an array - @sa see @ref is_object() -- returns whether value is an object - - @since version 1.0.0 - */ - constexpr bool is_structured() const noexcept - { - return is_array() || is_object(); - } - - /*! - @brief return whether value is null - - This function returns true if and only if the JSON value is null. - - @return `true` if type is null, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_null()` for all JSON - types.,is_null} - - @since version 1.0.0 - */ - constexpr bool is_null() const noexcept - { - return m_type == value_t::null; - } - - /*! - @brief return whether value is a boolean - - This function returns true if and only if the JSON value is a boolean. - - @return `true` if type is boolean, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_boolean()` for all JSON - types.,is_boolean} - - @since version 1.0.0 - */ - constexpr bool is_boolean() const noexcept - { - return m_type == value_t::boolean; - } - - /*! - @brief return whether value is a number - - This function returns true if and only if the JSON value is a number. This - includes both integer (signed and unsigned) and floating-point values. - - @return `true` if type is number (regardless whether integer, unsigned - integer or floating-type), `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number()` for all JSON - types.,is_number} - - @sa see @ref is_number_integer() -- check if value is an integer or unsigned - integer number - @sa see @ref is_number_unsigned() -- check if value is an unsigned integer - number - @sa see @ref is_number_float() -- check if value is a floating-point number - - @since version 1.0.0 - */ - constexpr bool is_number() const noexcept - { - return is_number_integer() || is_number_float(); - } - - /*! - @brief return whether value is an integer number - - This function returns true if and only if the JSON value is a signed or - unsigned integer number. This excludes floating-point values. - - @return `true` if type is an integer or unsigned integer number, `false` - otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number_integer()` for all - JSON types.,is_number_integer} - - @sa see @ref is_number() -- check if value is a number - @sa see @ref is_number_unsigned() -- check if value is an unsigned integer - number - @sa see @ref is_number_float() -- check if value is a floating-point number - - @since version 1.0.0 - */ - constexpr bool is_number_integer() const noexcept - { - return m_type == value_t::number_integer || m_type == value_t::number_unsigned; - } - - /*! - @brief return whether value is an unsigned integer number - - This function returns true if and only if the JSON value is an unsigned - integer number. This excludes floating-point and signed integer values. - - @return `true` if type is an unsigned integer number, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number_unsigned()` for all - JSON types.,is_number_unsigned} - - @sa see @ref is_number() -- check if value is a number - @sa see @ref is_number_integer() -- check if value is an integer or unsigned - integer number - @sa see @ref is_number_float() -- check if value is a floating-point number - - @since version 2.0.0 - */ - constexpr bool is_number_unsigned() const noexcept - { - return m_type == value_t::number_unsigned; - } - - /*! - @brief return whether value is a floating-point number - - This function returns true if and only if the JSON value is a - floating-point number. This excludes signed and unsigned integer values. - - @return `true` if type is a floating-point number, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number_float()` for all - JSON types.,is_number_float} - - @sa see @ref is_number() -- check if value is number - @sa see @ref is_number_integer() -- check if value is an integer number - @sa see @ref is_number_unsigned() -- check if value is an unsigned integer - number - - @since version 1.0.0 - */ - constexpr bool is_number_float() const noexcept - { - return m_type == value_t::number_float; - } - - /*! - @brief return whether value is an object - - This function returns true if and only if the JSON value is an object. - - @return `true` if type is object, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_object()` for all JSON - types.,is_object} - - @since version 1.0.0 - */ - constexpr bool is_object() const noexcept - { - return m_type == value_t::object; - } - - /*! - @brief return whether value is an array - - This function returns true if and only if the JSON value is an array. - - @return `true` if type is array, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_array()` for all JSON - types.,is_array} - - @since version 1.0.0 - */ - constexpr bool is_array() const noexcept - { - return m_type == value_t::array; - } - - /*! - @brief return whether value is a string - - This function returns true if and only if the JSON value is a string. - - @return `true` if type is string, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_string()` for all JSON - types.,is_string} - - @since version 1.0.0 - */ - constexpr bool is_string() const noexcept - { - return m_type == value_t::string; - } - - /*! - @brief return whether value is a binary array - - This function returns true if and only if the JSON value is a binary array. - - @return `true` if type is binary array, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_binary()` for all JSON - types.,is_binary} - - @since version 3.8.0 - */ - constexpr bool is_binary() const noexcept - { - return m_type == value_t::binary; - } - - /*! - @brief return whether value is discarded - - This function returns true if and only if the JSON value was discarded - during parsing with a callback function (see @ref parser_callback_t). - - @note This function will always be `false` for JSON values after parsing. - That is, discarded values can only occur during parsing, but will be - removed when inside a structured value or replaced by null in other cases. - - @return `true` if type is discarded, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_discarded()` for all JSON - types.,is_discarded} - - @since version 1.0.0 - */ - constexpr bool is_discarded() const noexcept - { - return m_type == value_t::discarded; - } - - /*! - @brief return the type of the JSON value (implicit) - - Implicitly return the type of the JSON value as a value from the @ref - value_t enumeration. - - @return the type of the JSON value - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies the @ref value_t operator for - all JSON types.,operator__value_t} - - @sa see @ref type() -- return the type of the JSON value (explicit) - @sa see @ref type_name() -- return the type as string - - @since version 1.0.0 - */ - constexpr operator value_t() const noexcept - { - return m_type; - } - - /// @} - - private: - ////////////////// - // value access // - ////////////////// - - /// get a boolean (explicit) - boolean_t get_impl(boolean_t* /*unused*/) const - { - if (JSON_HEDLEY_LIKELY(is_boolean())) - { - return m_value.boolean; - } - - JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this)); - } - - /// get a pointer to the value (object) - object_t* get_impl_ptr(object_t* /*unused*/) noexcept - { - return is_object() ? m_value.object : nullptr; - } - - /// get a pointer to the value (object) - constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept - { - return is_object() ? m_value.object : nullptr; - } - - /// get a pointer to the value (array) - array_t* get_impl_ptr(array_t* /*unused*/) noexcept - { - return is_array() ? m_value.array : nullptr; - } - - /// get a pointer to the value (array) - constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept - { - return is_array() ? m_value.array : nullptr; - } - - /// get a pointer to the value (string) - string_t* get_impl_ptr(string_t* /*unused*/) noexcept - { - return is_string() ? m_value.string : nullptr; - } - - /// get a pointer to the value (string) - constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept - { - return is_string() ? m_value.string : nullptr; - } - - /// get a pointer to the value (boolean) - boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept - { - return is_boolean() ? &m_value.boolean : nullptr; - } - - /// get a pointer to the value (boolean) - constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept - { - return is_boolean() ? &m_value.boolean : nullptr; - } - - /// get a pointer to the value (integer number) - number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept - { - return is_number_integer() ? &m_value.number_integer : nullptr; - } - - /// get a pointer to the value (integer number) - constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept - { - return is_number_integer() ? &m_value.number_integer : nullptr; - } - - /// get a pointer to the value (unsigned number) - number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept - { - return is_number_unsigned() ? &m_value.number_unsigned : nullptr; - } - - /// get a pointer to the value (unsigned number) - constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept - { - return is_number_unsigned() ? &m_value.number_unsigned : nullptr; - } - - /// get a pointer to the value (floating-point number) - number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept - { - return is_number_float() ? &m_value.number_float : nullptr; - } - - /// get a pointer to the value (floating-point number) - constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept - { - return is_number_float() ? &m_value.number_float : nullptr; - } - - /// get a pointer to the value (binary) - binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept - { - return is_binary() ? m_value.binary : nullptr; - } - - /// get a pointer to the value (binary) - constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept - { - return is_binary() ? m_value.binary : nullptr; - } - - /*! - @brief helper function to implement get_ref() - - This function helps to implement get_ref() without code duplication for - const and non-const overloads - - @tparam ThisType will be deduced as `basic_json` or `const basic_json` - - @throw type_error.303 if ReferenceType does not match underlying value - type of the current JSON - */ - template - static ReferenceType get_ref_impl(ThisType& obj) - { - // delegate the call to get_ptr<>() - auto* ptr = obj.template get_ptr::type>(); - - if (JSON_HEDLEY_LIKELY(ptr != nullptr)) - { - return *ptr; - } - - JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj)); - } - - public: - /// @name value access - /// Direct access to the stored value of a JSON value. - /// @{ - - /*! - @brief get a pointer value (implicit) - - Implicit pointer access to the internally stored JSON value. No copies are - made. - - @warning Writing data to the pointee of the result yields an undefined - state. - - @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref - object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, - @ref number_unsigned_t, or @ref number_float_t. Enforced by a static - assertion. - - @return pointer to the internally stored JSON value if the requested - pointer type @a PointerType fits to the JSON value; `nullptr` otherwise - - @complexity Constant. - - @liveexample{The example below shows how pointers to internal values of a - JSON value can be requested. Note that no type conversions are made and a - `nullptr` is returned if the value and the requested pointer type does not - match.,get_ptr} - - @since version 1.0.0 - */ - template::value, int>::type = 0> - auto get_ptr() noexcept -> decltype(std::declval().get_impl_ptr(std::declval())) - { - // delegate the call to get_impl_ptr<>() - return get_impl_ptr(static_cast(nullptr)); - } - - /*! - @brief get a pointer value (implicit) - @copydoc get_ptr() - */ - template < typename PointerType, typename std::enable_if < - std::is_pointer::value&& - std::is_const::type>::value, int >::type = 0 > - constexpr auto get_ptr() const noexcept -> decltype(std::declval().get_impl_ptr(std::declval())) - { - // delegate the call to get_impl_ptr<>() const - return get_impl_ptr(static_cast(nullptr)); - } - - private: - /*! - @brief get a value (explicit) - - Explicit type conversion between the JSON value and a compatible value - which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) - and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). - The value is converted by calling the @ref json_serializer - `from_json()` method. - - The function is equivalent to executing - @code {.cpp} - ValueType ret; - JSONSerializer::from_json(*this, ret); - return ret; - @endcode - - This overloads is chosen if: - - @a ValueType is not @ref basic_json, - - @ref json_serializer has a `from_json()` method of the form - `void from_json(const basic_json&, ValueType&)`, and - - @ref json_serializer does not have a `from_json()` method of - the form `ValueType from_json(const basic_json&)` - - @tparam ValueType the returned value type - - @return copy of the JSON value, converted to @a ValueType - - @throw what @ref json_serializer `from_json()` method throws - - @liveexample{The example below shows several conversions from JSON values - to other types. There a few things to note: (1) Floating-point numbers can - be converted to integers\, (2) A JSON array can be converted to a standard - `std::vector`\, (3) A JSON object can be converted to C++ - associative containers such as `std::unordered_map`.,get__ValueType_const} - - @since version 2.1.0 - */ - template < typename ValueType, - detail::enable_if_t < - detail::is_default_constructible::value&& - detail::has_from_json::value, - int > = 0 > - ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept( - JSONSerializer::from_json(std::declval(), std::declval()))) - { - ValueType ret{}; - JSONSerializer::from_json(*this, ret); - return ret; - } - - /*! - @brief get a value (explicit); special case - - Explicit type conversion between the JSON value and a compatible value - which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) - and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). - The value is converted by calling the @ref json_serializer - `from_json()` method. - - The function is equivalent to executing - @code {.cpp} - return JSONSerializer::from_json(*this); - @endcode - - This overloads is chosen if: - - @a ValueType is not @ref basic_json and - - @ref json_serializer has a `from_json()` method of the form - `ValueType from_json(const basic_json&)` - - @note If @ref json_serializer has both overloads of - `from_json()`, this one is chosen. - - @tparam ValueType the returned value type - - @return copy of the JSON value, converted to @a ValueType - - @throw what @ref json_serializer `from_json()` method throws - - @since version 2.1.0 - */ - template < typename ValueType, - detail::enable_if_t < - detail::has_non_default_from_json::value, - int > = 0 > - ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept( - JSONSerializer::from_json(std::declval()))) - { - return JSONSerializer::from_json(*this); - } - - /*! - @brief get special-case overload - - This overloads converts the current @ref basic_json in a different - @ref basic_json type - - @tparam BasicJsonType == @ref basic_json - - @return a copy of *this, converted into @a BasicJsonType - - @complexity Depending on the implementation of the called `from_json()` - method. - - @since version 3.2.0 - */ - template < typename BasicJsonType, - detail::enable_if_t < - detail::is_basic_json::value, - int > = 0 > - BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const - { - return *this; - } - - /*! - @brief get special-case overload - - This overloads avoids a lot of template boilerplate, it can be seen as the - identity method - - @tparam BasicJsonType == @ref basic_json - - @return a copy of *this - - @complexity Constant. - - @since version 2.1.0 - */ - template::value, - int> = 0> - basic_json get_impl(detail::priority_tag<3> /*unused*/) const - { - return *this; - } - - /*! - @brief get a pointer value (explicit) - @copydoc get() - */ - template::value, - int> = 0> - constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept - -> decltype(std::declval().template get_ptr()) - { - // delegate the call to get_ptr - return get_ptr(); - } - - public: - /*! - @brief get a (pointer) value (explicit) - - Performs explicit type conversion between the JSON value and a compatible value if required. - - - If the requested type is a pointer to the internally stored JSON value that pointer is returned. - No copies are made. - - - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible - from the current @ref basic_json. - - - Otherwise the value is converted by calling the @ref json_serializer `from_json()` - method. - - @tparam ValueTypeCV the provided value type - @tparam ValueType the returned value type - - @return copy of the JSON value, converted to @tparam ValueType if necessary - - @throw what @ref json_serializer `from_json()` method throws if conversion is required - - @since version 2.1.0 - */ - template < typename ValueTypeCV, typename ValueType = detail::uncvref_t> -#if defined(JSON_HAS_CPP_14) - constexpr -#endif - auto get() const noexcept( - noexcept(std::declval().template get_impl(detail::priority_tag<4> {}))) - -> decltype(std::declval().template get_impl(detail::priority_tag<4> {})) - { - // we cannot static_assert on ValueTypeCV being non-const, because - // there is support for get(), which is why we - // still need the uncvref - static_assert(!std::is_reference::value, - "get() cannot be used with reference types, you might want to use get_ref()"); - return get_impl(detail::priority_tag<4> {}); - } - - /*! - @brief get a pointer value (explicit) - - Explicit pointer access to the internally stored JSON value. No copies are - made. - - @warning The pointer becomes invalid if the underlying JSON object - changes. - - @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref - object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, - @ref number_unsigned_t, or @ref number_float_t. - - @return pointer to the internally stored JSON value if the requested - pointer type @a PointerType fits to the JSON value; `nullptr` otherwise - - @complexity Constant. - - @liveexample{The example below shows how pointers to internal values of a - JSON value can be requested. Note that no type conversions are made and a - `nullptr` is returned if the value and the requested pointer type does not - match.,get__PointerType} - - @sa see @ref get_ptr() for explicit pointer-member access - - @since version 1.0.0 - */ - template::value, int>::type = 0> - auto get() noexcept -> decltype(std::declval().template get_ptr()) - { - // delegate the call to get_ptr - return get_ptr(); - } - - /*! - @brief get a value (explicit) - - Explicit type conversion between the JSON value and a compatible value. - The value is filled into the input parameter by calling the @ref json_serializer - `from_json()` method. - - The function is equivalent to executing - @code {.cpp} - ValueType v; - JSONSerializer::from_json(*this, v); - @endcode - - This overloads is chosen if: - - @a ValueType is not @ref basic_json, - - @ref json_serializer has a `from_json()` method of the form - `void from_json(const basic_json&, ValueType&)`, and - - @tparam ValueType the input parameter type. - - @return the input parameter, allowing chaining calls. - - @throw what @ref json_serializer `from_json()` method throws - - @liveexample{The example below shows several conversions from JSON values - to other types. There a few things to note: (1) Floating-point numbers can - be converted to integers\, (2) A JSON array can be converted to a standard - `std::vector`\, (3) A JSON object can be converted to C++ - associative containers such as `std::unordered_map`.,get_to} - - @since version 3.3.0 - */ - template < typename ValueType, - detail::enable_if_t < - !detail::is_basic_json::value&& - detail::has_from_json::value, - int > = 0 > - ValueType & get_to(ValueType& v) const noexcept(noexcept( - JSONSerializer::from_json(std::declval(), v))) - { - JSONSerializer::from_json(*this, v); - return v; - } - - // specialization to allow to call get_to with a basic_json value - // see https://github.com/nlohmann/json/issues/2175 - template::value, - int> = 0> - ValueType & get_to(ValueType& v) const - { - v = *this; - return v; - } - - template < - typename T, std::size_t N, - typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - detail::enable_if_t < - detail::has_from_json::value, int > = 0 > - Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - noexcept(noexcept(JSONSerializer::from_json( - std::declval(), v))) - { - JSONSerializer::from_json(*this, v); - return v; - } - - /*! - @brief get a reference value (implicit) - - Implicit reference access to the internally stored JSON value. No copies - are made. - - @warning Writing data to the referee of the result yields an undefined - state. - - @tparam ReferenceType reference type; must be a reference to @ref array_t, - @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or - @ref number_float_t. Enforced by static assertion. - - @return reference to the internally stored JSON value if the requested - reference type @a ReferenceType fits to the JSON value; throws - type_error.303 otherwise - - @throw type_error.303 in case passed type @a ReferenceType is incompatible - with the stored JSON value; see example below - - @complexity Constant. - - @liveexample{The example shows several calls to `get_ref()`.,get_ref} - - @since version 1.1.0 - */ - template::value, int>::type = 0> - ReferenceType get_ref() - { - // delegate call to get_ref_impl - return get_ref_impl(*this); - } - - /*! - @brief get a reference value (implicit) - @copydoc get_ref() - */ - template < typename ReferenceType, typename std::enable_if < - std::is_reference::value&& - std::is_const::type>::value, int >::type = 0 > - ReferenceType get_ref() const - { - // delegate call to get_ref_impl - return get_ref_impl(*this); - } - - /*! - @brief get a value (implicit) - - Implicit type conversion between the JSON value and a compatible value. - The call is realized by calling @ref get() const. - - @tparam ValueType non-pointer type compatible to the JSON value, for - instance `int` for JSON integer numbers, `bool` for JSON booleans, or - `std::vector` types for JSON arrays. The character type of @ref string_t - as well as an initializer list of this type is excluded to avoid - ambiguities as these types implicitly convert to `std::string`. - - @return copy of the JSON value, converted to type @a ValueType - - @throw type_error.302 in case passed type @a ValueType is incompatible - to the JSON value type (e.g., the JSON value is of type boolean, but a - string is requested); see example below - - @complexity Linear in the size of the JSON value. - - @liveexample{The example below shows several conversions from JSON values - to other types. There a few things to note: (1) Floating-point numbers can - be converted to integers\, (2) A JSON array can be converted to a standard - `std::vector`\, (3) A JSON object can be converted to C++ - associative containers such as `std::unordered_map`.,operator__ValueType} - - @since version 1.0.0 - */ - template < typename ValueType, typename std::enable_if < - detail::conjunction < - detail::negation>, - detail::negation>>, - detail::negation>, - detail::negation>, - detail::negation>>, - -#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914)) - detail::negation>, -#endif - detail::is_detected_lazy - >::value, int >::type = 0 > - JSON_EXPLICIT operator ValueType() const - { - // delegate the call to get<>() const - return get(); - } - - /*! - @return reference to the binary value - - @throw type_error.302 if the value is not binary - - @sa see @ref is_binary() to check if the value is binary - - @since version 3.8.0 - */ - binary_t& get_binary() - { - if (!is_binary()) - { - JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this)); - } - - return *get_ptr(); - } - - /// @copydoc get_binary() - const binary_t& get_binary() const - { - if (!is_binary()) - { - JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this)); - } - - return *get_ptr(); - } - - /// @} - - - //////////////////// - // element access // - //////////////////// - - /// @name element access - /// Access to the JSON value. - /// @{ - - /*! - @brief access specified array element with bounds checking - - Returns a reference to the element at specified location @a idx, with - bounds checking. - - @param[in] idx index of the element to access - - @return reference to the element at index @a idx - - @throw type_error.304 if the JSON value is not an array; in this case, - calling `at` with an index makes no sense. See example below. - @throw out_of_range.401 if the index @a idx is out of range of the array; - that is, `idx >= size()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 1.0.0 - - @liveexample{The example below shows how array elements can be read and - written using `at()`. It also demonstrates the different exceptions that - can be thrown.,at__size_type} - */ - reference at(size_type idx) - { - // at only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - JSON_TRY - { - return set_parent(m_value.array->at(idx)); - } - JSON_CATCH (std::out_of_range&) - { - // create better exception explanation - JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this)); - } - } - else - { - JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief access specified array element with bounds checking - - Returns a const reference to the element at specified location @a idx, - with bounds checking. - - @param[in] idx index of the element to access - - @return const reference to the element at index @a idx - - @throw type_error.304 if the JSON value is not an array; in this case, - calling `at` with an index makes no sense. See example below. - @throw out_of_range.401 if the index @a idx is out of range of the array; - that is, `idx >= size()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 1.0.0 - - @liveexample{The example below shows how array elements can be read using - `at()`. It also demonstrates the different exceptions that can be thrown., - at__size_type_const} - */ - const_reference at(size_type idx) const - { - // at only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - JSON_TRY - { - return m_value.array->at(idx); - } - JSON_CATCH (std::out_of_range&) - { - // create better exception explanation - JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this)); - } - } - else - { - JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief access specified object element with bounds checking - - Returns a reference to the element at with specified key @a key, with - bounds checking. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw type_error.304 if the JSON value is not an object; in this case, - calling `at` with a key makes no sense. See example below. - @throw out_of_range.403 if the key @a key is is not stored in the object; - that is, `find(key) == end()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Logarithmic in the size of the container. - - @sa see @ref operator[](const typename object_t::key_type&) for unchecked - access by reference - @sa see @ref value() for access by value with a default value - - @since version 1.0.0 - - @liveexample{The example below shows how object elements can be read and - written using `at()`. It also demonstrates the different exceptions that - can be thrown.,at__object_t_key_type} - */ - reference at(const typename object_t::key_type& key) - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - JSON_TRY - { - return set_parent(m_value.object->at(key)); - } - JSON_CATCH (std::out_of_range&) - { - // create better exception explanation - JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this)); - } - } - else - { - JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief access specified object element with bounds checking - - Returns a const reference to the element at with specified key @a key, - with bounds checking. - - @param[in] key key of the element to access - - @return const reference to the element at key @a key - - @throw type_error.304 if the JSON value is not an object; in this case, - calling `at` with a key makes no sense. See example below. - @throw out_of_range.403 if the key @a key is is not stored in the object; - that is, `find(key) == end()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Logarithmic in the size of the container. - - @sa see @ref operator[](const typename object_t::key_type&) for unchecked - access by reference - @sa see @ref value() for access by value with a default value - - @since version 1.0.0 - - @liveexample{The example below shows how object elements can be read using - `at()`. It also demonstrates the different exceptions that can be thrown., - at__object_t_key_type_const} - */ - const_reference at(const typename object_t::key_type& key) const - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - JSON_TRY - { - return m_value.object->at(key); - } - JSON_CATCH (std::out_of_range&) - { - // create better exception explanation - JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this)); - } - } - else - { - JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief access specified array element - - Returns a reference to the element at specified location @a idx. - - @note If @a idx is beyond the range of the array (i.e., `idx >= size()`), - then the array is silently filled up with `null` values to make `idx` a - valid reference to the last stored element. - - @param[in] idx index of the element to access - - @return reference to the element at index @a idx - - @throw type_error.305 if the JSON value is not an array or null; in that - cases, using the [] operator with an index makes no sense. - - @complexity Constant if @a idx is in the range of the array. Otherwise - linear in `idx - size()`. - - @liveexample{The example below shows how array elements can be read and - written using `[]` operator. Note the addition of `null` - values.,operatorarray__size_type} - - @since version 1.0.0 - */ - reference operator[](size_type idx) - { - // implicitly convert null value to an empty array - if (is_null()) - { - m_type = value_t::array; - m_value.array = create(); - assert_invariant(); - } - - // operator[] only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - // fill up array with null values if given idx is outside range - if (idx >= m_value.array->size()) - { -#if JSON_DIAGNOSTICS - // remember array size before resizing - const auto previous_size = m_value.array->size(); -#endif - m_value.array->resize(idx + 1); - -#if JSON_DIAGNOSTICS - // set parent for values added above - set_parents(begin() + static_cast(previous_size), static_cast(idx + 1 - previous_size)); -#endif - } - - return m_value.array->operator[](idx); - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this)); - } - - /*! - @brief access specified array element - - Returns a const reference to the element at specified location @a idx. - - @param[in] idx index of the element to access - - @return const reference to the element at index @a idx - - @throw type_error.305 if the JSON value is not an array; in that case, - using the [] operator with an index makes no sense. - - @complexity Constant. - - @liveexample{The example below shows how array elements can be read using - the `[]` operator.,operatorarray__size_type_const} - - @since version 1.0.0 - */ - const_reference operator[](size_type idx) const - { - // const operator[] only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - return m_value.array->operator[](idx); - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this)); - } - - /*! - @brief access specified object element - - Returns a reference to the element at with specified key @a key. - - @note If @a key is not found in the object, then it is silently added to - the object and filled with a `null` value to make `key` a valid reference. - In case the value was `null` before, it is converted to an object. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw type_error.305 if the JSON value is not an object or null; in that - cases, using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read and - written using the `[]` operator.,operatorarray__key_type} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref value() for access by value with a default value - - @since version 1.0.0 - */ - reference operator[](const typename object_t::key_type& key) - { - // implicitly convert null value to an empty object - if (is_null()) - { - m_type = value_t::object; - m_value.object = create(); - assert_invariant(); - } - - // operator[] only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - return set_parent(m_value.object->operator[](key)); - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this)); - } - - /*! - @brief read-only access specified object element - - Returns a const reference to the element at with specified key @a key. No - bounds checking is performed. - - @warning If the element with key @a key does not exist, the behavior is - undefined. - - @param[in] key key of the element to access - - @return const reference to the element at key @a key - - @pre The element with key @a key must exist. **This precondition is - enforced with an assertion.** - - @throw type_error.305 if the JSON value is not an object; in that case, - using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read using - the `[]` operator.,operatorarray__key_type_const} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref value() for access by value with a default value - - @since version 1.0.0 - */ - const_reference operator[](const typename object_t::key_type& key) const - { - // const operator[] only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - JSON_ASSERT(m_value.object->find(key) != m_value.object->end()); - return m_value.object->find(key)->second; - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this)); - } - - /*! - @brief access specified object element - - Returns a reference to the element at with specified key @a key. - - @note If @a key is not found in the object, then it is silently added to - the object and filled with a `null` value to make `key` a valid reference. - In case the value was `null` before, it is converted to an object. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw type_error.305 if the JSON value is not an object or null; in that - cases, using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read and - written using the `[]` operator.,operatorarray__key_type} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref value() for access by value with a default value - - @since version 1.1.0 - */ - template - JSON_HEDLEY_NON_NULL(2) - reference operator[](T* key) - { - // implicitly convert null to object - if (is_null()) - { - m_type = value_t::object; - m_value = value_t::object; - assert_invariant(); - } - - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - return set_parent(m_value.object->operator[](key)); - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this)); - } - - /*! - @brief read-only access specified object element - - Returns a const reference to the element at with specified key @a key. No - bounds checking is performed. - - @warning If the element with key @a key does not exist, the behavior is - undefined. - - @param[in] key key of the element to access - - @return const reference to the element at key @a key - - @pre The element with key @a key must exist. **This precondition is - enforced with an assertion.** - - @throw type_error.305 if the JSON value is not an object; in that case, - using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read using - the `[]` operator.,operatorarray__key_type_const} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref value() for access by value with a default value - - @since version 1.1.0 - */ - template - JSON_HEDLEY_NON_NULL(2) - const_reference operator[](T* key) const - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - JSON_ASSERT(m_value.object->find(key) != m_value.object->end()); - return m_value.object->find(key)->second; - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this)); - } - - /*! - @brief access specified object element with default value - - Returns either a copy of an object's element at the specified key @a key - or a given default value if no element with key @a key exists. - - The function is basically equivalent to executing - @code {.cpp} - try { - return at(key); - } catch(out_of_range) { - return default_value; - } - @endcode - - @note Unlike @ref at(const typename object_t::key_type&), this function - does not throw if the given key @a key was not found. - - @note Unlike @ref operator[](const typename object_t::key_type& key), this - function does not implicitly add an element to the position defined by @a - key. This function is furthermore also applicable to const objects. - - @param[in] key key of the element to access - @param[in] default_value the value to return if @a key is not found - - @tparam ValueType type compatible to JSON values, for instance `int` for - JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for - JSON arrays. Note the type of the expected value at @a key and the default - value @a default_value must be compatible. - - @return copy of the element at key @a key or @a default_value if @a key - is not found - - @throw type_error.302 if @a default_value does not match the type of the - value at @a key - @throw type_error.306 if the JSON value is not an object; in that case, - using `value()` with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be queried - with a default value.,basic_json__value} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref operator[](const typename object_t::key_type&) for unchecked - access by reference - - @since version 1.0.0 - */ - // using std::is_convertible in a std::enable_if will fail when using explicit conversions - template < class ValueType, typename std::enable_if < - detail::is_getable::value - && !std::is_same::value, int >::type = 0 > - ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - // if key is found, return value and given default value otherwise - const auto it = find(key); - if (it != end()) - { - return it->template get(); - } - - return default_value; - } - - JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this)); - } - - /*! - @brief overload for a default value of type const char* - @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const - */ - string_t value(const typename object_t::key_type& key, const char* default_value) const - { - return value(key, string_t(default_value)); - } - - /*! - @brief access specified object element via JSON Pointer with default value - - Returns either a copy of an object's element at the specified key @a key - or a given default value if no element with key @a key exists. - - The function is basically equivalent to executing - @code {.cpp} - try { - return at(ptr); - } catch(out_of_range) { - return default_value; - } - @endcode - - @note Unlike @ref at(const json_pointer&), this function does not throw - if the given key @a key was not found. - - @param[in] ptr a JSON pointer to the element to access - @param[in] default_value the value to return if @a ptr found no value - - @tparam ValueType type compatible to JSON values, for instance `int` for - JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for - JSON arrays. Note the type of the expected value at @a key and the default - value @a default_value must be compatible. - - @return copy of the element at key @a key or @a default_value if @a key - is not found - - @throw type_error.302 if @a default_value does not match the type of the - value at @a ptr - @throw type_error.306 if the JSON value is not an object; in that case, - using `value()` with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be queried - with a default value.,basic_json__value_ptr} - - @sa see @ref operator[](const json_pointer&) for unchecked access by reference - - @since version 2.0.2 - */ - template::value, int>::type = 0> - ValueType value(const json_pointer& ptr, const ValueType& default_value) const - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - // if pointer resolves a value, return it or use default value - JSON_TRY - { - return ptr.get_checked(this).template get(); - } - JSON_INTERNAL_CATCH (out_of_range&) - { - return default_value; - } - } - - JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this)); - } - - /*! - @brief overload for a default value of type const char* - @copydoc basic_json::value(const json_pointer&, ValueType) const - */ - JSON_HEDLEY_NON_NULL(3) - string_t value(const json_pointer& ptr, const char* default_value) const - { - return value(ptr, string_t(default_value)); - } - - /*! - @brief access the first element - - Returns a reference to the first element in the container. For a JSON - container `c`, the expression `c.front()` is equivalent to `*c.begin()`. - - @return In case of a structured type (array or object), a reference to the - first element is returned. In case of number, string, boolean, or binary - values, a reference to the value is returned. - - @complexity Constant. - - @pre The JSON value must not be `null` (would throw `std::out_of_range`) - or an empty array or object (undefined behavior, **guarded by - assertions**). - @post The JSON value remains unchanged. - - @throw invalid_iterator.214 when called on `null` value - - @liveexample{The following code shows an example for `front()`.,front} - - @sa see @ref back() -- access the last element - - @since version 1.0.0 - */ - reference front() - { - return *begin(); - } - - /*! - @copydoc basic_json::front() - */ - const_reference front() const - { - return *cbegin(); - } - - /*! - @brief access the last element - - Returns a reference to the last element in the container. For a JSON - container `c`, the expression `c.back()` is equivalent to - @code {.cpp} - auto tmp = c.end(); - --tmp; - return *tmp; - @endcode - - @return In case of a structured type (array or object), a reference to the - last element is returned. In case of number, string, boolean, or binary - values, a reference to the value is returned. - - @complexity Constant. - - @pre The JSON value must not be `null` (would throw `std::out_of_range`) - or an empty array or object (undefined behavior, **guarded by - assertions**). - @post The JSON value remains unchanged. - - @throw invalid_iterator.214 when called on a `null` value. See example - below. - - @liveexample{The following code shows an example for `back()`.,back} - - @sa see @ref front() -- access the first element - - @since version 1.0.0 - */ - reference back() - { - auto tmp = end(); - --tmp; - return *tmp; - } - - /*! - @copydoc basic_json::back() - */ - const_reference back() const - { - auto tmp = cend(); - --tmp; - return *tmp; - } - - /*! - @brief remove element given an iterator - - Removes the element specified by iterator @a pos. The iterator @a pos must - be valid and dereferenceable. Thus the `end()` iterator (which is valid, - but is not dereferenceable) cannot be used as a value for @a pos. - - If called on a primitive type other than `null`, the resulting JSON value - will be `null`. - - @param[in] pos iterator to the element to remove - @return Iterator following the last removed element. If the iterator @a - pos refers to the last element, the `end()` iterator is returned. - - @tparam IteratorType an @ref iterator or @ref const_iterator - - @post Invalidates iterators and references at or after the point of the - erase, including the `end()` iterator. - - @throw type_error.307 if called on a `null` value; example: `"cannot use - erase() with null"` - @throw invalid_iterator.202 if called on an iterator which does not belong - to the current JSON value; example: `"iterator does not fit current - value"` - @throw invalid_iterator.205 if called on a primitive type with invalid - iterator (i.e., any iterator which is not `begin()`); example: `"iterator - out of range"` - - @complexity The complexity depends on the type: - - objects: amortized constant - - arrays: linear in distance between @a pos and the end of the container - - strings and binary: linear in the length of the member - - other types: constant - - @liveexample{The example shows the result of `erase()` for different JSON - types.,erase__IteratorType} - - @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in - the given range - @sa see @ref erase(const typename object_t::key_type&) -- removes the element - from an object at the given key - @sa see @ref erase(const size_type) -- removes the element from an array at - the given index - - @since version 1.0.0 - */ - template < class IteratorType, typename std::enable_if < - std::is_same::value || - std::is_same::value, int >::type - = 0 > - IteratorType erase(IteratorType pos) - { - // make sure iterator fits the current value - if (JSON_HEDLEY_UNLIKELY(this != pos.m_object)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this)); - } - - IteratorType result = end(); - - switch (m_type) - { - case value_t::boolean: - case value_t::number_float: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::string: - case value_t::binary: - { - if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin())) - { - JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this)); - } - - if (is_string()) - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, m_value.string); - std::allocator_traits::deallocate(alloc, m_value.string, 1); - m_value.string = nullptr; - } - else if (is_binary()) - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, m_value.binary); - std::allocator_traits::deallocate(alloc, m_value.binary, 1); - m_value.binary = nullptr; - } - - m_type = value_t::null; - assert_invariant(); - break; - } - - case value_t::object: - { - result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator); - break; - } - - case value_t::array: - { - result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator); - break; - } - - case value_t::null: - case value_t::discarded: - default: - JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this)); - } - - return result; - } - - /*! - @brief remove elements given an iterator range - - Removes the element specified by the range `[first; last)`. The iterator - @a first does not need to be dereferenceable if `first == last`: erasing - an empty range is a no-op. - - If called on a primitive type other than `null`, the resulting JSON value - will be `null`. - - @param[in] first iterator to the beginning of the range to remove - @param[in] last iterator past the end of the range to remove - @return Iterator following the last removed element. If the iterator @a - second refers to the last element, the `end()` iterator is returned. - - @tparam IteratorType an @ref iterator or @ref const_iterator - - @post Invalidates iterators and references at or after the point of the - erase, including the `end()` iterator. - - @throw type_error.307 if called on a `null` value; example: `"cannot use - erase() with null"` - @throw invalid_iterator.203 if called on iterators which does not belong - to the current JSON value; example: `"iterators do not fit current value"` - @throw invalid_iterator.204 if called on a primitive type with invalid - iterators (i.e., if `first != begin()` and `last != end()`); example: - `"iterators out of range"` - - @complexity The complexity depends on the type: - - objects: `log(size()) + std::distance(first, last)` - - arrays: linear in the distance between @a first and @a last, plus linear - in the distance between @a last and end of the container - - strings and binary: linear in the length of the member - - other types: constant - - @liveexample{The example shows the result of `erase()` for different JSON - types.,erase__IteratorType_IteratorType} - - @sa see @ref erase(IteratorType) -- removes the element at a given position - @sa see @ref erase(const typename object_t::key_type&) -- removes the element - from an object at the given key - @sa see @ref erase(const size_type) -- removes the element from an array at - the given index - - @since version 1.0.0 - */ - template < class IteratorType, typename std::enable_if < - std::is_same::value || - std::is_same::value, int >::type - = 0 > - IteratorType erase(IteratorType first, IteratorType last) - { - // make sure iterator fits the current value - if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object)) - { - JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this)); - } - - IteratorType result = end(); - - switch (m_type) - { - case value_t::boolean: - case value_t::number_float: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::string: - case value_t::binary: - { - if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin() - || !last.m_it.primitive_iterator.is_end())) - { - JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this)); - } - - if (is_string()) - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, m_value.string); - std::allocator_traits::deallocate(alloc, m_value.string, 1); - m_value.string = nullptr; - } - else if (is_binary()) - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, m_value.binary); - std::allocator_traits::deallocate(alloc, m_value.binary, 1); - m_value.binary = nullptr; - } - - m_type = value_t::null; - assert_invariant(); - break; - } - - case value_t::object: - { - result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator, - last.m_it.object_iterator); - break; - } - - case value_t::array: - { - result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator, - last.m_it.array_iterator); - break; - } - - case value_t::null: - case value_t::discarded: - default: - JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this)); - } - - return result; - } - - /*! - @brief remove element from a JSON object given a key - - Removes elements from a JSON object with the key value @a key. - - @param[in] key value of the elements to remove - - @return Number of elements removed. If @a ObjectType is the default - `std::map` type, the return value will always be `0` (@a key was not - found) or `1` (@a key was found). - - @post References and iterators to the erased elements are invalidated. - Other references and iterators are not affected. - - @throw type_error.307 when called on a type other than JSON object; - example: `"cannot use erase() with null"` - - @complexity `log(size()) + count(key)` - - @liveexample{The example shows the effect of `erase()`.,erase__key_type} - - @sa see @ref erase(IteratorType) -- removes the element at a given position - @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in - the given range - @sa see @ref erase(const size_type) -- removes the element from an array at - the given index - - @since version 1.0.0 - */ - size_type erase(const typename object_t::key_type& key) - { - // this erase only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - return m_value.object->erase(key); - } - - JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this)); - } - - /*! - @brief remove element from a JSON array given an index - - Removes element from a JSON array at the index @a idx. - - @param[in] idx index of the element to remove - - @throw type_error.307 when called on a type other than JSON object; - example: `"cannot use erase() with null"` - @throw out_of_range.401 when `idx >= size()`; example: `"array index 17 - is out of range"` - - @complexity Linear in distance between @a idx and the end of the container. - - @liveexample{The example shows the effect of `erase()`.,erase__size_type} - - @sa see @ref erase(IteratorType) -- removes the element at a given position - @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in - the given range - @sa see @ref erase(const typename object_t::key_type&) -- removes the element - from an object at the given key - - @since version 1.0.0 - */ - void erase(const size_type idx) - { - // this erase only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - if (JSON_HEDLEY_UNLIKELY(idx >= size())) - { - JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this)); - } - - m_value.array->erase(m_value.array->begin() + static_cast(idx)); - } - else - { - JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this)); - } - } - - /// @} - - - //////////// - // lookup // - //////////// - - /// @name lookup - /// @{ - - /*! - @brief find an element in a JSON object - - Finds an element in a JSON object with key equivalent to @a key. If the - element is not found or the JSON value is not an object, end() is - returned. - - @note This method always returns @ref end() when executed on a JSON type - that is not an object. - - @param[in] key key value of the element to search for. - - @return Iterator to an element with key equivalent to @a key. If no such - element is found or the JSON value is not an object, past-the-end (see - @ref end()) iterator is returned. - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The example shows how `find()` is used.,find__key_type} - - @sa see @ref contains(KeyT&&) const -- checks whether a key exists - - @since version 1.0.0 - */ - template - iterator find(KeyT&& key) - { - auto result = end(); - - if (is_object()) - { - result.m_it.object_iterator = m_value.object->find(std::forward(key)); - } - - return result; - } - - /*! - @brief find an element in a JSON object - @copydoc find(KeyT&&) - */ - template - const_iterator find(KeyT&& key) const - { - auto result = cend(); - - if (is_object()) - { - result.m_it.object_iterator = m_value.object->find(std::forward(key)); - } - - return result; - } - - /*! - @brief returns the number of occurrences of a key in a JSON object - - Returns the number of elements with key @a key. If ObjectType is the - default `std::map` type, the return value will always be `0` (@a key was - not found) or `1` (@a key was found). - - @note This method always returns `0` when executed on a JSON type that is - not an object. - - @param[in] key key value of the element to count - - @return Number of elements with key @a key. If the JSON value is not an - object, the return value will be `0`. - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The example shows how `count()` is used.,count} - - @since version 1.0.0 - */ - template - size_type count(KeyT&& key) const - { - // return 0 for all nonobject types - return is_object() ? m_value.object->count(std::forward(key)) : 0; - } - - /*! - @brief check the existence of an element in a JSON object - - Check whether an element exists in a JSON object with key equivalent to - @a key. If the element is not found or the JSON value is not an object, - false is returned. - - @note This method always returns false when executed on a JSON type - that is not an object. - - @param[in] key key value to check its existence. - - @return true if an element with specified @a key exists. If no such - element with such key is found or the JSON value is not an object, - false is returned. - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The following code shows an example for `contains()`.,contains} - - @sa see @ref find(KeyT&&) -- returns an iterator to an object element - @sa see @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer - - @since version 3.6.0 - */ - template < typename KeyT, typename std::enable_if < - !std::is_same::type, json_pointer>::value, int >::type = 0 > - bool contains(KeyT && key) const - { - return is_object() && m_value.object->find(std::forward(key)) != m_value.object->end(); - } - - /*! - @brief check the existence of an element in a JSON object given a JSON pointer - - Check whether the given JSON pointer @a ptr can be resolved in the current - JSON value. - - @note This method can be executed on any JSON value type. - - @param[in] ptr JSON pointer to check its existence. - - @return true if the JSON pointer can be resolved to a stored value, false - otherwise. - - @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The following code shows an example for `contains()`.,contains_json_pointer} - - @sa see @ref contains(KeyT &&) const -- checks the existence of a key - - @since version 3.7.0 - */ - bool contains(const json_pointer& ptr) const - { - return ptr.contains(this); - } - - /// @} - - - /////////////// - // iterators // - /////////////// - - /// @name iterators - /// @{ - - /*! - @brief returns an iterator to the first element - - Returns an iterator to the first element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return iterator to the first element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - @liveexample{The following code shows an example for `begin()`.,begin} - - @sa see @ref cbegin() -- returns a const iterator to the beginning - @sa see @ref end() -- returns an iterator to the end - @sa see @ref cend() -- returns a const iterator to the end - - @since version 1.0.0 - */ - iterator begin() noexcept - { - iterator result(this); - result.set_begin(); - return result; - } - - /*! - @copydoc basic_json::cbegin() - */ - const_iterator begin() const noexcept - { - return cbegin(); - } - - /*! - @brief returns a const iterator to the first element - - Returns a const iterator to the first element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return const iterator to the first element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast(*this).begin()`. - - @liveexample{The following code shows an example for `cbegin()`.,cbegin} - - @sa see @ref begin() -- returns an iterator to the beginning - @sa see @ref end() -- returns an iterator to the end - @sa see @ref cend() -- returns a const iterator to the end - - @since version 1.0.0 - */ - const_iterator cbegin() const noexcept - { - const_iterator result(this); - result.set_begin(); - return result; - } - - /*! - @brief returns an iterator to one past the last element - - Returns an iterator to one past the last element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return iterator one past the last element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - @liveexample{The following code shows an example for `end()`.,end} - - @sa see @ref cend() -- returns a const iterator to the end - @sa see @ref begin() -- returns an iterator to the beginning - @sa see @ref cbegin() -- returns a const iterator to the beginning - - @since version 1.0.0 - */ - iterator end() noexcept - { - iterator result(this); - result.set_end(); - return result; - } - - /*! - @copydoc basic_json::cend() - */ - const_iterator end() const noexcept - { - return cend(); - } - - /*! - @brief returns a const iterator to one past the last element - - Returns a const iterator to one past the last element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return const iterator one past the last element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast(*this).end()`. - - @liveexample{The following code shows an example for `cend()`.,cend} - - @sa see @ref end() -- returns an iterator to the end - @sa see @ref begin() -- returns an iterator to the beginning - @sa see @ref cbegin() -- returns a const iterator to the beginning - - @since version 1.0.0 - */ - const_iterator cend() const noexcept - { - const_iterator result(this); - result.set_end(); - return result; - } - - /*! - @brief returns an iterator to the reverse-beginning - - Returns an iterator to the reverse-beginning; that is, the last element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `reverse_iterator(end())`. - - @liveexample{The following code shows an example for `rbegin()`.,rbegin} - - @sa see @ref crbegin() -- returns a const reverse iterator to the beginning - @sa see @ref rend() -- returns a reverse iterator to the end - @sa see @ref crend() -- returns a const reverse iterator to the end - - @since version 1.0.0 - */ - reverse_iterator rbegin() noexcept - { - return reverse_iterator(end()); - } - - /*! - @copydoc basic_json::crbegin() - */ - const_reverse_iterator rbegin() const noexcept - { - return crbegin(); - } - - /*! - @brief returns an iterator to the reverse-end - - Returns an iterator to the reverse-end; that is, one before the first - element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `reverse_iterator(begin())`. - - @liveexample{The following code shows an example for `rend()`.,rend} - - @sa see @ref crend() -- returns a const reverse iterator to the end - @sa see @ref rbegin() -- returns a reverse iterator to the beginning - @sa see @ref crbegin() -- returns a const reverse iterator to the beginning - - @since version 1.0.0 - */ - reverse_iterator rend() noexcept - { - return reverse_iterator(begin()); - } - - /*! - @copydoc basic_json::crend() - */ - const_reverse_iterator rend() const noexcept - { - return crend(); - } - - /*! - @brief returns a const reverse iterator to the last element - - Returns a const iterator to the reverse-beginning; that is, the last - element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast(*this).rbegin()`. - - @liveexample{The following code shows an example for `crbegin()`.,crbegin} - - @sa see @ref rbegin() -- returns a reverse iterator to the beginning - @sa see @ref rend() -- returns a reverse iterator to the end - @sa see @ref crend() -- returns a const reverse iterator to the end - - @since version 1.0.0 - */ - const_reverse_iterator crbegin() const noexcept - { - return const_reverse_iterator(cend()); - } - - /*! - @brief returns a const reverse iterator to one before the first - - Returns a const reverse iterator to the reverse-end; that is, one before - the first element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast(*this).rend()`. - - @liveexample{The following code shows an example for `crend()`.,crend} - - @sa see @ref rend() -- returns a reverse iterator to the end - @sa see @ref rbegin() -- returns a reverse iterator to the beginning - @sa see @ref crbegin() -- returns a const reverse iterator to the beginning - - @since version 1.0.0 - */ - const_reverse_iterator crend() const noexcept - { - return const_reverse_iterator(cbegin()); - } - - public: - /*! - @brief wrapper to access iterator member functions in range-based for - - This function allows to access @ref iterator::key() and @ref - iterator::value() during range-based for loops. In these loops, a - reference to the JSON values is returned, so there is no access to the - underlying iterator. - - For loop without iterator_wrapper: - - @code{cpp} - for (auto it = j_object.begin(); it != j_object.end(); ++it) - { - std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; - } - @endcode - - Range-based for loop without iterator proxy: - - @code{cpp} - for (auto it : j_object) - { - // "it" is of type json::reference and has no key() member - std::cout << "value: " << it << '\n'; - } - @endcode - - Range-based for loop with iterator proxy: - - @code{cpp} - for (auto it : json::iterator_wrapper(j_object)) - { - std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; - } - @endcode - - @note When iterating over an array, `key()` will return the index of the - element as string (see example). - - @param[in] ref reference to a JSON value - @return iteration proxy object wrapping @a ref with an interface to use in - range-based for loops - - @liveexample{The following code shows how the wrapper is used,iterator_wrapper} - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @note The name of this function is not yet final and may change in the - future. - - @deprecated This stream operator is deprecated and will be removed in - future 4.0.0 of the library. Please use @ref items() instead; - that is, replace `json::iterator_wrapper(j)` with `j.items()`. - */ - JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items()) - static iteration_proxy iterator_wrapper(reference ref) noexcept - { - return ref.items(); - } - - /*! - @copydoc iterator_wrapper(reference) - */ - JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items()) - static iteration_proxy iterator_wrapper(const_reference ref) noexcept - { - return ref.items(); - } - - /*! - @brief helper to access iterator member functions in range-based for - - This function allows to access @ref iterator::key() and @ref - iterator::value() during range-based for loops. In these loops, a - reference to the JSON values is returned, so there is no access to the - underlying iterator. - - For loop without `items()` function: - - @code{cpp} - for (auto it = j_object.begin(); it != j_object.end(); ++it) - { - std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; - } - @endcode - - Range-based for loop without `items()` function: - - @code{cpp} - for (auto it : j_object) - { - // "it" is of type json::reference and has no key() member - std::cout << "value: " << it << '\n'; - } - @endcode - - Range-based for loop with `items()` function: - - @code{cpp} - for (auto& el : j_object.items()) - { - std::cout << "key: " << el.key() << ", value:" << el.value() << '\n'; - } - @endcode - - The `items()` function also allows to use - [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding) - (C++17): - - @code{cpp} - for (auto& [key, val] : j_object.items()) - { - std::cout << "key: " << key << ", value:" << val << '\n'; - } - @endcode - - @note When iterating over an array, `key()` will return the index of the - element as string (see example). For primitive types (e.g., numbers), - `key()` returns an empty string. - - @warning Using `items()` on temporary objects is dangerous. Make sure the - object's lifetime exeeds the iteration. See - for more - information. - - @return iteration proxy object wrapping @a ref with an interface to use in - range-based for loops - - @liveexample{The following code shows how the function is used.,items} - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 3.1.0, structured bindings support since 3.5.0. - */ - iteration_proxy items() noexcept - { - return iteration_proxy(*this); - } - - /*! - @copydoc items() - */ - iteration_proxy items() const noexcept - { - return iteration_proxy(*this); - } - - /// @} - - - ////////////// - // capacity // - ////////////// - - /// @name capacity - /// @{ - - /*! - @brief checks whether the container is empty. - - Checks if a JSON value has no elements (i.e. whether its @ref size is `0`). - - @return The return value depends on the different types and is - defined as follows: - Value type | return value - ----------- | ------------- - null | `true` - boolean | `false` - string | `false` - number | `false` - binary | `false` - object | result of function `object_t::empty()` - array | result of function `array_t::empty()` - - @liveexample{The following code uses `empty()` to check if a JSON - object contains any elements.,empty} - - @complexity Constant, as long as @ref array_t and @ref object_t satisfy - the Container concept; that is, their `empty()` functions have constant - complexity. - - @iterators No changes. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @note This function does not return whether a string stored as JSON value - is empty - it returns whether the JSON container itself is empty which is - false in the case of a string. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `begin() == end()`. - - @sa see @ref size() -- returns the number of elements - - @since version 1.0.0 - */ - bool empty() const noexcept - { - switch (m_type) - { - case value_t::null: - { - // null values are empty - return true; - } - - case value_t::array: - { - // delegate call to array_t::empty() - return m_value.array->empty(); - } - - case value_t::object: - { - // delegate call to object_t::empty() - return m_value.object->empty(); - } - - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - // all other types are nonempty - return false; - } - } - } - - /*! - @brief returns the number of elements - - Returns the number of elements in a JSON value. - - @return The return value depends on the different types and is - defined as follows: - Value type | return value - ----------- | ------------- - null | `0` - boolean | `1` - string | `1` - number | `1` - binary | `1` - object | result of function object_t::size() - array | result of function array_t::size() - - @liveexample{The following code calls `size()` on the different value - types.,size} - - @complexity Constant, as long as @ref array_t and @ref object_t satisfy - the Container concept; that is, their size() functions have constant - complexity. - - @iterators No changes. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @note This function does not return the length of a string stored as JSON - value - it returns the number of elements in the JSON value which is 1 in - the case of a string. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `std::distance(begin(), end())`. - - @sa see @ref empty() -- checks whether the container is empty - @sa see @ref max_size() -- returns the maximal number of elements - - @since version 1.0.0 - */ - size_type size() const noexcept - { - switch (m_type) - { - case value_t::null: - { - // null values are empty - return 0; - } - - case value_t::array: - { - // delegate call to array_t::size() - return m_value.array->size(); - } - - case value_t::object: - { - // delegate call to object_t::size() - return m_value.object->size(); - } - - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - // all other types have size 1 - return 1; - } - } - } - - /*! - @brief returns the maximum possible number of elements - - Returns the maximum number of elements a JSON value is able to hold due to - system or library implementation limitations, i.e. `std::distance(begin(), - end())` for the JSON value. - - @return The return value depends on the different types and is - defined as follows: - Value type | return value - ----------- | ------------- - null | `0` (same as `size()`) - boolean | `1` (same as `size()`) - string | `1` (same as `size()`) - number | `1` (same as `size()`) - binary | `1` (same as `size()`) - object | result of function `object_t::max_size()` - array | result of function `array_t::max_size()` - - @liveexample{The following code calls `max_size()` on the different value - types. Note the output is implementation specific.,max_size} - - @complexity Constant, as long as @ref array_t and @ref object_t satisfy - the Container concept; that is, their `max_size()` functions have constant - complexity. - - @iterators No changes. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of returning `b.size()` where `b` is the largest - possible JSON value. - - @sa see @ref size() -- returns the number of elements - - @since version 1.0.0 - */ - size_type max_size() const noexcept - { - switch (m_type) - { - case value_t::array: - { - // delegate call to array_t::max_size() - return m_value.array->max_size(); - } - - case value_t::object: - { - // delegate call to object_t::max_size() - return m_value.object->max_size(); - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - // all other types have max_size() == size() - return size(); - } - } - } - - /// @} - - - /////////////// - // modifiers // - /////////////// - - /// @name modifiers - /// @{ - - /*! - @brief clears the contents - - Clears the content of a JSON value and resets it to the default value as - if @ref basic_json(value_t) would have been called with the current value - type from @ref type(): - - Value type | initial value - ----------- | ------------- - null | `null` - boolean | `false` - string | `""` - number | `0` - binary | An empty byte vector - object | `{}` - array | `[]` - - @post Has the same effect as calling - @code {.cpp} - *this = basic_json(type()); - @endcode - - @liveexample{The example below shows the effect of `clear()` to different - JSON types.,clear} - - @complexity Linear in the size of the JSON value. - - @iterators All iterators, pointers and references related to this container - are invalidated. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @sa see @ref basic_json(value_t) -- constructor that creates an object with the - same value than calling `clear()` - - @since version 1.0.0 - */ - void clear() noexcept - { - switch (m_type) - { - case value_t::number_integer: - { - m_value.number_integer = 0; - break; - } - - case value_t::number_unsigned: - { - m_value.number_unsigned = 0; - break; - } - - case value_t::number_float: - { - m_value.number_float = 0.0; - break; - } - - case value_t::boolean: - { - m_value.boolean = false; - break; - } - - case value_t::string: - { - m_value.string->clear(); - break; - } - - case value_t::binary: - { - m_value.binary->clear(); - break; - } - - case value_t::array: - { - m_value.array->clear(); - break; - } - - case value_t::object: - { - m_value.object->clear(); - break; - } - - case value_t::null: - case value_t::discarded: - default: - break; - } - } - - /*! - @brief add an object to an array - - Appends the given element @a val to the end of the JSON value. If the - function is called on a JSON null value, an empty array is created before - appending @a val. - - @param[in] val the value to add to the JSON array - - @throw type_error.308 when called on a type other than JSON array or - null; example: `"cannot use push_back() with number"` - - @complexity Amortized constant. - - @liveexample{The example shows how `push_back()` and `+=` can be used to - add elements to a JSON array. Note how the `null` value was silently - converted to a JSON array.,push_back} - - @since version 1.0.0 - */ - void push_back(basic_json&& val) - { - // push_back only works for null objects or arrays - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) - { - JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this)); - } - - // transform null object into an array - if (is_null()) - { - m_type = value_t::array; - m_value = value_t::array; - assert_invariant(); - } - - // add element to array (move semantics) - const auto old_capacity = m_value.array->capacity(); - m_value.array->push_back(std::move(val)); - set_parent(m_value.array->back(), old_capacity); - // if val is moved from, basic_json move constructor marks it null so we do not call the destructor - } - - /*! - @brief add an object to an array - @copydoc push_back(basic_json&&) - */ - reference operator+=(basic_json&& val) - { - push_back(std::move(val)); - return *this; - } - - /*! - @brief add an object to an array - @copydoc push_back(basic_json&&) - */ - void push_back(const basic_json& val) - { - // push_back only works for null objects or arrays - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) - { - JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this)); - } - - // transform null object into an array - if (is_null()) - { - m_type = value_t::array; - m_value = value_t::array; - assert_invariant(); - } - - // add element to array - const auto old_capacity = m_value.array->capacity(); - m_value.array->push_back(val); - set_parent(m_value.array->back(), old_capacity); - } - - /*! - @brief add an object to an array - @copydoc push_back(basic_json&&) - */ - reference operator+=(const basic_json& val) - { - push_back(val); - return *this; - } - - /*! - @brief add an object to an object - - Inserts the given element @a val to the JSON object. If the function is - called on a JSON null value, an empty object is created before inserting - @a val. - - @param[in] val the value to add to the JSON object - - @throw type_error.308 when called on a type other than JSON object or - null; example: `"cannot use push_back() with number"` - - @complexity Logarithmic in the size of the container, O(log(`size()`)). - - @liveexample{The example shows how `push_back()` and `+=` can be used to - add elements to a JSON object. Note how the `null` value was silently - converted to a JSON object.,push_back__object_t__value} - - @since version 1.0.0 - */ - void push_back(const typename object_t::value_type& val) - { - // push_back only works for null objects or objects - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object()))) - { - JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this)); - } - - // transform null object into an object - if (is_null()) - { - m_type = value_t::object; - m_value = value_t::object; - assert_invariant(); - } - - // add element to object - auto res = m_value.object->insert(val); - set_parent(res.first->second); - } - - /*! - @brief add an object to an object - @copydoc push_back(const typename object_t::value_type&) - */ - reference operator+=(const typename object_t::value_type& val) - { - push_back(val); - return *this; - } - - /*! - @brief add an object to an object - - This function allows to use `push_back` with an initializer list. In case - - 1. the current value is an object, - 2. the initializer list @a init contains only two elements, and - 3. the first element of @a init is a string, - - @a init is converted into an object element and added using - @ref push_back(const typename object_t::value_type&). Otherwise, @a init - is converted to a JSON value and added using @ref push_back(basic_json&&). - - @param[in] init an initializer list - - @complexity Linear in the size of the initializer list @a init. - - @note This function is required to resolve an ambiguous overload error, - because pairs like `{"key", "value"}` can be both interpreted as - `object_t::value_type` or `std::initializer_list`, see - https://github.com/nlohmann/json/issues/235 for more information. - - @liveexample{The example shows how initializer lists are treated as - objects when possible.,push_back__initializer_list} - */ - void push_back(initializer_list_t init) - { - if (is_object() && init.size() == 2 && (*init.begin())->is_string()) - { - basic_json&& key = init.begin()->moved_or_copied(); - push_back(typename object_t::value_type( - std::move(key.get_ref()), (init.begin() + 1)->moved_or_copied())); - } - else - { - push_back(basic_json(init)); - } - } - - /*! - @brief add an object to an object - @copydoc push_back(initializer_list_t) - */ - reference operator+=(initializer_list_t init) - { - push_back(init); - return *this; - } - - /*! - @brief add an object to an array - - Creates a JSON value from the passed parameters @a args to the end of the - JSON value. If the function is called on a JSON null value, an empty array - is created before appending the value created from @a args. - - @param[in] args arguments to forward to a constructor of @ref basic_json - @tparam Args compatible types to create a @ref basic_json object - - @return reference to the inserted element - - @throw type_error.311 when called on a type other than JSON array or - null; example: `"cannot use emplace_back() with number"` - - @complexity Amortized constant. - - @liveexample{The example shows how `push_back()` can be used to add - elements to a JSON array. Note how the `null` value was silently converted - to a JSON array.,emplace_back} - - @since version 2.0.8, returns reference since 3.7.0 - */ - template - reference emplace_back(Args&& ... args) - { - // emplace_back only works for null objects or arrays - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) - { - JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this)); - } - - // transform null object into an array - if (is_null()) - { - m_type = value_t::array; - m_value = value_t::array; - assert_invariant(); - } - - // add element to array (perfect forwarding) - const auto old_capacity = m_value.array->capacity(); - m_value.array->emplace_back(std::forward(args)...); - return set_parent(m_value.array->back(), old_capacity); - } - - /*! - @brief add an object to an object if key does not exist - - Inserts a new element into a JSON object constructed in-place with the - given @a args if there is no element with the key in the container. If the - function is called on a JSON null value, an empty object is created before - appending the value created from @a args. - - @param[in] args arguments to forward to a constructor of @ref basic_json - @tparam Args compatible types to create a @ref basic_json object - - @return a pair consisting of an iterator to the inserted element, or the - already-existing element if no insertion happened, and a bool - denoting whether the insertion took place. - - @throw type_error.311 when called on a type other than JSON object or - null; example: `"cannot use emplace() with number"` - - @complexity Logarithmic in the size of the container, O(log(`size()`)). - - @liveexample{The example shows how `emplace()` can be used to add elements - to a JSON object. Note how the `null` value was silently converted to a - JSON object. Further note how no value is added if there was already one - value stored with the same key.,emplace} - - @since version 2.0.8 - */ - template - std::pair emplace(Args&& ... args) - { - // emplace only works for null objects or arrays - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object()))) - { - JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this)); - } - - // transform null object into an object - if (is_null()) - { - m_type = value_t::object; - m_value = value_t::object; - assert_invariant(); - } - - // add element to array (perfect forwarding) - auto res = m_value.object->emplace(std::forward(args)...); - set_parent(res.first->second); - - // create result iterator and set iterator to the result of emplace - auto it = begin(); - it.m_it.object_iterator = res.first; - - // return pair of iterator and boolean - return {it, res.second}; - } - - /// Helper for insertion of an iterator - /// @note: This uses std::distance to support GCC 4.8, - /// see https://github.com/nlohmann/json/pull/1257 - template - iterator insert_iterator(const_iterator pos, Args&& ... args) - { - iterator result(this); - JSON_ASSERT(m_value.array != nullptr); - - auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator); - m_value.array->insert(pos.m_it.array_iterator, std::forward(args)...); - result.m_it.array_iterator = m_value.array->begin() + insert_pos; - - // This could have been written as: - // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val); - // but the return value of insert is missing in GCC 4.8, so it is written this way instead. - - set_parents(); - return result; - } - - /*! - @brief inserts element - - Inserts element @a val before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] val element to insert - @return iterator pointing to the inserted @a val. - - @throw type_error.309 if called on JSON values other than arrays; - example: `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - - @complexity Constant plus linear in the distance between @a pos and end of - the container. - - @liveexample{The example shows how `insert()` is used.,insert} - - @since version 1.0.0 - */ - iterator insert(const_iterator pos, const basic_json& val) - { - // insert only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this)); - } - - // insert to array and return iterator - return insert_iterator(pos, val); - } - - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this)); - } - - /*! - @brief inserts element - @copydoc insert(const_iterator, const basic_json&) - */ - iterator insert(const_iterator pos, basic_json&& val) - { - return insert(pos, val); - } - - /*! - @brief inserts elements - - Inserts @a cnt copies of @a val before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] cnt number of copies of @a val to insert - @param[in] val element to insert - @return iterator pointing to the first element inserted, or @a pos if - `cnt==0` - - @throw type_error.309 if called on JSON values other than arrays; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - - @complexity Linear in @a cnt plus linear in the distance between @a pos - and end of the container. - - @liveexample{The example shows how `insert()` is used.,insert__count} - - @since version 1.0.0 - */ - iterator insert(const_iterator pos, size_type cnt, const basic_json& val) - { - // insert only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this)); - } - - // insert to array and return iterator - return insert_iterator(pos, cnt, val); - } - - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this)); - } - - /*! - @brief inserts elements - - Inserts elements from range `[first, last)` before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] first begin of the range of elements to insert - @param[in] last end of the range of elements to insert - - @throw type_error.309 if called on JSON values other than arrays; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - @throw invalid_iterator.210 if @a first and @a last do not belong to the - same JSON value; example: `"iterators do not fit"` - @throw invalid_iterator.211 if @a first or @a last are iterators into - container for which insert is called; example: `"passed iterators may not - belong to container"` - - @return iterator pointing to the first element inserted, or @a pos if - `first==last` - - @complexity Linear in `std::distance(first, last)` plus linear in the - distance between @a pos and end of the container. - - @liveexample{The example shows how `insert()` is used.,insert__range} - - @since version 1.0.0 - */ - iterator insert(const_iterator pos, const_iterator first, const_iterator last) - { - // insert only works for arrays - if (JSON_HEDLEY_UNLIKELY(!is_array())) - { - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this)); - } - - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this)); - } - - // check if range iterators belong to the same JSON object - if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) - { - JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this)); - } - - if (JSON_HEDLEY_UNLIKELY(first.m_object == this)) - { - JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this)); - } - - // insert to array and return iterator - return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator); - } - - /*! - @brief inserts elements - - Inserts elements from initializer list @a ilist before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] ilist initializer list to insert the values from - - @throw type_error.309 if called on JSON values other than arrays; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - - @return iterator pointing to the first element inserted, or @a pos if - `ilist` is empty - - @complexity Linear in `ilist.size()` plus linear in the distance between - @a pos and end of the container. - - @liveexample{The example shows how `insert()` is used.,insert__ilist} - - @since version 1.0.0 - */ - iterator insert(const_iterator pos, initializer_list_t ilist) - { - // insert only works for arrays - if (JSON_HEDLEY_UNLIKELY(!is_array())) - { - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this)); - } - - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this)); - } - - // insert to array and return iterator - return insert_iterator(pos, ilist.begin(), ilist.end()); - } - - /*! - @brief inserts elements - - Inserts elements from range `[first, last)`. - - @param[in] first begin of the range of elements to insert - @param[in] last end of the range of elements to insert - - @throw type_error.309 if called on JSON values other than objects; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if iterator @a first or @a last does does not - point to an object; example: `"iterators first and last must point to - objects"` - @throw invalid_iterator.210 if @a first and @a last do not belong to the - same JSON value; example: `"iterators do not fit"` - - @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number - of elements to insert. - - @liveexample{The example shows how `insert()` is used.,insert__range_object} - - @since version 3.0.0 - */ - void insert(const_iterator first, const_iterator last) - { - // insert only works for objects - if (JSON_HEDLEY_UNLIKELY(!is_object())) - { - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this)); - } - - // check if range iterators belong to the same JSON object - if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) - { - JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this)); - } - - // passed iterators must belong to objects - if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object())) - { - JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this)); - } - - m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator); - } - - /*! - @brief updates a JSON object from another object, overwriting existing keys - - Inserts all values from JSON object @a j and overwrites existing keys. - - @param[in] j JSON object to read values from - - @throw type_error.312 if called on JSON values other than objects; example: - `"cannot use update() with string"` - - @complexity O(N*log(size() + N)), where N is the number of elements to - insert. - - @liveexample{The example shows how `update()` is used.,update} - - @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update - - @since version 3.0.0 - */ - void update(const_reference j) - { - // implicitly convert null value to an empty object - if (is_null()) - { - m_type = value_t::object; - m_value.object = create(); - assert_invariant(); - } - - if (JSON_HEDLEY_UNLIKELY(!is_object())) - { - JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this)); - } - if (JSON_HEDLEY_UNLIKELY(!j.is_object())) - { - JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this)); - } - - for (auto it = j.cbegin(); it != j.cend(); ++it) - { - m_value.object->operator[](it.key()) = it.value(); - } - } - - /*! - @brief updates a JSON object from another object, overwriting existing keys - - Inserts all values from from range `[first, last)` and overwrites existing - keys. - - @param[in] first begin of the range of elements to insert - @param[in] last end of the range of elements to insert - - @throw type_error.312 if called on JSON values other than objects; example: - `"cannot use update() with string"` - @throw invalid_iterator.202 if iterator @a first or @a last does does not - point to an object; example: `"iterators first and last must point to - objects"` - @throw invalid_iterator.210 if @a first and @a last do not belong to the - same JSON value; example: `"iterators do not fit"` - - @complexity O(N*log(size() + N)), where N is the number of elements to - insert. - - @liveexample{The example shows how `update()` is used__range.,update} - - @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update - - @since version 3.0.0 - */ - void update(const_iterator first, const_iterator last) - { - // implicitly convert null value to an empty object - if (is_null()) - { - m_type = value_t::object; - m_value.object = create(); - assert_invariant(); - } - - if (JSON_HEDLEY_UNLIKELY(!is_object())) - { - JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this)); - } - - // check if range iterators belong to the same JSON object - if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) - { - JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this)); - } - - // passed iterators must belong to objects - if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object() - || !last.m_object->is_object())) - { - JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this)); - } - - for (auto it = first; it != last; ++it) - { - m_value.object->operator[](it.key()) = it.value(); - } - } - - /*! - @brief exchanges the values - - Exchanges the contents of the JSON value with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other JSON value to exchange the contents with - - @complexity Constant. - - @liveexample{The example below shows how JSON values can be swapped with - `swap()`.,swap__reference} - - @since version 1.0.0 - */ - void swap(reference other) noexcept ( - std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_assignable::value&& - std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_assignable::value - ) - { - std::swap(m_type, other.m_type); - std::swap(m_value, other.m_value); - - set_parents(); - other.set_parents(); - assert_invariant(); - } - - /*! - @brief exchanges the values - - Exchanges the contents of the JSON value from @a left with those of @a right. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. implemented as a friend function callable via ADL. - - @param[in,out] left JSON value to exchange the contents with - @param[in,out] right JSON value to exchange the contents with - - @complexity Constant. - - @liveexample{The example below shows how JSON values can be swapped with - `swap()`.,swap__reference} - - @since version 1.0.0 - */ - friend void swap(reference left, reference right) noexcept ( - std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_assignable::value&& - std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_assignable::value - ) - { - left.swap(right); - } - - /*! - @brief exchanges the values - - Exchanges the contents of a JSON array with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other array to exchange the contents with - - @throw type_error.310 when JSON value is not an array; example: `"cannot - use swap() with string"` - - @complexity Constant. - - @liveexample{The example below shows how arrays can be swapped with - `swap()`.,swap__array_t} - - @since version 1.0.0 - */ - void swap(array_t& other) // NOLINT(bugprone-exception-escape) - { - // swap only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - std::swap(*(m_value.array), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief exchanges the values - - Exchanges the contents of a JSON object with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other object to exchange the contents with - - @throw type_error.310 when JSON value is not an object; example: - `"cannot use swap() with string"` - - @complexity Constant. - - @liveexample{The example below shows how objects can be swapped with - `swap()`.,swap__object_t} - - @since version 1.0.0 - */ - void swap(object_t& other) // NOLINT(bugprone-exception-escape) - { - // swap only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - std::swap(*(m_value.object), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief exchanges the values - - Exchanges the contents of a JSON string with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other string to exchange the contents with - - @throw type_error.310 when JSON value is not a string; example: `"cannot - use swap() with boolean"` - - @complexity Constant. - - @liveexample{The example below shows how strings can be swapped with - `swap()`.,swap__string_t} - - @since version 1.0.0 - */ - void swap(string_t& other) // NOLINT(bugprone-exception-escape) - { - // swap only works for strings - if (JSON_HEDLEY_LIKELY(is_string())) - { - std::swap(*(m_value.string), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief exchanges the values - - Exchanges the contents of a JSON string with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other binary to exchange the contents with - - @throw type_error.310 when JSON value is not a string; example: `"cannot - use swap() with boolean"` - - @complexity Constant. - - @liveexample{The example below shows how strings can be swapped with - `swap()`.,swap__binary_t} - - @since version 3.8.0 - */ - void swap(binary_t& other) // NOLINT(bugprone-exception-escape) - { - // swap only works for strings - if (JSON_HEDLEY_LIKELY(is_binary())) - { - std::swap(*(m_value.binary), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this)); - } - } - - /// @copydoc swap(binary_t&) - void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape) - { - // swap only works for strings - if (JSON_HEDLEY_LIKELY(is_binary())) - { - std::swap(*(m_value.binary), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this)); - } - } - - /// @} - - public: - ////////////////////////////////////////// - // lexicographical comparison operators // - ////////////////////////////////////////// - - /// @name lexicographical comparison operators - /// @{ - - /*! - @brief comparison: equal - - Compares two JSON values for equality according to the following rules: - - Two JSON values are equal if (1) they are from the same type and (2) - their stored values are the same according to their respective - `operator==`. - - Integer and floating-point numbers are automatically converted before - comparison. Note that two NaN values are always treated as unequal. - - Two JSON null values are equal. - - @note Floating-point inside JSON values numbers are compared with - `json::number_float_t::operator==` which is `double::operator==` by - default. To compare floating-point while respecting an epsilon, an alternative - [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39) - could be used, for instance - @code {.cpp} - template::value, T>::type> - inline bool is_same(T a, T b, T epsilon = std::numeric_limits::epsilon()) noexcept - { - return std::abs(a - b) <= epsilon; - } - @endcode - Or you can self-defined operator equal function like this: - @code {.cpp} - bool my_equal(const_reference lhs, const_reference rhs) { - const auto lhs_type lhs.type(); - const auto rhs_type rhs.type(); - if (lhs_type == rhs_type) { - switch(lhs_type) - // self_defined case - case value_t::number_float: - return std::abs(lhs - rhs) <= std::numeric_limits::epsilon(); - // other cases remain the same with the original - ... - } - ... - } - @endcode - - @note NaN values never compare equal to themselves or to other NaN values. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether the values @a lhs and @a rhs are equal - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @complexity Linear. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__equal} - - @since version 1.0.0 - */ - friend bool operator==(const_reference lhs, const_reference rhs) noexcept - { -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - const auto lhs_type = lhs.type(); - const auto rhs_type = rhs.type(); - - if (lhs_type == rhs_type) - { - switch (lhs_type) - { - case value_t::array: - return *lhs.m_value.array == *rhs.m_value.array; - - case value_t::object: - return *lhs.m_value.object == *rhs.m_value.object; - - case value_t::null: - return true; - - case value_t::string: - return *lhs.m_value.string == *rhs.m_value.string; - - case value_t::boolean: - return lhs.m_value.boolean == rhs.m_value.boolean; - - case value_t::number_integer: - return lhs.m_value.number_integer == rhs.m_value.number_integer; - - case value_t::number_unsigned: - return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned; - - case value_t::number_float: - return lhs.m_value.number_float == rhs.m_value.number_float; - - case value_t::binary: - return *lhs.m_value.binary == *rhs.m_value.binary; - - case value_t::discarded: - default: - return false; - } - } - else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) - { - return static_cast(lhs.m_value.number_integer) == rhs.m_value.number_float; - } - else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) - { - return lhs.m_value.number_float == static_cast(rhs.m_value.number_integer); - } - else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) - { - return static_cast(lhs.m_value.number_unsigned) == rhs.m_value.number_float; - } - else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) - { - return lhs.m_value.number_float == static_cast(rhs.m_value.number_unsigned); - } - else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) - { - return static_cast(lhs.m_value.number_unsigned) == rhs.m_value.number_integer; - } - else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) - { - return lhs.m_value.number_integer == static_cast(rhs.m_value.number_unsigned); - } - - return false; -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - } - - /*! - @brief comparison: equal - @copydoc operator==(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator==(const_reference lhs, ScalarType rhs) noexcept - { - return lhs == basic_json(rhs); - } - - /*! - @brief comparison: equal - @copydoc operator==(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator==(ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) == rhs; - } - - /*! - @brief comparison: not equal - - Compares two JSON values for inequality by calculating `not (lhs == rhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether the values @a lhs and @a rhs are not equal - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__notequal} - - @since version 1.0.0 - */ - friend bool operator!=(const_reference lhs, const_reference rhs) noexcept - { - return !(lhs == rhs); - } - - /*! - @brief comparison: not equal - @copydoc operator!=(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept - { - return lhs != basic_json(rhs); - } - - /*! - @brief comparison: not equal - @copydoc operator!=(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) != rhs; - } - - /*! - @brief comparison: less than - - Compares whether one JSON value @a lhs is less than another JSON value @a - rhs according to the following rules: - - If @a lhs and @a rhs have the same type, the values are compared using - the default `<` operator. - - Integer and floating-point numbers are automatically converted before - comparison - - In case @a lhs and @a rhs have different types, the values are ignored - and the order of the types is considered, see - @ref operator<(const value_t, const value_t). - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is less than @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__less} - - @since version 1.0.0 - */ - friend bool operator<(const_reference lhs, const_reference rhs) noexcept - { - const auto lhs_type = lhs.type(); - const auto rhs_type = rhs.type(); - - if (lhs_type == rhs_type) - { - switch (lhs_type) - { - case value_t::array: - // note parentheses are necessary, see - // https://github.com/nlohmann/json/issues/1530 - return (*lhs.m_value.array) < (*rhs.m_value.array); - - case value_t::object: - return (*lhs.m_value.object) < (*rhs.m_value.object); - - case value_t::null: - return false; - - case value_t::string: - return (*lhs.m_value.string) < (*rhs.m_value.string); - - case value_t::boolean: - return (lhs.m_value.boolean) < (rhs.m_value.boolean); - - case value_t::number_integer: - return (lhs.m_value.number_integer) < (rhs.m_value.number_integer); - - case value_t::number_unsigned: - return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned); - - case value_t::number_float: - return (lhs.m_value.number_float) < (rhs.m_value.number_float); - - case value_t::binary: - return (*lhs.m_value.binary) < (*rhs.m_value.binary); - - case value_t::discarded: - default: - return false; - } - } - else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) - { - return static_cast(lhs.m_value.number_integer) < rhs.m_value.number_float; - } - else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) - { - return lhs.m_value.number_float < static_cast(rhs.m_value.number_integer); - } - else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) - { - return static_cast(lhs.m_value.number_unsigned) < rhs.m_value.number_float; - } - else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) - { - return lhs.m_value.number_float < static_cast(rhs.m_value.number_unsigned); - } - else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) - { - return lhs.m_value.number_integer < static_cast(rhs.m_value.number_unsigned); - } - else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) - { - return static_cast(lhs.m_value.number_unsigned) < rhs.m_value.number_integer; - } - - // We only reach this line if we cannot compare values. In that case, - // we compare types. Note we have to call the operator explicitly, - // because MSVC has problems otherwise. - return operator<(lhs_type, rhs_type); - } - - /*! - @brief comparison: less than - @copydoc operator<(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator<(const_reference lhs, ScalarType rhs) noexcept - { - return lhs < basic_json(rhs); - } - - /*! - @brief comparison: less than - @copydoc operator<(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator<(ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) < rhs; - } - - /*! - @brief comparison: less than or equal - - Compares whether one JSON value @a lhs is less than or equal to another - JSON value by calculating `not (rhs < lhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is less than or equal to @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__greater} - - @since version 1.0.0 - */ - friend bool operator<=(const_reference lhs, const_reference rhs) noexcept - { - return !(rhs < lhs); - } - - /*! - @brief comparison: less than or equal - @copydoc operator<=(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept - { - return lhs <= basic_json(rhs); - } - - /*! - @brief comparison: less than or equal - @copydoc operator<=(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) <= rhs; - } - - /*! - @brief comparison: greater than - - Compares whether one JSON value @a lhs is greater than another - JSON value by calculating `not (lhs <= rhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is greater than to @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__lessequal} - - @since version 1.0.0 - */ - friend bool operator>(const_reference lhs, const_reference rhs) noexcept - { - return !(lhs <= rhs); - } - - /*! - @brief comparison: greater than - @copydoc operator>(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator>(const_reference lhs, ScalarType rhs) noexcept - { - return lhs > basic_json(rhs); - } - - /*! - @brief comparison: greater than - @copydoc operator>(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator>(ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) > rhs; - } - - /*! - @brief comparison: greater than or equal - - Compares whether one JSON value @a lhs is greater than or equal to another - JSON value by calculating `not (lhs < rhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is greater than or equal to @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__greaterequal} - - @since version 1.0.0 - */ - friend bool operator>=(const_reference lhs, const_reference rhs) noexcept - { - return !(lhs < rhs); - } - - /*! - @brief comparison: greater than or equal - @copydoc operator>=(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept - { - return lhs >= basic_json(rhs); - } - - /*! - @brief comparison: greater than or equal - @copydoc operator>=(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) >= rhs; - } - - /// @} - - /////////////////// - // serialization // - /////////////////// - - /// @name serialization - /// @{ -#ifndef JSON_NO_IO - /*! - @brief serialize to stream - - Serialize the given JSON value @a j to the output stream @a o. The JSON - value will be serialized using the @ref dump member function. - - - The indentation of the output can be controlled with the member variable - `width` of the output stream @a o. For instance, using the manipulator - `std::setw(4)` on @a o sets the indentation level to `4` and the - serialization result is the same as calling `dump(4)`. - - - The indentation character can be controlled with the member variable - `fill` of the output stream @a o. For instance, the manipulator - `std::setfill('\\t')` sets indentation to use a tab character rather than - the default space character. - - @param[in,out] o stream to serialize to - @param[in] j JSON value to serialize - - @return the stream @a o - - @throw type_error.316 if a string stored inside the JSON value is not - UTF-8 encoded - - @complexity Linear. - - @liveexample{The example below shows the serialization with different - parameters to `width` to adjust the indentation level.,operator_serialize} - - @since version 1.0.0; indentation character added in version 3.0.0 - */ - friend std::ostream& operator<<(std::ostream& o, const basic_json& j) - { - // read width member and use it as indentation parameter if nonzero - const bool pretty_print = o.width() > 0; - const auto indentation = pretty_print ? o.width() : 0; - - // reset width to 0 for subsequent calls to this stream - o.width(0); - - // do the actual serialization - serializer s(detail::output_adapter(o), o.fill()); - s.dump(j, pretty_print, false, static_cast(indentation)); - return o; - } - - /*! - @brief serialize to stream - @deprecated This stream operator is deprecated and will be removed in - future 4.0.0 of the library. Please use - @ref operator<<(std::ostream&, const basic_json&) - instead; that is, replace calls like `j >> o;` with `o << j;`. - @since version 1.0.0; deprecated since version 3.0.0 - */ - JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&)) - friend std::ostream& operator>>(const basic_json& j, std::ostream& o) - { - return o << j; - } -#endif // JSON_NO_IO - /// @} - - - ///////////////////// - // deserialization // - ///////////////////// - - /// @name deserialization - /// @{ - - /*! - @brief deserialize from a compatible input - - @tparam InputType A compatible input, for instance - - an std::istream object - - a FILE pointer - - a C-style array of characters - - a pointer to a null-terminated string of single byte characters - - an object obj for which begin(obj) and end(obj) produces a valid pair of - iterators. - - @param[in] i input to read from - @param[in] cb a parser callback function of type @ref parser_callback_t - which is used to control the deserialization by filtering unwanted values - (optional) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.101 if a parse error occurs; example: `""unexpected end - of input; expected string literal""` - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. The complexity can be higher if the parser callback function - @a cb or reading from the input @a i has a super-linear complexity. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below demonstrates the `parse()` function reading - from an array.,parse__array__parser_callback_t} - - @liveexample{The example below demonstrates the `parse()` function with - and without callback function.,parse__string__parser_callback_t} - - @liveexample{The example below demonstrates the `parse()` function with - and without callback function.,parse__istream__parser_callback_t} - - @liveexample{The example below demonstrates the `parse()` function reading - from a contiguous container.,parse__contiguouscontainer__parser_callback_t} - - @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to - ignore comments. - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json parse(InputType&& i, - const parser_callback_t cb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false) - { - basic_json result; - parser(detail::input_adapter(std::forward(i)), cb, allow_exceptions, ignore_comments).parse(true, result); - return result; - } - - /*! - @brief deserialize from a pair of character iterators - - The value_type of the iterator must be a integral type with size of 1, 2 or - 4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32. - - @param[in] first iterator to start of character range - @param[in] last iterator to end of character range - @param[in] cb a parser callback function of type @ref parser_callback_t - which is used to control the deserialization by filtering unwanted values - (optional) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.101 if a parse error occurs; example: `""unexpected end - of input; expected string literal""` - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json parse(IteratorType first, - IteratorType last, - const parser_callback_t cb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false) - { - basic_json result; - parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result); - return result; - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len)) - static basic_json parse(detail::span_input_adapter&& i, - const parser_callback_t cb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false) - { - basic_json result; - parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result); - return result; - } - - /*! - @brief check if the input is valid JSON - - Unlike the @ref parse(InputType&&, const parser_callback_t,const bool) - function, this function neither throws an exception in case of invalid JSON - input (i.e., a parse error) nor creates diagnostic information. - - @tparam InputType A compatible input, for instance - - an std::istream object - - a FILE pointer - - a C-style array of characters - - a pointer to a null-terminated string of single byte characters - - an object obj for which begin(obj) and end(obj) produces a valid pair of - iterators. - - @param[in] i input to read from - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default) - - @return Whether the input read from @a i is valid JSON. - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below demonstrates the `accept()` function reading - from a string.,accept__string} - */ - template - static bool accept(InputType&& i, - const bool ignore_comments = false) - { - return parser(detail::input_adapter(std::forward(i)), nullptr, false, ignore_comments).accept(true); - } - - template - static bool accept(IteratorType first, IteratorType last, - const bool ignore_comments = false) - { - return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true); - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len)) - static bool accept(detail::span_input_adapter&& i, - const bool ignore_comments = false) - { - return parser(i.get(), nullptr, false, ignore_comments).accept(true); - } - - /*! - @brief generate SAX events - - The SAX event lister must follow the interface of @ref json_sax. - - This function reads from a compatible input. Examples are: - - an std::istream object - - a FILE pointer - - a C-style array of characters - - a pointer to a null-terminated string of single byte characters - - an object obj for which begin(obj) and end(obj) produces a valid pair of - iterators. - - @param[in] i input to read from - @param[in,out] sax SAX event listener - @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON) - @param[in] strict whether the input has to be consumed completely - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default); only applies to the JSON file format. - - @return return value of the last processed SAX event - - @throw parse_error.101 if a parse error occurs; example: `""unexpected end - of input; expected string literal""` - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. The complexity can be higher if the SAX consumer @a sax has - a super-linear complexity. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below demonstrates the `sax_parse()` function - reading from string and processing the events with a user-defined SAX - event consumer.,sax_parse} - - @since version 3.2.0 - */ - template - JSON_HEDLEY_NON_NULL(2) - static bool sax_parse(InputType&& i, SAX* sax, - input_format_t format = input_format_t::json, - const bool strict = true, - const bool ignore_comments = false) - { - auto ia = detail::input_adapter(std::forward(i)); - return format == input_format_t::json - ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - : detail::binary_reader(std::move(ia)).sax_parse(format, sax, strict); - } - - template - JSON_HEDLEY_NON_NULL(3) - static bool sax_parse(IteratorType first, IteratorType last, SAX* sax, - input_format_t format = input_format_t::json, - const bool strict = true, - const bool ignore_comments = false) - { - auto ia = detail::input_adapter(std::move(first), std::move(last)); - return format == input_format_t::json - ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - : detail::binary_reader(std::move(ia)).sax_parse(format, sax, strict); - } - - template - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...)) - JSON_HEDLEY_NON_NULL(2) - static bool sax_parse(detail::span_input_adapter&& i, SAX* sax, - input_format_t format = input_format_t::json, - const bool strict = true, - const bool ignore_comments = false) - { - auto ia = i.get(); - return format == input_format_t::json - // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - : detail::binary_reader(std::move(ia)).sax_parse(format, sax, strict); - } -#ifndef JSON_NO_IO - /*! - @brief deserialize from stream - @deprecated This stream operator is deprecated and will be removed in - version 4.0.0 of the library. Please use - @ref operator>>(std::istream&, basic_json&) - instead; that is, replace calls like `j << i;` with `i >> j;`. - @since version 1.0.0; deprecated since version 3.0.0 - */ - JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&)) - friend std::istream& operator<<(basic_json& j, std::istream& i) - { - return operator>>(i, j); - } - - /*! - @brief deserialize from stream - - Deserializes an input stream to a JSON value. - - @param[in,out] i input stream to read a serialized JSON value from - @param[in,out] j JSON value to write the deserialized input to - - @throw parse_error.101 in case of an unexpected token - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below shows how a JSON value is constructed by - reading a serialization from a stream.,operator_deserialize} - - @sa parse(std::istream&, const parser_callback_t) for a variant with a - parser callback function to filter values while parsing - - @since version 1.0.0 - */ - friend std::istream& operator>>(std::istream& i, basic_json& j) - { - parser(detail::input_adapter(i)).parse(false, j); - return i; - } -#endif // JSON_NO_IO - /// @} - - /////////////////////////// - // convenience functions // - /////////////////////////// - - /*! - @brief return the type as string - - Returns the type name as string to be used in error messages - usually to - indicate that a function was called on a wrong JSON type. - - @return a string representation of a the @a m_type member: - Value type | return value - ----------- | ------------- - null | `"null"` - boolean | `"boolean"` - string | `"string"` - number | `"number"` (for all number types) - object | `"object"` - array | `"array"` - binary | `"binary"` - discarded | `"discarded"` - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @complexity Constant. - - @liveexample{The following code exemplifies `type_name()` for all JSON - types.,type_name} - - @sa see @ref type() -- return the type of the JSON value - @sa see @ref operator value_t() -- return the type of the JSON value (implicit) - - @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept` - since 3.0.0 - */ - JSON_HEDLEY_RETURNS_NON_NULL - const char* type_name() const noexcept - { - { - switch (m_type) - { - case value_t::null: - return "null"; - case value_t::object: - return "object"; - case value_t::array: - return "array"; - case value_t::string: - return "string"; - case value_t::boolean: - return "boolean"; - case value_t::binary: - return "binary"; - case value_t::discarded: - return "discarded"; - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - default: - return "number"; - } - } - } - - - JSON_PRIVATE_UNLESS_TESTED: - ////////////////////// - // member variables // - ////////////////////// - - /// the type of the current element - value_t m_type = value_t::null; - - /// the value of the current element - json_value m_value = {}; - -#if JSON_DIAGNOSTICS - /// a pointer to a parent value (for debugging purposes) - basic_json* m_parent = nullptr; -#endif - - ////////////////////////////////////////// - // binary serialization/deserialization // - ////////////////////////////////////////// - - /// @name binary serialization/deserialization support - /// @{ - - public: - /*! - @brief create a CBOR serialization of a given JSON value - - Serializes a given JSON value @a j to a byte vector using the CBOR (Concise - Binary Object Representation) serialization format. CBOR is a binary - serialization format which aims to be more compact than JSON itself, yet - more efficient to parse. - - The library uses the following mapping from JSON values types to - CBOR types according to the CBOR specification (RFC 7049): - - JSON value type | value/range | CBOR type | first byte - --------------- | ------------------------------------------ | ---------------------------------- | --------------- - null | `null` | Null | 0xF6 - boolean | `true` | True | 0xF5 - boolean | `false` | False | 0xF4 - number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B - number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A - number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39 - number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38 - number_integer | -24..-1 | Negative integer | 0x20..0x37 - number_integer | 0..23 | Integer | 0x00..0x17 - number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18 - number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 - number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A - number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B - number_unsigned | 0..23 | Integer | 0x00..0x17 - number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18 - number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 - number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A - number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B - number_float | *any value representable by a float* | Single-Precision Float | 0xFA - number_float | *any value NOT representable by a float* | Double-Precision Float | 0xFB - string | *length*: 0..23 | UTF-8 string | 0x60..0x77 - string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78 - string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79 - string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A - string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B - array | *size*: 0..23 | array | 0x80..0x97 - array | *size*: 23..255 | array (1 byte follow) | 0x98 - array | *size*: 256..65535 | array (2 bytes follow) | 0x99 - array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A - array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B - object | *size*: 0..23 | map | 0xA0..0xB7 - object | *size*: 23..255 | map (1 byte follow) | 0xB8 - object | *size*: 256..65535 | map (2 bytes follow) | 0xB9 - object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA - object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB - binary | *size*: 0..23 | byte string | 0x40..0x57 - binary | *size*: 23..255 | byte string (1 byte follow) | 0x58 - binary | *size*: 256..65535 | byte string (2 bytes follow) | 0x59 - binary | *size*: 65536..4294967295 | byte string (4 bytes follow) | 0x5A - binary | *size*: 4294967296..18446744073709551615 | byte string (8 bytes follow) | 0x5B - - Binary values with subtype are mapped to tagged values (0xD8..0xDB) - depending on the subtype, followed by a byte string, see "binary" cells - in the table above. - - @note The mapping is **complete** in the sense that any JSON value type - can be converted to a CBOR value. - - @note If NaN or Infinity are stored inside a JSON number, they are - serialized properly. This behavior differs from the @ref dump() - function which serializes NaN or Infinity to `null`. - - @note The following CBOR types are not used in the conversion: - - UTF-8 strings terminated by "break" (0x7F) - - arrays terminated by "break" (0x9F) - - maps terminated by "break" (0xBF) - - byte strings terminated by "break" (0x5F) - - date/time (0xC0..0xC1) - - bignum (0xC2..0xC3) - - decimal fraction (0xC4) - - bigfloat (0xC5) - - expected conversions (0xD5..0xD7) - - simple values (0xE0..0xF3, 0xF8) - - undefined (0xF7) - - half-precision floats (0xF9) - - break (0xFF) - - @param[in] j JSON value to serialize - @return CBOR serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in CBOR format.,to_cbor} - - @sa http://cbor.io - @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the - analogous deserialization - @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format - @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the - related UBJSON format - - @since version 2.0.9; compact representation of floating-point numbers - since version 3.8.0 - */ - static std::vector to_cbor(const basic_json& j) - { - std::vector result; - to_cbor(j, result); - return result; - } - - static void to_cbor(const basic_json& j, detail::output_adapter o) - { - binary_writer(o).write_cbor(j); - } - - static void to_cbor(const basic_json& j, detail::output_adapter o) - { - binary_writer(o).write_cbor(j); - } - - /*! - @brief create a MessagePack serialization of a given JSON value - - Serializes a given JSON value @a j to a byte vector using the MessagePack - serialization format. MessagePack is a binary serialization format which - aims to be more compact than JSON itself, yet more efficient to parse. - - The library uses the following mapping from JSON values types to - MessagePack types according to the MessagePack specification: - - JSON value type | value/range | MessagePack type | first byte - --------------- | --------------------------------- | ---------------- | ---------- - null | `null` | nil | 0xC0 - boolean | `true` | true | 0xC3 - boolean | `false` | false | 0xC2 - number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3 - number_integer | -2147483648..-32769 | int32 | 0xD2 - number_integer | -32768..-129 | int16 | 0xD1 - number_integer | -128..-33 | int8 | 0xD0 - number_integer | -32..-1 | negative fixint | 0xE0..0xFF - number_integer | 0..127 | positive fixint | 0x00..0x7F - number_integer | 128..255 | uint 8 | 0xCC - number_integer | 256..65535 | uint 16 | 0xCD - number_integer | 65536..4294967295 | uint 32 | 0xCE - number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF - number_unsigned | 0..127 | positive fixint | 0x00..0x7F - number_unsigned | 128..255 | uint 8 | 0xCC - number_unsigned | 256..65535 | uint 16 | 0xCD - number_unsigned | 65536..4294967295 | uint 32 | 0xCE - number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF - number_float | *any value representable by a float* | float 32 | 0xCA - number_float | *any value NOT representable by a float* | float 64 | 0xCB - string | *length*: 0..31 | fixstr | 0xA0..0xBF - string | *length*: 32..255 | str 8 | 0xD9 - string | *length*: 256..65535 | str 16 | 0xDA - string | *length*: 65536..4294967295 | str 32 | 0xDB - array | *size*: 0..15 | fixarray | 0x90..0x9F - array | *size*: 16..65535 | array 16 | 0xDC - array | *size*: 65536..4294967295 | array 32 | 0xDD - object | *size*: 0..15 | fix map | 0x80..0x8F - object | *size*: 16..65535 | map 16 | 0xDE - object | *size*: 65536..4294967295 | map 32 | 0xDF - binary | *size*: 0..255 | bin 8 | 0xC4 - binary | *size*: 256..65535 | bin 16 | 0xC5 - binary | *size*: 65536..4294967295 | bin 32 | 0xC6 - - @note The mapping is **complete** in the sense that any JSON value type - can be converted to a MessagePack value. - - @note The following values can **not** be converted to a MessagePack value: - - strings with more than 4294967295 bytes - - byte strings with more than 4294967295 bytes - - arrays with more than 4294967295 elements - - objects with more than 4294967295 elements - - @note Any MessagePack output created @ref to_msgpack can be successfully - parsed by @ref from_msgpack. - - @note If NaN or Infinity are stored inside a JSON number, they are - serialized properly. This behavior differs from the @ref dump() - function which serializes NaN or Infinity to `null`. - - @param[in] j JSON value to serialize - @return MessagePack serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in MessagePack format.,to_msgpack} - - @sa http://msgpack.org - @sa see @ref from_msgpack for the analogous deserialization - @sa see @ref to_cbor(const basic_json& for the related CBOR format - @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the - related UBJSON format - - @since version 2.0.9 - */ - static std::vector to_msgpack(const basic_json& j) - { - std::vector result; - to_msgpack(j, result); - return result; - } - - static void to_msgpack(const basic_json& j, detail::output_adapter o) - { - binary_writer(o).write_msgpack(j); - } - - static void to_msgpack(const basic_json& j, detail::output_adapter o) - { - binary_writer(o).write_msgpack(j); - } - - /*! - @brief create a UBJSON serialization of a given JSON value - - Serializes a given JSON value @a j to a byte vector using the UBJSON - (Universal Binary JSON) serialization format. UBJSON aims to be more compact - than JSON itself, yet more efficient to parse. - - The library uses the following mapping from JSON values types to - UBJSON types according to the UBJSON specification: - - JSON value type | value/range | UBJSON type | marker - --------------- | --------------------------------- | ----------- | ------ - null | `null` | null | `Z` - boolean | `true` | true | `T` - boolean | `false` | false | `F` - number_integer | -9223372036854775808..-2147483649 | int64 | `L` - number_integer | -2147483648..-32769 | int32 | `l` - number_integer | -32768..-129 | int16 | `I` - number_integer | -128..127 | int8 | `i` - number_integer | 128..255 | uint8 | `U` - number_integer | 256..32767 | int16 | `I` - number_integer | 32768..2147483647 | int32 | `l` - number_integer | 2147483648..9223372036854775807 | int64 | `L` - number_unsigned | 0..127 | int8 | `i` - number_unsigned | 128..255 | uint8 | `U` - number_unsigned | 256..32767 | int16 | `I` - number_unsigned | 32768..2147483647 | int32 | `l` - number_unsigned | 2147483648..9223372036854775807 | int64 | `L` - number_unsigned | 2147483649..18446744073709551615 | high-precision | `H` - number_float | *any value* | float64 | `D` - string | *with shortest length indicator* | string | `S` - array | *see notes on optimized format* | array | `[` - object | *see notes on optimized format* | map | `{` - - @note The mapping is **complete** in the sense that any JSON value type - can be converted to a UBJSON value. - - @note The following values can **not** be converted to a UBJSON value: - - strings with more than 9223372036854775807 bytes (theoretical) - - @note The following markers are not used in the conversion: - - `Z`: no-op values are not created. - - `C`: single-byte strings are serialized with `S` markers. - - @note Any UBJSON output created @ref to_ubjson can be successfully parsed - by @ref from_ubjson. - - @note If NaN or Infinity are stored inside a JSON number, they are - serialized properly. This behavior differs from the @ref dump() - function which serializes NaN or Infinity to `null`. - - @note The optimized formats for containers are supported: Parameter - @a use_size adds size information to the beginning of a container and - removes the closing marker. Parameter @a use_type further checks - whether all elements of a container have the same type and adds the - type marker to the beginning of the container. The @a use_type - parameter must only be used together with @a use_size = true. Note - that @a use_size = true alone may result in larger representations - - the benefit of this parameter is that the receiving side is - immediately informed on the number of elements of the container. - - @note If the JSON data contains the binary type, the value stored is a list - of integers, as suggested by the UBJSON documentation. In particular, - this means that serialization and the deserialization of a JSON - containing binary values into UBJSON and back will result in a - different JSON object. - - @param[in] j JSON value to serialize - @param[in] use_size whether to add size annotations to container types - @param[in] use_type whether to add type annotations to container types - (must be combined with @a use_size = true) - @return UBJSON serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in UBJSON format.,to_ubjson} - - @sa http://ubjson.org - @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the - analogous deserialization - @sa see @ref to_cbor(const basic_json& for the related CBOR format - @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format - - @since version 3.1.0 - */ - static std::vector to_ubjson(const basic_json& j, - const bool use_size = false, - const bool use_type = false) - { - std::vector result; - to_ubjson(j, result, use_size, use_type); - return result; - } - - static void to_ubjson(const basic_json& j, detail::output_adapter o, - const bool use_size = false, const bool use_type = false) - { - binary_writer(o).write_ubjson(j, use_size, use_type); - } - - static void to_ubjson(const basic_json& j, detail::output_adapter o, - const bool use_size = false, const bool use_type = false) - { - binary_writer(o).write_ubjson(j, use_size, use_type); - } - - - /*! - @brief Serializes the given JSON object `j` to BSON and returns a vector - containing the corresponding BSON-representation. - - BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are - stored as a single entity (a so-called document). - - The library uses the following mapping from JSON values types to BSON types: - - JSON value type | value/range | BSON type | marker - --------------- | --------------------------------- | ----------- | ------ - null | `null` | null | 0x0A - boolean | `true`, `false` | boolean | 0x08 - number_integer | -9223372036854775808..-2147483649 | int64 | 0x12 - number_integer | -2147483648..2147483647 | int32 | 0x10 - number_integer | 2147483648..9223372036854775807 | int64 | 0x12 - number_unsigned | 0..2147483647 | int32 | 0x10 - number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12 - number_unsigned | 9223372036854775808..18446744073709551615| -- | -- - number_float | *any value* | double | 0x01 - string | *any value* | string | 0x02 - array | *any value* | document | 0x04 - object | *any value* | document | 0x03 - binary | *any value* | binary | 0x05 - - @warning The mapping is **incomplete**, since only JSON-objects (and things - contained therein) can be serialized to BSON. - Also, integers larger than 9223372036854775807 cannot be serialized to BSON, - and the keys may not contain U+0000, since they are serialized a - zero-terminated c-strings. - - @throw out_of_range.407 if `j.is_number_unsigned() && j.get() > 9223372036854775807` - @throw out_of_range.409 if a key in `j` contains a NULL (U+0000) - @throw type_error.317 if `!j.is_object()` - - @pre The input `j` is required to be an object: `j.is_object() == true`. - - @note Any BSON output created via @ref to_bson can be successfully parsed - by @ref from_bson. - - @param[in] j JSON value to serialize - @return BSON serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in BSON format.,to_bson} - - @sa http://bsonspec.org/spec.html - @sa see @ref from_bson(detail::input_adapter&&, const bool strict) for the - analogous deserialization - @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the - related UBJSON format - @sa see @ref to_cbor(const basic_json&) for the related CBOR format - @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format - */ - static std::vector to_bson(const basic_json& j) - { - std::vector result; - to_bson(j, result); - return result; - } - - /*! - @brief Serializes the given JSON object `j` to BSON and forwards the - corresponding BSON-representation to the given output_adapter `o`. - @param j The JSON object to convert to BSON. - @param o The output adapter that receives the binary BSON representation. - @pre The input `j` shall be an object: `j.is_object() == true` - @sa see @ref to_bson(const basic_json&) - */ - static void to_bson(const basic_json& j, detail::output_adapter o) - { - binary_writer(o).write_bson(j); - } - - /*! - @copydoc to_bson(const basic_json&, detail::output_adapter) - */ - static void to_bson(const basic_json& j, detail::output_adapter o) - { - binary_writer(o).write_bson(j); - } - - - /*! - @brief create a JSON value from an input in CBOR format - - Deserializes a given input @a i to a JSON value using the CBOR (Concise - Binary Object Representation) serialization format. - - The library maps CBOR types to JSON value types as follows: - - CBOR type | JSON value type | first byte - ---------------------- | --------------- | ---------- - Integer | number_unsigned | 0x00..0x17 - Unsigned integer | number_unsigned | 0x18 - Unsigned integer | number_unsigned | 0x19 - Unsigned integer | number_unsigned | 0x1A - Unsigned integer | number_unsigned | 0x1B - Negative integer | number_integer | 0x20..0x37 - Negative integer | number_integer | 0x38 - Negative integer | number_integer | 0x39 - Negative integer | number_integer | 0x3A - Negative integer | number_integer | 0x3B - Byte string | binary | 0x40..0x57 - Byte string | binary | 0x58 - Byte string | binary | 0x59 - Byte string | binary | 0x5A - Byte string | binary | 0x5B - UTF-8 string | string | 0x60..0x77 - UTF-8 string | string | 0x78 - UTF-8 string | string | 0x79 - UTF-8 string | string | 0x7A - UTF-8 string | string | 0x7B - UTF-8 string | string | 0x7F - array | array | 0x80..0x97 - array | array | 0x98 - array | array | 0x99 - array | array | 0x9A - array | array | 0x9B - array | array | 0x9F - map | object | 0xA0..0xB7 - map | object | 0xB8 - map | object | 0xB9 - map | object | 0xBA - map | object | 0xBB - map | object | 0xBF - False | `false` | 0xF4 - True | `true` | 0xF5 - Null | `null` | 0xF6 - Half-Precision Float | number_float | 0xF9 - Single-Precision Float | number_float | 0xFA - Double-Precision Float | number_float | 0xFB - - @warning The mapping is **incomplete** in the sense that not all CBOR - types can be converted to a JSON value. The following CBOR types - are not supported and will yield parse errors (parse_error.112): - - date/time (0xC0..0xC1) - - bignum (0xC2..0xC3) - - decimal fraction (0xC4) - - bigfloat (0xC5) - - expected conversions (0xD5..0xD7) - - simple values (0xE0..0xF3, 0xF8) - - undefined (0xF7) - - @warning CBOR allows map keys of any type, whereas JSON only allows - strings as keys in object values. Therefore, CBOR maps with keys - other than UTF-8 strings are rejected (parse_error.113). - - @note Any CBOR output created @ref to_cbor can be successfully parsed by - @ref from_cbor. - - @param[in] i an input in CBOR format convertible to an input adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - @param[in] tag_handler how to treat CBOR tags (optional, error by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.110 if the given input ends prematurely or the end of - file was not reached when @a strict was set to true - @throw parse_error.112 if unsupported features from CBOR were - used in the given input @a v or if the input is not valid CBOR - @throw parse_error.113 if a string was expected as map key, but not found - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in CBOR - format to a JSON value.,from_cbor} - - @sa http://cbor.io - @sa see @ref to_cbor(const basic_json&) for the analogous serialization - @sa see @ref from_msgpack(InputType&&, const bool, const bool) for the - related MessagePack format - @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the - related UBJSON format - - @since version 2.0.9; parameter @a start_index since 2.1.1; changed to - consume input adapters, removed start_index parameter, and added - @a strict parameter since 3.0.0; added @a allow_exceptions parameter - since 3.2.0; added @a tag_handler parameter since 3.9.0. - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_cbor(InputType&& i, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::forward(i)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @copydoc from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_cbor(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::move(first), std::move(last)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); - return res ? result : basic_json(value_t::discarded); - } - - template - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len)) - static basic_json from_cbor(const T* ptr, std::size_t len, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler); - } - - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len)) - static basic_json from_cbor(detail::span_input_adapter&& i, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = i.get(); - // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @brief create a JSON value from an input in MessagePack format - - Deserializes a given input @a i to a JSON value using the MessagePack - serialization format. - - The library maps MessagePack types to JSON value types as follows: - - MessagePack type | JSON value type | first byte - ---------------- | --------------- | ---------- - positive fixint | number_unsigned | 0x00..0x7F - fixmap | object | 0x80..0x8F - fixarray | array | 0x90..0x9F - fixstr | string | 0xA0..0xBF - nil | `null` | 0xC0 - false | `false` | 0xC2 - true | `true` | 0xC3 - float 32 | number_float | 0xCA - float 64 | number_float | 0xCB - uint 8 | number_unsigned | 0xCC - uint 16 | number_unsigned | 0xCD - uint 32 | number_unsigned | 0xCE - uint 64 | number_unsigned | 0xCF - int 8 | number_integer | 0xD0 - int 16 | number_integer | 0xD1 - int 32 | number_integer | 0xD2 - int 64 | number_integer | 0xD3 - str 8 | string | 0xD9 - str 16 | string | 0xDA - str 32 | string | 0xDB - array 16 | array | 0xDC - array 32 | array | 0xDD - map 16 | object | 0xDE - map 32 | object | 0xDF - bin 8 | binary | 0xC4 - bin 16 | binary | 0xC5 - bin 32 | binary | 0xC6 - ext 8 | binary | 0xC7 - ext 16 | binary | 0xC8 - ext 32 | binary | 0xC9 - fixext 1 | binary | 0xD4 - fixext 2 | binary | 0xD5 - fixext 4 | binary | 0xD6 - fixext 8 | binary | 0xD7 - fixext 16 | binary | 0xD8 - negative fixint | number_integer | 0xE0-0xFF - - @note Any MessagePack output created @ref to_msgpack can be successfully - parsed by @ref from_msgpack. - - @param[in] i an input in MessagePack format convertible to an input - adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.110 if the given input ends prematurely or the end of - file was not reached when @a strict was set to true - @throw parse_error.112 if unsupported features from MessagePack were - used in the given input @a i or if the input is not valid MessagePack - @throw parse_error.113 if a string was expected as map key, but not found - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in - MessagePack format to a JSON value.,from_msgpack} - - @sa http://msgpack.org - @sa see @ref to_msgpack(const basic_json&) for the analogous serialization - @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the - related CBOR format - @sa see @ref from_ubjson(InputType&&, const bool, const bool) for - the related UBJSON format - @sa see @ref from_bson(InputType&&, const bool, const bool) for - the related BSON format - - @since version 2.0.9; parameter @a start_index since 2.1.1; changed to - consume input adapters, removed start_index parameter, and added - @a strict parameter since 3.0.0; added @a allow_exceptions parameter - since 3.2.0 - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_msgpack(InputType&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::forward(i)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @copydoc from_msgpack(InputType&&, const bool, const bool) - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_msgpack(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::move(first), std::move(last)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - - template - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len)) - static basic_json from_msgpack(const T* ptr, std::size_t len, - const bool strict = true, - const bool allow_exceptions = true) - { - return from_msgpack(ptr, ptr + len, strict, allow_exceptions); - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len)) - static basic_json from_msgpack(detail::span_input_adapter&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = i.get(); - // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - - /*! - @brief create a JSON value from an input in UBJSON format - - Deserializes a given input @a i to a JSON value using the UBJSON (Universal - Binary JSON) serialization format. - - The library maps UBJSON types to JSON value types as follows: - - UBJSON type | JSON value type | marker - ----------- | --------------------------------------- | ------ - no-op | *no value, next value is read* | `N` - null | `null` | `Z` - false | `false` | `F` - true | `true` | `T` - float32 | number_float | `d` - float64 | number_float | `D` - uint8 | number_unsigned | `U` - int8 | number_integer | `i` - int16 | number_integer | `I` - int32 | number_integer | `l` - int64 | number_integer | `L` - high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H' - string | string | `S` - char | string | `C` - array | array (optimized values are supported) | `[` - object | object (optimized values are supported) | `{` - - @note The mapping is **complete** in the sense that any UBJSON value can - be converted to a JSON value. - - @param[in] i an input in UBJSON format convertible to an input adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.110 if the given input ends prematurely or the end of - file was not reached when @a strict was set to true - @throw parse_error.112 if a parse error occurs - @throw parse_error.113 if a string could not be parsed successfully - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in - UBJSON format to a JSON value.,from_ubjson} - - @sa http://ubjson.org - @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the - analogous serialization - @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the - related CBOR format - @sa see @ref from_msgpack(InputType&&, const bool, const bool) for - the related MessagePack format - @sa see @ref from_bson(InputType&&, const bool, const bool) for - the related BSON format - - @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0 - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_ubjson(InputType&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::forward(i)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @copydoc from_ubjson(InputType&&, const bool, const bool) - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_ubjson(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::move(first), std::move(last)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - template - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len)) - static basic_json from_ubjson(const T* ptr, std::size_t len, - const bool strict = true, - const bool allow_exceptions = true) - { - return from_ubjson(ptr, ptr + len, strict, allow_exceptions); - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len)) - static basic_json from_ubjson(detail::span_input_adapter&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = i.get(); - // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - - /*! - @brief Create a JSON value from an input in BSON format - - Deserializes a given input @a i to a JSON value using the BSON (Binary JSON) - serialization format. - - The library maps BSON record types to JSON value types as follows: - - BSON type | BSON marker byte | JSON value type - --------------- | ---------------- | --------------------------- - double | 0x01 | number_float - string | 0x02 | string - document | 0x03 | object - array | 0x04 | array - binary | 0x05 | binary - undefined | 0x06 | still unsupported - ObjectId | 0x07 | still unsupported - boolean | 0x08 | boolean - UTC Date-Time | 0x09 | still unsupported - null | 0x0A | null - Regular Expr. | 0x0B | still unsupported - DB Pointer | 0x0C | still unsupported - JavaScript Code | 0x0D | still unsupported - Symbol | 0x0E | still unsupported - JavaScript Code | 0x0F | still unsupported - int32 | 0x10 | number_integer - Timestamp | 0x11 | still unsupported - 128-bit decimal float | 0x13 | still unsupported - Max Key | 0x7F | still unsupported - Min Key | 0xFF | still unsupported - - @warning The mapping is **incomplete**. The unsupported mappings - are indicated in the table above. - - @param[in] i an input in BSON format convertible to an input adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.114 if an unsupported BSON record type is encountered - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in - BSON format to a JSON value.,from_bson} - - @sa http://bsonspec.org/spec.html - @sa see @ref to_bson(const basic_json&) for the analogous serialization - @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the - related CBOR format - @sa see @ref from_msgpack(InputType&&, const bool, const bool) for - the related MessagePack format - @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the - related UBJSON format - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_bson(InputType&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::forward(i)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @copydoc from_bson(InputType&&, const bool, const bool) - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_bson(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::move(first), std::move(last)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - template - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len)) - static basic_json from_bson(const T* ptr, std::size_t len, - const bool strict = true, - const bool allow_exceptions = true) - { - return from_bson(ptr, ptr + len, strict, allow_exceptions); - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len)) - static basic_json from_bson(detail::span_input_adapter&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = i.get(); - // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - /// @} - - ////////////////////////// - // JSON Pointer support // - ////////////////////////// - - /// @name JSON Pointer functions - /// @{ - - /*! - @brief access specified element via JSON Pointer - - Uses a JSON pointer to retrieve a reference to the respective JSON value. - No bound checking is performed. Similar to @ref operator[](const typename - object_t::key_type&), `null` values are created in arrays and objects if - necessary. - - In particular: - - If the JSON pointer points to an object key that does not exist, it - is created an filled with a `null` value before a reference to it - is returned. - - If the JSON pointer points to an array index that does not exist, it - is created an filled with a `null` value before a reference to it - is returned. All indices between the current maximum and the given - index are also filled with `null`. - - The special value `-` is treated as a synonym for the index past the - end. - - @param[in] ptr a JSON pointer - - @return reference to the element pointed to by @a ptr - - @complexity Constant. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.404 if the JSON pointer can not be resolved - - @liveexample{The behavior is shown in the example.,operatorjson_pointer} - - @since version 2.0.0 - */ - reference operator[](const json_pointer& ptr) - { - return ptr.get_unchecked(this); - } - - /*! - @brief access specified element via JSON Pointer - - Uses a JSON pointer to retrieve a reference to the respective JSON value. - No bound checking is performed. The function does not change the JSON - value; no `null` values are created. In particular, the special value - `-` yields an exception. - - @param[in] ptr JSON pointer to the desired element - - @return const reference to the element pointed to by @a ptr - - @complexity Constant. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.402 if the array index '-' is used - @throw out_of_range.404 if the JSON pointer can not be resolved - - @liveexample{The behavior is shown in the example.,operatorjson_pointer_const} - - @since version 2.0.0 - */ - const_reference operator[](const json_pointer& ptr) const - { - return ptr.get_unchecked(this); - } - - /*! - @brief access specified element via JSON Pointer - - Returns a reference to the element at with specified JSON pointer @a ptr, - with bounds checking. - - @param[in] ptr JSON pointer to the desired element - - @return reference to the element pointed to by @a ptr - - @throw parse_error.106 if an array index in the passed JSON pointer @a ptr - begins with '0'. See example below. - - @throw parse_error.109 if an array index in the passed JSON pointer @a ptr - is not a number. See example below. - - @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr - is out of range. See example below. - - @throw out_of_range.402 if the array index '-' is used in the passed JSON - pointer @a ptr. As `at` provides checked access (and no elements are - implicitly inserted), the index '-' is always invalid. See example below. - - @throw out_of_range.403 if the JSON pointer describes a key of an object - which cannot be found. See example below. - - @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved. - See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 2.0.0 - - @liveexample{The behavior is shown in the example.,at_json_pointer} - */ - reference at(const json_pointer& ptr) - { - return ptr.get_checked(this); - } - - /*! - @brief access specified element via JSON Pointer - - Returns a const reference to the element at with specified JSON pointer @a - ptr, with bounds checking. - - @param[in] ptr JSON pointer to the desired element - - @return reference to the element pointed to by @a ptr - - @throw parse_error.106 if an array index in the passed JSON pointer @a ptr - begins with '0'. See example below. - - @throw parse_error.109 if an array index in the passed JSON pointer @a ptr - is not a number. See example below. - - @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr - is out of range. See example below. - - @throw out_of_range.402 if the array index '-' is used in the passed JSON - pointer @a ptr. As `at` provides checked access (and no elements are - implicitly inserted), the index '-' is always invalid. See example below. - - @throw out_of_range.403 if the JSON pointer describes a key of an object - which cannot be found. See example below. - - @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved. - See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 2.0.0 - - @liveexample{The behavior is shown in the example.,at_json_pointer_const} - */ - const_reference at(const json_pointer& ptr) const - { - return ptr.get_checked(this); - } - - /*! - @brief return flattened JSON value - - The function creates a JSON object whose keys are JSON pointers (see [RFC - 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all - primitive. The original JSON value can be restored using the @ref - unflatten() function. - - @return an object that maps JSON pointers to primitive values - - @note Empty objects and arrays are flattened to `null` and will not be - reconstructed correctly by the @ref unflatten() function. - - @complexity Linear in the size the JSON value. - - @liveexample{The following code shows how a JSON object is flattened to an - object whose keys consist of JSON pointers.,flatten} - - @sa see @ref unflatten() for the reverse function - - @since version 2.0.0 - */ - basic_json flatten() const - { - basic_json result(value_t::object); - json_pointer::flatten("", *this, result); - return result; - } - - /*! - @brief unflatten a previously flattened JSON value - - The function restores the arbitrary nesting of a JSON value that has been - flattened before using the @ref flatten() function. The JSON value must - meet certain constraints: - 1. The value must be an object. - 2. The keys must be JSON pointers (see - [RFC 6901](https://tools.ietf.org/html/rfc6901)) - 3. The mapped values must be primitive JSON types. - - @return the original JSON from a flattened version - - @note Empty objects and arrays are flattened by @ref flatten() to `null` - values and can not unflattened to their original type. Apart from - this example, for a JSON value `j`, the following is always true: - `j == j.flatten().unflatten()`. - - @complexity Linear in the size the JSON value. - - @throw type_error.314 if value is not an object - @throw type_error.315 if object values are not primitive - - @liveexample{The following code shows how a flattened JSON object is - unflattened into the original nested JSON object.,unflatten} - - @sa see @ref flatten() for the reverse function - - @since version 2.0.0 - */ - basic_json unflatten() const - { - return json_pointer::unflatten(*this); - } - - /// @} - - ////////////////////////// - // JSON Patch functions // - ////////////////////////// - - /// @name JSON Patch functions - /// @{ - - /*! - @brief applies a JSON patch - - [JSON Patch](http://jsonpatch.com) defines a JSON document structure for - expressing a sequence of operations to apply to a JSON) document. With - this function, a JSON Patch is applied to the current JSON value by - executing all operations from the patch. - - @param[in] json_patch JSON patch document - @return patched document - - @note The application of a patch is atomic: Either all operations succeed - and the patched document is returned or an exception is thrown. In - any case, the original value is not changed: the patch is applied - to a copy of the value. - - @throw parse_error.104 if the JSON patch does not consist of an array of - objects - - @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory - attributes are missing); example: `"operation add must have member path"` - - @throw out_of_range.401 if an array index is out of range. - - @throw out_of_range.403 if a JSON pointer inside the patch could not be - resolved successfully in the current JSON value; example: `"key baz not - found"` - - @throw out_of_range.405 if JSON pointer has no parent ("add", "remove", - "move") - - @throw other_error.501 if "test" operation was unsuccessful - - @complexity Linear in the size of the JSON value and the length of the - JSON patch. As usually only a fraction of the JSON value is affected by - the patch, the complexity can usually be neglected. - - @liveexample{The following code shows how a JSON patch is applied to a - value.,patch} - - @sa see @ref diff -- create a JSON patch by comparing two JSON values - - @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) - @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) - - @since version 2.0.0 - */ - basic_json patch(const basic_json& json_patch) const - { - // make a working copy to apply the patch to - basic_json result = *this; - - // the valid JSON Patch operations - enum class patch_operations {add, remove, replace, move, copy, test, invalid}; - - const auto get_op = [](const std::string & op) - { - if (op == "add") - { - return patch_operations::add; - } - if (op == "remove") - { - return patch_operations::remove; - } - if (op == "replace") - { - return patch_operations::replace; - } - if (op == "move") - { - return patch_operations::move; - } - if (op == "copy") - { - return patch_operations::copy; - } - if (op == "test") - { - return patch_operations::test; - } - - return patch_operations::invalid; - }; - - // wrapper for "add" operation; add value at ptr - const auto operation_add = [&result](json_pointer & ptr, basic_json val) - { - // adding to the root of the target document means replacing it - if (ptr.empty()) - { - result = val; - return; - } - - // make sure the top element of the pointer exists - json_pointer top_pointer = ptr.top(); - if (top_pointer != ptr) - { - result.at(top_pointer); - } - - // get reference to parent of JSON pointer ptr - const auto last_path = ptr.back(); - ptr.pop_back(); - basic_json& parent = result[ptr]; - - switch (parent.m_type) - { - case value_t::null: - case value_t::object: - { - // use operator[] to add value - parent[last_path] = val; - break; - } - - case value_t::array: - { - if (last_path == "-") - { - // special case: append to back - parent.push_back(val); - } - else - { - const auto idx = json_pointer::array_index(last_path); - if (JSON_HEDLEY_UNLIKELY(idx > parent.size())) - { - // avoid undefined behavior - JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent)); - } - - // default case: insert add offset - parent.insert(parent.begin() + static_cast(idx), val); - } - break; - } - - // if there exists a parent it cannot be primitive - case value_t::string: // LCOV_EXCL_LINE - case value_t::boolean: // LCOV_EXCL_LINE - case value_t::number_integer: // LCOV_EXCL_LINE - case value_t::number_unsigned: // LCOV_EXCL_LINE - case value_t::number_float: // LCOV_EXCL_LINE - case value_t::binary: // LCOV_EXCL_LINE - case value_t::discarded: // LCOV_EXCL_LINE - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - }; - - // wrapper for "remove" operation; remove value at ptr - const auto operation_remove = [this, &result](json_pointer & ptr) - { - // get reference to parent of JSON pointer ptr - const auto last_path = ptr.back(); - ptr.pop_back(); - basic_json& parent = result.at(ptr); - - // remove child - if (parent.is_object()) - { - // perform range check - auto it = parent.find(last_path); - if (JSON_HEDLEY_LIKELY(it != parent.end())) - { - parent.erase(it); - } - else - { - JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this)); - } - } - else if (parent.is_array()) - { - // note erase performs range check - parent.erase(json_pointer::array_index(last_path)); - } - }; - - // type check: top level value must be an array - if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array())) - { - JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch)); - } - - // iterate and apply the operations - for (const auto& val : json_patch) - { - // wrapper to get a value for an operation - const auto get_value = [&val](const std::string & op, - const std::string & member, - bool string_type) -> basic_json & - { - // find value - auto it = val.m_value.object->find(member); - - // context-sensitive error message - const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'"; - - // check if desired value is present - if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end())) - { - // NOLINTNEXTLINE(performance-inefficient-string-concatenation) - JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val)); - } - - // check if result is of type string - if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string())) - { - // NOLINTNEXTLINE(performance-inefficient-string-concatenation) - JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val)); - } - - // no error: return value - return it->second; - }; - - // type check: every element of the array must be an object - if (JSON_HEDLEY_UNLIKELY(!val.is_object())) - { - JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val)); - } - - // collect mandatory members - const auto op = get_value("op", "op", true).template get(); - const auto path = get_value(op, "path", true).template get(); - json_pointer ptr(path); - - switch (get_op(op)) - { - case patch_operations::add: - { - operation_add(ptr, get_value("add", "value", false)); - break; - } - - case patch_operations::remove: - { - operation_remove(ptr); - break; - } - - case patch_operations::replace: - { - // the "path" location must exist - use at() - result.at(ptr) = get_value("replace", "value", false); - break; - } - - case patch_operations::move: - { - const auto from_path = get_value("move", "from", true).template get(); - json_pointer from_ptr(from_path); - - // the "from" location must exist - use at() - basic_json v = result.at(from_ptr); - - // The move operation is functionally identical to a - // "remove" operation on the "from" location, followed - // immediately by an "add" operation at the target - // location with the value that was just removed. - operation_remove(from_ptr); - operation_add(ptr, v); - break; - } - - case patch_operations::copy: - { - const auto from_path = get_value("copy", "from", true).template get(); - const json_pointer from_ptr(from_path); - - // the "from" location must exist - use at() - basic_json v = result.at(from_ptr); - - // The copy is functionally identical to an "add" - // operation at the target location using the value - // specified in the "from" member. - operation_add(ptr, v); - break; - } - - case patch_operations::test: - { - bool success = false; - JSON_TRY - { - // check if "value" matches the one at "path" - // the "path" location must exist - use at() - success = (result.at(ptr) == get_value("test", "value", false)); - } - JSON_INTERNAL_CATCH (out_of_range&) - { - // ignore out of range errors: success remains false - } - - // throw an exception if test fails - if (JSON_HEDLEY_UNLIKELY(!success)) - { - JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val)); - } - - break; - } - - case patch_operations::invalid: - default: - { - // op must be "add", "remove", "replace", "move", "copy", or - // "test" - JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val)); - } - } - } - - return result; - } - - /*! - @brief creates a diff as a JSON patch - - Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can - be changed into the value @a target by calling @ref patch function. - - @invariant For two JSON values @a source and @a target, the following code - yields always `true`: - @code {.cpp} - source.patch(diff(source, target)) == target; - @endcode - - @note Currently, only `remove`, `add`, and `replace` operations are - generated. - - @param[in] source JSON value to compare from - @param[in] target JSON value to compare against - @param[in] path helper value to create JSON pointers - - @return a JSON patch to convert the @a source to @a target - - @complexity Linear in the lengths of @a source and @a target. - - @liveexample{The following code shows how a JSON patch is created as a - diff for two JSON values.,diff} - - @sa see @ref patch -- apply a JSON patch - @sa see @ref merge_patch -- apply a JSON Merge Patch - - @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) - - @since version 2.0.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json diff(const basic_json& source, const basic_json& target, - const std::string& path = "") - { - // the patch - basic_json result(value_t::array); - - // if the values are the same, return empty patch - if (source == target) - { - return result; - } - - if (source.type() != target.type()) - { - // different types: replace value - result.push_back( - { - {"op", "replace"}, {"path", path}, {"value", target} - }); - return result; - } - - switch (source.type()) - { - case value_t::array: - { - // first pass: traverse common elements - std::size_t i = 0; - while (i < source.size() && i < target.size()) - { - // recursive call to compare array values at index i - auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i)); - result.insert(result.end(), temp_diff.begin(), temp_diff.end()); - ++i; - } - - // i now reached the end of at least one array - // in a second pass, traverse the remaining elements - - // remove my remaining elements - const auto end_index = static_cast(result.size()); - while (i < source.size()) - { - // add operations in reverse order to avoid invalid - // indices - result.insert(result.begin() + end_index, object( - { - {"op", "remove"}, - {"path", path + "/" + std::to_string(i)} - })); - ++i; - } - - // add other remaining elements - while (i < target.size()) - { - result.push_back( - { - {"op", "add"}, - {"path", path + "/-"}, - {"value", target[i]} - }); - ++i; - } - - break; - } - - case value_t::object: - { - // first pass: traverse this object's elements - for (auto it = source.cbegin(); it != source.cend(); ++it) - { - // escape the key name to be used in a JSON patch - const auto path_key = path + "/" + detail::escape(it.key()); - - if (target.find(it.key()) != target.end()) - { - // recursive call to compare object values at key it - auto temp_diff = diff(it.value(), target[it.key()], path_key); - result.insert(result.end(), temp_diff.begin(), temp_diff.end()); - } - else - { - // found a key that is not in o -> remove it - result.push_back(object( - { - {"op", "remove"}, {"path", path_key} - })); - } - } - - // second pass: traverse other object's elements - for (auto it = target.cbegin(); it != target.cend(); ++it) - { - if (source.find(it.key()) == source.end()) - { - // found a key that is not in this -> add it - const auto path_key = path + "/" + detail::escape(it.key()); - result.push_back( - { - {"op", "add"}, {"path", path_key}, - {"value", it.value()} - }); - } - } - - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - // both primitive type: replace value - result.push_back( - { - {"op", "replace"}, {"path", path}, {"value", target} - }); - break; - } - } - - return result; - } - - /// @} - - //////////////////////////////// - // JSON Merge Patch functions // - //////////////////////////////// - - /// @name JSON Merge Patch functions - /// @{ - - /*! - @brief applies a JSON Merge Patch - - The merge patch format is primarily intended for use with the HTTP PATCH - method as a means of describing a set of modifications to a target - resource's content. This function applies a merge patch to the current - JSON value. - - The function implements the following algorithm from Section 2 of - [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396): - - ``` - define MergePatch(Target, Patch): - if Patch is an Object: - if Target is not an Object: - Target = {} // Ignore the contents and set it to an empty Object - for each Name/Value pair in Patch: - if Value is null: - if Name exists in Target: - remove the Name/Value pair from Target - else: - Target[Name] = MergePatch(Target[Name], Value) - return Target - else: - return Patch - ``` - - Thereby, `Target` is the current object; that is, the patch is applied to - the current value. - - @param[in] apply_patch the patch to apply - - @complexity Linear in the lengths of @a patch. - - @liveexample{The following code shows how a JSON Merge Patch is applied to - a JSON document.,merge_patch} - - @sa see @ref patch -- apply a JSON patch - @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) - - @since version 3.0.0 - */ - void merge_patch(const basic_json& apply_patch) - { - if (apply_patch.is_object()) - { - if (!is_object()) - { - *this = object(); - } - for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it) - { - if (it.value().is_null()) - { - erase(it.key()); - } - else - { - operator[](it.key()).merge_patch(it.value()); - } - } - } - else - { - *this = apply_patch; - } - } - - /// @} -}; - -/*! -@brief user-defined to_string function for JSON values - -This function implements a user-defined to_string for JSON objects. - -@param[in] j a JSON object -@return a std::string object -*/ - -NLOHMANN_BASIC_JSON_TPL_DECLARATION -std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j) -{ - return j.dump(); -} -} // namespace nlohmann - -/////////////////////// -// nonmember support // -/////////////////////// - -// specialization of std::swap, and std::hash -namespace std -{ - -/// hash value for JSON objects -template<> -struct hash -{ - /*! - @brief return a hash value for a JSON object - - @since version 1.0.0 - */ - std::size_t operator()(const nlohmann::json& j) const - { - return nlohmann::detail::hash(j); - } -}; - -/// specialization for std::less -/// @note: do not remove the space after '<', -/// see https://github.com/nlohmann/json/pull/679 -template<> -struct less<::nlohmann::detail::value_t> -{ - /*! - @brief compare two value_t enum values - @since version 3.0.0 - */ - bool operator()(nlohmann::detail::value_t lhs, - nlohmann::detail::value_t rhs) const noexcept - { - return nlohmann::detail::operator<(lhs, rhs); - } -}; - -// C++20 prohibit function specialization in the std namespace. -#ifndef JSON_HAS_CPP_20 - -/*! -@brief exchanges the values of two JSON objects - -@since version 1.0.0 -*/ -template<> -inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name) - is_nothrow_move_constructible::value&& // NOLINT(misc-redundant-expression) - is_nothrow_move_assignable::value - ) -{ - j1.swap(j2); -} - -#endif - -} // namespace std - -/*! -@brief user-defined string literal for JSON values - -This operator implements a user-defined string literal for JSON objects. It -can be used by adding `"_json"` to a string literal and returns a JSON object -if no parse error occurred. - -@param[in] s a string representation of a JSON object -@param[in] n the length of string @a s -@return a JSON object - -@since version 1.0.0 -*/ -JSON_HEDLEY_NON_NULL(1) -inline nlohmann::json operator "" _json(const char* s, std::size_t n) -{ - return nlohmann::json::parse(s, s + n); -} - -/*! -@brief user-defined string literal for JSON pointer - -This operator implements a user-defined string literal for JSON Pointers. It -can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer -object if no parse error occurred. - -@param[in] s a string representation of a JSON Pointer -@param[in] n the length of string @a s -@return a JSON pointer object - -@since version 2.0.0 -*/ -JSON_HEDLEY_NON_NULL(1) -inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n) -{ - return nlohmann::json::json_pointer(std::string(s, n)); -} - -// #include - - -// restore clang diagnostic settings -#if defined(__clang__) - #pragma clang diagnostic pop -#endif - -// clean up -#undef JSON_ASSERT -#undef JSON_INTERNAL_CATCH -#undef JSON_CATCH -#undef JSON_THROW -#undef JSON_TRY -#undef JSON_PRIVATE_UNLESS_TESTED -#undef JSON_HAS_CPP_11 -#undef JSON_HAS_CPP_14 -#undef JSON_HAS_CPP_17 -#undef JSON_HAS_CPP_20 -#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION -#undef NLOHMANN_BASIC_JSON_TPL -#undef JSON_EXPLICIT - -// #include - - -#undef JSON_HEDLEY_ALWAYS_INLINE -#undef JSON_HEDLEY_ARM_VERSION -#undef JSON_HEDLEY_ARM_VERSION_CHECK -#undef JSON_HEDLEY_ARRAY_PARAM -#undef JSON_HEDLEY_ASSUME -#undef JSON_HEDLEY_BEGIN_C_DECLS -#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE -#undef JSON_HEDLEY_CLANG_HAS_BUILTIN -#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE -#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE -#undef JSON_HEDLEY_CLANG_HAS_EXTENSION -#undef JSON_HEDLEY_CLANG_HAS_FEATURE -#undef JSON_HEDLEY_CLANG_HAS_WARNING -#undef JSON_HEDLEY_COMPCERT_VERSION -#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK -#undef JSON_HEDLEY_CONCAT -#undef JSON_HEDLEY_CONCAT3 -#undef JSON_HEDLEY_CONCAT3_EX -#undef JSON_HEDLEY_CONCAT_EX -#undef JSON_HEDLEY_CONST -#undef JSON_HEDLEY_CONSTEXPR -#undef JSON_HEDLEY_CONST_CAST -#undef JSON_HEDLEY_CPP_CAST -#undef JSON_HEDLEY_CRAY_VERSION -#undef JSON_HEDLEY_CRAY_VERSION_CHECK -#undef JSON_HEDLEY_C_DECL -#undef JSON_HEDLEY_DEPRECATED -#undef JSON_HEDLEY_DEPRECATED_FOR -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#undef JSON_HEDLEY_DIAGNOSTIC_POP -#undef JSON_HEDLEY_DIAGNOSTIC_PUSH -#undef JSON_HEDLEY_DMC_VERSION -#undef JSON_HEDLEY_DMC_VERSION_CHECK -#undef JSON_HEDLEY_EMPTY_BASES -#undef JSON_HEDLEY_EMSCRIPTEN_VERSION -#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK -#undef JSON_HEDLEY_END_C_DECLS -#undef JSON_HEDLEY_FLAGS -#undef JSON_HEDLEY_FLAGS_CAST -#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE -#undef JSON_HEDLEY_GCC_HAS_BUILTIN -#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE -#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE -#undef JSON_HEDLEY_GCC_HAS_EXTENSION -#undef JSON_HEDLEY_GCC_HAS_FEATURE -#undef JSON_HEDLEY_GCC_HAS_WARNING -#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK -#undef JSON_HEDLEY_GCC_VERSION -#undef JSON_HEDLEY_GCC_VERSION_CHECK -#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE -#undef JSON_HEDLEY_GNUC_HAS_BUILTIN -#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE -#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE -#undef JSON_HEDLEY_GNUC_HAS_EXTENSION -#undef JSON_HEDLEY_GNUC_HAS_FEATURE -#undef JSON_HEDLEY_GNUC_HAS_WARNING -#undef JSON_HEDLEY_GNUC_VERSION -#undef JSON_HEDLEY_GNUC_VERSION_CHECK -#undef JSON_HEDLEY_HAS_ATTRIBUTE -#undef JSON_HEDLEY_HAS_BUILTIN -#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE -#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS -#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE -#undef JSON_HEDLEY_HAS_EXTENSION -#undef JSON_HEDLEY_HAS_FEATURE -#undef JSON_HEDLEY_HAS_WARNING -#undef JSON_HEDLEY_IAR_VERSION -#undef JSON_HEDLEY_IAR_VERSION_CHECK -#undef JSON_HEDLEY_IBM_VERSION -#undef JSON_HEDLEY_IBM_VERSION_CHECK -#undef JSON_HEDLEY_IMPORT -#undef JSON_HEDLEY_INLINE -#undef JSON_HEDLEY_INTEL_CL_VERSION -#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK -#undef JSON_HEDLEY_INTEL_VERSION -#undef JSON_HEDLEY_INTEL_VERSION_CHECK -#undef JSON_HEDLEY_IS_CONSTANT -#undef JSON_HEDLEY_IS_CONSTEXPR_ -#undef JSON_HEDLEY_LIKELY -#undef JSON_HEDLEY_MALLOC -#undef JSON_HEDLEY_MCST_LCC_VERSION -#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK -#undef JSON_HEDLEY_MESSAGE -#undef JSON_HEDLEY_MSVC_VERSION -#undef JSON_HEDLEY_MSVC_VERSION_CHECK -#undef JSON_HEDLEY_NEVER_INLINE -#undef JSON_HEDLEY_NON_NULL -#undef JSON_HEDLEY_NO_ESCAPE -#undef JSON_HEDLEY_NO_RETURN -#undef JSON_HEDLEY_NO_THROW -#undef JSON_HEDLEY_NULL -#undef JSON_HEDLEY_PELLES_VERSION -#undef JSON_HEDLEY_PELLES_VERSION_CHECK -#undef JSON_HEDLEY_PGI_VERSION -#undef JSON_HEDLEY_PGI_VERSION_CHECK -#undef JSON_HEDLEY_PREDICT -#undef JSON_HEDLEY_PRINTF_FORMAT -#undef JSON_HEDLEY_PRIVATE -#undef JSON_HEDLEY_PUBLIC -#undef JSON_HEDLEY_PURE -#undef JSON_HEDLEY_REINTERPRET_CAST -#undef JSON_HEDLEY_REQUIRE -#undef JSON_HEDLEY_REQUIRE_CONSTEXPR -#undef JSON_HEDLEY_REQUIRE_MSG -#undef JSON_HEDLEY_RESTRICT -#undef JSON_HEDLEY_RETURNS_NON_NULL -#undef JSON_HEDLEY_SENTINEL -#undef JSON_HEDLEY_STATIC_ASSERT -#undef JSON_HEDLEY_STATIC_CAST -#undef JSON_HEDLEY_STRINGIFY -#undef JSON_HEDLEY_STRINGIFY_EX -#undef JSON_HEDLEY_SUNPRO_VERSION -#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK -#undef JSON_HEDLEY_TINYC_VERSION -#undef JSON_HEDLEY_TINYC_VERSION_CHECK -#undef JSON_HEDLEY_TI_ARMCL_VERSION -#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK -#undef JSON_HEDLEY_TI_CL2000_VERSION -#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK -#undef JSON_HEDLEY_TI_CL430_VERSION -#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK -#undef JSON_HEDLEY_TI_CL6X_VERSION -#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK -#undef JSON_HEDLEY_TI_CL7X_VERSION -#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK -#undef JSON_HEDLEY_TI_CLPRU_VERSION -#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK -#undef JSON_HEDLEY_TI_VERSION -#undef JSON_HEDLEY_TI_VERSION_CHECK -#undef JSON_HEDLEY_UNAVAILABLE -#undef JSON_HEDLEY_UNLIKELY -#undef JSON_HEDLEY_UNPREDICTABLE -#undef JSON_HEDLEY_UNREACHABLE -#undef JSON_HEDLEY_UNREACHABLE_RETURN -#undef JSON_HEDLEY_VERSION -#undef JSON_HEDLEY_VERSION_DECODE_MAJOR -#undef JSON_HEDLEY_VERSION_DECODE_MINOR -#undef JSON_HEDLEY_VERSION_DECODE_REVISION -#undef JSON_HEDLEY_VERSION_ENCODE -#undef JSON_HEDLEY_WARNING -#undef JSON_HEDLEY_WARN_UNUSED_RESULT -#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG -#undef JSON_HEDLEY_FALL_THROUGH - - - -#endif // INCLUDE_NLOHMANN_JSON_HPP_ diff --git a/ext/opentelemetry-cpp-1.21.0/.bazelignore b/ext/opentelemetry-cpp-1.21.0/.bazelignore deleted file mode 100644 index 56306fc4b..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.bazelignore +++ /dev/null @@ -1,3 +0,0 @@ -third_party -tools -out diff --git a/ext/opentelemetry-cpp-1.21.0/.bazelrc b/ext/opentelemetry-cpp-1.21.0/.bazelrc deleted file mode 100644 index 57cd0a2fa..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.bazelrc +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# bazel configurations for running tests under sanitizers. -# Based on https://github.com/bazelment/trunk/blob/master/tools/bazel.rc - -# Enable automatic configs based on platform -common --enable_platform_specific_config - -# Make globs that don't match anything fail -common --incompatible_disallow_empty_glob - -# Needed by gRPC to build on some platforms. -build --copt -DGRPC_BAZEL_BUILD - -# Workaround abseil libraries missing symbols -build:windows --dynamic_mode=off - -# Set minimum supported C++ version -build:macos --host_cxxopt=-std=c++14 --cxxopt=-std=c++14 -build:linux --host_cxxopt=-std=c++14 --cxxopt=-std=c++14 -build:windows --host_cxxopt=/std:c++14 --cxxopt=/std:c++14 - -# --config=asan : Address Sanitizer. -common:asan --copt -DADDRESS_SANITIZER -common:asan --copt -fsanitize=address,bool,float-cast-overflow,integer-divide-by-zero,null,return,returns-nonnull-attribute,shift-exponent,signed-integer-overflow,unreachable,vla-bound -common:asan --copt -fsanitize-address-use-after-scope -common:asan --copt -fno-sanitize-recover=all -common:asan --linkopt -fsanitize=address,bool,float-cast-overflow,integer-divide-by-zero,null,return,returns-nonnull-attribute,shift-exponent,signed-integer-overflow,unreachable,vla-bound -common:asan --linkopt -fsanitize-address-use-after-scope -common:asan --linkopt -fno-sanitize-recover=all -common:asan --cc_output_directory_tag=asan - -# --config=tsan : Thread Sanitizer. -common:tsan --copt -fsanitize=thread -common:tsan --copt -DTHREAD_SANITIZER -common:tsan --linkopt -fsanitize=thread -common:tsan --cc_output_directory_tag=tsan -# This is needed to address false positive problem with abseil.The same setting as gRPC -# https://github.com/google/sanitizers/issues/953 -common:tsan --test_env=TSAN_OPTIONS=report_atomic_races=0 diff --git a/ext/opentelemetry-cpp-1.21.0/.bazelversion b/ext/opentelemetry-cpp-1.21.0/.bazelversion deleted file mode 100644 index 21c8c7b46..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.bazelversion +++ /dev/null @@ -1 +0,0 @@ -7.1.1 diff --git a/ext/opentelemetry-cpp-1.21.0/.clang-format b/ext/opentelemetry-cpp-1.21.0/.clang-format deleted file mode 100644 index 1b5d0d488..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.clang-format +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# See Clang docs: http://clang.llvm.org/docs/ClangFormatStyleOptions.html -BasedOnStyle: Chromium - -# Allow double brackets such as std::vector>. -Standard: Cpp11 - -# Indent 2 spaces at a time. -IndentWidth: 2 - -# Keep lines under 100 columns long. -ColumnLimit: 100 - -# Always break before braces -BreakBeforeBraces: Custom -BraceWrapping: -# TODO(lujc) wait for clang-format-9 support in Chromium tools -# AfterCaseLabel: true - AfterClass: true - AfterControlStatement: true - AfterEnum: true - AfterFunction: true - AfterNamespace: true - AfterStruct: true - AfterUnion: true - BeforeCatch: true - BeforeElse: true - IndentBraces: false - SplitEmptyFunction: false - SplitEmptyRecord: false - SplitEmptyNamespace: false - - # Keeps extern "C" blocks unindented. - AfterExternBlock: false - -# Indent case labels. -IndentCaseLabels: true - -# Right-align pointers and references -PointerAlignment: Right - -# ANGLE likes to align things as much as possible. -AlignOperands: true -AlignConsecutiveAssignments: true - -# Use 2 space negative offset for access modifiers -AccessModifierOffset: -2 - -# TODO(jmadill): Decide if we want this on. Doesn't have an "all or none" mode. -AllowShortCaseLabelsOnASingleLine: false - -# Useful for spacing out functions in classes -KeepEmptyLinesAtTheStartOfBlocks: true - -# Indent nested PP directives. -IndentPPDirectives: AfterHash - -# Include blocks style -IncludeBlocks: Preserve - -AttributeMacros: - - OPENTELEMETRY_UNLIKELY - - OPENTELEMETRY_LIKELY - - OPENTELEMETRY_MAYBE_UNUSED - - OPENTELEMETRY_DEPRECATED - - OPENTELEMETRY_API_SINGLETON - - OPENTELEMETRY_LOCAL_SYMBOL - - OPENTELEMETRY_EXPORT - - OPENTELEMETRY_SANITIZER_NO_MEMORY - - OPENTELEMETRY_SANITIZER_NO_THREAD - - OPENTELEMETRY_SANITIZER_NO_ADDRESS \ No newline at end of file diff --git a/ext/opentelemetry-cpp-1.21.0/.clang-tidy b/ext/opentelemetry-cpp-1.21.0/.clang-tidy deleted file mode 100644 index db61b810c..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.clang-tidy +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -Checks: > - -*, - performance-*, - portability-*, - abseil-*, - -abseil-string-find-str-contains, - bugprone-*, - -bugprone-easily-swappable-parameters, - -bugprone-implicit-widening-of-multiplication-result, - -bugprone-inc-dec-in-conditions, - -bugprone-narrowing-conversions, - -bugprone-unchecked-optional-access, - -bugprone-unhandled-exception-at-new, - -bugprone-unused-local-non-trivial-variable, - google-*, - -google-build-using-namespace, - -google-default-arguments, - -google-explicit-constructor, - -google-readability-avoid-underscore-in-googletest-name, - -google-readability-braces-around-statements, - -google-readability-namespace-comments, - -google-readability-todo, - -google-runtime-references, - misc-*, - -misc-const-correctness, - -misc-include-cleaner, - -misc-non-private-member-variables-in-classes, - -misc-unused-alias-decls, - -misc-use-anonymous-namespace, - cppcoreguidelines-*, - -cppcoreguidelines-owning-memory, - -cppcoreguidelines-avoid-do-while, - -cppcoreguidelines-avoid-c-arrays, - -cppcoreguidelines-avoid-magic-numbers, - -cppcoreguidelines-init-variables, - -cppcoreguidelines-macro-usage, - -cppcoreguidelines-non-private-member-variables-in-classes, - -cppcoreguidelines-avoid-non-const-global-variables, - -cppcoreguidelines-pro-* \ No newline at end of file diff --git a/ext/opentelemetry-cpp-1.21.0/.cmake-format.py b/ext/opentelemetry-cpp-1.21.0/.cmake-format.py deleted file mode 100644 index d232ac8eb..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.cmake-format.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# If comment markup is enabled, don't reflow the first comment block in -# eachlistfile. Use this to preserve formatting of your -# copyright/licensestatements. -first_comment_is_literal = True diff --git a/ext/opentelemetry-cpp-1.21.0/.copyright-ignore b/ext/opentelemetry-cpp-1.21.0/.copyright-ignore deleted file mode 100644 index 81c51bcd5..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.copyright-ignore +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# Ignore the following directories - -./.git/* -./.github/* -./third_party/benchmark/* -./third_party/boost/* -./third_party/googletest/* -./third_party/ms-gsl/* -./third_party/nlohmann-json/* -./third_party/opentelemetry-proto/* -./third_party/prometheus-cpp/* -./tools/vcpkg/* -./tools/ports/* - -# Third party code - -./api/include/opentelemetry/nostd/internal/absl/* -./exporters/jaeger/thrift-gen/* -./exporters/etw/include/opentelemetry/exporters/etw/TraceLoggingDynamic.h - -# Doc - -./docs/* - -## Ignore the following files patterns - -*.md -*.rst -*.png -*.log -*.patch -*.json -*.nuspec -*.pem - -# Packaging -*/CONTROL - -# LICENSE files -*/LICENSE - -# Ignore the following misc files - -./.bazelignore -./.bazelversion -./docker/.gitignore -.markdownlintignore -./ci/toc.yml -./ci/valgrind-suppressions diff --git a/ext/opentelemetry-cpp-1.21.0/.devcontainer/Dockerfile.conan b/ext/opentelemetry-cpp-1.21.0/.devcontainer/Dockerfile.conan deleted file mode 100644 index 05f6ae27f..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.devcontainer/Dockerfile.conan +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -FROM ubuntu:24.04@sha256:1e622c5f073b4f6bfad6632f2616c7f59ef256e96fe78bf6a595d1dc4376ac02 - -RUN apt update && apt install -y \ - build-essential \ - ca-certificates \ - wget \ - cmake \ - git \ - sudo \ - nano \ - pkg-config \ - ninja-build \ - clang-format \ - clang-tidy \ - autoconf \ - automake \ - libtool \ - python3-pip - -RUN pip install "conan==2.15.1" --break-system-packages - -ARG USER_UID=1000 -ARG USER_GID=1000 -ARG USER_NAME=devuser -ENV USER_NAME=devuser -ENV USER_UID=${USER_UID} -ENV USER_GID=${USER_GID} -ENV INSTALL_PACKAGES= -ENV IS_CONTAINER_BUILD=true - -COPY ./.devcontainer/customize_container.sh /tmp/opentelemetry_cpp/devcontainer/customize_container.sh -RUN /tmp/opentelemetry_cpp/devcontainer/customize_container.sh -USER devuser - -RUN conan profile detect --force - -ARG CONAN_FILE=conanfile_stable.txt -ARG CONAN_BUILD_TYPE=Debug -ARG CXX_STANDARD=17 -WORKDIR /home/devuser/conan -COPY ./install/conan/ . - -RUN conan install ./${CONAN_FILE} --build=missing -s build_type=${CONAN_BUILD_TYPE} -ENV CMAKE_TOOLCHAIN_FILE=/home/devuser/conan/build/${CONAN_BUILD_TYPE}/generators/conan_toolchain.cmake -ENV CXX_STANDARD=${CXX_STANDARD} -ENV BUILD_TYPE=${CONAN_BUILD_TYPE} -ENV CONAN_FILE=${CONAN_FILE} - -WORKDIR /workspaces/opentelemetry-cpp - -ENTRYPOINT [] - -CMD ["/bin/bash"] diff --git a/ext/opentelemetry-cpp-1.21.0/.devcontainer/Dockerfile.dev b/ext/opentelemetry-cpp-1.21.0/.devcontainer/Dockerfile.dev deleted file mode 100644 index c0eea6d32..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.devcontainer/Dockerfile.dev +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -FROM otel/cpp_format_tools - -ARG USER_UID=1000 -ARG USER_GID=1000 -ARG INSTALL_PACKAGES= - -ARG CXX_STANDARD=17 -ARG CMAKE_VERSION=3.31.6 -ARG ABSEIL_CPP_VERSION=20230125.3 -ARG PROTOBUF_VERSION=23.3 -ARG GRPC_VERSION=v1.55.0 - -ENV CXX_STANDARD=${CXX_STANDARD} -ENV CMAKE_VERSION=${CMAKE_VERSION} -ENV ABSEIL_CPP_VERSION=${ABSEIL_CPP_VERSION} -ENV PROTOBUF_VERSION=${PROTOBUF_VERSION} -ENV GRPC_VERSION=${GRPC_VERSION} - -COPY ci /opt/ci - -RUN apt update && apt install -y wget \ - ninja-build \ - libcurl4-openssl-dev \ - clang-tidy \ - shellcheck - -RUN cd /opt/ci && bash setup_cmake.sh -RUN cd /opt/ci && bash setup_ci_environment.sh -RUN cd /opt && bash ci/setup_googletest.sh \ - && bash ci/install_abseil.sh \ - && bash ci/install_protobuf.sh \ - && bash ci/setup_grpc.sh -r $GRPC_VERSION -s $CXX_STANDARD -p protobuf -p abseil-cpp - -ADD https://github.com/bazelbuild/bazelisk/releases/download/v1.22.1/bazelisk-linux-amd64 /usr/local/bin - -RUN git config --global core.autocrlf input \ - && chmod +x /usr/local/bin/bazelisk-linux-amd64 - -ENV INSTALL_PACKAGES=${INSTALL_PACKAGES} -ENV USER_NAME=devuser -ENV USER_UID=${USER_UID} -ENV USER_GID=${USER_GID} -ENV IS_CONTAINER_BUILD=true - -COPY ./.devcontainer/customize_container.sh /tmp/opentelemetry_cpp/devcontainer/customize_container.sh -RUN /tmp/opentelemetry_cpp/devcontainer/customize_container.sh -RUN apt install -y npm && npm install -g markdownlint-cli@0.44.0 - -USER devuser - -WORKDIR /workspaces/opentelemetry-cpp - -ENTRYPOINT [] - -CMD ["/bin/bash"] \ No newline at end of file diff --git a/ext/opentelemetry-cpp-1.21.0/.devcontainer/README.md b/ext/opentelemetry-cpp-1.21.0/.devcontainer/README.md deleted file mode 100644 index bea6f8c4d..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.devcontainer/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Customizing Your Dev Container - -Customize your dev container using build arguments (for direct Docker builds) or -environment variables (for evaluation in `devcontainer.json`). - -* **CMake version:** - The version of cmake to install. (Default: 3.31.6) - * Docker ARG: - `CMAKE_VERSION` - * Host Environment Variable: - `OTEL_CPP_DEVCONTAINER_CMAKE_VERSION` - -* **CXX standard:** - This is the C++ standard to build from (eg: 17, 20, ...). (Default: 17) - * Docker ARG: - `CXX_STANDARD` - * Host Environment Variable: - `OTEL_CPP_DEVCONTAINER_CXX_STANDARD` - -* **abseil-cpp version:** - This is the version of abseil-cpp that will be used to build protobuf, gRPC, - and opentelemetry-cpp. - * Docker ARG: - `ABSEIL_CPP_VERSION` - * Host Environment Variable: - `OTEL_CPP_DEVCONTAINER_ABSEIL_CPP_VERSION` - -* **Protobuf version:** - * Docker ARG: - `PROTOBUF_VERSION` - * Host Environment Variable: - `OTEL_CPP_DEVCONTAINER_PROTOBUF_VERSION` - -* **gRPC version:** - * Docker ARG: - `GRPC_VERSION` - * Host Environment Variable: - `OTEL_CPP_DEVCONTAINER_GRPC_VERSION` - -* **User ID (UID):** - User ID (Default: `1000`) - * Docker ARG: - `USER_UID` - * Host Environment Variable: - `OTEL_CPP_DEVCONTAINER_USER_UID` - -* **Group ID (GID):** - User group ID (Default: `1000`) - * Docker ARG: - `USER_GID` - * Host Environment Variable: - `OTEL_CPP_DEVCONTAINER_USER_GID` - -* **Install Packages:** - These are the additional packages that will be installed via `apt install` in the devcontainer. This is a space separated list. - * Docker ARG: - `INSTALL_PACKAGES` (Default: ``) - * Host Environment Variable: - `OTEL_CPP_DEVCONTAINER_INSTALL_PACKAGES` (Default: ``) - -## Examples - -* `docker build --build-arg CXX_STANDARD="20" --build-arg INSTALL_PACKAGES="nano gitk"...` -* `export OTEL_CPP_DEVCONTAINER_CXX_STANDARD=20` -* `export OTEL_CPP_DEVCONTAINER_INSTALL_PACKAGES="nano gitk"` diff --git a/ext/opentelemetry-cpp-1.21.0/.devcontainer/customize_container.sh b/ext/opentelemetry-cpp-1.21.0/.devcontainer/customize_container.sh deleted file mode 100755 index ba9614e67..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.devcontainer/customize_container.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -set -eu - -if [[ $IS_CONTAINER_BUILD != "true" ]]; then - echo "This script should only run inside a Docker container." - exit 1 -fi - -if [[ -n "$INSTALL_PACKAGES" ]]; then - packages=($INSTALL_PACKAGES) - for package in "${packages[@]}"; do - apt install -y "$package" - done -fi - -if [[ $(id "$USER_NAME" 2>/dev/null) ]]; then - echo "User '$USER_NAME' already exists. Removing it." - userdel -rf "$USER_NAME" -elif [[ $(id -u "$USER_UID" 2>/dev/null) ]]; then - OTHER_USER=$(getent passwd "$USER_UID" | cut -d: -f1) - echo "User '$OTHER_USER' exists with UID $USER_UID. Removing it." - userdel -rf "$OTHER_USER" -fi - -if [[ ! $(getent group "$USER_GID" 2>/dev/null) ]]; then - echo "Group '$USER_GID' does not exist. Adding it." - groupadd -g "$USER_GID" "$USER_NAME" -fi - -useradd -m -u "$USER_UID" -g "$USER_GID" -s /bin/bash "$USER_NAME" -echo "Created user '$USER_NAME' (UID: $USER_UID, GID: $USER_GID)." - -echo "$USER_NAME ALL=(ALL) NOPASSWD:ALL" | tee /etc/sudoers.d/"$USER_NAME" - -echo "User and group setup complete." diff --git a/ext/opentelemetry-cpp-1.21.0/.devcontainer/devcontainer.json b/ext/opentelemetry-cpp-1.21.0/.devcontainer/devcontainer.json deleted file mode 100644 index 808712242..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.devcontainer/devcontainer.json +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: -// https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/javascript-node -{ - "name": "opentelemetry-cpp", - "build": { - "context": "..", - "dockerfile": "Dockerfile.dev", - "args": { - "USER_UID": "${localEnv:OTEL_CPP_DEVCONTAINER_USER_UID:1000}", - "USER_GID": "${localEnv:OTEL_CPP_DEVCONTAINER_USER_GID:1000}", - "INSTALL_PACKAGES": "${localEnv:OTEL_CPP_DEVCONTAINER_INSTALL_PACKAGES:}", - "CMAKE_VERSION": "${localEnv:OTEL_CPP_DEVCONTAINER_CMAKE_VERSION:3.31.6}", - "CXX_STANDARD": "${localEnv:OTEL_CPP_DEVCONTAINER_CXX_STANDARD:17}", - "GRPC_VERSION": "${localEnv:OTEL_CPP_DEVCONTAINER_GRPC_VERSION:v1.55.0}", - "PROTOBUF_VERSION": "${localEnv:OTEL_CPP_DEVCONTAINER_PROTOBUF_VERSION:23.3}", - "ABSEIL_CPP_VERSION":"${localEnv:OTEL_CPP_DEVCONTAINER_ABSEIL_CPP_VERSION:20230125.3}" - } - }, - "customizations": { - "vscode": { - "extensions": [ - "ms-vscode.cpptools", - "ms-azuretools.vscode-docker", - "ms-vscode.cpptools-extension-pack" - ], - "settings": { - "terminal.integrated.shell.linux": "/bin/bash", - } - } - }, - - "remoteUser": "devuser" -} diff --git a/ext/opentelemetry-cpp-1.21.0/.gitattributes b/ext/opentelemetry-cpp-1.21.0/.gitattributes deleted file mode 100644 index ca2467b47..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.gitattributes +++ /dev/null @@ -1,47 +0,0 @@ -##### Source code ##### - -## C++ and C source files -*.c text eol=lf diff=cpp -*.h text eol=lf diff=cpp -*.cc text eol=lf diff=cpp -*.cpp text eol=lf diff=cpp -*.cxx text eol=lf diff=cpp -*.hpp text eol=lf diff=cpp - -## Python scripts -*.py text eol=lf diff=python - -## Perl scripts/libraries/modules -*.perl text eol=lf diff=perl -*.pl text eol=lf diff=perl -*.pm text eol=lf diff=perl - -## Shell scripts -*.sh text eol=lf -*.bash text eol=lf - -## Windows batch and PowerShell scripts -*.bat text eol=crlf -*.cmd text eol=crlf -*.ps1 text eol=crlf - -##### Other file types ##### - -## Text files and documentation -*.txt text -README* text -INSTALL* text -LICENSE* text - -## Non-text documentation -*.html text diff=html -*.pdf binary -*.rtf binary - -## git files -.gitignore text eol=lf -.gitattributes text eol=lf - -## bazel files -WORKSPACE text eol=lf -BUILD text eol=lf diff --git a/ext/opentelemetry-cpp-1.21.0/.github/.codecov.yaml b/ext/opentelemetry-cpp-1.21.0/.github/.codecov.yaml deleted file mode 100644 index 1b9921ac4..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/.codecov.yaml +++ /dev/null @@ -1,50 +0,0 @@ -codecov: - require_ci_to_pass: false - max_report_age: off - -coverage: - precision: 2 - round: up - range: "80...100" - status: - project: - default: - informational: true - target: auto - threshold: 10% - patch: false - -parsers: - gcov: - branch_detection: - conditional: yes - loop: yes - method: no - macro: no - -comment: - layout: "reach,diff,flags,tree" - behavior: default - require_changes: false - -# Relative file path fixing. -# CI file paths must match Git file paths. -# This fix removes the "/home/runner/" prefix -# to coverage report file paths. -fixes: - - "/home/runner/::" - -ignore: - - "docs/**/*" - - "docker/**/*" - - "examples/**/*" - - "bazel/**/*" - - "cmake/**/*" - - "buildscripts/**/*" - - "third_party/**/*" - - "test_common/**/*" - - "tools/**/*" - - ".vscode/**/*" - - ".github/**/*" - - "**/test/**/*" - - "**.md" \ No newline at end of file diff --git a/ext/opentelemetry-cpp-1.21.0/.github/CODEOWNERS b/ext/opentelemetry-cpp-1.21.0/.github/CODEOWNERS deleted file mode 100644 index 7a40cd0b0..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/CODEOWNERS +++ /dev/null @@ -1,8 +0,0 @@ -# Code owners file. -# This file controls who is tagged for review for any given pull request. - -# For ETW exporter -exporters/etw/* @reyang @maxgolov @lalitb @ThomsonTan @open-telemetry/cpp-approvers - -# For anything not explicitly taken by someone else: -* @open-telemetry/cpp-approvers diff --git a/ext/opentelemetry-cpp-1.21.0/.github/ISSUE_TEMPLATE/bug_report.md b/ext/opentelemetry-cpp-1.21.0/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index e0bb4cca2..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: Bug Report -about: Create a report to help us improve -labels: bug ---- - -**Describe your environment** Describe any aspect of your environment relevant to the problem, including your platform, build system, version numbers of installed dependencies, etc. If you're reporting a problem with a specific version of a library in this repo, please check whether the problem has been fixed on main branch. - -**Steps to reproduce** -Describe exactly how to reproduce the error. Include a code sample if applicable. - -**What is the expected behavior?** -What did you expect to see? - -**What is the actual behavior?** -What did you see instead? - -**Additional context** -Add any other context about the problem here. diff --git a/ext/opentelemetry-cpp-1.21.0/.github/ISSUE_TEMPLATE/feature_request.md b/ext/opentelemetry-cpp-1.21.0/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 973549ab2..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: Feature Request -about: Suggest an idea for this project -labels: feature-request ---- - -Before opening a feature request against this repo, consider whether the feature should/could be implemented in the [other OpenTelemetry client libraries](https://github.com/open-telemetry/). If so, please [open an issue on opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/issues/new) first. - -**Is your feature request related to a problem?** -If so, provide a concise description of the problem. - -**Describe the solution you'd like** -What do you want to happen instead? What is the expected behavior? - -**Describe alternatives you've considered** -Which alternative solutions or features have you considered? - -**Additional context** -Add any other context about the feature request here. diff --git a/ext/opentelemetry-cpp-1.21.0/.github/dependabot.yml b/ext/opentelemetry-cpp-1.21.0/.github/dependabot.yml deleted file mode 100644 index 5cfb4cb89..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/dependabot.yml +++ /dev/null @@ -1,13 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "daily" - labels: - - "GHA" - - - package-ecosystem: "devcontainers" - directory: "/" - schedule: - interval: daily diff --git a/ext/opentelemetry-cpp-1.21.0/.github/pull_request_template.md b/ext/opentelemetry-cpp-1.21.0/.github/pull_request_template.md deleted file mode 100644 index e54760323..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/pull_request_template.md +++ /dev/null @@ -1,11 +0,0 @@ -Fixes # (issue) - -## Changes - -Please provide a brief description of the changes here. - -For significant contributions please make sure you have completed the following items: - -* [ ] `CHANGELOG.md` updated for non-trivial changes -* [ ] Unit tests have been added -* [ ] Changes in public API reviewed \ No newline at end of file diff --git a/ext/opentelemetry-cpp-1.21.0/.github/repository-settings.md b/ext/opentelemetry-cpp-1.21.0/.github/repository-settings.md deleted file mode 100644 index fa86d02cf..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/repository-settings.md +++ /dev/null @@ -1,38 +0,0 @@ -# Process - -This file documents local admin changes for opentelemetry-cpp, -per the community process: https://github.com/open-telemetry/community/blob/main/docs/how-to-configure-new-repository.md - -Please note that the EasyCLA check **MUST** stay **REQUIRED**, -it should never be disabled or bypassed, at the risk of tainting the repository. - -# Guidelines - -The best is to open a PR first that describes the change, -so it can be discussed during review (maybe it is not needed, -maybe there is an alternate solution, ...). - -The PR must add a log entry in this file, detailing: - -* the date the change is implemented -* what is changed exactly (which setting) -* a short rationale - -Admin changes are then applied only when the PR is merged. - -If for some reason a change is implemented in emergency, -before a PR can be discussed and merged, -a PR should still be prepared and pushed after the fact to -describe the settings changed. - -# Log of local changes - -## 2023-11-03 - -Created log file `.github/repository-settings.md`, since admin permissions are now granted to maintainers. - -See https://github.com/open-telemetry/community/issues/1727 - -No setting changed. - - diff --git a/ext/opentelemetry-cpp-1.21.0/.github/workflows/benchmark.yml b/ext/opentelemetry-cpp-1.21.0/.github/workflows/benchmark.yml deleted file mode 100644 index eaad6b280..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/workflows/benchmark.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: OpenTelemetry-cpp benchmarks -on: - push: - branches: - - main - -permissions: - contents: write - deployments: write - -jobs: - benchmark: - name: Run OpenTelemetry-cpp benchmarks - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Mount Bazel Cache - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - env: - cache-name: bazel_cache - with: - path: /home/runner/.cache/bazel - key: bazel_benchmark - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: Run benchmark - id: run_benchmarks - run: | - ./ci/do_ci.sh bazel.benchmark - mkdir -p benchmarks - mv api-benchmark_result.json benchmarks - mv sdk-benchmark_result.json benchmarks - mv exporters-benchmark_result.json benchmarks - - uses: actions/upload-artifact@6027e3dd177782cd8ab9af838c04fd81a07f1d47 # main March 2025 - with: - name: benchmark_results - path: benchmarks - store_benchmark: - needs: benchmark - strategy: - matrix: - components: ["api", "sdk", "exporters"] - name: Store benchmark result - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # main March 2025 - with: - name: benchmark_results - path: benchmarks - - name: Print json files - id: print_json - run: | - cat benchmarks/* - - name: Push benchmark result - uses: benchmark-action/github-action-benchmark@d48d326b4ca9ba73ca0cd0d59f108f9e02a381c7 # v1.20.4 - with: - name: OpenTelemetry-cpp ${{ matrix.components }} Benchmark - tool: 'googlecpp' - output-file-path: benchmarks/${{ matrix.components }}-benchmark_result.json - github-token: ${{ secrets.GITHUB_TOKEN }} - auto-push: true - # Show alert with commit comment on detecting possible performance regression - alert-threshold: '200%' - comment-on-alert: true - fail-on-alert: false - gh-pages-branch: gh-pages - benchmark-data-dir-path: benchmarks diff --git a/ext/opentelemetry-cpp-1.21.0/.github/workflows/ci.yml b/ext/opentelemetry-cpp-1.21.0/.github/workflows/ci.yml deleted file mode 100644 index bc585fc26..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/workflows/ci.yml +++ /dev/null @@ -1,1247 +0,0 @@ -name: CI - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -permissions: - contents: read - -jobs: - -# Commented 2024-11-06, lack of workers in github causes CI failures -# arm64_test: -# name: CMake test arm64 (with modern protobuf,grpc and abseil) -# runs-on: actuated-arm64-4cpu-16gb -# steps: -# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 -# with: -# submodules: 'recursive' -# - name: setup -# env: -# PROTOBUF_VERSION: '23.3' -# ABSEIL_CPP_VERSION: '20230125.3' -# CXX_STANDARD: '14' -# CC: /usr/bin/gcc-10 -# CXX: /usr/bin/g++-10 -# run: | -# sudo -E ./ci/setup_gcc10.sh -# sudo -E ./ci/setup_ci_environment.sh -# sudo -E ./ci/setup_cmake.sh -# sudo -E ./ci/setup_googletest.sh -# sudo -E ./ci/install_abseil.sh -# sudo -E ./ci/install_protobuf.sh - - cmake_test: - name: CMake test (prometheus, elasticsearch, zipkin) - runs-on: ubuntu-22.04 - env: - CXX_STANDARD: '17' - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run cmake tests - run: | - ./ci/do_ci.sh cmake.test - - cmake_fetch_content_test: - name: CMake FetchContent usage with opentelemetry-cpp - runs-on: ubuntu-24.04 - env: - CXX_STANDARD: '17' - BUILD_TYPE: 'Debug' - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: Install abseil, protobuf, and grpc with apt - run: | - sudo -E apt-get update - sudo -E apt-get install -y libabsl-dev libprotobuf-dev libgrpc++-dev protobuf-compiler protobuf-compiler-grpc - - name: run fetch content cmake test - run: | - ./ci/do_ci.sh cmake.fetch_content.test - - cmake_gcc_maintainer_sync_test: - name: CMake gcc 14 (maintainer mode, sync) - runs-on: ubuntu-24.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - env: - CC: /usr/bin/gcc-14 - CXX: /usr/bin/g++-14 - PROTOBUF_VERSION: 21.12 - run: | - sudo apt remove needrestart #refer: https://github.com/actions/runner-images/issues/9937 - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - sudo -E ./ci/install_protobuf.sh - - name: setup grpc - run: | - sudo ./ci/setup_grpc.sh - - name: run cmake gcc (maintainer mode, sync) - env: - CC: /usr/bin/gcc-14 - CXX: /usr/bin/g++-14 - run: | - ./ci/do_ci.sh cmake.maintainer.sync.test - - name: generate test cert - env: - CFSSL_VERSION: 1.6.3 - run: | - sudo -E ./tools/setup-cfssl.sh - (cd ./functional/cert; ./generate_cert.sh) - - name: run func test - run: | - (cd ./functional/otlp; ./run_test.sh) - - cmake_gcc_maintainer_async_test: - name: CMake gcc 14 (maintainer mode, async) - runs-on: ubuntu-24.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - env: - CC: /usr/bin/gcc-14 - CXX: /usr/bin/g++-14 - PROTOBUF_VERSION: 21.12 - run: | - sudo apt remove needrestart #refer: https://github.com/actions/runner-images/issues/9937 - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - sudo -E ./ci/install_protobuf.sh - - name: setup grpc - run: | - sudo ./ci/setup_grpc.sh - - name: run cmake gcc (maintainer mode, async) - env: - CC: /usr/bin/gcc-14 - CXX: /usr/bin/g++-14 - run: | - ./ci/do_ci.sh cmake.maintainer.async.test - - name: generate test cert - env: - CFSSL_VERSION: 1.6.3 - run: | - sudo -E ./tools/setup-cfssl.sh - (cd ./functional/cert; ./generate_cert.sh) - - name: run func test - run: | - (cd ./functional/otlp; ./run_test.sh) - - cmake_clang_maintainer_sync_test: - name: CMake clang 18 (maintainer mode, sync) - runs-on: ubuntu-24.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - env: - CC: /usr/bin/clang-18 - CXX: /usr/bin/clang++-18 - PROTOBUF_VERSION: 21.12 - run: | - sudo apt remove needrestart #refer: https://github.com/actions/runner-images/issues/9937 - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - sudo -E ./ci/install_protobuf.sh - - name: setup grpc - run: | - sudo ./ci/setup_grpc.sh - - name: run cmake clang (maintainer mode, sync) - env: - CC: /usr/bin/clang-18 - CXX: /usr/bin/clang++-18 - run: | - ./ci/do_ci.sh cmake.maintainer.sync.test - - name: generate test cert - env: - CFSSL_VERSION: 1.6.3 - run: | - sudo -E ./tools/setup-cfssl.sh - (cd ./functional/cert; ./generate_cert.sh) - - name: run func test - run: | - (cd ./functional/otlp; ./run_test.sh) - - cmake_clang_maintainer_async_test: - name: CMake clang 18 (maintainer mode, async) - runs-on: ubuntu-24.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - env: - CC: /usr/bin/clang-18 - CXX: /usr/bin/clang++-18 - PROTOBUF_VERSION: 21.12 - run: | - sudo apt remove needrestart #refer: https://github.com/actions/runner-images/issues/9937 - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - sudo -E ./ci/install_protobuf.sh - - name: setup grpc - run: | - sudo ./ci/setup_grpc.sh - - name: run cmake clang (maintainer mode, async) - env: - CC: /usr/bin/clang-18 - CXX: /usr/bin/clang++-18 - run: | - ./ci/do_ci.sh cmake.maintainer.async.test - - name: generate test cert - env: - CFSSL_VERSION: 1.6.3 - run: | - sudo -E ./tools/setup-cfssl.sh - (cd ./functional/cert; ./generate_cert.sh) - - name: run func test - run: | - (cd ./functional/otlp; ./run_test.sh) - - cmake_clang_maintainer_abiv2_test: - name: CMake clang 18 (maintainer mode, abiv2) - runs-on: ubuntu-24.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - env: - CC: /usr/bin/clang-18 - CXX: /usr/bin/clang++-18 - PROTOBUF_VERSION: 21.12 - run: | - sudo apt remove needrestart #refer: https://github.com/actions/runner-images/issues/9937 - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - sudo -E ./ci/install_protobuf.sh - - name: setup grpc - run: | - sudo ./ci/setup_grpc.sh - - name: run cmake clang (maintainer mode, abiv2) - env: - CC: /usr/bin/clang-18 - CXX: /usr/bin/clang++-18 - run: | - ./ci/do_ci.sh cmake.maintainer.abiv2.test - - name: generate test cert - env: - CFSSL_VERSION: 1.6.3 - run: | - sudo -E ./tools/setup-cfssl.sh - (cd ./functional/cert; ./generate_cert.sh) - - name: run func test - run: | - (cd ./functional/otlp; ./run_test.sh) - - cmake_msvc_maintainer_test: - name: CMake msvc (maintainer mode) - runs-on: windows-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - ./ci/setup_cmake.ps1 - ./ci/setup_windows_ci_environment.ps1 - - name: run tests - run: ./ci/do_ci.ps1 cmake.maintainer.test - - cmake_msvc_maintainer_test_stl_cxx20: - name: CMake msvc (maintainer mode) with C++20 - runs-on: windows-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - ./ci/setup_cmake.ps1 - ./ci/setup_windows_ci_environment.ps1 - - name: run tests - env: - CXX_STANDARD: '20' - run: ./ci/do_ci.ps1 cmake.maintainer.cxx20.stl.test - - cmake_msvc_maintainer_abiv2_test: - name: CMake msvc (maintainer mode, abiv2) - runs-on: windows-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - ./ci/setup_cmake.ps1 - ./ci/setup_windows_ci_environment.ps1 - - name: run tests - env: - CXX_STANDARD: '20' - run: ./ci/do_ci.ps1 cmake.maintainer.abiv2.test - - cmake_with_async_export_test: - name: CMake test (without otlp-exporter and with async export) - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - env: - CC: /usr/bin/gcc-12 - CXX: /usr/bin/g++-12 - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run cmake tests (without otlp-exporter) - env: - CC: /usr/bin/gcc-12 - CXX: /usr/bin/g++-12 - run: | - ./ci/do_ci.sh cmake.with_async_export.test - - cmake_opentracing_shim_test: - name: CMake test (with opentracing-shim) - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run cmake tests (enable opentracing-shim) - run: ./ci/do_ci.sh cmake.opentracing_shim.test - - cmake_test_cxx14_gcc: - name: CMake C++14 test(GCC) - runs-on: ubuntu-22.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run tests (enable stl) - env: - CXX_STANDARD: '14' - run: ./ci/do_ci.sh cmake.c++14.stl.test - - cmake_test_cxx17_gcc: - name: CMake C++17 test(GCC) - runs-on: ubuntu-22.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run tests (enable stl) - env: - CXX_STANDARD: '17' - run: ./ci/do_ci.sh cmake.c++17.stl.test - - cmake_test_cxx20_gcc: - name: CMake C++20 test(GCC) - runs-on: ubuntu-22.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run tests - env: - CXX_STANDARD: '20' - run: ./ci/do_ci.sh cmake.c++20.test - - name: run tests (enable stl) - env: - CXX_STANDARD: '20' - run: ./ci/do_ci.sh cmake.c++20.stl.test - - cmake_test_cxx20_clang: - name: CMake C++20 test(Clang with libc++) - runs-on: ubuntu-22.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - env: - CC: /usr/bin/clang - CXX: /usr/bin/clang++ - CXXFLAGS: "-stdlib=libc++" - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run tests - env: - CC: /usr/bin/clang - CXX: /usr/bin/clang++ - CXXFLAGS: "-stdlib=libc++" - CXX_STANDARD: '20' - run: ./ci/do_ci.sh cmake.c++20.test - - name: run tests (enable stl) - env: - CC: /usr/bin/clang - CXX: /usr/bin/clang++ - CXXFLAGS: "-stdlib=libc++" - CXX_STANDARD: '20' - run: ./ci/do_ci.sh cmake.c++20.stl.test - - cmake_test_cxx23_gcc: - name: CMake C++23 test(GCC) - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run tests - env: - CXX_STANDARD: '23' - run: ./ci/do_ci.sh cmake.c++23.test - - name: run tests (enable stl) - env: - CXX_STANDARD: '23' - run: ./ci/do_ci.sh cmake.c++23.stl.test - - cmake_test_cxx23_clang: - name: CMake C++23 test(Clang with libc++) - runs-on: ubuntu-22.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - env: - CC: /usr/bin/clang - CXX: /usr/bin/clang++ - CXXFLAGS: "-stdlib=libc++" - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run tests - env: - CC: /usr/bin/clang - CXX: /usr/bin/clang++ - CXXFLAGS: "-stdlib=libc++" - CXX_STANDARD: '23' - run: ./ci/do_ci.sh cmake.c++23.test - - name: run tests (enable stl) - env: - CC: /usr/bin/clang - CXX: /usr/bin/clang++ - CXXFLAGS: "-stdlib=libc++" - CXX_STANDARD: '23' - run: ./ci/do_ci.sh cmake.c++23.stl.test - - cmake_otprotocol_test: - name: CMake test (with otlp-exporter) - runs-on: ubuntu-22.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run otlp exporter tests - run: | - sudo ./ci/setup_grpc.sh - ./ci/do_ci.sh cmake.exporter.otprotocol.test - - name: generate test cert - env: - CFSSL_VERSION: 1.6.3 - run: | - sudo -E ./tools/setup-cfssl.sh - (cd ./functional/cert; ./generate_cert.sh) - - name: run func test - run: | - (cd ./functional/otlp; ./run_test.sh) - - cmake_modern_protobuf_grpc_with_abseil_test: - name: CMake test (with modern protobuf,grpc and abseil) - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - env: - PROTOBUF_VERSION: '23.3' - ABSEIL_CPP_VERSION: '20230125.3' - CXX_STANDARD: '14' - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - sudo -E ./ci/install_abseil.sh - sudo -E ./ci/install_protobuf.sh - - name: run otlp exporter tests - env: - CXX_STANDARD: '14' - run: | - sudo -E ./ci/setup_grpc.sh -m -p protobuf -p abseil-cpp - ./ci/do_ci.sh cmake.exporter.otprotocol.test - - cmake_do_not_install_test: - name: CMake do not install test (with otlp-exporter) - runs-on: ubuntu-22.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run otlp exporter tests - run: | - sudo ./ci/setup_grpc.sh - ./ci/do_ci.sh cmake.do_not_install.test - - cmake_otprotocol_shared_libs_with_static_grpc_test: - name: CMake test (build shared libraries with otlp-exporter and static gRPC) - runs-on: ubuntu-22.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run otlp exporter tests - run: | - sudo ./ci/setup_grpc.sh -T - ./ci/do_ci.sh cmake.exporter.otprotocol.shared_libs.with_static_grpc.test - - plugin_test: - name: Plugin -> CMake - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - env: - CC: /usr/bin/gcc-12 - CXX: /usr/bin/g++-12 - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run tests - env: - CC: /usr/bin/gcc-12 - CXX: /usr/bin/g++-12 - run: ./ci/do_ci.sh cmake.test_example_plugin - - bazel_test: - name: Bazel - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Mount Bazel Cache - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - env: - cache-name: bazel_cache - with: - path: /home/runner/.cache/bazel - key: bazel_test - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/setup_cmake.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.test - - bazel_no_bzlmod_test: - name: Bazel without bzlmod - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Mount Bazel Cache - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - env: - cache-name: bazel_cache - with: - path: /home/runner/.cache/bazel - key: bazel_test - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/setup_cmake.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.no_bzlmod.test - - bazel_test_async: - name: Bazel with async export - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Mount Bazel Cache - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - env: - cache-name: bazel_cache - with: - path: /home/runner/.cache/bazel - key: bazel_test - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/setup_cmake.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.with_async_export.test - - bazel_valgrind: - name: Bazel valgrind - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Mount Bazel Cache - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - env: - cache-name: bazel_cache - with: - path: /home/runner/.cache/bazel - key: bazel_valgrind - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/setup_cmake.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.valgrind - - bazel_noexcept: - name: Bazel noexcept - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Mount Bazel Cache - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - env: - cache-name: bazel_cache - with: - path: /home/runner/.cache/bazel - key: bazel_noexcept - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/setup_cmake.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.noexcept - - bazel_nortti: - name: Bazel nortti - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Mount Bazel Cache - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - env: - cache-name: bazel_cache - with: - path: /home/runner/.cache/bazel - key: bazel_nortti - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/setup_cmake.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.nortti - - bazel_asan: - name: Bazel asan config - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Mount Bazel Cache - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - env: - cache-name: bazel_cache - with: - path: /home/runner/.cache/bazel - key: bazel_asan - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/setup_cmake.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.asan - - bazel_tsan: - name: Bazel tsan config - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Mount Bazel Cache - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - env: - cache-name: bazel_cache - with: - path: /home/runner/.cache/bazel - key: bazel_tsan - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/setup_cmake.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.tsan - - bazel_osx: - name: Bazel on MacOS - runs-on: macos-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Mount Bazel Cache - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - env: - cache-name: bazel_cache - with: - path: /Users/runner/.cache/bazel - key: bazel_osx - - name: run tests - run: ./ci/do_ci.sh bazel.macos.test - - benchmark: - name: Benchmark - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Mount Bazel Cache - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - env: - cache-name: bazel_cache - with: - path: /home/runner/.cache/bazel - key: bazel_benchmark - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: | - env BENCHMARK_DIR=/benchmark - ./ci/do_ci.sh benchmark - - name: Upload benchmark results - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: benchmark_reports - path: /home/runner/benchmark - - format: - name: Format - runs-on: ubuntu-24.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: setup - run: sudo apt remove needrestart && sudo ./ci/install_format_tools.sh #refer: https://github.com/actions/runner-images/issues/9937 - - name: run tests - run: ./ci/do_ci.sh format - - copyright: - name: Copyright - runs-on: ubuntu-22.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: check copyright - run: ./tools/check_copyright.sh - - windows: - name: CMake -> exporter proto - runs-on: windows-2019 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - ./ci/setup_cmake.ps1 - ./ci/setup_windows_ci_environment.ps1 - ./ci/install_windows_protobuf.ps1 - - name: run cmake test - run: ./ci/do_ci.ps1 cmake.test - - name: run otprotocol test - run: ./ci/do_ci.ps1 cmake.exporter.otprotocol.test - - windows-build-dll: - name: CMake -> exporter proto (Build as DLL) - runs-on: windows-2019 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - ./ci/setup_cmake.ps1 - ./ci/setup_windows_ci_environment.ps1 - ./ci/install_windows_protobuf.ps1 - - name: run cmake test (DLL build) - run: ./ci/do_ci.ps1 cmake.dll.test - - name: run cmake cxx20 test (DLL build) - run: ./ci/do_ci.ps1 cmake.dll.cxx20.test - - name: run otprotocol test (DLL build) - run: ./ci/do_ci.ps1 cmake.exporter.otprotocol.dll.test - - windows_with_async_export: - name: CMake (With async export) -> exporter proto - runs-on: windows-2019 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - ./ci/setup_cmake.ps1 - ./ci/setup_windows_ci_environment.ps1 - ./ci/install_windows_protobuf.ps1 - - name: run cmake test - run: ./ci/do_ci.ps1 cmake.with_async_export.test - - name: run otprotocol test - run: ./ci/do_ci.ps1 cmake.exporter.otprotocol.with_async_export.test - - windows_bazel: - name: Bazel Windows - runs-on: windows-2019 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - ./ci/install_windows_bazelisk.ps1 - - name: run tests - run: ./ci/do_ci.ps1 bazel.build - - windows_plugin_test: - name: Plugin -> CMake Windows - runs-on: windows-2019 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - run: | - ./ci/setup_cmake.ps1 - ./ci/setup_windows_ci_environment.ps1 - - name: run tests - run: ./ci/do_ci.ps1 cmake.test_example_plugin - - code_coverage: - name: Code coverage - runs-on: ubuntu-22.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - env: - CC: /usr/bin/gcc-10 - CXX: /usr/bin/g++-10 - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run tests and generate report - env: - CC: /usr/bin/gcc-10 - CXX: /usr/bin/g++-10 - run: ./ci/do_ci.sh code.coverage - - name: upload report - uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3 - with: - files: /home/runner/build/coverage.info - - markdown-lint: - runs-on: ubuntu-latest - - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - name: check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: install markdownlint-cli - run: sudo npm install -g markdownlint-cli@0.44.0 - - - name: run markdownlint - run: markdownlint . - - shellcheck: - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - name: check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: install shellcheck - run: sudo apt install --assume-yes shellcheck - - name: run shellcheck - run: find . -name \*.sh | xargs shellcheck --severity=error - - misspell: - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - name: check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: install misspell - run: | - curl -L -o ./install-misspell.sh https://git.io/misspell - sh ./install-misspell.sh - - name: run misspell - run: ./bin/misspell -error . - - docfx_check: - name: DocFX check - runs-on: windows-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: install docfx - run: choco install docfx -y --version=2.58.5 - - name: run ./ci/docfx.cmd - shell: cmd - run: ./ci/docfx.cmd - - w3c_trace_context_compliance_v1: - name: W3C Distributed Tracing Validation V1 - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - name: Checkout open-telemetry/opentelemetry-cpp - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: setup - env: - CC: /usr/bin/gcc-12 - CXX: /usr/bin/g++-12 - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: run w3c trace-context test server (background) - env: - CXX_STANDARD: '14' - run: | - ./ci/do_ci.sh cmake.w3c.trace-context.build-server - cd $HOME/build/ext/test/w3c_tracecontext_http_test_server - ./w3c_tracecontext_http_test_server & - - name: Checkout w3c/trace-context repo - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - repository: w3c/trace-context - path: trace-context - - name: install dependencies - run: | - sudo apt update && sudo apt install python3-pip - sudo pip3 install aiohttp==3.11.18 - - name: run w3c trace-context test suite - env: - SPEC_LEVEL: 1 - run: - | - python ${GITHUB_WORKSPACE}/trace-context/test/test.py http://localhost:30000/test TraceContextTest AdvancedTest - curl http://localhost:30000/stop diff --git a/ext/opentelemetry-cpp-1.21.0/.github/workflows/clang-tidy.yaml b/ext/opentelemetry-cpp-1.21.0/.github/workflows/clang-tidy.yaml deleted file mode 100644 index aec027f64..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/workflows/clang-tidy.yaml +++ /dev/null @@ -1,89 +0,0 @@ -name: clang-tidy - -on: - push: - branches: [main] - pull_request: - branches: [main] - -permissions: - contents: read - -jobs: - clang-tidy: - runs-on: ubuntu-24.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: recursive - - - name: Setup Environment - env: - PROTOBUF_VERSION: '23.3' - ABSEIL_CPP_VERSION: '20230125.3' - CXX_STANDARD: '14' - run: | - sudo apt update -y - sudo apt install -y --no-install-recommends --no-install-suggests \ - build-essential \ - iwyu \ - cmake \ - libssl-dev \ - libcurl4-openssl-dev \ - libprotobuf-dev \ - protobuf-compiler \ - libgmock-dev \ - libgtest-dev \ - libbenchmark-dev - - if ! command -v clang-tidy &> /dev/null; then - echo "clang-tidy could not be found" - exit 1 - fi - echo "Using clang-tidy version: $(clang-tidy --version)" - echo "clang-tidy installed at: $(which clang-tidy)" - - - - name: Prepare CMake - env: - CC: clang - CXX: clang++ - run: | - echo "Running cmake..." - cmake -B build \ - -DCMAKE_CXX_STANDARD=14 \ - -DWITH_STL=CXX14 \ - -DWITH_OTLP_HTTP=ON \ - -DWITH_OTLP_FILE=ON \ - -DWITH_PROMETHEUS=ON \ - -DWITH_ZIPKIN=ON \ - -DWITH_ELASTICSEARCH=ON \ - -DWITH_OTLP_HTTP_COMPRESSION=ON \ - -DWITH_EXAMPLES=ON \ - -DWITH_EXAMPLES_HTTP=ON \ - -DBUILD_W3CTRACECONTEXT_TEST=ON \ - -DWITH_METRICS_EXEMPLAR_PREVIEW=ON \ - -DWITH_ASYNC_EXPORT_PREVIEW=ON \ - -DCMAKE_EXPORT_COMPILE_COMMANDS=ON - - - name: Run clang-tidy - run: | - cmake --build build --target opentelemetry_proto - jq -r .[].file build/compile_commands.json | grep -vE '/(generated|third_party)/' | xargs -P $(nproc) -n 1 clang-tidy --quiet -p build 2>&1 | tee -a clang-tidy.log - - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: Logs (clang-tidy) - path: ./clang-tidy.log - - - name: Count warnings - run: | - COUNT=$(grep -c "warning:" clang-tidy.log) - echo "clang-tidy reported ${COUNT} warning(s)" - -# TODO: include WITH_OTLP_GRPC flags. diff --git a/ext/opentelemetry-cpp-1.21.0/.github/workflows/cmake_install.yml b/ext/opentelemetry-cpp-1.21.0/.github/workflows/cmake_install.yml deleted file mode 100644 index c62d7def8..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/workflows/cmake_install.yml +++ /dev/null @@ -1,372 +0,0 @@ -name: CMake Install Tests - -on: - workflow_dispatch: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -permissions: - contents: read - -jobs: - windows_2022_vcpkg_submodule: - name: Windows 2022 vcpkg submodule versions cxx17 (static libs - dll) - runs-on: windows-2022 - env: - # Set to the latest version of cmake 3.x - CMAKE_VERSION: '3.31.6' - # cxx17 is the default for windows-2022 - CXX_STANDARD: '17' - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Build dependencies with vcpkg submodule - run: | - ./ci/setup_cmake.ps1 - ./ci/setup_windows_ci_environment.ps1 - - name: Run Tests - run: ./ci/do_ci.ps1 cmake.install.test - - name: Run DLL Tests - run: ./ci/do_ci.ps1 cmake.dll.install.test - - windows_2019_vcpkg_submodule_min_cmake: - name: Windows 2019 vcpkg submodule versions minimum cmake cxx14 (static libs) - runs-on: windows-2019 - env: - # cmake 3.15 is the minimum for windows builds (See https://github.com/open-telemetry/opentelemetry-cpp/pull/3349#discussion_r2030319430) - CMAKE_VERSION: '3.15.0' - # cxx14 is the default for windows-2019 - CXX_STANDARD: '14' - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Build dependencies with vcpkg submodule - run: | - ./ci/setup_cmake.ps1 - ./ci/setup_windows_ci_environment.ps1 - - name: Run Tests - run: ./ci/do_ci.ps1 cmake.install.test - - ubuntu_2404_system_packages: - name: Ubuntu 24.04 apt packages cxx17 (static libs - shared libs) - runs-on: ubuntu-24.04 - env: - INSTALL_TEST_DIR: '/home/runner/install_test' - # CMake 3.28 is apt package version for Ubuntu 24.04 - CMAKE_VERSION: '3.28.3' - # cxx17 is the default for Ubuntu 24.04 - CXX_STANDARD: '17' - BUILD_TYPE: 'Debug' - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Install libcurl, zlib, nlohmann-json with apt - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: Install abseil, protobuf, and grpc with apt - run: | - sudo -E apt-get update - sudo -E apt-get install -y libabsl-dev libprotobuf-dev libgrpc++-dev protobuf-compiler protobuf-compiler-grpc - - name: Run Tests (static libs) - env: - BUILD_SHARED_LIBS: 'OFF' - run: ./ci/do_ci.sh cmake.install.test - - name: Run Tests (shared libs) - env: - BUILD_SHARED_LIBS: 'ON' - run: ./ci/do_ci.sh cmake.install.test - - ubuntu_2404_latest: - name: Ubuntu 24.04 latest versions cxx20 (static libs) - runs-on: ubuntu-24.04 - env: - INSTALL_TEST_DIR: '/home/runner/install_test' - # Set to the latest version of cmake 3.x - CMAKE_VERSION: '3.31.6' - # Set to the latest cxx standard supported by opentelemetry-cpp - CXX_STANDARD: '20' - # Versions below set to the latest version available - # The abseil and protobuf versions are taken from - # the grpc submodules at the GRPC_VERSION tag - GOOGLETEST_VERSION: '1.16.0' - ABSEIL_CPP_VERSION: '20240722.1' - PROTOBUF_VERSION: '29.0' - GRPC_VERSION: 'v1.71.0' - BUILD_TYPE: 'Debug' - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Install gtest, libcurl, zlib, nlohmann-json with apt - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: Build abseil, protobuf, and grpc with ci scripts - run: | - sudo -E ./ci/install_abseil.sh - sudo -E ./ci/install_protobuf.sh - sudo -E ./ci/setup_grpc.sh -r $GRPC_VERSION -s $CXX_STANDARD -p protobuf -p abseil-cpp - - name: Run Tests (static libs) - env: - BUILD_SHARED_LIBS: 'OFF' - run: ./ci/do_ci.sh cmake.install.test - - ubuntu_2204_stable: - name: Ubuntu 22.04 stable versions cxx17 (static libs - shared libs) - runs-on: ubuntu-22.04 - env: - INSTALL_TEST_DIR: '/home/runner/install_test' - # CMake 3.22 is the apt package version for Ubuntu 22.04 - CMAKE_VERSION: '3.22.0' - CXX_STANDARD: '17' - # These are stable versions tested in the main ci workflow - # and defaults in the devcontainer - GOOGLETEST_VERSION: '1.14.0' - ABSEIL_CPP_VERSION: '20230125.3' - PROTOBUF_VERSION: '23.3' - GRPC_VERSION: 'v1.55.0' - BUILD_TYPE: 'Debug' - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Install gtest, libcurl, zlib, nlohmann-json with apt - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: Build abseil, protobuf, and grpc with ci scripts - run: | - sudo -E ./ci/install_abseil.sh - sudo -E ./ci/install_protobuf.sh - sudo -E ./ci/setup_grpc.sh -r $GRPC_VERSION -s $CXX_STANDARD -p protobuf -p abseil-cpp - - name: Run Tests (static libs) - env: - BUILD_SHARED_LIBS: 'OFF' - run: ./ci/do_ci.sh cmake.install.test - - name: Run Tests (shared libs) - env: - BUILD_SHARED_LIBS: 'ON' - run: ./ci/do_ci.sh cmake.install.test - - ubuntu_2204_minimum: - name: Ubuntu 22.04 minimum versions cxx14 (static libs - shared libs) - runs-on: ubuntu-22.04 - env: - INSTALL_TEST_DIR: '/home/runner/install_test' - # Set to the current minimum version of cmake - CMAKE_VERSION: '3.14.0' - # cxx14 is the default for Ubuntu 22.04 - CXX_STANDARD: '14' - # This is the apt package version of googletest for Ubuntu 22.04 - GOOGLETEST_VERSION: '1.11.0' - # These are minimum versions tested in the main ci workflow - ABSEIL_CPP_VERSION: '20220623.2' - PROTOBUF_VERSION: '21.12' - GRPC_VERSION: 'v1.49.2' - BUILD_TYPE: 'Debug' - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Install gtest, libcurl, zlib, nlohmann-json with apt - run: | - sudo -E ./ci/setup_ci_environment.sh - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_googletest.sh - - name: Build abseil, protobuf, and grpc with ci scripts - run: | - sudo -E ./ci/install_abseil.sh - sudo -E ./ci/install_protobuf.sh - sudo -E ./ci/setup_grpc.sh -r $GRPC_VERSION -s $CXX_STANDARD -p protobuf -p abseil-cpp - - name: Run Tests (static libs) - env: - BUILD_SHARED_LIBS: 'OFF' - run: ./ci/do_ci.sh cmake.install.test - - name: Run Tests (shared libs) - env: - BUILD_SHARED_LIBS: 'ON' - run: ./ci/do_ci.sh cmake.install.test - - ubuntu_2404_conan_stable: - name: Ubuntu 24.04 conan stable versions cxx17 (static libs - shared libs - opentracing shim) - runs-on: ubuntu-24.04 - env: - INSTALL_TEST_DIR: '/home/runner/install_test' - # CMake 3.28 is apt package version for Ubuntu 24.04 - CMAKE_VERSION: '3.28.3' - CXX_STANDARD: '17' - CMAKE_TOOLCHAIN_FILE: /home/runner/conan/build/Debug/generators/conan_toolchain.cmake - BUILD_TYPE: 'Debug' - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Install Conan - run: | - python3 -m pip install pip==25.0.1 - pip install "conan==2.15.1" - conan profile detect --force - - name: Install or build all dependencies with Conan - run: | - sudo -E ./ci/setup_cmake.sh - conan install install/conan/conanfile_stable.txt --build=missing -of /home/runner/conan -s build_type=${BUILD_TYPE} -s compiler.cppstd=${CXX_STANDARD} - - name: Run Tests (static libs) - env: - BUILD_SHARED_LIBS: 'OFF' - run: ./ci/do_ci.sh cmake.install.test - - name: Run Tests (shared libs) - env: - BUILD_SHARED_LIBS: 'ON' - run: ./ci/do_ci.sh cmake.install.test - - name: verify pkgconfig packages - run: | - export PKG_CONFIG_PATH=$INSTALL_TEST_DIR/lib/pkgconfig:$PKG_CONFIG_PATH - ./ci/verify_packages.sh - - name: Run OpenTracing Shim Test - run: ./ci/do_ci.sh cmake.opentracing_shim.install.test - - ubuntu_2404_conan_latest: - name: Ubuntu 24.04 conan latest versions cxx17 (static libs) - runs-on: ubuntu-24.04 - env: - INSTALL_TEST_DIR: '/home/runner/install_test' - # Set to the latest version of cmake 3.x - CMAKE_VERSION: '3.31.6' - CXX_STANDARD: '17' - CMAKE_TOOLCHAIN_FILE: /home/runner/conan/build/Debug/generators/conan_toolchain.cmake - BUILD_TYPE: 'Debug' - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Install Conan - run: | - python3 -m pip install pip==25.0.1 - pip install "conan==2.15.1" - conan profile detect --force - - name: Install or build all dependencies with Conan - run: | - sudo -E ./ci/setup_cmake.sh - conan install install/conan/conanfile_latest.txt --build=missing -of /home/runner/conan -s build_type=${BUILD_TYPE} -s compiler.cppstd=${CXX_STANDARD} - - name: Run Tests (static libs) - env: - BUILD_SHARED_LIBS: 'OFF' - run: ./ci/do_ci.sh cmake.install.test - - name: verify pkgconfig packages - run: | - export PKG_CONFIG_PATH=$INSTALL_TEST_DIR/lib/pkgconfig:$PKG_CONFIG_PATH - ./ci/verify_packages.sh - - macos_14_conan_stable: - name: macOS 14 conan stable versions cxx17 (static libs) - runs-on: macos-14 - env: - INSTALL_TEST_DIR: '/Users/runner/install_test' - CMAKE_VERSION: '3.28.3' - CXX_STANDARD: '17' - CMAKE_TOOLCHAIN_FILE: '/Users/runner/conan/build/Debug/generators/conan_toolchain.cmake' - BUILD_TYPE: 'Debug' - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Install Conan and tools - run: | - brew install conan autoconf automake libtool coreutils - ./ci/setup_cmake_macos.sh - conan profile detect --force - - name: Install or build all dependencies with Conan - run: conan install install/conan/conanfile_stable.txt --build=missing -of /Users/runner/conan -s build_type=${BUILD_TYPE} -s compiler.cppstd=${CXX_STANDARD} - - name: Run Tests (static libs) - env: - BUILD_SHARED_LIBS: 'OFF' - run: ./ci/do_ci.sh cmake.install.test - - macos_14_brew_packages: - name: macOS 14 brew latest versions cxx17 (static libs) - runs-on: macos-14 - env: - INSTALL_TEST_DIR: '/Users/runner/install_test' - # Set to the latest version of cmake 3.x - CMAKE_VERSION: '3.31.6' - CXX_STANDARD: '17' - BUILD_TYPE: 'Debug' - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Install Dependencies with Homebrew - run: | - ./ci/setup_cmake_macos.sh - brew install coreutils - brew install googletest - brew install google-benchmark - brew install zlib - brew install abseil - brew install protobuf - brew install grpc - brew install nlohmann-json - brew install prometheus-cpp - - name: Run Tests (static libs) - env: - BUILD_SHARED_LIBS: 'OFF' - run: ./ci/do_ci.sh cmake.install.test \ No newline at end of file diff --git a/ext/opentelemetry-cpp-1.21.0/.github/workflows/codeql-analysis.yml b/ext/opentelemetry-cpp-1.21.0/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 9d2fe02d7..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: [main] - pull_request: - # The branches below must be a subset of the branches above - branches: [main] - -permissions: - contents: read - -jobs: - CodeQL-Build: - permissions: - actions: read # for github/codeql-action/init to get workflow details - contents: read # for actions/checkout to fetch code - security-events: write # for github/codeql-action/autobuild to send a status report - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - name: Remove Third_party Modules from Code Scan - run: | - rm -rf third_party - - name: Setup - env: - CC: /usr/bin/gcc-12 - CXX: /usr/bin/g++-12 - GOOGLETEST_VERSION: 1.12.1 - run: | - sudo -E ./ci/setup_googletest.sh - sudo -E ./ci/setup_ci_environment.sh - - name: Initialize CodeQL - uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 - with: - languages: cpp - - name: Autobuild - uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 diff --git a/ext/opentelemetry-cpp-1.21.0/.github/workflows/cppcheck.yml b/ext/opentelemetry-cpp-1.21.0/.github/workflows/cppcheck.yml deleted file mode 100644 index 53057354b..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/workflows/cppcheck.yml +++ /dev/null @@ -1,77 +0,0 @@ - -name: cppcheck - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -permissions: - contents: read - -jobs: - cppcheck: - runs-on: ubuntu-24.04 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - - name: Set up dependencies - run: | - sudo apt update -y - sudo apt install -y cppcheck - - - name: Run cppcheck - run: | - cppcheck --version | tee cppcheck.log - cppcheck \ - --force \ - --enable=warning,performance,portability \ - --inline-suppr \ - --suppress=unknownMacro:exporters/etw/include/opentelemetry/exporters/etw/TraceLoggingDynamic.h \ - --language=c++ \ - --std=c++14 \ - -I api/include \ - -I exporters/elasticsearch/include \ - -I exporters/etw/include \ - -I exporters/memory/include \ - -I exporters/ostream/include \ - -I exporters/otlp/include \ - -I exporters/prometheus/include \ - -I exporters/zipkin/include \ - -I ext/include \ - -I opentracing-shim/include \ - -I sdk/include \ - -i build \ - -i test \ - -i third_party \ - -j $(nproc) \ - . 2>&1 | tee --append cppcheck.log - - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - if: success() || failure() - with: - name: Logs (cppcheck) - path: ./cppcheck.log - - - name: Count warnings - run: | - set +e - readonly WARNING_COUNT=`grep -c -E "\[.+\]" cppcheck.log` - echo "cppcheck reported ${WARNING_COUNT} warning(s)" - # Acceptable limit, to decrease over time down to 0 - readonly WARNING_LIMIT=10 - # FAIL the build if WARNING_COUNT > WARNING_LIMIT - if [ $WARNING_COUNT -gt $WARNING_LIMIT ] ; then - exit 1 - # WARN in annotations if WARNING_COUNT > 0 - elif [ $WARNING_COUNT -gt 0 ] ; then - echo "::warning::cppcheck reported ${WARNING_COUNT} warning(s)" - fi diff --git a/ext/opentelemetry-cpp-1.21.0/.github/workflows/dependencies_image.yml b/ext/opentelemetry-cpp-1.21.0/.github/workflows/dependencies_image.yml deleted file mode 100644 index 3163dd8ca..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/workflows/dependencies_image.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: 'OpenTelemetry-cpp dependencies image' -on: - schedule: - - cron: "0 3 * * 6" - -permissions: - contents: read - -jobs: - docker_image: - name: Docker Image - runs-on: ubuntu-latest - timeout-minutes: 300 - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Set up QEMU - uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 - - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 - - - name: Build Image - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - builder: ${{ steps.buildx.outputs.name }} - context: ci/ - file: ./docker/Dockerfile - build-args: BASE_IMAGE=ubuntu:latest - platforms: linux/amd64 - # platforms: linux/amd64,linux/arm64 - push: false - tags: otel-cpp-deps - load: true - - - name: Save Image - run: | - docker images - docker save -o /opt/otel-cpp-deps-debian.tar otel-cpp-deps - - - name: Upload Image - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: otel-cpp-deps - path: /opt/otel-cpp-deps-debian.tar - retention-days: 14 diff --git a/ext/opentelemetry-cpp-1.21.0/.github/workflows/fossa.yml b/ext/opentelemetry-cpp-1.21.0/.github/workflows/fossa.yml deleted file mode 100644 index 8b90aa167..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/workflows/fossa.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: FOSSA scanning - -on: - push: - branches: - - main - -permissions: - contents: read - -jobs: - fossa: - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - uses: fossas/fossa-action@3ebcea1862c6ffbd5cf1b4d0bd6b3fe7bd6f2cac # v1.7.0 - with: - api-key: ${{secrets.FOSSA_API_KEY}} - team: OpenTelemetry diff --git a/ext/opentelemetry-cpp-1.21.0/.github/workflows/iwyu.yml b/ext/opentelemetry-cpp-1.21.0/.github/workflows/iwyu.yml deleted file mode 100644 index 42881ec6b..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/workflows/iwyu.yml +++ /dev/null @@ -1,92 +0,0 @@ - -name: include-what-you-use - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -permissions: - contents: read - -jobs: - iwyu: - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - submodules: 'recursive' - - - name: setup dependencies - run: | - sudo apt update -y - sudo apt install -y --no-install-recommends --no-install-suggests \ - build-essential \ - iwyu \ - ninja-build \ - libssl-dev \ - libcurl4-openssl-dev \ - libprotobuf-dev \ - protobuf-compiler \ - libgmock-dev \ - libgtest-dev \ - libbenchmark-dev - sudo ./ci/setup_cmake.sh - - - - name: setup grpc - run: | - sudo ./ci/setup_grpc.sh - - - name: Prepare CMake - run: | - TOPDIR=`pwd` - mkdir build && cd build - CC="clang" CXX="clang++" cmake \ - -DCMAKE_CXX_STANDARD=14 \ - -DWITH_STL=CXX14 \ - -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE="include-what-you-use;-w;-Xiwyu;--mapping_file=${TOPDIR}/.iwyu.imp;" \ - -DBUILD_TESTING=ON \ - -DBUILD_W3CTRACECONTEXT_TEST=ON \ - -DWITH_OTLP_GRPC=ON \ - -DWITH_OTLP_HTTP=ON \ - -DWITH_OTLP_FILE=ON \ - -DWITH_OPENTRACING=ON \ - -DWITH_OTLP_HTTP_COMPRESSION=ON \ - -DWITH_THREAD_INSTRUMENTATION=ON \ - -DWITH_ZIPKIN=ON \ - -DWITH_PROMETHEUS=ON \ - .. - - - name: iwyu_tool - run: | - cd build - make -k 2>&1 | tee -a iwyu.log - - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - if: success() || failure() - with: - name: Logs (include-what-you-use) - path: ./build/*.log - - - name: count warnings - run: | - set +e - cd build - readonly WARNING_COUNT=`grep -c "include-what-you-use reported diagnostics:" iwyu.log` - echo "include-what-you-use reported ${WARNING_COUNT} warning(s)" - # Acceptable limit, to decrease over time down to 0 - readonly WARNING_LIMIT=0 - # FAIL the build if WARNING_COUNT > WARNING_LIMIT - if [ $WARNING_COUNT -gt $WARNING_LIMIT ] ; then - exit 1 - # WARN in annotations if WARNING_COUNT > 0 - elif [ $WARNING_COUNT -gt 0 ] ; then - echo "::warning::include-what-you-use reported ${WARNING_COUNT} warning(s)" - fi diff --git a/ext/opentelemetry-cpp-1.21.0/.github/workflows/ossf-scorecard.yml b/ext/opentelemetry-cpp-1.21.0/.github/workflows/ossf-scorecard.yml deleted file mode 100644 index 4ecbe8bf8..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/workflows/ossf-scorecard.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: OSSF Scorecard - -on: - push: - branches: - - main - schedule: - - cron: "56 23 * * 6" # once a week - workflow_dispatch: - -permissions: read-all - -jobs: - analysis: - runs-on: ubuntu-latest - permissions: - # Needed for Code scanning upload - security-events: write - # Needed for GitHub OIDC token if publish_results is true - id-token: write - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - - uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 - with: - results_file: results.sarif - results_format: sarif - publish_results: true - - # Upload the results as artifacts (optional). Commenting out will disable - # uploads of run results in SARIF format to the repository Actions tab. - # https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts - - name: "Upload artifact" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: SARIF file - path: results.sarif - retention-days: 5 - - # Upload the results to GitHub's code scanning dashboard (optional). - # Commenting out will disable upload of results to your repo's Code Scanning dashboard - - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 - with: - sarif_file: results.sarif diff --git a/ext/opentelemetry-cpp-1.21.0/.github/workflows/project_management_comment.yml b/ext/opentelemetry-cpp-1.21.0/.github/workflows/project_management_comment.yml deleted file mode 100644 index 6e64cf0aa..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/workflows/project_management_comment.yml +++ /dev/null @@ -1,28 +0,0 @@ - -name: Add comment -on: - issues: - types: - - labeled -permissions: - contents: read - -jobs: - add-comment: - if: github.event.label.name == 'help wanted' - runs-on: ubuntu-latest - permissions: - issues: write - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - name: Add comment - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 - with: - issue-number: ${{ github.event.issue.number }} - body: | - This issue is available for anyone to work on. **Make sure to reference this issue in your pull request.** - :sparkles: Thank you for your contribution! :sparkles: diff --git a/ext/opentelemetry-cpp-1.21.0/.github/workflows/project_management_issue_open.yml b/ext/opentelemetry-cpp-1.21.0/.github/workflows/project_management_issue_open.yml deleted file mode 100644 index 14750d1a6..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/workflows/project_management_issue_open.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: OpenTelemetry-cpp project -on: - issues: - types: - - reopened - - opened -permissions: - contents: read - -jobs: - label_issues: - runs-on: ubuntu-latest - permissions: - issues: write - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - with: - script: | - github.rest.issues.addLabels({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - labels: ["needs-triage"] - }) diff --git a/ext/opentelemetry-cpp-1.21.0/.github/workflows/stale.yml b/ext/opentelemetry-cpp-1.21.0/.github/workflows/stale.yml deleted file mode 100644 index 931403638..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.github/workflows/stale.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: "Mark stale issues" -on: - schedule: - - cron: "30 1 * * *" - -permissions: - contents: read - -jobs: - stale: - permissions: - issues: write # for actions/stale to close stale issues - pull-requests: write # for actions/stale to close stale PRs - runs-on: ubuntu-latest - steps: - - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 - with: - stale-issue-message: "This issue was marked as stale due to lack of activity." - days-before-issue-stale: 60 - days-before-close: -1 - exempt-issue-labels: "do-not-stale" diff --git a/ext/opentelemetry-cpp-1.21.0/.gitignore b/ext/opentelemetry-cpp-1.21.0/.gitignore deleted file mode 100644 index 580df5ac3..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.gitignore +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# Ref. https://github.com/github/gitignore/blob/master/C%2B%2B.gitignore -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll -*.pdb - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -# Bazel files -MODULE.bazel.lock -/bazel-* - -# Mac -.DS_Store - -# Output directories -/out -/out.* -# Indicator that the tools were deployed -.buildtools - -# Temporary Bazel directories -/bazel-* -/plugin -/build - -tags -.cache/clangd/* - -# Temporary dir used when generating semconv -buildscripts/semantic-convention/tmp-semconv/ - -# Generated cert keys in functional tests -functional/cert/ca.csr -functional/cert/ca.pem -functional/cert/ca-key.pem -functional/cert/client_cert.csr -functional/cert/client_cert.pem -functional/cert/client_cert-key.pem -functional/cert/server_cert.csr -functional/cert/server_cert.pem -functional/cert/server_cert-key.pem -functional/cert/ca_b.csr -functional/cert/ca_b.pem -functional/cert/ca_b-key.pem -functional/cert/client_cert_b.csr -functional/cert/client_cert_b.pem -functional/cert/client_cert_b-key.pem -functional/cert/server_cert_b.csr -functional/cert/server_cert_b.pem -functional/cert/server_cert_b-key.pem -functional/cert/unreadable.pem - -localinstall \ No newline at end of file diff --git a/ext/opentelemetry-cpp-1.21.0/.gitmodules b/ext/opentelemetry-cpp-1.21.0/.gitmodules deleted file mode 100644 index 88a78e5f9..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.gitmodules +++ /dev/null @@ -1,39 +0,0 @@ -[submodule "third_party/prometheus-cpp"] -path = third_party/prometheus-cpp -url = https://github.com/jupp0r/prometheus-cpp -branch = master - -[submodule "tools/vcpkg"] -path = tools/vcpkg -url = https://github.com/Microsoft/vcpkg -branch = master - -[submodule "third_party/ms-gsl"] -path = third_party/ms-gsl -url = https://github.com/microsoft/GSL -branch = main - -[submodule "third_party/googletest"] -path = third_party/googletest -url = https://github.com/google/googletest -branch = main - -[submodule "third_party/benchmark"] -path = third_party/benchmark -url = https://github.com/google/benchmark -branch = main - -[submodule "third_party/opentelemetry-proto"] -path = third_party/opentelemetry-proto -url = https://github.com/open-telemetry/opentelemetry-proto -branch = main - -[submodule "third_party/nlohmann-json"] -path = third_party/nlohmann-json -url = https://github.com/nlohmann/json -branch = master - -[submodule "third_party/opentracing-cpp"] -path = third_party/opentracing-cpp -url = https://github.com/opentracing/opentracing-cpp.git -branch = master diff --git a/ext/opentelemetry-cpp-1.21.0/.iwyu.imp b/ext/opentelemetry-cpp-1.21.0/.iwyu.imp deleted file mode 100644 index 123e72f32..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.iwyu.imp +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# include-what-you-use mapping file - -[ - # Work around for C++ STL - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - - # Local opentelemetry-cpp style - - # We prefer to include for simplicity - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - - # We prefer to include for simplicity - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - - # We prefer to include for simplicity - { "include": ["", "private", "", "public"] }, -] - diff --git a/ext/opentelemetry-cpp-1.21.0/.markdownlint.json b/ext/opentelemetry-cpp-1.21.0/.markdownlint.json deleted file mode 100644 index 48c2ae2a3..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.markdownlint.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "default": true, - "MD013": - { - "code_blocks": false, - "tables": false - } -} diff --git a/ext/opentelemetry-cpp-1.21.0/.markdownlintignore b/ext/opentelemetry-cpp-1.21.0/.markdownlintignore deleted file mode 100644 index f0cec48db..000000000 --- a/ext/opentelemetry-cpp-1.21.0/.markdownlintignore +++ /dev/null @@ -1,3 +0,0 @@ -third_party/** -tools/** -examples/otlp/README.md diff --git a/ext/opentelemetry-cpp-1.21.0/CHANGELOG.md b/ext/opentelemetry-cpp-1.21.0/CHANGELOG.md deleted file mode 100644 index 30c94679e..000000000 --- a/ext/opentelemetry-cpp-1.21.0/CHANGELOG.md +++ /dev/null @@ -1,2816 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## Guideline to update the version - -Increment the: - -* MAJOR version when you make incompatible API/ABI changes, -* MINOR version when you add functionality in a backwards compatible manner, and -* PATCH version when you make backwards compatible bug fixes. - -## [Unreleased] - -## [1.21 2025-05-28] - -* [BUILD] Remove WITH_ABSEIL - [#3318](https://github.com/open-telemetry/opentelemetry-cpp/pull/3318) - -* [INSTALL] Add CMake components to the opentelemetry-cpp package - [#3320](https://github.com/open-telemetry/opentelemetry-cpp/pull/3220) - -* [CI] Harden GitHub Actions - [#3338](https://github.com/open-telemetry/opentelemetry-cpp/pull/3338) - -* [StepSecurity] Harden GibHub Actions, part 2 - [#3340](https://github.com/open-telemetry/opentelemetry-cpp/pull/3340) - -* Bump github/codeql-action from 3.28.12 to 3.28.13 - [#3341](https://github.com/open-telemetry/opentelemetry-cpp/pull/3341) - -* [DEVCONTAINER] expose cmake version setting as docker arg and environment variable - [#3347](https://github.com/open-telemetry/opentelemetry-cpp/pull/3347) - -* [CI] disable bzip2 in conan builds - [#3352](https://github.com/open-telemetry/opentelemetry-cpp/pull/3352) - -* [SEMANTIC CONVENTIONS] Upgrade semantic conventions to 1.32.0 - [#3351](https://github.com/open-telemetry/opentelemetry-cpp/pull/3351) - -* Bump github/codeql-action from 3.28.13 to 3.28.15 - [#3353](https://github.com/open-telemetry/opentelemetry-cpp/pull/3353) - -* [CMAKE] bump cmake minimum required version to 3.14 - [#3349](https://github.com/open-telemetry/opentelemetry-cpp/pull/3349) - -* Bump codecov/codecov-action from 5.4.0 to 5.4.2 - [#3362](https://github.com/open-telemetry/opentelemetry-cpp/pull/3362) - -* [DOC] Fix documentation tags in logger API - [#3371](https://github.com/open-telemetry/opentelemetry-cpp/pull/3371) - -* [CI] fix artifacts download/upload - [#3369](https://github.com/open-telemetry/opentelemetry-cpp/pull/3369) - -* [API] Add Enabled method to Tracer - [#3357](https://github.com/open-telemetry/opentelemetry-cpp/pull/3357) - -* [BUILD] Fixes warnings of ciso646 in C++17 - [#3360](https://github.com/open-telemetry/opentelemetry-cpp/pull/3360) - -* Bump github/codeql-action from 3.28.15 to 3.28.16 - [#3377](https://github.com/open-telemetry/opentelemetry-cpp/pull/3377) - -* Bump step-security/harden-runner from 2.11.1 to 2.12.0 - [#3373](https://github.com/open-telemetry/opentelemetry-cpp/pull/3373) - -* Bump docker/build-push-action from 6.15.0 to 6.16.0 - [#3382](https://github.com/open-telemetry/opentelemetry-cpp/pull/3382) - -* Bump actions/download-artifact from 4.2.1 to 4.3.0 - [#3381](https://github.com/open-telemetry/opentelemetry-cpp/pull/3381) - -* [CI] Harden Github actions - pinned-dependencies (part -1) - [#3380](https://github.com/open-telemetry/opentelemetry-cpp/pull/3380) - -* [StepSecurity] ci: Harden GitHub Actions - [#3378](https://github.com/open-telemetry/opentelemetry-cpp/pull/3378) - -* [SDK] Base2 exponential histogram aggregation - [#3346](https://github.com/open-telemetry/opentelemetry-cpp/pull/3346) - -* [StepSecurity] ci: Harden GitHub Actions - [#3379](https://github.com/open-telemetry/opentelemetry-cpp/pull/3379) - -* [BUILD] Fixes glibc++ 5 checking - [#3355](https://github.com/open-telemetry/opentelemetry-cpp/pull/3355) - -* [TEST] Add stress test for histogram metric for multiple threads validation - [#3388](https://github.com/open-telemetry/opentelemetry-cpp/pull/3388) - -* Bump github/codeql-action from 3.28.16 to 3.28.17 - [#3389](https://github.com/open-telemetry/opentelemetry-cpp/pull/3389) - -* [SDK] Optimize PeriodicExportingMetricReader Thread Usage - [#3383](https://github.com/open-telemetry/opentelemetry-cpp/pull/3383) - -* [Metrics SDK] Use nostd::function_ref in AttributesHashMap - [#3393](https://github.com/open-telemetry/opentelemetry-cpp/pull/3393) - -* [SDK] support aggregation of identical instruments - [#3358](https://github.com/open-telemetry/opentelemetry-cpp/pull/3358) - -* [BUILD] Fixes unused var - [#3397](https://github.com/open-telemetry/opentelemetry-cpp/pull/3397) - -* [INSTALL] Unify cmake install functions and dynamically set component dependencies - [#3368](https://github.com/open-telemetry/opentelemetry-cpp/pull/3368) - -* [BUILD] Upgrade nlohmann_json to 3.12.0 - [#3406](https://github.com/open-telemetry/opentelemetry-cpp/pull/3406) - -* [BUILD] Upgrade opentelemetry-proto to 1.6.0 - [#3407](https://github.com/open-telemetry/opentelemetry-cpp/pull/3407) - -* [CMAKE] add generated protobuf headers to the opentelemetry_proto target - [#3400](https://github.com/open-telemetry/opentelemetry-cpp/pull/3400) - -* [MERGE] Fix accidental rollback of nlohmann-json submodule - [#3415](https://github.com/open-telemetry/opentelemetry-cpp/pull/3415) - -* Bump fossas/fossa-action from 1.6.0 to 1.7.0 - [#3414](https://github.com/open-telemetry/opentelemetry-cpp/pull/3414) - -* Bump docker/build-push-action from 6.16.0 to 6.17.0 - [#3420](https://github.com/open-telemetry/opentelemetry-cpp/pull/3420) - -* Bump codecov/codecov-action from 5.4.2 to 5.4.3 - [#3419](https://github.com/open-telemetry/opentelemetry-cpp/pull/3419) - -* [SEMANTIC CONVENTIONS] Upgrade semantic conventions to 1.33 - [#3416](https://github.com/open-telemetry/opentelemetry-cpp/pull/3416) - -* [DOCS] update the INSTALL guide on cmake components - [#3422](https://github.com/open-telemetry/opentelemetry-cpp/pull/3422) - -* Bump github/codeql-action from 3.28.17 to 3.28.18 - [#3423](https://github.com/open-telemetry/opentelemetry-cpp/pull/3423) - -* [CMAKE] update cmake files in examples directory - [#3421](https://github.com/open-telemetry/opentelemetry-cpp/pull/3421) - -* [SDK] Fix Base2ExponentialHistogramAggregation Merge with empty buckets - [#3425](https://github.com/open-telemetry/opentelemetry-cpp/pull/3425) - -* [SDK] Fix MetricProducer interface - [#3413](https://github.com/open-telemetry/opentelemetry-cpp/pull/3413) - -* [CMAKE] remove global include_directories usage and rely on target properties - [#3426](https://github.com/open-telemetry/opentelemetry-cpp/pull/3426) - -* [BUILD] remove unused WITH_CURL build flag - [#3429](https://github.com/open-telemetry/opentelemetry-cpp/pull/3429) - -* [SEMANTIC CONVENTIONS] Upgrade to semantic conventions 1.34.0 - [#3428](https://github.com/open-telemetry/opentelemetry-cpp/pull/3428) - -* [EXPORTER] ostream log exporter, fix memory ownership issues - [#3417](https://github.com/open-telemetry/opentelemetry-cpp/pull/3417) - -* [TEST] add all components to the cmake fetch content test - [#3433](https://github.com/open-telemetry/opentelemetry-cpp/pull/3433) - -* [BUILD] Error out when building DLL without MSVC - [#3438](https://github.com/open-telemetry/opentelemetry-cpp/pull/3438) - -* [BUILD] Add missing CMake keyword for target_link_libraries - [#3442](https://github.com/open-telemetry/opentelemetry-cpp/pull/3442) - -* [CMAKE] Remove third-party version mismatch warning - [#3432](https://github.com/open-telemetry/opentelemetry-cpp/pull/3432) - -* Bump docker/build-push-action from 6.17.0 to 6.18.0 - [#3446](https://github.com/open-telemetry/opentelemetry-cpp/pull/3446) - -* [SEMANTIC CONVENTIONS] Fix comment style to preserve markup. - [#3444](https://github.com/open-telemetry/opentelemetry-cpp/pull/3444) - -* [EXPORTER] support unix sockets in grpc client - [#3410](https://github.com/open-telemetry/opentelemetry-cpp/pull/3410) - -* [BUILD] Propagate INTERFACE_COMPILE_DEFINITIONS from API through common_foo_library - [#3440](https://github.com/open-telemetry/opentelemetry-cpp/pull/3440) - -New Features: - -* [SDK] Base2 exponential histogram aggregation - [#3346](https://github.com/open-telemetry/opentelemetry-cpp/pull/3346) - - * Add base2 exponential histogram aggregation. Includes a new aggregation type, - ostream exporter, and otlp/grpc exporter. Updated histogram aggregation and - benchmark tests. - -Important changes: - -* [EXPORTER] ostream log exporter, fixed memory ownership issues - [#3417](https://github.com/open-telemetry/opentelemetry-cpp/pull/3417) - - * In the SDK, the following classes implementation has changed: - - * opentelemetry::sdk::logs::ReadableLogRecord - * opentelemetry::sdk::logs::ReadWriteLogRecord - - * An application implementing a custom log record exporter, - that reuses these classes from the opentelemetry-cpp SDK, - will need code adjustments, in particular for methods: - - * GetBody() - * GetAttributes() - - * Applications not using these SDK classes directly are not affected. - -* [BUILD] Remove WITH_ABSEIL - [#3318](https://github.com/open-telemetry/opentelemetry-cpp/pull/3318) - - * The build option `WITH_ABSEIL` is no longer used, and opentelemetry-cpp - will no longer use any release of abseil provided externally, - for its own use. - - * Instead, opentelemetry-cpp will only use an internal abseil version. - - * This change resolves long standing binary integrity issues, - that occurred in the past when mixing several versions of abseil - in the build. - -## [1.20 2025-04-01] - -* [BUILD] Update opentelemetry-proto version - [#3254](https://github.com/open-telemetry/opentelemetry-cpp/pull/3254) - -* [BUILD] Build break with CURL 7.29.0 - [#3255](https://github.com/open-telemetry/opentelemetry-cpp/pull/3255) - -* [SEMANTIC CONVENTIONS] Upgrade to semantic conventions 1.30.0 - [#3258](https://github.com/open-telemetry/opentelemetry-cpp/pull/3258) - -* [SDK] Add tracer scope configurator - [#3137](https://github.com/open-telemetry/opentelemetry-cpp/pull/3137) - -* [DOC] Add document and example for sharing gRPC Client - [#3260](https://github.com/open-telemetry/opentelemetry-cpp/pull/3260) - -* [SDK] Fix BatchLogRecordProcessor to instrument shutdown - [#3262](https://github.com/open-telemetry/opentelemetry-cpp/pull/3262) - -* [SDK] Support OTEL_SDK_DISABLED environment variable - [#3245](https://github.com/open-telemetry/opentelemetry-cpp/pull/3245) - -* [CI] OTLP in Windows builds - [#3263](https://github.com/open-telemetry/opentelemetry-cpp/pull/3263) - -* [BUILD] Fixes compatibility of type_traits - [#3274](https://github.com/open-telemetry/opentelemetry-cpp/pull/3274) - -* [BUILD] Fix compilation with Regex being disabled - [#3276](https://github.com/open-telemetry/opentelemetry-cpp/pull/3276) - -* [EXPORTER] Support exporting event_name using OTLP Exporter - [#3277](https://github.com/open-telemetry/opentelemetry-cpp/pull/3277) - -* [CI] Add FOSSA scanning workflow - [#3279](https://github.com/open-telemetry/opentelemetry-cpp/pull/3279) - -* [BUILD] Adding typecast without whom c++latest build fails - [#3281](https://github.com/open-telemetry/opentelemetry-cpp/pull/3281) - -* [ADMIN] Add FOSSA badges - [#3280](https://github.com/open-telemetry/opentelemetry-cpp/pull/3280) - -* [BUILD] Fix compiling problems with abiv2 and MSVC - [#3284](https://github.com/open-telemetry/opentelemetry-cpp/pull/3284) - -* [BUILD] Enable old behavior of CMP0092 - [#3269](https://github.com/open-telemetry/opentelemetry-cpp/pull/3269) - -* [SDK] Add meter scope configurator - [#3268](https://github.com/open-telemetry/opentelemetry-cpp/pull/3268) - -* [DEVCONTAINER] Support customization and run as non-root user - [#3270](https://github.com/open-telemetry/opentelemetry-cpp/pull/3270) - -* [ETW] Add configuration to export 64-bit integer as timestamp - [#3286](https://github.com/open-telemetry/opentelemetry-cpp/pull/3286) - -* [API] Deprecate event logger - [#3285](https://github.com/open-telemetry/opentelemetry-cpp/pull/3285) - -* [BUILD] Add link directory to support curl 8.12 - [#3272](https://github.com/open-telemetry/opentelemetry-cpp/pull/3272) - -* [API] Change the param-pack unpacking order to start from left to right - [#3296](https://github.com/open-telemetry/opentelemetry-cpp/pull/3296) - -* [SDK] Implement spec: MetricFilter - [#3235](https://github.com/open-telemetry/opentelemetry-cpp/pull/3235) - -* [SEMANTIC CONVENTIONS] Upgrade semantic conventions to 1.31.0 - [#3297](https://github.com/open-telemetry/opentelemetry-cpp/pull/3297) - -* [SDK] Add logger scope configurator - [#3282](https://github.com/open-telemetry/opentelemetry-cpp/pull/3282) - -* [EXAMPLE] fix buffer overrun in the gRPC sample project - [#3304](https://github.com/open-telemetry/opentelemetry-cpp/pull/3304) - -* [CI] Bump fossas/fossa-action from 1.5.0 to 1.6.0 - [#3305](https://github.com/open-telemetry/opentelemetry-cpp/pull/3305) - -* [TEST] fix segfault in singleton test with cmake on macos-latest - [#3316](https://github.com/open-telemetry/opentelemetry-cpp/pull/3316) - -* [TEST] fix test failure with elasticsearch exporter on cxx20 - [#3308](https://github.com/open-telemetry/opentelemetry-cpp/pull/3308) - -* [TEST] otlp grpc exporter retry test fix - [#3311](https://github.com/open-telemetry/opentelemetry-cpp/pull/3311) - -* [SDK] Use OPENTELEMETRY_EXPORT and static local variables - [#3314](https://github.com/open-telemetry/opentelemetry-cpp/pull/3314) - -* [BUILD] Fix elasticsearch exporter json compatibility - [#3313](https://github.com/open-telemetry/opentelemetry-cpp/pull/3313) - -* [BUILD] Fix missing exported definition for OTLP file exporter and forceflush - [#3319](https://github.com/open-telemetry/opentelemetry-cpp/pull/3319) - -* [BUILD] Remove gRPC header including in OtlpGrpcClientFactory - [#3321](https://github.com/open-telemetry/opentelemetry-cpp/pull/3321) - -* [ADMIN] Add Pranav Sharma in cpp-approvers - [#3323](https://github.com/open-telemetry/opentelemetry-cpp/pull/3323) - -* [DEVCONTAINER] fix grpc install - [#3325](https://github.com/open-telemetry/opentelemetry-cpp/pull/3325) - -* [ADMIN] Add dbarker to approvers - [#3331](https://github.com/open-telemetry/opentelemetry-cpp/pull/3331) - -* [CI] Upgrade CI to ubuntu 22.04 - [#3330](https://github.com/open-telemetry/opentelemetry-cpp/pull/3330) - -* [CI] Add ossf-scorecard scanning workflow - [#3332](https://github.com/open-telemetry/opentelemetry-cpp/pull/3332) - -* [CI] pin cmake in ci and devcontainer - [#3336](https://github.com/open-telemetry/opentelemetry-cpp/pull/3336) - -* [METRICS SDK] Fix hash collision in MetricAttributes - [#3322](https://github.com/open-telemetry/opentelemetry-cpp/pull/3322) - -Important changes: - -* [SDK] Support OTEL_SDK_DISABLED environment variable - [#3245](https://github.com/open-telemetry/opentelemetry-cpp/pull/3245) - - * The SDK now exposes the following new methods: - - * opentelemetry::sdk::trace::Provider::SetTracerProvider() - * opentelemetry::sdk::metrics::Provider::SetMeterProvider() - * opentelemetry::sdk::logs::Provider::SetLoggerProvider() - - * These methods do support the `OTEL_SDK_DISABLED` environment variable, - unlike the corresponding existing API Provider classes. - - * Applications are encouraged to migrate from the API to the SDK - `Provider` classes, to benefit from this feature. - - * All the example code has been updated to reflect the new usage. - -## [1.19 2025-01-22] - -* [PROMETHEUS_EXPORTER] Fix default for emitting otel_scope attributes - [#3171](https://github.com/open-telemetry/opentelemetry-cpp/pull/3171) - -* [Code health] Include what you use cleanup, part 5 - [#3140](https://github.com/open-telemetry/opentelemetry-cpp/pull/3140) - -* [BUILD] Upgrade cmake - [#3167](https://github.com/open-telemetry/opentelemetry-cpp/pull/3167) - -* [SHIM] Fix string_view mappings between OT and OTel - [#3181](https://github.com/open-telemetry/opentelemetry-cpp/pull/3181) - -* [EXPORTER] Refactor ElasticSearchRecordable - [#3164](https://github.com/open-telemetry/opentelemetry-cpp/pull/3164) - -* [SEMANTIC CONVENTIONS] Upgrade to semantic conventions 1.29.0 - [#3182](https://github.com/open-telemetry/opentelemetry-cpp/pull/3182) - -* [BUILD] Fix cross-compilation with protoc - [#3186](https://github.com/open-telemetry/opentelemetry-cpp/pull/3186) - -* [Code health] Perform cppcheck cleanup - [#3150](https://github.com/open-telemetry/opentelemetry-cpp/pull/3150) - -* [EXPORTER] add instrumentation scope attributes - to otlp proto messages for traces and metrics - [#3185](https://github.com/open-telemetry/opentelemetry-cpp/pull/3185) - -* [SDK] Tracer provider shutdown blocks in-definitively - [#3191](https://github.com/open-telemetry/opentelemetry-cpp/pull/3191) - -* [SEMANTIC CONVENTIONS] Upgrade to weaver 0.11.0 - [#3194](https://github.com/open-telemetry/opentelemetry-cpp/pull/3194) - -* [DOC] Update existing maintaining dependencies doc - [#3195](https://github.com/open-telemetry/opentelemetry-cpp/pull/3195) - -* [TEST] Change is_called_ and got_response_ to use atomic - [#3204](https://github.com/open-telemetry/opentelemetry-cpp/pull/3204) - -* [SEMANTIC CONVENTIONS] update links to openmetrics to reference the v1.0.0 release - [#3205](https://github.com/open-telemetry/opentelemetry-cpp/pull/3205) - -* [CI] Fix CI on ubuntu-latest - [#3207](https://github.com/open-telemetry/opentelemetry-cpp/pull/3207) - -* [BUILD] Build break using protoc 3.14 - [#3211](https://github.com/open-telemetry/opentelemetry-cpp/pull/3211) - -* [TEST] Build the singleton test on windows - [#3183](https://github.com/open-telemetry/opentelemetry-cpp/pull/3183) - -* [BUILD] Add cxx feature detections - [#3203](https://github.com/open-telemetry/opentelemetry-cpp/pull/3203) - -* [SDK] Do not frequently create and destroy http client threads - [#3198](https://github.com/open-telemetry/opentelemetry-cpp/pull/3198) - -* [EXPORTER] Optimize OTLP HTTP compression - [#3178](https://github.com/open-telemetry/opentelemetry-cpp/pull/3178) - -* [SDK] Fix include instrumentation scope attributes in equal method - [#3214](https://github.com/open-telemetry/opentelemetry-cpp/pull/3214) - -* Upgrade to opentelemetry-proto 1.5.0 - [#3210](https://github.com/open-telemetry/opentelemetry-cpp/pull/3210) - -* [TEST] Added support for SELINUX in functional tests - [#3212](https://github.com/open-telemetry/opentelemetry-cpp/pull/3212) - -* [EDITORIAL] fix changelog entry for PR 3185 - [#3217](https://github.com/open-telemetry/opentelemetry-cpp/pull/3217) - -* [TEST] Functional tests for OTLP/gRPC with mutual TLS - [#3227](https://github.com/open-telemetry/opentelemetry-cpp/pull/3227) - -* [SEMCONV] Metrics are incorrectly prefixed with 'metric' - [#3228](https://github.com/open-telemetry/opentelemetry-cpp/pull/3228) - -* [BUILD] Add OTLP/file exporter for dll and examples - [#3231](https://github.com/open-telemetry/opentelemetry-cpp/pull/3231) - -* [Code Health] Include what you use, part 6 - [#3216](https://github.com/open-telemetry/opentelemetry-cpp/pull/3216) - -* [CI] Spurious test failures - [#3233](https://github.com/open-telemetry/opentelemetry-cpp/pull/3233) - -* [BUILD] Fix error ‘uint8_t’ does not name a type with gcc-15 - [#3240](https://github.com/open-telemetry/opentelemetry-cpp/pull/3240) - -* [EXPORTER] fix throw in OtlpGrpcMetricExporter with shared grpc client - [#3243](https://github.com/open-telemetry/opentelemetry-cpp/pull/3243) - -* [SDK] Better control of threads executed by opentelemetry-cpp - [#3175](https://github.com/open-telemetry/opentelemetry-cpp/pull/3175) - -* [Code Health] Include what you use, part 7 - [#3238](https://github.com/open-telemetry/opentelemetry-cpp/pull/3238) - -* [SDK] Fix lifetime of GlobalLogHandler - [#3221](https://github.com/open-telemetry/opentelemetry-cpp/pull/3221) - -* [MAINTAINER] Add devcontainer - [#3123](https://github.com/open-telemetry/opentelemetry-cpp/pull/3123) - -* [SDK] enable deriving from ResourceDetector to create a Resource - [#3247](https://github.com/open-telemetry/opentelemetry-cpp/pull/3247) - -* [EXPORTER] Support handling retry-able errors for OTLP/HTTP - [#3223](https://github.com/open-telemetry/opentelemetry-cpp/pull/3223) - -* [CI] Add GRPC in maintainer CI - [#3248](https://github.com/open-telemetry/opentelemetry-cpp/pull/3248) - -* [EXPORTER] Support handling retry-able errors for OTLP/gRPC - [#3219](https://github.com/open-telemetry/opentelemetry-cpp/pull/3219) - -* [SDK] Optimize Metric Processing for Single Collector with Delta Temporality - [#3236](https://github.com/open-telemetry/opentelemetry-cpp/pull/3236) - -New features: - -* [SDK] Better control of threads executed by opentelemetry-cpp - [#3175](https://github.com/open-telemetry/opentelemetry-cpp/pull/3175) - - * This feature provides a way for applications, - when configuring the SDK and exporters, - to participate in the execution path - of internal opentelemetry-cpp threads. - - * The opentelemetry-cpp library provides the following: - - * a new ThreadInstrumentation interface, - * new runtime options structures, to optionally configure the SDK: - * BatchSpanProcessorRuntimeOptions - * PeriodicExportingMetricReaderRuntimeOptions - * BatchLogRecordProcessorRuntimeOptions - * new runtime options structures, - to optionally configure the OTLP HTTP exporters: - * OtlpHttpExporterRuntimeOptions - * OtlpHttpMetricExporterRuntimeOptions - * OtlpHttpLogRecordExporterRuntimeOptions - * new ThreadInstrumentation parameters, - to optionally configure the CURL HttpClient - * new runtime options structures, - to optionally configure the OTLP FILE exporters: - * OtlpFileExporterRuntimeOptions - * OtlpFileMetricExporterRuntimeOptions - * OtlpFileLogRecordExporterRuntimeOptions - * new runtime options structure, - to optionally configure the OTLP FILE client: - * OtlpFileClientRuntimeOptions - - * Using the optional runtime options structures, - an application can subclass the ThreadInstrumentation interface, - and be notified of specific events of interest during the execution - of an internal opentelemetry-cpp thread. - - * This allows an application to call, for example: - - * pthread_setaffinity_np(), for better performances, - * setns(), to control the network namespace used by HTTP CURL connections - * pthread_setname_np(), for better observability from the operating system - * many more specific apis, as needed - - * See the documentation for ThreadInstrumentation for details. - - * A new example program, example_otlp_instrumented_http, - shows how to use the feature, - and add application logic in the thread execution code path. - - * Note that this feature is experimental, - protected by a WITH_THREAD_INSTRUMENTATION_PREVIEW - flag in CMake. Various runtime options structures, - as well as the thread instrumentation interface, - may change without notice before this feature is declared stable. - -* [EXPORTER] Support handling retry-able errors for OTLP/HTTP - [#3223](https://github.com/open-telemetry/opentelemetry-cpp/pull/3223) - - * This feature is experimental, - protected by a WITH_OTLP_RETRY_PREVIEW - flag in CMake. - -* [EXPORTER] Support handling retry-able errors for OTLP/gRPC - [#3219](https://github.com/open-telemetry/opentelemetry-cpp/pull/3219) - - * This feature is experimental, - protected by a WITH_OTLP_RETRY_PREVIEW - flag in CMake. - -## [1.18 2024-11-25] - -* [EXPORTER] Fix crash in ElasticsearchLogRecordExporter - [#3082](https://github.com/open-telemetry/opentelemetry-cpp/pull/3082) - -* [BUILD] Avoid buggy warning with gcc <= 8 - [#3087](https://github.com/open-telemetry/opentelemetry-cpp/pull/3087) - -* [API] Jaeger Propagator should not be deprecated - [#3086](https://github.com/open-telemetry/opentelemetry-cpp/pull/3086) - -* Update bzlmod version - [#3093](https://github.com/open-telemetry/opentelemetry-cpp/pull/3093) - -* [BUILD] Remove std::make_unique - [#3098](https://github.com/open-telemetry/opentelemetry-cpp/pull/3098) - -* [BUILD] Fix compiling problems for gcc 4.8 - [#3100](https://github.com/open-telemetry/opentelemetry-cpp/pull/3100) - -* [TEST] Fix linking order and gmock linking - [#3106](https://github.com/open-telemetry/opentelemetry-cpp/pull/3106) - -* [EXPORTER] Add config options to prometheus exporter - [#3104](https://github.com/open-telemetry/opentelemetry-cpp/pull/3104) - -* [BUILD] Add a CMake option to disable shared libs - [#3095](https://github.com/open-telemetry/opentelemetry-cpp/pull/3095) - -* [EXPORTER] Remove out of date ETW exporter doc - [#3103](https://github.com/open-telemetry/opentelemetry-cpp/pull/3103) - -* [EXPORTER] Add logging for async gRPC errors - [#3108](https://github.com/open-telemetry/opentelemetry-cpp/pull/3108) - -* [BUILD] Remove aligned_storage from nostd - [#3112](https://github.com/open-telemetry/opentelemetry-cpp/pull/3112) - -* [EXPORTER] Elastic Search exporter follow ECS guidelines - [#3107](https://github.com/open-telemetry/opentelemetry-cpp/pull/3107) - -* [INSTALL] Resolve dependencies in opentelemetry-cpp-config.cmake - [#3094](https://github.com/open-telemetry/opentelemetry-cpp/pull/3094) - -* [API] Add synchronous gauge - [#3029](https://github.com/open-telemetry/opentelemetry-cpp/pull/3029) - -* [BUILD] allow building with -DWITH_OTLP_HTTP_COMPRESSION=OFF without zlib - [#3120](https://github.com/open-telemetry/opentelemetry-cpp/pull/3120) - -* [CI] Comment the arm64 CI - [#3125](https://github.com/open-telemetry/opentelemetry-cpp/pull/3125) - -* [API] Comply with W3C Trace Context - [#3115](https://github.com/open-telemetry/opentelemetry-cpp/pull/3115) - -* [EXPORTER] bump prometheus to v1.3.0 - [#3122](https://github.com/open-telemetry/opentelemetry-cpp/pull/3122) - -* [EXPORTER] Log SSL Connection Information - [#3113](https://github.com/open-telemetry/opentelemetry-cpp/pull/3113) - -* [BUILD] Improve how to handle yield() in ARM - [#3129](https://github.com/open-telemetry/opentelemetry-cpp/pull/3129) - -* [BUILD] Fix -Wmissing-template-arg-list-after-template-kw warning - [#3133](https://github.com/open-telemetry/opentelemetry-cpp/pull/3133) - -* [EXPORTER]: Elasticsearch exporter put log resource in root instead of under 'resources' - [#3131](https://github.com/open-telemetry/opentelemetry-cpp/pull/3131) - -* [TEST] Rename w3c_tracecontext_test to w3c_tracecontext_http_test_server - [#3132](https://github.com/open-telemetry/opentelemetry-cpp/pull/3132) - -* [BUILD] Patches for building on AIX - [#3127](https://github.com/open-telemetry/opentelemetry-cpp/pull/3127) - -* [SEMANTIC CONVENTIONS] Migration to weaver - [#3105](https://github.com/open-telemetry/opentelemetry-cpp/pull/3105) - -* [SEMANTIC CONVENTIONS] Upgrade to semantic conventions 1.28.0 - [#3139](https://github.com/open-telemetry/opentelemetry-cpp/pull/3139) - -* [EXPORTER] handling of invalid ports in UrlParser - [#3142](https://github.com/open-telemetry/opentelemetry-cpp/pull/3142) - -* [CI] speed up clang-tidy workflow - [#3148](https://github.com/open-telemetry/opentelemetry-cpp/pull/3148) - -* [EXPORTER] Allow to share gRPC clients between OTLP exporters - [#3041](https://github.com/open-telemetry/opentelemetry-cpp/pull/3041) - -* Bump codecov/codecov-action from 4 to 5 - [#3143](https://github.com/open-telemetry/opentelemetry-cpp/pull/3143) - -* [CI] Add cppcheck in the build - [#3151](https://github.com/open-telemetry/opentelemetry-cpp/pull/3151) - -* [BUILD] Fix error message - [#3152](https://github.com/open-telemetry/opentelemetry-cpp/pull/3152) - -* [EXPORTER] fix clang-tidy warnings in UrlParser - [#3146](https://github.com/open-telemetry/opentelemetry-cpp/pull/3146) - -* [EXPORTER] Upgrade to opentelemetry-proto 1.4.0 - [#3157](https://github.com/open-telemetry/opentelemetry-cpp/pull/3157) - -* [TEST] refactor UrlParser tests to use value-paramterized tests - [#3153](https://github.com/open-telemetry/opentelemetry-cpp/pull/3153) - -* [TEST] add a test for ElasticSearchRecordable - [#3154](https://github.com/open-telemetry/opentelemetry-cpp/pull/3154) - -* [BUILD] Fix missing dependency on protoc compiler - [#3159](https://github.com/open-telemetry/opentelemetry-cpp/pull/3159) - -* [bazel] Update prometheus-cpp in MODULE.bazel - [#3162](https://github.com/open-telemetry/opentelemetry-cpp/pull/3162) - -* [bazel] Enable --incompatible_disallow_empty_glob - [#2642](https://github.com/open-telemetry/opentelemetry-cpp/pull/2642) - -* [INSTALL] Fix cmake/opentelemetry-cpp-config.cmake.in - [#3165](https://github.com/open-telemetry/opentelemetry-cpp/pull/3165) - -* [BUILD] Do not set OTELCPP_PROTO_PATH in the CMake cache - [#3160](https://github.com/open-telemetry/opentelemetry-cpp/pull/3160) - -* [BUILD] Fix build for esp32 - [#3155](https://github.com/open-telemetry/opentelemetry-cpp/pull/3155) - -* [bazel] Update opentelemetry-proto in MODULE.bazel - [#3163](https://github.com/open-telemetry/opentelemetry-cpp/pull/3163) - -Important changes: - -* [API] Jaeger Propagator should not be deprecated - [#3086](https://github.com/open-telemetry/opentelemetry-cpp/pull/3086) - - * Deprecation of the Jaeger propagator, as announced on 2023-01-31 - in version 1.8.2, is now reverted. - * This deprecation turned out to be not justified, - as the Jaeger propagator can be used without the (now removed) - Jaeger exporter. - -* [EXPORTER] Change log resources location for ElasticsearchLogRecordExporter - [#3119](https://github.com/open-telemetry/opentelemetry-cpp/pull/3131) - - * Moved from `root/resources` to `root` - -* [SEMANTIC CONVENTIONS] Migration to weaver - [#3105](https://github.com/open-telemetry/opentelemetry-cpp/pull/3105) - - * `semantic_convention.h` header files are deprecated, - replaced by `semconv/xxx_attributes.h` header files, - for each `xxx` semantic attribute group. - * See file DEPRECATED.md for details. - -Deprecations: - -* This release contains deprecations, see file DEPRECATED.md for details. - -## [1.17 2024-10-07] - -* [CI] Add a clang-tidy build - [#3001](https://github.com/open-telemetry/opentelemetry-cpp/pull/3001) - -* [BUILD] Upgrade to opentelemetry-proto 1.3.2 - [#2991](https://github.com/open-telemetry/opentelemetry-cpp/pull/2991) - -* [REMOVAL] Remove build option `WITH_DEPRECATED_SDK_FACTORY` - [#2717](https://github.com/open-telemetry/opentelemetry-cpp/pull/2717) - -* [EXPORTER] ForceFlush before canceling the running requests on shutdown - [#2727](https://github.com/open-telemetry/opentelemetry-cpp/pull/2727) - -* [SDK] Fix crash in PeriodicExportingMetricReader - [#2983](https://github.com/open-telemetry/opentelemetry-cpp/pull/2983) - -* [SDK] Fix memory leak in TlsRandomNumberGenerator() constructor - [#2661](https://github.com/open-telemetry/opentelemetry-cpp/pull/2661) - -* [EXPORTER] Ignore exception when create thread in OTLP file exporter - [#3012](https://github.com/open-telemetry/opentelemetry-cpp/pull/3012) - -* [BUILD] Update the version in MODULE.bazel - [#3015](https://github.com/open-telemetry/opentelemetry-cpp/pull/3015) - -* [BUILD] Fix build without vcpkg on Windows when gRPC is disabled - [#3016](https://github.com/open-telemetry/opentelemetry-cpp/pull/3016) - -* [BUILD] Add abi_version_no bazel flag - [#3020](https://github.com/open-telemetry/opentelemetry-cpp/pull/3020) - -* [Code health] Expand iwyu coverage to include unit tests - [#3022](https://github.com/open-telemetry/opentelemetry-cpp/pull/3022) - -* [BUILD] Version opentelemetry_proto/proto_grpc shared libraries - [#2992](https://github.com/open-telemetry/opentelemetry-cpp/pull/2992) - -* [SEMANTIC CONVENTIONS] Upgrade semantic conventions to 1.27.0 - [#3023](https://github.com/open-telemetry/opentelemetry-cpp/pull/3023) - -* [SDK] Support empty histogram buckets - [#3027](https://github.com/open-telemetry/opentelemetry-cpp/pull/3027) - -* [TEST] Fix sync problems in OTLP File exporter tests - [#3031](https://github.com/open-telemetry/opentelemetry-cpp/pull/3031) - -* [SDK] PeriodicExportingMetricReader: future is never set, blocks until timeout - [#3030](https://github.com/open-telemetry/opentelemetry-cpp/pull/3030) - -* [Code Health] Clang Tidy cleanup, Part 2 - [#3038](https://github.com/open-telemetry/opentelemetry-cpp/pull/3038) - -* [Code Health] include-what-you-use cleanup, part 3 - [#3004](https://github.com/open-telemetry/opentelemetry-cpp/pull/3004) - -* [SDK] Fix overflow in timeout logic - [#3046](https://github.com/open-telemetry/opentelemetry-cpp/pull/3046) - -* [TEST] Add missing tests to Bazel build - [#3045](https://github.com/open-telemetry/opentelemetry-cpp/pull/3045) - -* [TEST] update collector tests with debug exporter - [#3050](https://github.com/open-telemetry/opentelemetry-cpp/pull/3050) - -* [EXAMPLE] update collector example with debug exporter - [#3049](https://github.com/open-telemetry/opentelemetry-cpp/pull/3049) - -* [TEST] update references to logging exporter - [#3053](https://github.com/open-telemetry/opentelemetry-cpp/pull/3053) - -* [EXAMPLE] Clean the tracer initialization in OStream example - [#3051](https://github.com/open-telemetry/opentelemetry-cpp/pull/3051) - -* [EXPORTER] Fix the format of SpanLink for ETW - [#3054](https://github.com/open-telemetry/opentelemetry-cpp/pull/3054) - -* [EXPORTER] Add in-memory metric exporter - [#3043](https://github.com/open-telemetry/opentelemetry-cpp/pull/3043) - -* [Code Health] include-what-you-use cleanup, part 4 - [#3040](https://github.com/open-telemetry/opentelemetry-cpp/pull/3040) - -* [BUILD] add loongarch info - [#3052](https://github.com/open-telemetry/opentelemetry-cpp/pull/3052) - -* [CI] Update otel-collector version - [#3067](https://github.com/open-telemetry/opentelemetry-cpp/pull/3067) - -* [SDK] Update MetricProducer interface to match spec - [#3044](https://github.com/open-telemetry/opentelemetry-cpp/pull/3044) - -* [EXPORTER] Fix URL in ES exporter, fix ipv6 supporting for http client - [#3081](https://github.com/open-telemetry/opentelemetry-cpp/pull/3081) - -* [EXPORTER] Add HttpHeaders in ElasticsearchLogRecordExporter - [#3083](https://github.com/open-telemetry/opentelemetry-cpp/pull/3083) - -Breaking changes: - -* [REMOVAL] Remove build option `WITH_DEPRECATED_SDK_FACTORY` - [#2717](https://github.com/open-telemetry/opentelemetry-cpp/pull/2717) - - * As announced in opentelemetry-cpp previous release 1.16.0, - CMake option `WITH_DEPRECATED_SDK_FACTORY` was temporary, - and to be removed by the next release. - * This option is now removed. - * Code configuring the SDK must be adjusted, as previously described: - - * [API/SDK] Provider cleanup - [#2664](https://github.com/open-telemetry/opentelemetry-cpp/pull/2664) - - * Before this fix: - * SDK factory methods such as: - * opentelemetry::sdk::trace::TracerProviderFactory::Create() - * opentelemetry::sdk::metrics::MeterProviderFactory::Create() - * opentelemetry::sdk::logs::LoggerProviderFactory::Create() - * opentelemetry::sdk::logs::EventLoggerProviderFactory::Create() - - returned an API object (opentelemetry::trace::TracerProvider) - to the caller. - - * After this fix, these methods return an SDK level object - (opentelemetry::sdk::trace::TracerProvider) to the caller. - * Returning an SDK object is necessary for the application to - cleanup and invoke SDK level methods, such as ForceFlush(), - on a provider. - * The application code that configures the SDK, by calling - the various provider factories, may need adjustment. - * All the examples have been updated, and in particular no - longer perform static_cast do convert an API object to an SDK object. - Please refer to examples for guidance on how to adjust. - -## [1.16.1 2024-07-17] - -* [BUILD] Add bazel missing BUILD file - [#2720](https://github.com/open-telemetry/opentelemetry-cpp/pull/2720) - -* [SDK] Added reserve for spans array in BatchSpanProcessor. - [#2724](https://github.com/open-telemetry/opentelemetry-cpp/pull/2724) - -* [DOC] Update "Using triplets" section in building-with-vcpkg documentation. - [#2726](https://github.com/open-telemetry/opentelemetry-cpp/pull/2726) - -* [DOC] Remove comment for unused LoggerProvider initialization params - [#2972](https://github.com/open-telemetry/opentelemetry-cpp/pull/2972) - -* [SECURITY] Remove OTLP HTTP support for TLS 1.0 and TLS 1.1, - require TLS 1.2 or better - [#2722](https://github.com/open-telemetry/opentelemetry-cpp/pull/2722) - -* [TEST] Fix opentelemetry-collector bind address - [#2989](https://github.com/open-telemetry/opentelemetry-cpp/pull/2989) - -* [EXPORTER] Fix references in AttributeValueVisitor - [#2985](https://github.com/open-telemetry/opentelemetry-cpp/pull/2985) - -* [Code health] include-what-you-use cleanup, part 2 - [#2704](https://github.com/open-telemetry/opentelemetry-cpp/pull/2704) - -* [Code Health] clang-tidy cleanup, part 1 - [#2990](https://github.com/open-telemetry/opentelemetry-cpp/pull/2990) - -* [CI] Build failures with ABSEIL 20240116 and CMAKE 3.30 - [#3002](https://github.com/open-telemetry/opentelemetry-cpp/pull/3002) - -* [CI] Enable bzlmod - [#2995](https://github.com/open-telemetry/opentelemetry-cpp/pull/2995) - -* [Metrics SDK] Fix hash calculation for nostd::string - [#2999](https://github.com/open-telemetry/opentelemetry-cpp/pull/2999) - -Breaking changes: - -* [SECURITY] Remove OTLP HTTP support for TLS 1.0 and TLS 1.1, - require TLS 1.2 or better - [#2722](https://github.com/open-telemetry/opentelemetry-cpp/pull/2722) - * The OTLP HTTP exporter no longer accept options like: - * min_TLS = 1.0 - * min_TLS = 1.1 - * max_TLS = 1.0 - * max_TLS = 1.1 - * When connecting to an OTLP HTTP endpoint, using `https`, - the connection will require TLS 1.2 by default, - unless min_TLS is set to 1.3 - * Plain `http` connections (insecure) are not affected. - -## [1.16.0] 2024-06-21 - -* [BUILD] Upgrade bazel abseil from 20220623.1 to 20230802.2 - [#2650](https://github.com/open-telemetry/opentelemetry-cpp/pull/2650) -* [BUILD] Use nostd::enable_if_t instead of std::enable_if_t - [#2648](https://github.com/open-telemetry/opentelemetry-cpp/pull/2648) -* [EXEMPLAR] Update ExemplarFilter and ExemplarReservoir for spec - [#2372](https://github.com/open-telemetry/opentelemetry-cpp/pull/2372) -* [BUILD] Link CoreFoundation on apple systems - [#2655](https://github.com/open-telemetry/opentelemetry-cpp/pull/2655) -* [SDK] Avoid missing conditional variable update and simplify atomic bool - [#2553](https://github.com/open-telemetry/opentelemetry-cpp/pull/2553) -* [BUILD] Build break in OLTP_FILE tests - [#2659](https://github.com/open-telemetry/opentelemetry-cpp/pull/2659) -* [EXPORTER] General cleanup for is_shutdown flags in exporters. - [#2663](https://github.com/open-telemetry/opentelemetry-cpp/pull/2663) -* [CI] Upgrade Maintainers CI to ubuntu-24.04 - [#2670](https://github.com/open-telemetry/opentelemetry-cpp/pull/2670) -* [BUILD] Upgrade to opentelemetry-proto 1.3.1 - [#2669](https://github.com/open-telemetry/opentelemetry-cpp/pull/2669) -* [API] Return NoopLogRecord from NoopLogger - [#2668](https://github.com/open-telemetry/opentelemetry-cpp/pull/2668) -* [BUILD] Remove the hard-coded separator in tracestate - [#2672](https://github.com/open-telemetry/opentelemetry-cpp/pull/2672) -* [SDK] Fix forceflush may wait for ever - [#2584](https://github.com/open-telemetry/opentelemetry-cpp/pull/2584) -* [API] DO not allow unsafe Logger::EmitLogRecord - [#2673](https://github.com/open-telemetry/opentelemetry-cpp/pull/2673) -* [BUILD] Read default proto version from third_party_release - [#2677](https://github.com/open-telemetry/opentelemetry-cpp/pull/2677) -* [CI] include-what-you-use - [#2629](https://github.com/open-telemetry/opentelemetry-cpp/pull/2629) -* [CI] Upgrade to clang-format 18 - [#2684](https://github.com/open-telemetry/opentelemetry-cpp/pull/2684) -* [CI] Fix CI failures on Ubuntu 24.04 - [#2686](https://github.com/open-telemetry/opentelemetry-cpp/pull/2686) -* [SEMANTIC CONVENTIONS] Upgrade to version 1.26.0 - [#2687](https://github.com/open-telemetry/opentelemetry-cpp/pull/2687) -* [API/SDK] Provider cleanup - [#2664](https://github.com/open-telemetry/opentelemetry-cpp/pull/2664) -* [ETW] Add table name mapping for Logs other than the default Log table - [#2691](https://github.com/open-telemetry/opentelemetry-cpp/pull/2691) -* [CI] Remove benchmark overlay for vcpkg - [#2695](https://github.com/open-telemetry/opentelemetry-cpp/pull/2695) -* [BUILD] Remove the incorrect set of CMAKE_MSVC_RUNTIME_LIBRARY for vcpkg - [#2696](https://github.com/open-telemetry/opentelemetry-cpp/pull/2696) -* [BUILD] CMakeLists.txt: Enable CMAKE_MSVC_RUNTIME_LIBRARY support - [#2652](https://github.com/open-telemetry/opentelemetry-cpp/pull/2652) -* [EXPORTER] OTLP file: use thread-safe file/io - [#2675](https://github.com/open-telemetry/opentelemetry-cpp/pull/2675) -* [bazel] Bump version and deps - [#2679](https://github.com/open-telemetry/opentelemetry-cpp/pull/2679) -* [BUILD] Add support for bzlmod - [#2608](https://github.com/open-telemetry/opentelemetry-cpp/pull/2608) -* [BUILD] Fix Import Abseil-cpp - [#2701](https://github.com/open-telemetry/opentelemetry-cpp/pull/2701) -* [Code health] include-what-you-use cleanup - [#2692](https://github.com/open-telemetry/opentelemetry-cpp/pull/2692) -* [BUILD] Restore Bazel flag removed from public API - [#2702](https://github.com/open-telemetry/opentelemetry-cpp/pull/2702) -* [DOC] Fix typo tace_id -> trace_id in logger.h - [#2703](https://github.com/open-telemetry/opentelemetry-cpp/pull/2703) -* Bump docker/build-push-action from 5 to 6 - [#2705](https://github.com/open-telemetry/opentelemetry-cpp/pull/2705) -* [CI] Enable ARM64 build in CI - [#2699](https://github.com/open-telemetry/opentelemetry-cpp/pull/2699) -* [Code health] Remove Unicode Text from Source files - [#2707](https://github.com/open-telemetry/opentelemetry-cpp/pull/2707) -* [BUILD] Add option WITH_OTLP_GRPC_SSL_MTLS_PREVIEW - [#2714](https://github.com/open-telemetry/opentelemetry-cpp/pull/2714) -* [EXPORTER] All 2xx return codes should be considered successful. - [#2712](https://github.com/open-telemetry/opentelemetry-cpp/pull/2712) - -Important changes: - -* [API/SDK] Provider cleanup - [#2664](https://github.com/open-telemetry/opentelemetry-cpp/pull/2664) - * Before this fix: - * The API class `opentelemetry::trace::Tracer` exposed methods such - as `ForceFlush()`, `ForceFlushWithMicroseconds()`, `Close()` - and `CloseWithMicroseconds()`. - * These methods are meant to be used when configuring the SDK, - and should not be part of the API. Exposing them was an oversight. - * Two of these methods are virtual, and therefore part of the ABI. - * After this fix: - * In `OPENTELEMETRY_ABI_VERSION_NO 1`, nothing is changed, - because removing this code would break the ABI. - * In `OPENTELEMETRY_ABI_VERSION_NO 2`, these methods are moved - from the API to the SDK. This is a breaking change for ABI version 2, - which is still experimental. - * In all cases, instrumenting an application should not - invoke flush or close on a tracer, do not use these methods. - -Breaking changes: - -* [API/SDK] Provider cleanup - [#2664](https://github.com/open-telemetry/opentelemetry-cpp/pull/2664) - * Before this fix: - * SDK factory methods such as: - * opentelemetry::sdk::trace::TracerProviderFactory::Create() - * opentelemetry::sdk::metrics::MeterProviderFactory::Create() - * opentelemetry::sdk::logs::LoggerProviderFactory::Create() - * opentelemetry::sdk::logs::EventLoggerProviderFactory::Create() - returned an API object (opentelemetry::trace::TracerProvider) - to the caller. - * After this fix, these methods return an SDK level object - (opentelemetry::sdk::trace::TracerProvider) to the caller. - * Returning an SDK object is necessary for the application to - cleanup and invoke SDK level methods, such as ForceFlush(), - on a provider. - * The application code that configures the SDK, by calling - the various provider factories, may need adjustment. - * All the examples have been updated, and in particular no - longer perform static_cast do convert an API object to an SDK object. - Please refer to examples for guidance on how to adjust. - * If adjusting application code is impractical, - an alternate and temporary solution is to build with option - WITH_DEPRECATED_SDK_FACTORY=ON in CMake. - * Option WITH_DEPRECATED_SDK_FACTORY=ON will allow to build code - without application changes, posponing changes for later. - * WITH_DEPRECATED_SDK_FACTORY=ON is temporary, only to provide - an easier migration path. Expect this flag to be removed, - as early as by the next release. - -Notes on experimental features: - -* [#2372](https://github.com/open-telemetry/opentelemetry-cpp/issues/2372) - introduced `MeterProvider::SetExemplar()` which accepts en - `ExemplarFilterType` enumeration with `kAlwaysOff`, `kAlwaysOn` and - `kTraceBased`. - -## [1.15.0] 2024-04-21 - -* [EXPORTER] Change OTLP HTTP content_type default to binary - [#2564](https://github.com/open-telemetry/opentelemetry-cpp/pull/2564) -* [DOC] Fix OTLP documentation: Default endpoint is wrong for OTLP/HTTP - [#2560](https://github.com/open-telemetry/opentelemetry-cpp/pull/2560) -* [BUILD] Fix old style cast warning - [#2567](https://github.com/open-telemetry/opentelemetry-cpp/pull/2567) -* [EXPORTER] Gzip compression support for OTLP/HTTP and OTLP/gRPC exporter - [#2530](https://github.com/open-telemetry/opentelemetry-cpp/pull/2530) -* [BUILD] update vcpkg submodule to 2024.02.14 - [#2575](https://github.com/open-telemetry/opentelemetry-cpp/pull/2575) -* [SDK] Support for OTEL_SERVICE_NAME - [#2577](https://github.com/open-telemetry/opentelemetry-cpp/pull/2577) -* [EXPORTER] Support URL-encoded values for `OTEL_EXPORTER_OTLP_HEADERS` - [#2579](https://github.com/open-telemetry/opentelemetry-cpp/pull/2579) -* [BUILD] CMake cleanup for message() - [#2582](https://github.com/open-telemetry/opentelemetry-cpp/pull/2582) -* [BUILD] Bump CMake minimum required version to 3.9 - [#2581](https://github.com/open-telemetry/opentelemetry-cpp/pull/2581) -* [BUILD] Provide LIKELY / UNLIKELY macros - [#2580](https://github.com/open-telemetry/opentelemetry-cpp/pull/2580) -* [EXPORTER] OTLP: Fix missing ResourceMetrics SchemaURL - [#2587](https://github.com/open-telemetry/opentelemetry-cpp/pull/2587) -* [ETW] cleanup include path - [#2594](https://github.com/open-telemetry/opentelemetry-cpp/pull/2594) -* Upgrade to googletest 1.14.0 - [#2596](https://github.com/open-telemetry/opentelemetry-cpp/pull/2596) -* Upgrade to nlohmann_json 3.11.3 - [#2595](https://github.com/open-telemetry/opentelemetry-cpp/pull/2595) -* [BAZEL] Move -std=c++14 to .bazelrc - [#2600](https://github.com/open-telemetry/opentelemetry-cpp/pull/2600) -* [BAZEL] Fix -std=c++14 warning on Windows - [#2601](https://github.com/open-telemetry/opentelemetry-cpp/pull/2601) -* Upgrade to benchmark 1.8.3 - [#2597](https://github.com/open-telemetry/opentelemetry-cpp/pull/2597) -* Upgrade to prometheus 1.2.4 - [#2598](https://github.com/open-telemetry/opentelemetry-cpp/pull/2598) -* [DOC] Fix typo: Asynchronouse -> Asynchronous in meter.h - [#2604](https://github.com/open-telemetry/opentelemetry-cpp/pull/2604) -* [BUILD] Do not link prometheus-cpp::util when it doesn't exist - [#2606](https://github.com/open-telemetry/opentelemetry-cpp/pull/2606) -* [SDK] Remove unused variable - [#2609](https://github.com/open-telemetry/opentelemetry-cpp/pull/2609) -* [METRICS SDK] Remove extra OfferMeasurement call - in SyncMetricsStorage::OfferMeasurement - [#2610](https://github.com/open-telemetry/opentelemetry-cpp/pull/2610) -* [MISC] Use set -e on all shell scripts and pass shellcheck --severity=error - [#2616](https://github.com/open-telemetry/opentelemetry-cpp/pull/2616) -* [CI] Add shellcheck --severity=error as a CI step - [#2618](https://github.com/open-telemetry/opentelemetry-cpp/pull/2618) -* [CI] Upgrade to abseil 20240116.1 (CMake only) - [#2599](https://github.com/open-telemetry/opentelemetry-cpp/pull/2599) -* [CI] Benchmark, provide units with --benchmark_min_time - [#2621](https://github.com/open-telemetry/opentelemetry-cpp/pull/2621) -* [EXPORTER] OTLP file exporter - [#2540](https://github.com/open-telemetry/opentelemetry-cpp/pull/2540) -* [CI] Use platform CMake - [#2627](https://github.com/open-telemetry/opentelemetry-cpp/pull/2627) -* [PROTO] Upgrade to opentelemetry-proto 1.2.0 - [#2631](https://github.com/open-telemetry/opentelemetry-cpp/pull/2631) -* [SDK] DefaultLogHandler to print errors to std::cerr, add LogLevel::None - [#2622](https://github.com/open-telemetry/opentelemetry-cpp/pull/2622) -* [SEMANTIC CONVENTIONS] Upgrade to semantic convention 1.25.0 - [#2633](https://github.com/open-telemetry/opentelemetry-cpp/pull/2633) -* [DOC] Add readme and examples for OTLP FILE exporters. - [#2638](https://github.com/open-telemetry/opentelemetry-cpp/pull/2638) -* [SEMANTIC CONVENTIONS] Rework on semantic conventions 1.25.0 - [#2640](https://github.com/open-telemetry/opentelemetry-cpp/pull/2640) -* [DOC] Update INSTALL.md - [#2592](https://github.com/open-telemetry/opentelemetry-cpp/pull/2592) - -Important changes: - -* [EXPORTER] Gzip compression support for OTLP/HTTP and OTLP/gRPC exporter - [#2530](https://github.com/open-telemetry/opentelemetry-cpp/pull/2530) - * In the `OtlpHttpExporterOptions` and `OtlpGrpcExporterOptions`, a new - field called compression has been introduced. This field can be set - to "gzip” to enable gzip compression. - * The CMake option `WITH_OTLP_HTTP_COMPRESSION` is introduced to enable - gzip compression support for the OTLP HTTP Exporter and includes a - dependency on zlib. -* [SDK] Change OTLP HTTP content_type default to binary - [#2558](https://github.com/open-telemetry/opentelemetry-cpp/pull/2558) -* [CI] Use platform CMake - [#2627](https://github.com/open-telemetry/opentelemetry-cpp/pull/2627) - * The `CI` in github no longer install a different version of `cmake`. - * It now always use the `cmake` provided by the platform. - * As part of this change, the script `ci/setup_cmake.sh` was renamed - to `ci/setup_googletest.sh`, for clarity, now that this script - only installs googletest. -* [SDK] DefaultLogHandler to print to std::cerr, add LogLevel::None - [#2622](https://github.com/open-telemetry/opentelemetry-cpp/pull/2622) - * Change DefaultLogHandler output - * Before, the default internal logger, DefaultLogHandler, - used to print to std::cout. - * Now, DefaultLogHandler prints errors and warnings to std::cerr, - as expected, while printing info and debug messages to std::cout. - * Applications that expected to find the opentelemetry-cpp internal - error log in std::cout may need adjustments, either by looking - at std::cerr instead, or by using a custom log handler. - * Additional LogLevel::None - * LogLevel::None is a new supported log level, which does not print - any message. - * Custom log handlers may need to implement a new case, to avoid - compiler warnings. - * Numbering of log levels like OTEL_INTERNAL_LOG_LEVEL_ERROR - has changed, which requires to rebuild, as the SDK ABI differs. - -## [1.14.2] 2024-02-27 - -* [SDK] Fix observable attributes drop - [#2557](https://github.com/open-telemetry/opentelemetry-cpp/pull/2557) - -## [1.14.1] 2024-02-23 - -* [SDK] Restore Recordable API compatibility with versions < 1.14.0 - [#2547](https://github.com/open-telemetry/opentelemetry-cpp/pull/2547) -* [DOC] Add missing CHANGELOG. - [#2549](https://github.com/open-telemetry/opentelemetry-cpp/pull/2549) -* [EXPORTER] Error when grpc endpoint is empty - [#2507](https://github.com/open-telemetry/opentelemetry-cpp/pull/2507) -* [DOC] Fix typo in benchmarks.rst - [#2542](https://github.com/open-telemetry/opentelemetry-cpp/pull/2542) - -Important changes: - -* [SDK] Restore Recordable API compatibility with versions < 1.14.0 - [#2547](https://github.com/open-telemetry/opentelemetry-cpp/pull/2547) - * For third party _extending_ the SDK, release 1.14.0 introduced - an API breaking change compared to 1.13.0 - * This fix restores API (but not ABI) compatibility of - release 1.14.1 with release 1.13.0. - * This allows to build a third party exporter with no source code changes, - for both releases 1.14.1 and 1.13.0. - -## [1.14.0] 2024-02-16 - -* [BUILD] Add DLL build CI pipeline with CXX20 - [#2465](https://github.com/open-telemetry/opentelemetry-cpp/pull/2465) -* [EXPORTER] Set `is_monotonic` flag for Observable Counters - [#2478](https://github.com/open-telemetry/opentelemetry-cpp/pull/2478) -* [PROTO] Upgrade to opentelemetry-proto v1.1.0 - [#2488](https://github.com/open-telemetry/opentelemetry-cpp/pull/2488) -* [BUILD] Introduce CXX 20 CI pipeline for MSVC/Windows - [#2450](https://github.com/open-telemetry/opentelemetry-cpp/pull/2450) -* [API] Propagation: fix for hex conversion to binary for odd hex strings - [#2533](https://github.com/open-telemetry/opentelemetry-cpp/pull/2533) -* [DOC] Fix calendar link - [#2532](https://github.com/open-telemetry/opentelemetry-cpp/pull/2532) -* [ETW EXPORTER] Remove namespace using in ETW exporter which affects global - namespace - [#2531](https://github.com/open-telemetry/opentelemetry-cpp/pull/2531) -* [BUILD] Don't invoke vcpkg from this repo with CMAKE_TOOLCHAIN_FILE set - [#2527](https://github.com/open-telemetry/opentelemetry-cpp/pull/2527) -* [EXPORTER] Async exporting for otlp grpc - [#2407](https://github.com/open-telemetry/opentelemetry-cpp/pull/2407) -* [METRICS SDK] Fix attribute filtering for synchronous instruments. - [#2472](https://github.com/open-telemetry/opentelemetry-cpp/pull/2472) -* [BUILD] Better handling of OPENTELEMETRY_STL_VERSION under Bazel. - [#2503](https://github.com/open-telemetry/opentelemetry-cpp/pull/2503) -* [DOC] Fixes CI markdown error MD055 - Table pipe style - [#2517](https://github.com/open-telemetry/opentelemetry-cpp/pull/2517) -* [API] Propagators: do not overwrite the active span with a default invalid - span [#2511](https://github.com/open-telemetry/opentelemetry-cpp/pull/2511) -* [BUILD] Updated the recorded vcpkg submodule version - [#2513](https://github.com/open-telemetry/opentelemetry-cpp/pull/2513) -* [BUILD] Remove unnecessary usage/includes of nostd/type_traits - [#2509](https://github.com/open-telemetry/opentelemetry-cpp/pull/2509) -* [SEMANTIC CONVENTIONS] Upgrade to version 1.24.0 - [#2461](https://github.com/open-telemetry/opentelemetry-cpp/pull/2461) -* [EXAMPLES] Improve readme of Metrics example - [#2510](https://github.com/open-telemetry/opentelemetry-cpp/pull/2510) -* [BUILD] Clang-15 warning about `__has_trivial_destructor` - [#2502](https://github.com/open-telemetry/opentelemetry-cpp/pull/2502) -* [BUILD] Fix multiple assignment operators for SpinLockMutex - [#2501](https://github.com/open-telemetry/opentelemetry-cpp/pull/2501) -* [BUILD] Alternative way of exporting symbols (generating .def file) - [#2476](https://github.com/open-telemetry/opentelemetry-cpp/pull/2476) -* [CI] Make cmake.c++20*.test actually use C++20 and add cmake.c++23*.test - [#2496](https://github.com/open-telemetry/opentelemetry-cpp/pull/2496) -* [DOCUMENTATION] Add api reference documentation for logs - [#2497](https://github.com/open-telemetry/opentelemetry-cpp/pull/2497) -* [BUILD] Fix variable shadow - [#2498](https://github.com/open-telemetry/opentelemetry-cpp/pull/2498) -* [BUILD] Fix checks on __cplusplus under MSVC, do not assume /Zc - [#2493](https://github.com/open-telemetry/opentelemetry-cpp/pull/2493) -* [EXAMPLES] Use logs API instead of logs bridge API in the example - [#2494](https://github.com/open-telemetry/opentelemetry-cpp/pull/2494) -* [EXPORTER] Fix forward protocol encoding for ETW exporter - [#2473](https://github.com/open-telemetry/opentelemetry-cpp/pull/2473) -* [BUILD] Skip patch alias target - [#2457](https://github.com/open-telemetry/opentelemetry-cpp/pull/2457) -* [EXPORTER] Rename populate_otel_scope to without_otel_scope - [#2479](https://github.com/open-telemetry/opentelemetry-cpp/pull/2479) -* [EXPORTER SDK] Additional fixes after NOMINMAX removal on Windows - [#2475](https://github.com/open-telemetry/opentelemetry-cpp/pull/2475) -* [EXPORTER] Do not use regex in `CleanUpString` because some implementations of - STL may crash. - [#2464](https://github.com/open-telemetry/opentelemetry-cpp/pull/2464) -* [EXPORTER] Fix Aggregation type detection in OTLP Exporter - [#2467](https://github.com/open-telemetry/opentelemetry-cpp/pull/2467) -* [EXPORTER] Add option to disable Prometheus otel_scope_name and - otel_scope_version attributes - [#2451](https://github.com/open-telemetry/opentelemetry-cpp/pull/2451) -* [SEMANTIC CONVENTIONS] Code generation script fails on SELINUX - [#2455](https://github.com/open-telemetry/opentelemetry-cpp/pull/2455) -* [BUILD] Fix removing of NOMINMAX on Windows - [#2449](https://github.com/open-telemetry/opentelemetry-cpp/pull/2449) -* [BUILD] Accept path list in OPENTELEMETRY_EXTERNAL_COMPONENT_PATH - [#2439](https://github.com/open-telemetry/opentelemetry-cpp/pull/2439) -* [BUILD] Remove gmock from GTEST_BOTH_LIBRARIES - [#2437](https://github.com/open-telemetry/opentelemetry-cpp/pull/2437) -* [REMOVAL] Remove option WITH_OTLP_HTTP_SSL_PREVIEW - [#2435](https://github.com/open-telemetry/opentelemetry-cpp/pull/2435) - -Important changes: - -Breaking changes: - -* [REMOVAL] Remove option WITH_OTLP_HTTP_SSL_PREVIEW - [#2435](https://github.com/open-telemetry/opentelemetry-cpp/pull/2435) - * CMake options `WITH_OTLP_HTTP_SSL_PREVIEW` and - `WITH_OTLP_HTTP_SSL_TLS_PREVIEW` are removed. Building opentelemetry-cpp - without SSL support is no longer possible. - -* [PROTO] Upgrade to opentelemetry-proto v1.1.0 - [#2488](https://github.com/open-telemetry/opentelemetry-cpp/pull/2488) - * Class `opentelemetry::sdk::trace::Recordable` has a new virtual method, - `SetTraceFlags()`. - * This is an incompatible change for the SDK Recordable API and ABI. - * Applications _configuring_ the SDK are not affected. - * Third parties providing SDK _extensions_ are affected, - and must provide a `SetTraceFlags()` implementation, - starting with opentelemetry-cpp 1.14.0. - -## [1.13.0] 2023-12-06 - -* [BUILD] Remove WITH_REMOVE_METER_PREVIEW, use WITH_ABI_VERSION_2 instead - [#2370](https://github.com/open-telemetry/opentelemetry-cpp/pull/2370) -* [SDK] Metrics ObservableRegistry Cleanup - [#2376](https://github.com/open-telemetry/opentelemetry-cpp/pull/2376) -* [BUILD] Make WITH_OTLP_HTTP_SSL_PREVIEW mainstream - [#2378](https://github.com/open-telemetry/opentelemetry-cpp/pull/2378) -* [SDK] Creating DoubleUpDownCounter with no matching view - [#2379](https://github.com/open-telemetry/opentelemetry-cpp/pull/2379) -* [API] Add InstrumentationScope attributes in TracerProvider::GetTracer() - [#2371](https://github.com/open-telemetry/opentelemetry-cpp/pull/2371) -* [BUILD] DLL export interface for Metrics - [#2344](https://github.com/open-telemetry/opentelemetry-cpp/pull/2344) -* [BUILD] enum CanonicalCode names too generic... conflict with old C defines - [#2385](https://github.com/open-telemetry/opentelemetry-cpp/pull/2385) -* [BUILD] Fix cpack broken package version - [#2386](https://github.com/open-telemetry/opentelemetry-cpp/pull/2386) -* [API] Add a new AddLink() operation to Span - [#2380](https://github.com/open-telemetry/opentelemetry-cpp/pull/2380) -* [opentracing-shim] Add check for sampled context - [#2390](https://github.com/open-telemetry/opentelemetry-cpp/pull/2390) -* [BUILD] Fix exported definitions when building DLL with STL - [#2387](https://github.com/open-telemetry/opentelemetry-cpp/pull/2387) -* [BUILD] Add missing includes to runtime_context_test - [#2395](https://github.com/open-telemetry/opentelemetry-cpp/pull/2395) -* [ADMIN] Add file .github/repository-settings.md - [#2392](https://github.com/open-telemetry/opentelemetry-cpp/pull/2392) -* [SDK] Fix GetLogger with empty library name - [#2398](https://github.com/open-telemetry/opentelemetry-cpp/pull/2398) -* [TEST] Fix compiling problem and removed -DENABLE_TEST - [#2401](https://github.com/open-telemetry/opentelemetry-cpp/pull/2401) -* [BUILD] Check windows options are not passed to non-Windows build - [#2399](https://github.com/open-telemetry/opentelemetry-cpp/pull/2399) -* [EXPORTER] Rework OTLP/HTTP and OTLP/GRPC exporter options - [#2388](https://github.com/open-telemetry/opentelemetry-cpp/pull/2388) -* [Build] Update vcpkg to latest release - [#2412](https://github.com/open-telemetry/opentelemetry-cpp/pull/2412) -* [SDK] Cardinality limits for metrics streams - (Sync Instruments + Delta Temporality) - [#2255](https://github.com/open-telemetry/opentelemetry-cpp/pull/2255) -* [EXPORTER] Prometheus: Add unit to names, convert to word - [#2213](https://github.com/open-telemetry/opentelemetry-cpp/pull/2213) -* [Metrics] Make context optional for histogram instruments in Metrics SDK - [#2416](https://github.com/open-telemetry/opentelemetry-cpp/pull/2416) -* [BUILD] Fix references to trace namespace to be fully qualified - [#2422](https://github.com/open-telemetry/opentelemetry-cpp/pull/2422) -* [BUILD] Bump third_party/googletest to same version as bazel - [#2421](https://github.com/open-telemetry/opentelemetry-cpp/pull/2421) -* [BUILD] Remove defining NOMINMAX from api - [#2420](https://github.com/open-telemetry/opentelemetry-cpp/pull/2420) -* [BUILD] 'uint8_t' not declared in this scope with gcc 13.2.1 - [#2423](https://github.com/open-telemetry/opentelemetry-cpp/pull/2423) -* [BUILD] Improve the handling of OPENTELEMETRY_HAVE_WORKING_REGEX - [#2430](https://github.com/open-telemetry/opentelemetry-cpp/pull/2430) -* [SEMANTIC CONVENTION] Upgrade to semconv 1.23.1 - [#2428](https://github.com/open-telemetry/opentelemetry-cpp/pull/2428) -* [BUILD] Use fully qualified references to trace/common namespace - [#2424](https://github.com/open-telemetry/opentelemetry-cpp/pull/2424) -* [API] Create root span with active span - [#2427](https://github.com/open-telemetry/opentelemetry-cpp/pull/2427) -* [REMOVAL] Remove ZPAGES - [#2433](https://github.com/open-telemetry/opentelemetry-cpp/pull/2433) - -Important changes: - -* [API] Add InstrumentationScope attributes in TracerProvider::GetTracer() - [#2371](https://github.com/open-telemetry/opentelemetry-cpp/pull/2371) - * TracerProvider::GetTracer() now accepts InstrumentationScope attributes. - * Because this is an `ABI` breaking change, the fix is only available - with the `CMake` option `WITH_ABI_VERSION_2=ON`. - * When building with `CMake` option `WITH_ABI_VERSION_1=ON` (by default) - the `ABI` is unchanged, and the fix is not available. - -* [API] Add a new AddLink() operation to Span - [#2380](https://github.com/open-telemetry/opentelemetry-cpp/pull/2380) - * New `API` Span::AddLink() adds a single link to a span. - * New `API` Span::AddLinks() adds multiple links to a span. - * Because this is an `ABI` breaking change, the fix is only available - with the `CMake` option `WITH_ABI_VERSION_2=ON`. - * When building with `CMake` option `WITH_ABI_VERSION_1=ON` (by default) - the `ABI` is unchanged, and the fix is not available. - -* [BUILD] Make WITH_OTLP_HTTP_SSL_PREVIEW mainstream - [#2378](https://github.com/open-telemetry/opentelemetry-cpp/pull/2378) - * The experimental `CMake` option `WITH_OTLP_HTTP_SSL_PREVIEW` - is now promoted to stable. The default is changed to `ON`. - * The experimental `CMake` option `WITH_OTLP_HTTP_SSL_TLS_PREVIEW` - is now promoted to stable. The default is changed to `ON`. - * These build options are scheduled to be removed by the next release, - building without SSL/TLS will no longer be possible. - -* [EXPORTER] Rework OTLP/HTTP and OTLP/GRPC exporter options - [#2388](https://github.com/open-telemetry/opentelemetry-cpp/pull/2388) - * `OtlpGrpcMetricExporterOptions` used to honor `_TRACES_` - environment variables, instead of `_METRICS_` environment variables. - * The implementation of `OtlpGrpcMetricExporterOptions` is now fixed. - * Please check configuration variables, - to make sure `_METRICS_` variables are set as expected. - -Breaking changes: - -* [BUILD] Remove WITH_REMOVE_METER_PREVIEW, use WITH_ABI_VERSION_2 instead - [#2370](https://github.com/open-telemetry/opentelemetry-cpp/pull/2370) - * The experimental `CMake` option `WITH_REMOVE_METER_PREVIEW` is removed, - use option `WITH_ABI_VERSION_2` instead. - -* [BUILD] enum CanonicalCode names too generic... conflict with old C defines - [#2385](https://github.com/open-telemetry/opentelemetry-cpp/pull/2385) - * Header file `opentelemetry/trace/canonical_code.h` is unused, - and is now removed. - * This header should not be included directly in an application. - If this is the case, please remove any remaining include directives. - -* [BUILD] Fix exported definitions when building DLL with STL - [#2387](https://github.com/open-telemetry/opentelemetry-cpp/pull/2387) - * The MeterSelector, MeterSelectorFactory, InstrumentSelector, - and InstrumentSelectorFactory APIs now use const std::string& - instead of nostd::string_view for name, version and schema to - maintain a single export definition for DLL. - -* [EXPORTER] Rework OTLP/HTTP and OTLP/GRPC exporter options - [#2388](https://github.com/open-telemetry/opentelemetry-cpp/pull/2388) - * `OtlpGrpcLogRecordExporter` incorrectly used `OtlpGrpcExporterOptions`, - which are options for traces and not logs. - * This created a bug: the `OtlpGrpcLogRecordExporter` honors `_TRACES_` - environment variables, instead of `_LOGS_` environment variables. - * `OtlpGrpcLogRecordExporter` is changed to use - `OtlpGrpcLogRecordExporterOptions` instead, fixing the bug. - * User code that initializes the SDK with a GRPC Log exporter, - and uses exporter options, should adjust to replace - `OtlpGrpcExporterOptions` with `OtlpGrpcLogRecordExporterOptions`. - * Please check configuration variables, - to make sure `_LOGS_` variables are set as expected. - -* [REMOVAL] Remove ZPAGES - [#2433](https://github.com/open-telemetry/opentelemetry-cpp/pull/2433) - * As announced in release 1.12.0, - the deprecated ZPAGES exporter is now removed. - -## [1.12.0] 2023-10-16 - -* [BUILD] Support `pkg-config` - [#2269](https://github.com/open-telemetry/opentelemetry-cpp/pull/2269) -* [CI] Do not automatically close stale issues - [#2277](https://github.com/open-telemetry/opentelemetry-cpp/pull/2277) -* [CI] Benchmark workflow fails, C++14 required to build grpc - [#2278](https://github.com/open-telemetry/opentelemetry-cpp/pull/2278) -* [SDK] Increase metric name maximum length from 63 to 255 characters - [#2284](https://github.com/open-telemetry/opentelemetry-cpp/pull/2284) -* [SEMANTIC CONVENTION] Deprecated semconv (in the spec) - not deprecated (in C++) - [#2285](https://github.com/open-telemetry/opentelemetry-cpp/pull/2285) -* [SDK] Remove unused member variables from SyncMetricStorage - [#2294](https://github.com/open-telemetry/opentelemetry-cpp/pull/2294) -* [DEPRECATION] Deprecate ZPAGES - [#2291](https://github.com/open-telemetry/opentelemetry-cpp/pull/2291) -* [API] Deliver ABI breaking changes - [#2222](https://github.com/open-telemetry/opentelemetry-cpp/pull/2222) -* [SDK] Allow metric instrument names to contain / characters - [#2310](https://github.com/open-telemetry/opentelemetry-cpp/pull/2310) -* [SDK] Fix Observable Counters/UpDownCounters - [#2298](https://github.com/open-telemetry/opentelemetry-cpp/pull/2298) -* [SDK] Add exemplar reservoir to async metric storage - [#2319](https://github.com/open-telemetry/opentelemetry-cpp/pull/2319) -* [TEST] Fix lifetime issues in prometheus test utils - [#2322](https://github.com/open-telemetry/opentelemetry-cpp/pull/2322) -* [EXPORTER] Prometheus: Remove explicit timestamps from metric points - [#2324](https://github.com/open-telemetry/opentelemetry-cpp/pull/2324) -* [EXPORTER] Prometheus: Handle attribute key collisions from sanitation - [#2326](https://github.com/open-telemetry/opentelemetry-cpp/pull/2326) -* [EXPORTER] Prometheus cleanup, test with TranslateToPrometheus - [#2329](https://github.com/open-telemetry/opentelemetry-cpp/pull/2329) -* [SDK] Fix log message in Meter::RegisterSyncMetricStorage - [#2325](https://github.com/open-telemetry/opentelemetry-cpp/pull/2325) -* [DOC] Simplify the project status section - [#2332](https://github.com/open-telemetry/opentelemetry-cpp/pull/2332) -* [EXPORTER] Prometheus: Sanitize labels according to spec - [#2330](https://github.com/open-telemetry/opentelemetry-cpp/pull/2330) -* [SDK] Fix deadlock when shuting down http client - [#2337](https://github.com/open-telemetry/opentelemetry-cpp/pull/2337) -* [Exporter] Group spans by resource and instrumentation scope - in OTLP export requests - [#2335](https://github.com/open-telemetry/opentelemetry-cpp/pull/2335) -* [BUILD] Need fine-grained HAVE_CPP_STDLIB - [#2304](https://github.com/open-telemetry/opentelemetry-cpp/pull/2304) -* [API] Add InstrumentationScope attributes in MeterProvider::GetMeter() - [#2224](https://github.com/open-telemetry/opentelemetry-cpp/pull/2224) -* [REMOVAL] Drop C++11 support - [#2342](https://github.com/open-telemetry/opentelemetry-cpp/pull/2342) -* [EXPORTER] prometheus: add otel_scope_name and otel_scope_version labels - [#2293](https://github.com/open-telemetry/opentelemetry-cpp/pull/2293) -* [EXPORTER] Export resource for prometheus - [#2301](https://github.com/open-telemetry/opentelemetry-cpp/pull/2301) -* [BUILD] error: read-only reference ‘value’ used as ‘asm’ output - [#2354](https://github.com/open-telemetry/opentelemetry-cpp/pull/2354) -* [BUILD] Build break with external CMake nlohman_json package - [#2353](https://github.com/open-telemetry/opentelemetry-cpp/pull/2353) -* [BUILD] Upgrade libcurl to version 8.4.0 - [#2358](https://github.com/open-telemetry/opentelemetry-cpp/pull/2358) -* [BUILD] Fix opentracing-shim when added in super project - [#2356](https://github.com/open-telemetry/opentelemetry-cpp/pull/2356) -* [BUILD] Fix protoc searching with non-imported protobuf::protoc target - [#2362](https://github.com/open-telemetry/opentelemetry-cpp/pull/2362) -* [BUILD] Support to use different cmake package CONFIG of dependencies - [#2263](https://github.com/open-telemetry/opentelemetry-cpp/pull/2263) -* [SEMANTIC CONVENTION] Upgrade to semconv 1.22.0 - [#2368](https://github.com/open-telemetry/opentelemetry-cpp/pull/2368) - -Important changes: - -* [API] Add InstrumentationScope attributes in MeterProvider::GetMeter() - [#2224](https://github.com/open-telemetry/opentelemetry-cpp/pull/2224) - * MeterProvider::GetMeter() now accepts InstrumentationScope attributes. - * Because this is an `ABI` breaking change, the fix is only available - with the `CMake` option `WITH_ABI_VERSION_2=ON`. - * When building with `CMake` option `WITH_ABI_VERSION_1=ON` (by default) - the `ABI` is unchanged, and the fix is not available. - -Breaking changes: - -* [BUILD] Need fine-grained HAVE_CPP_STDLIB - [#2304](https://github.com/open-telemetry/opentelemetry-cpp/pull/2304) - * In `CMAKE`, the boolean option `WITH_STL` as changed to an option - that accepts the values `OFF`, `ON`, `CXX11`, `CXX14`, `CXX17`, - `CXX20` and `CXX23`. - * Applications makefiles that did not set WITH_STL need to use - `WITH_STL=OFF` instead (this is the default). - * Applications makefiles that did set WITH_STL need to use - `WITH_STL=ON` instead, or may choose to pick a specific value. - * In the `API` header files, the preprocessor symbol `HAVE_CPP_STDLIB` - is no longer used. - * Applications that did set `HAVE_CPP_STDLIB` before, need to set - `OPENTELEMETRY_STL_VERSION=` instead, to build with a - specific STL version (2011, 2014, 2017, 2020, 2023). - * The opentelemetry-cpp makefile no longer sets - CMAKE_CXX_STANDARD by itself. - Instead, the CMAKE_CXX_STANDARD and/or compiler options -stdc++ used - by the caller are honored. - * Applications that set neither CMAKE_CXX_STANDARD nor -stdc++ - options may need to provide a C++ standard in their makefiles. - -* [REMOVAL] Drop C++11 support - [#2342](https://github.com/open-telemetry/opentelemetry-cpp/pull/2342) - * Building with C++11 is no longer supported. - -Deprecations: - -* [DEPRECATION] Deprecate ZPAGES - [#2291](https://github.com/open-telemetry/opentelemetry-cpp/pull/2291) - -## [1.11.0] 2023-08-21 - -* [BUILD] Fix more cases for symbol name for 32-bit win32 DLL build - [#2264](https://github.com/open-telemetry/opentelemetry-cpp/pull/2264) -* [BUILD] added public link of `opentelemetry_proto_grpc` against gRPC lib (only - if gRPC library is shared) - [#2268](https://github.com/open-telemetry/opentelemetry-cpp/pull/2268) -* [CI] use ubuntu-latest for tsan CI - [#2267](https://github.com/open-telemetry/opentelemetry-cpp/pull/2267) -* [SDK] Fixing an apparent logging macro bug - [#2265](https://github.com/open-telemetry/opentelemetry-cpp/pull/2265) -* [BUILD] Support protobuf 3.22 or upper - [#2163](https://github.com/open-telemetry/opentelemetry-cpp/pull/2163) -* [BUILD] Remove extra includes - [#2252](https://github.com/open-telemetry/opentelemetry-cpp/pull/2252) -* [LOGS API SDK] Mark logs signal as stable API/SDK - [#2229](https://github.com/open-telemetry/opentelemetry-cpp/pull/2229) -* [SEMANTIC CONVENTIONS] Upgrade to 1.21.0 - [#2248](https://github.com/open-telemetry/opentelemetry-cpp/pull/2248) -* [SDK] Valgrind errors on std::atomic variables - [#2244](https://github.com/open-telemetry/opentelemetry-cpp/pull/2244) -* [BUILD] Fix compile with clang 16 and libc++ - [#2242](https://github.com/open-telemetry/opentelemetry-cpp/pull/2242) -* [Metrics SDK] Add unit to Instrument selection criteria - [#2236](https://github.com/open-telemetry/opentelemetry-cpp/pull/2236) -* [SDK] Add OStreamLogRecordExporterFactory - [#2240](https://github.com/open-telemetry/opentelemetry-cpp/pull/2240) -* [SDK] Add support for LowMemory metrics temporality - [#2234](https://github.com/open-telemetry/opentelemetry-cpp/pull/2234) -* [CI] Misc build scripts cleanup - [#2232](https://github.com/open-telemetry/opentelemetry-cpp/pull/2232) -* [CI] Upgrade GoogleTest version from 1.12.1 to 1.13.0 - [#2114](https://github.com/open-telemetry/opentelemetry-cpp/pull/2114) -* [BUILD] include cstdint - [#2230](https://github.com/open-telemetry/opentelemetry-cpp/pull/2230) -* [EXPORTER] Support protobuf 3.22 or upper - [#2163](https://github.com/open-telemetry/opentelemetry-cpp/pull/2163) -* [SDK] Mark logs signal as stable API/SDK - [#2229](https://github.com/open-telemetry/opentelemetry-cpp/pull/2229) - -Breaking changes: - -* [SDK] Add unit to Instrument selection criteria - [#2236](https://github.com/open-telemetry/opentelemetry-cpp/pull/2236) - * The `View` constructor and `ViewFactory::Create` method now takes a - `unit` criteria as optional third argument. - * Please adjust SDK configuration code accordingly. - -## [1.10.0] 2023-07-11 - -* [REMOVAL] Remove the jaeger exporter - [#2031](https://github.com/open-telemetry/opentelemetry-cpp/pull/2031) - -* [CI] Add a C++11 build - [#2152](https://github.com/open-telemetry/opentelemetry-cpp/pull/2152) - -* [CI] Add Include what you use - [#2214](https://github.com/open-telemetry/opentelemetry-cpp/pull/2214) - -* [CI] opentelemetry-cpp project CI - [#2071](https://github.com/open-telemetry/opentelemetry-cpp/pull/2071) - -* [CI] Do not tag pull_request with the "need-triage" label - [#2228](https://github.com/open-telemetry/opentelemetry-cpp/pull/2228) - -* [BUILD] Fixing CMake to build GTest on Windows - [#1887](https://github.com/open-telemetry/opentelemetry-cpp/pull/1887) - -* [BUILD] Remove option WITH_OTLP - [#2161](https://github.com/open-telemetry/opentelemetry-cpp/pull/2161) - -* [BUILD] Link to opentelemetry_logs even without OTLP - [#2177](https://github.com/open-telemetry/opentelemetry-cpp/pull/2177) - -* [BUILD] Avoid dependency on protobuf from the OTLP HTTP metrics exporter header - [#2179](https://github.com/open-telemetry/opentelemetry-cpp/pull/2179) - -* [BUILD] Add ctime header to metrics_exporter.cc - [#2187](https://github.com/open-telemetry/opentelemetry-cpp/pull/2187) - -* [BUILD] Fix the exported symbol name for 32-bit win32 DLL - [#2190](https://github.com/open-telemetry/opentelemetry-cpp/pull/2190) - -* [BUILD] Upgrade to opentelemetry-proto 0.20.0 - [#2195](https://github.com/open-telemetry/opentelemetry-cpp/pull/2195) - -* [BUILD] SDK Header files cleanup, use forward declarations - [#2182](https://github.com/open-telemetry/opentelemetry-cpp/pull/2182) - -* [BUILD] Enable building otel-cpp extensions from main repo - [#1937](https://github.com/open-telemetry/opentelemetry-cpp/pull/1937) - -* [BUILD] Fix if check on environment variable and add CMake variable - [#2207](https://github.com/open-telemetry/opentelemetry-cpp/pull/2207) - -* [BUILD] Add `OPENTELEMETRY_CPP_FOUND` into cmake CONFIG file - [#2215](https://github.com/open-telemetry/opentelemetry-cpp/pull/2215) - -* [BUILD] Upgrade opentelemetry-proto to 1.0.0 - [#2216](https://github.com/open-telemetry/opentelemetry-cpp/pull/2216) - -* [BUILD] Include nostd/string_view which is used in severity.h - [#2219](https://github.com/open-telemetry/opentelemetry-cpp/pull/2219) - -* [TEST] Expand api singleton test to cover explicit dlopen() - [#2164](https://github.com/open-telemetry/opentelemetry-cpp/pull/2164) - -* [API] Remove include_trace_context - [#2194](https://github.com/open-telemetry/opentelemetry-cpp/pull/2194) - -* [API] Remove Meters - [#2205](https://github.com/open-telemetry/opentelemetry-cpp/pull/2205) - -* [SDK] Add AdaptingCircularBufferCounter for exponential histograms - [#2158](https://github.com/open-telemetry/opentelemetry-cpp/pull/2158) - -* [SDK] Add base2 exponential histogram indexer - [#2173](https://github.com/open-telemetry/opentelemetry-cpp/pull/2173) - -* [SDK] Simplify SDK version - [#2180](https://github.com/open-telemetry/opentelemetry-cpp/pull/2180) - -* [SDK] Add benchmark for base2 exponential histogram indexer - [#2181](https://github.com/open-telemetry/opentelemetry-cpp/pull/2181) - -* [SDK] Provide builders to avoid exposing Metrics SDK internals - [#2189](https://github.com/open-telemetry/opentelemetry-cpp/pull/2189) - -* [SDK] MeterProvider should own MeterContext, not share it - [#2218](https://github.com/open-telemetry/opentelemetry-cpp/pull/2218) - -* [SDK] TracerProvider should own TracerContext, not share it - [#2221](https://github.com/open-telemetry/opentelemetry-cpp/pull/2221) - -* [EXPORTER] Change OTLP Json field name to camelCase - [#2162](https://github.com/open-telemetry/opentelemetry-cpp/pull/2162) - -* [EXPORTER] Support empty arrays in `OtlpRecordable` attributes - [#2166](https://github.com/open-telemetry/opentelemetry-cpp/pull/2166) - -* [EXPORTER] set is_monotonic only for instrument type kCounter - [#2171](https://github.com/open-telemetry/opentelemetry-cpp/pull/2171) - -* [EXPORTER] Fixed HTTP CURL for 32bits platforms - [#2178](https://github.com/open-telemetry/opentelemetry-cpp/pull/2178) - -* [EXPORTER] Fix OTLP HTTP exporting in sync mode - [#2193](https://github.com/open-telemetry/opentelemetry-cpp/pull/2193) - -* [EXPORTER] Prometheus exporter sanitizes invalid characters - [#1934](https://github.com/open-telemetry/opentelemetry-cpp/pull/1934) - -* [EXPORTER] Prometheus: Error on ingesting samples - with different value but same timestamp - [#2200](https://github.com/open-telemetry/opentelemetry-cpp/pull/2200) - -* [EXPORTER] OTLP GRPC mTLS support - [#2120](https://github.com/open-telemetry/opentelemetry-cpp/pull/2120) - -* [DOC] Small fix for Histogram documentation - [#2156](https://github.com/open-telemetry/opentelemetry-cpp/pull/2156) - -* [DOC] Move Reiley Yang to emeritus - [#2198](https://github.com/open-telemetry/opentelemetry-cpp/pull/2198) - -Important changes: - -* [API] Remove Meters - [#2205](https://github.com/open-telemetry/opentelemetry-cpp/pull/2205) - * The CMake option `WITH_REMOVE_METER_PREVIEW` was added. - * This option is experimental, and may change in the future. - * Enabling it is an ABI breaking change. - -Breaking changes: - -* [REMOVAL] Remove the jaeger exporter - [#2031](https://github.com/open-telemetry/opentelemetry-cpp/pull/2031) - * The CMake `WITH_JAEGER` option has been removed - * Please remove usage of `WITH_JAEGER` from user scripts and makefiles. - -* [SDK] MeterProvider should own MeterContext, not share it - [#2218](https://github.com/open-telemetry/opentelemetry-cpp/pull/2218) - * The `MeterProvider` constructor now takes a `unique_ptr` on - `MeterContext`, instead of a `shared_ptr`. - * Please adjust SDK configuration code accordingly. - -* [SDK] TracerProvider should own TracerContext, not share it - [#2221](https://github.com/open-telemetry/opentelemetry-cpp/pull/2221) - * The `TracerProvider` constructor now takes a `unique_ptr` on - `TracerContext`, instead of a `shared_ptr`. - * The `LoggerProvider` constructor now takes a `unique_ptr` on - `LoggerContext`, instead of a `shared_ptr`. - * Please adjust SDK configuration code accordingly. - -## [1.9.1] 2023-05-26 - -* [DEPRECATION] Drop C++11 support - [#2146](https://github.com/open-telemetry/opentelemetry-cpp/pull/2146) - -* [CI] Upgrade Bazel and Bazelisk version - [#2118](https://github.com/open-telemetry/opentelemetry-cpp/pull/2118) -* [CI] Upgrade Google Benchmark version from 1.6.0 to 1.7.1 - [#2116](https://github.com/open-telemetry/opentelemetry-cpp/pull/2116) -* [CI] Upgrade Nlohmann JSON library version from 3.10.5 to 3.11.2 - [#2115](https://github.com/open-telemetry/opentelemetry-cpp/pull/2115) - -* [BUILD] Missed include - [#2143](https://github.com/open-telemetry/opentelemetry-cpp/pull/2143) -* [BUILD] Add opentelemetry_proto_grpc and allow build shared - opentelemetry_proto and opentelemetry_proto_grpc on non-Windows platform. - [#2097](https://github.com/open-telemetry/opentelemetry-cpp/pull/2097) -* [BUILD] Warning cleanup, single character wrapped by std::string - [#2137](https://github.com/open-telemetry/opentelemetry-cpp/pull/2137) -* [BUILD] Add missing target dependencies - [#2128](https://github.com/open-telemetry/opentelemetry-cpp/pull/2128) -* [BUILD] Fix if JSON library already added another CMake target - [#2126](https://github.com/open-telemetry/opentelemetry-cpp/pull/2126) -* [BUILD] shared libraries with version suffix, along with the symbolic link - [#2109](https://github.com/open-telemetry/opentelemetry-cpp/pull/2109) -* [BUILD] Show warning message if WITH_OTLP is enabled - [#2112](https://github.com/open-telemetry/opentelemetry-cpp/pull/2112) -* [BUILD] Add missing STL header. - [#2107](https://github.com/open-telemetry/opentelemetry-cpp/pull/2107) -* [BUILD] Build break with old curl, macro CURL_VERSION_BITS unknown - [#2102](https://github.com/open-telemetry/opentelemetry-cpp/pull/2102) -* [BUILD] Transitive dependency issue with the otlp http exporter - [#2154](https://github.com/open-telemetry/opentelemetry-cpp/pull/2154) - -* [TEST] Add unit test for log body implicit conversions. - [#2136](https://github.com/open-telemetry/opentelemetry-cpp/pull/2136) -* [TEST] Add event id to logger benchmark method - [#2133](https://github.com/open-telemetry/opentelemetry-cpp/pull/2133) - -* [API] Fix inclusion header files and use forward declaration - [#2124](https://github.com/open-telemetry/opentelemetry-cpp/pull/2124) -* [API] Add user facing Logging API and Benchmarks - [#2094](https://github.com/open-telemetry/opentelemetry-cpp/pull/2094) - -* [SDK] SDK support for the new OTel log - [#2123](https://github.com/open-telemetry/opentelemetry-cpp/pull/2123) - -* [EXPORTER] Fixed HTTP session cleanup on shutdown - [#2111](https://github.com/open-telemetry/opentelemetry-cpp/pull/2111) -* [EXPORTER] Delegate all API calls of gRPC into - opentelemetry_exporter_otlp_grpc_client, - and make it contains all symbols needed. - [#2005](https://github.com/open-telemetry/opentelemetry-cpp/pull/2005) - -* [DOC] Add Marc as maintainer. - [#2027](https://github.com/open-telemetry/opentelemetry-cpp/pull/2027) - -Breaking changes: - -* Add opentelemetry_proto_grpc and move gRPC sources into it. - [#2097](https://github.com/open-telemetry/opentelemetry-cpp/pull/2097) - * There will be no breaking changes for users who only use OTLP exporters and - do not directly use opentelemetry-cpp::proto. However, it is important to - note that `opentelemetry-cpp::proto` no longer contains generated gRPC codes - , and all components that depend on these gRPC codes should also link to - `opentelemetry-cpp::proto_grpc`. - -Deprecations: - -* The Jaeger Exporter is deprecated, see [DEPRECATED](./DEPRECATED.md) for details. -* C++11 support is to end, C++14 will be supported instead, - see [DEPRECATED](./DEPRECATED.md) for details. - -## [1.9.0] 2023-04-12 - -* [CI] Make build environment parallel (Windows) - [#2080](https://github.com/open-telemetry/opentelemetry-cpp/pull/2080) -* [CI] Make build environment parallel (Linux) - [#2076](https://github.com/open-telemetry/opentelemetry-cpp/pull/2076) -* [CI] Remove separate run of metrics ostream example - [#2030](https://github.com/open-telemetry/opentelemetry-cpp/pull/2030) - -* [BUILD] Include directory path added for Zipkin exporter example - [#2069](https://github.com/open-telemetry/opentelemetry-cpp/pull/2069) -* [BUILD] Ignore more warning in generated protobuf files - [#2067](https://github.com/open-telemetry/opentelemetry-cpp/pull/2067) -* [BUILD] Clean warnings in ETW exporters - [#2063](https://github.com/open-telemetry/opentelemetry-cpp/pull/2063) -* [BUILD] Fix default value of OPENTELEMETRY_INSTALL_default - [#2062](https://github.com/open-telemetry/opentelemetry-cpp/pull/2062) - -* [SEMANTIC CONVENTIONS] Upgrade to version 1.20.0 - [#2088](https://github.com/open-telemetry/opentelemetry-cpp/pull/2088) -* [SEMANTIC CONVENTIONS] Upgrade to version 1.19.0 - [#2017](https://github.com/open-telemetry/opentelemetry-cpp/pull/2017) - -* [API] Checking indices before dereference in string utils - [#2040](https://github.com/open-telemetry/opentelemetry-cpp/pull/2040) -* [API] Export factory class of log provider - [#2041](https://github.com/open-telemetry/opentelemetry-cpp/pull/2041) - -* [SDK] Implement Forceflush for Periodic Metric Reader - [#2064](https://github.com/open-telemetry/opentelemetry-cpp/pull/2064) -* [SDK] Add `ForceFlush` for all `LogRecordExporter` and `SpanExporter` - [#2000](https://github.com/open-telemetry/opentelemetry-cpp/pull/2000) -* [SDK] Fix schema URL precedence bug in `Resource::Merge` - [#2036](https://github.com/open-telemetry/opentelemetry-cpp/pull/2036) -* [SDK] Use sdk_start_ts for MetricData start_ts for instruments having - cumulative aggregation temporality. - [#2086](https://github.com/open-telemetry/opentelemetry-cpp/pull/2086) - -* [EXPORTER] Add OTLP HTTP SSL support - [#1793](https://github.com/open-telemetry/opentelemetry-cpp/pull/1793) -* [EXPORTER] GRPC endpoint scheme should take precedence over OTEL_EXPORTER_OTLP_TRACES_INSECURE - [#2060](https://github.com/open-telemetry/opentelemetry-cpp/pull/2060) - -* [EXAMPLES] Remove unused 'alerting' section from prometheus.yml in examples - [#2055](https://github.com/open-telemetry/opentelemetry-cpp/pull/2055) -* [EXAMPLES] Fix view names in Prometheus example - [#2034](https://github.com/open-telemetry/opentelemetry-cpp/pull/2034) - -* [DOC] Fix some docs typo - [#2057](https://github.com/open-telemetry/opentelemetry-cpp/pull/2057) -* [DOC] Update OpenTracing shim README.md - [#2028](https://github.com/open-telemetry/opentelemetry-cpp/pull/2028) -* [DOC] INSTALL doc clarifications - [#2078](https://github.com/open-telemetry/opentelemetry-cpp/pull/2078) - -Important changes: - -* [EXPORTER] GRPC endpoint scheme should take precedence over OTEL_EXPORTER_OTLP_TRACES_INSECURE - [#2060](https://github.com/open-telemetry/opentelemetry-cpp/pull/2060) - * The logic to decide whether or not an OTLP GRPC exporter uses SSL has - changed to comply with the specification: - * Before this change, the following settings were evaluated, in order: - * OTEL_EXPORTER_OTLP_TRACES_INSECURE (starting with 1.8.3) - * OTEL_EXPORTER_OTLP_INSECURE (starting with 1.8.3) - * OTEL_EXPORTER_OTLP_TRACES_SSL_ENABLE - * OTEL_EXPORTER_OTLP_SSL_ENABLE - * With this change, the following settings are evaluated, in order: - * The GRPC endpoint scheme, if provided: - * "https" imply with SSL, - * "http" imply without ssl. - * OTEL_EXPORTER_OTLP_TRACES_INSECURE - * OTEL_EXPORTER_OTLP_INSECURE - * OTEL_EXPORTER_OTLP_TRACES_SSL_ENABLE - * OTEL_EXPORTER_OTLP_SSL_ENABLE - * As a result, a behavior change for GRPC SSL is possible, - because the endpoint scheme now takes precedence. - Please verify configuration settings for the GRPC endpoint. -* [SDK] Add `ForceFlush` for all `LogRecordExporter` and `SpanExporter` - [#2000](https://github.com/open-telemetry/opentelemetry-cpp/pull/2000) - * `LogRecordExporter` and `SpanExporter` add a new virtual function - `ForceFlush`, and if users implement any customized `LogRecordExporter` and - `SpanExporter`, they should also implement this function. - There should be no impact if users only use factory to create exporters. - -Deprecations: - -* The Jaeger Exporter is deprecated, see [DEPRECATED](./DEPRECATED.md) for details. - -## [1.8.3] 2023-03-06 - -* Provide version major/minor/patch macros - [#2014](https://github.com/open-telemetry/opentelemetry-cpp/pull/2014) -* [BUILD] Add `OPENTELEMETRY_INSTALL` to allow user to skip install targets. - [#2022](https://github.com/open-telemetry/opentelemetry-cpp/pull/2022) -* [SDK] Rename the global SDK version variables to avoid naming clash - [#2011](https://github.com/open-telemetry/opentelemetry-cpp/pull/2011) -* [BUILD] Fix typo in CMakeLists.txt - [#2010](https://github.com/open-telemetry/opentelemetry-cpp/pull/2010) -* [EXPORTER] fix Prometheus test iterator iterator increment - [#2006](https://github.com/open-telemetry/opentelemetry-cpp/pull/2006) -* [SDK]Add attributes for InstrumentationScope - [#2004](https://github.com/open-telemetry/opentelemetry-cpp/pull/2004) -* [METRICS SDK] Performance improvement in measurement processing - [#1993](https://github.com/open-telemetry/opentelemetry-cpp/pull/1993) -* [EXAMPLE] Add example for logs ostream exporter - [#1992](https://github.com/open-telemetry/opentelemetry-cpp/pull/1992) -* [ETW Exporter] Support serialize span/log attributes into JSON - [#1991](https://github.com/open-telemetry/opentelemetry-cpp/pull/1991) -* [ETW Exporter]Do not overwrite ParentId when setting attribute on Span - [#1989](https://github.com/open-telemetry/opentelemetry-cpp/pull/1989) -* Upgrade prometheus-cpp to v1.1.0 - [#1954](https://github.com/open-telemetry/opentelemetry-cpp/pull/1954) -* Convert Prometheus Exporter to Pull MetricReader - [#1953](https://github.com/open-telemetry/opentelemetry-cpp/pull/1953) -* [DOCS] Add alpine packages to INSTALL.md - [#1957](https://github.com/open-telemetry/opentelemetry-cpp/pull/1957) -* [METRICS SDK] Add benchmark tests for Sum Aggregation. - [#1948](https://github.com/open-telemetry/opentelemetry-cpp/pull/1948) -* [BUILD] Build OpenTelemetry SDK and exporters into DLL - [#1932](https://github.com/open-telemetry/opentelemetry-cpp/pull/1932) -* [CI] Enforce copyright check in CI - [#1965](https://github.com/open-telemetry/opentelemetry-cpp/pull/1965) -* [BUILD] Fix typo GENENV -> GETENV - [#1972](https://github.com/open-telemetry/opentelemetry-cpp/pull/1972) -* [SEMANTIC CONVENTIONS] Upgrade to version 1.18.0 - [#1974](https://github.com/open-telemetry/opentelemetry-cpp/pull/1974) -* [EXT] Fix thread-safety when shutdown. - [#1977](https://github.com/open-telemetry/opentelemetry-cpp/pull/1977) -* [SDK] Fix missing ObservedTimestamp. - [#1985](https://github.com/open-telemetry/opentelemetry-cpp/pull/1985) -* [METRICS SDK] fix variable names - [#1987](https://github.com/open-telemetry/opentelemetry-cpp/pull/1987) -* [EXPORTER] Fix Prometheus server crash on listening to already used port - [#1986](https://github.com/open-telemetry/opentelemetry-cpp/pull/1986) -* [EXPORTER] Boolean environment variables not parsed per the spec - [#1982](https://github.com/open-telemetry/opentelemetry-cpp/pull/1982) -* [EXPORTER] Opentracing shim - [#1909](https://github.com/open-telemetry/opentelemetry-cpp/pull/1909) - -## [1.8.2] 2023-01-31 - -* Remove redundant macro check in nostd::shared_ptr [#1939](https://github.com/open-telemetry/opentelemetry-cpp/pull/1939) -* Fix typo in packages.cmake causing incorrect nuget package versions [#1936](https://github.com/open-telemetry/opentelemetry-cpp/pull/1936) -* [METRICS] Custom Aggregation support [#1899](https://github.com/open-telemetry/opentelemetry-cpp/pull/1899) -* Small fix in INSTALL.md for enabling building package. [#1930](https://github.com/open-telemetry/opentelemetry-cpp/pull/1930) -* [METRICS] Fix warning for misconfiguration of PeriodicExportingMetricReader [#1929](https://github.com/open-telemetry/opentelemetry-cpp/pull/1929) -* Make macros.h available for all source files via version.h [#1918](https://github.com/open-telemetry/opentelemetry-cpp/pull/1918) -* [METRICS] Histogram Aggregation: Fix bucket detection logic, - performance improvements, and benchmark tests [#1869](https://github.com/open-telemetry/opentelemetry-cpp/pull/1869) -* Remove unused namespace alias for nostd [#1914](https://github.com/open-telemetry/opentelemetry-cpp/pull/1914) -* [METRICS] Update meter.h [#1907](https://github.com/open-telemetry/opentelemetry-cpp/pull/1907) -* sdk::resource::Resource::Merge should be const [#1905](https://github.com/open-telemetry/opentelemetry-cpp/pull/1905) -* [METRICS] Collect and Export metric data before - PeriodicMetricReader shutdown. [#1860](https://github.com/open-telemetry/opentelemetry-cpp/pull/1860) -* [ETW EXPORTER] Add Virtual destructor for TailSampler, Update Maintainer - mode warnings for MSVC [#1897](https://github.com/open-telemetry/opentelemetry-cpp/pull/1897) -* Fix #1867 Orderly shutdown in examples [#1868](https://github.com/open-telemetry/opentelemetry-cpp/pull/1868) -* [METRICS] minor metrics handling optimizations [#1890](https://github.com/open-telemetry/opentelemetry-cpp/pull/1890) -* fix SpinLockMutex for Intel Compiler [#1885](https://github.com/open-telemetry/opentelemetry-cpp/pull/1885) -* [LOGS] Change BatchLogRecordProcessorFactory::Create to static method [#1876](https://github.com/open-telemetry/opentelemetry-cpp/pull/1876) -* Enable generating deb, rpm, NuGet, tgz, zip package through cmake build [#1662](https://github.com/open-telemetry/opentelemetry-cpp/pull/1662) -* Updated clone command in INSTALL.md [#1818](https://github.com/open-telemetry/opentelemetry-cpp/pull/1818) -* Small cleanup to remove old metrics design docs [#1855](https://github.com/open-telemetry/opentelemetry-cpp/pull/1855) -* [BUILD] Fix build error with older version of VS2017 compiler. [1857](https://github.com/open-telemetry/opentelemetry-cpp/pull/1857) -* [EXPORTERS] Enable setting Span endtime for ETW exporter [#1846](https://github.com/open-telemetry/opentelemetry-cpp/pull/1846) -* [REMOVAL] Remove deprecated experimental semantic conventions [#1743](https://github.com/open-telemetry/opentelemetry-cpp/pull/1743) -* [EXPORTERS] Fix console debug logs for otlp exporters. [#1848](https://github.com/open-telemetry/opentelemetry-cpp/pull/1848) -* [LOGS] Add `include_trace_context` and `EventLogger` [#1884](https://github.com/open-telemetry/opentelemetry-cpp/pull/1884) -* [METRICS] Change BatchLogRecordProcessorFactory::Create to static method -* [BUILD] Fix OTELCPP_MAINTAINER_MODE [#1844](https://github.com/open-telemetry/opentelemetry-cpp/pull/1844) -* [BUILD] Fix compatibility when using clang and libc++, upgrade GTest and - cmake when using C++20 [#1852](https://github.com/open-telemetry/opentelemetry-cpp/pull/1852) -* [SEMANTIC CONVENTIONS] Upgrade to version 1.16.0 - [#1854](https://github.com/open-telemetry/opentelemetry-cpp/pull/1854) -* [SDK] BatchSpanProcessor now logs a warning when dropping a span because the - queue is full - [1871](https://github.com/open-telemetry/opentelemetry-cpp/pull/1871) -* [BUILD] Migrate from @bazel_tools//platforms to [Bazel Platforms](https://github.com/bazelbuild/platforms) - to enable Bazel 6.0.0 compatibility [#1873](https://github.com/open-telemetry/opentelemetry-cpp/pull/1873) -* [BUILD] Cleanup CMake makefiles for nlohmann_json - [#1912](https://github.com/open-telemetry/opentelemetry-cpp/pull/1912) -* [BUILD] Cleanup CMake makefiles for CURL usage - [#1916](https://github.com/open-telemetry/opentelemetry-cpp/pull/1916) -* [SEMANTIC CONVENTIONS] Upgrade to version 1.17.0 - [#1927](https://github.com/open-telemetry/opentelemetry-cpp/pull/1927) -* [MAINTAINER DOC] Define and document a deprecation process, - [DEPRECATION] Deprecate the Jaeger exporter, - implemented by [#1923](https://github.com/open-telemetry/opentelemetry-cpp/pull/1923) -* [BUILD] OTLP HTTP Exporter has build warnings in maintainer mode - [#1943](https://github.com/open-telemetry/opentelemetry-cpp/pull/1943) - -Deprecations: - -* [MAINTAINER DOC] Define and document a deprecation process, - [#1923](https://github.com/open-telemetry/opentelemetry-cpp/pull/1923) - * A new file, [DEPRECATED](./DEPRECATED.md) list all the code currently - deprecated. - * A new [deprecation process](./docs/deprecation-process.md) details the plan to - deprecate and later remove code. -* [DEPRECATION] Deprecate the Jaeger exporter - [#1923](https://github.com/open-telemetry/opentelemetry-cpp/pull/1923) - * The Jaeger Exporter is deprecated, see [DEPRECATED](./DEPRECATED.md) for details. - -Important changes: - -* [BUILD] Cleanup CMake makefiles for CURL usage - [#1916](https://github.com/open-telemetry/opentelemetry-cpp/pull/1916) - * CMake option `WITH_OTLP_HTTP` - * Before this change, the CMake option `WITH_OTLP_HTTP` was unpredictable, - sometime set to ON and sometime set to OFF by default, - depending on whether a CURL package was found or not. - The option `WITH_OTLP_HTTP` was sometime not displayed in the ccmake - UI, making it impossible to even discover there is an option of that name. - * With this change, CMake option `WITH_OTLP_HTTP` is always OFF by - default. WITH_OTLP_HTTP MUST be set to ON explicitly to build the - OTLP HTTP exporter. The option is always visible in the ccmake UI. - * CMake option `BUILD_W3CTRACECONTEXT_TEST` - * Before this change, the W3C trace context tests were built, or - not, in an unpredictable way, depending on the presence, or not, of a - CURL package. In particular, the build could ignore the W3C trace - context tests even when BUILD_W3CTRACECONTEXT_TEST=ON. - * With this change, option BUILD_W3CTRACECONTEXT_TEST is honored. - * HTTP client/server examples - * Before this change, the HTTP client/server examples were built, or - not, in an unpredictable way, depending on the presence, or not, of a - CURL package. - * With this change, a new option `WITH_EXAMPLES_HTTP` is used to - build the HTTP client/server examples. - -## [1.8.1] 2022-12-04 - -* [ETW Exporter] Tail based sampling support [#1780](https://github.com/open-telemetry/opentelemetry-cpp/pull/1780) -* [EXPORTERS] fix typo [affecting otlp exported histogram metrics max uint] [#1827](https://github.com/open-telemetry/opentelemetry-cpp/pull/1827) -* [EXPORTERS] fix enum-compare-switch warning [#1833](https://github.com/open-telemetry/opentelemetry-cpp/pull/1833) -* [METRICS] Change default temporality as "Cumulative" for OTLP metrics -exporters [#1828](https://github.com/open-telemetry/opentelemetry-cpp/pull/1828) -* [BUILD] Moved otlp_grpc_utils.cc to opentelemetry_exporter_otlp_grpc_client. -[#1829](https://github.com/open-telemetry/opentelemetry-cpp/pull/1829) -* Fix type mismatch when move nostd::shared_ptr [#1815](https://github.com/open-telemetry/opentelemetry-cpp/pull/1815) -* [BUILD] Fix Prometheus target name [#1820](https://github.com/open-telemetry/opentelemetry-cpp/pull/1820) -* Clean unused docker files [#1817](https://github.com/open-telemetry/opentelemetry-cpp/pull/1817) -* [BUILD] Fix default bazel build [#1816](https://github.com/open-telemetry/opentelemetry-cpp/pull/1816) -* [BUILD] move client::nosend under test_common [#1811](https://github.com/open-telemetry/opentelemetry-cpp/pull/1811) -* [BUILD] Fix opentelemetry-proto file exists check [#1824](https://github.com/open-telemetry/opentelemetry-cpp/pull/1824) - -## [1.8.0] 2022-11-27 - -* [DOC] Update Metrics status in README.md [#1722](https://github.com/open-telemetry/opentelemetry-cpp/pull/1722) -* [DOC] Remove misleading comments about ABI compatibility for nostd::span [#1731](https://github.com/open-telemetry/opentelemetry-cpp/pull/1731) -* [BUILD] Bump abseil-cpp for cmake CI [#1807](https://github.com/open-telemetry/opentelemetry-cpp/pull/1807) -* [Exporter] Add status code to OTLP grpc trace log [#1792](https://github.com/open-telemetry/opentelemetry-cpp/pull/1792) -* [Exporter] add fix for prometheus exporter build [#1795](https://github.com/open-telemetry/opentelemetry-cpp/pull/1795) -* [BUILD] Add option WITH_BENCHMARK to disable building benchmarks [#1794](https://github.com/open-telemetry/opentelemetry-cpp/pull/1794) -* [BUILD] Fix CI benchmark [#1799](https://github.com/open-telemetry/opentelemetry-cpp/pull/1799) -* [BUILD] bump to gRPC v1.48.1 for bazel CIs [#1786](https://github.com/open-telemetry/opentelemetry-cpp/pull/1786) -* [BUILD] Fix CI build [#1798](https://github.com/open-telemetry/opentelemetry-cpp/pull/1798) -* [BUILD] Fix clang-format in CI [#1796](https://github.com/open-telemetry/opentelemetry-cpp/pull/1796) -* Fix session lock of OtlpHttpClient [#1760](https://github.com/open-telemetry/opentelemetry-cpp/pull/1760) -* [Metrics SDK] Add MeterContext::ForEachMeter() method to process callbacks on - Meter in thread-safe manner [#1783](https://github.com/open-telemetry/opentelemetry-cpp/pull/1783) -* [DOC] Document that clang-format version 10.0 is used. [#1782](https://github.com/open-telemetry/opentelemetry-cpp/pull/1782) -* [BUILD] Upgrade bazel build to use abseil-cpp-20220623.1 [#1779](https://github.com/open-telemetry/opentelemetry-cpp/pull/1779) -* Fix GlobalLogHandler singleton creation order [#1767](https://github.com/open-telemetry/opentelemetry-cpp/pull/1767) -* [Metrics SDK] Change Prometheus CMake target name [#1765](https://github.com/open-telemetry/opentelemetry-cpp/pull/1765) -* [DOC] Cleanup INSTALL.md [#1757](https://github.com/open-telemetry/opentelemetry-cpp/pull/1757) -* [DOC] Format config options in OTLP exporter readme [#1748](https://github.com/open-telemetry/opentelemetry-cpp/pull/1748) -* [DOC] Cleanup ENABLE_METRICS_PREVIEW [#1745](https://github.com/open-telemetry/opentelemetry-cpp/pull/1745) -* [Build] Multiple CURL packages leads to invalid build (#1738) [#1739](https://github.com/open-telemetry/opentelemetry-cpp/pull/1739) -* [Metrics SDK] Cleanup ENABLE_METRICS_PREVIEW [#1735](https://github.com/open-telemetry/opentelemetry-cpp/pull/1735) -* [Logs SDK] LogProcessor, LogExporter class name [#1736](https://github.com/open-telemetry/opentelemetry-cpp/pull/1736) -* [Metrics SDK] Cleanup of old _metric api/sdk [#1734](https://github.com/open-telemetry/opentelemetry-cpp/pull/1734) -* [ETW Exporter] Fix span timestamp(s) precision to nanoseconds [#1726](https://github.com/open-telemetry/opentelemetry-cpp/pull/1726) -* [LOGS SDK] Rename LogProcessor and LogExporter to LogRecordProcessor and LogRecordExporter - [#1727](https://github.com/open-telemetry/opentelemetry-cpp/pull/1727) -* [METRICS SDK] - Remove old metrics from Github CI - [#1733](https://github.com/open-telemetry/opentelemetry-cpp/pull/1733) -* [BUILD] Add CMake OTELCPP_PROTO_PATH [#1730](https://github.com/open-telemetry/opentelemetry-cpp/pull/1730) -* [SEMANTIC CONVENTIONS] Upgrade to version 1.15.0 - [#1761](https://github.com/open-telemetry/opentelemetry-cpp/pull/1761) -* [LOGS SDK] New LogRecord and logs::Recordable implementations. - [#1766](https://github.com/open-telemetry/opentelemetry-cpp/pull/1766) - -Deprecation notes: - -* [Deprecation] Deprecate experimental semantic conventions - [#1744](https://github.com/open-telemetry/opentelemetry-cpp/pull/1744) - * The file - `api/include/opentelemetry/trace/experimental_semantic_conventions.h` - is deprecated, and will be removed in a future release. - Use file - `api/include/opentelemetry/trace/semantic_conventions.h` - instead. - - * The file - `sdk/include/opentelemetry/sdk/resource/experimental_semantic_conventions.h` - is deprecated, and will be removed in a future release. - Use file - `sdk/include/opentelemetry/sdk/resource/semantic_conventions.h` - instead. - - * The function, declared in the global namespace - `uint32_t hashCode(const char *str, uint32_t h = 0)` - is deprecated, and will be removed in a future release. - No replacement will be provided. - Note that function `opentelemetry::utils::hashCode`, - declared in the ETW exporter, is not affected by this deprecation. - -Breaking changes: - -* [SEMANTIC CONVENTIONS] Upgrade to version 1.15.0 - [#1761](https://github.com/open-telemetry/opentelemetry-cpp/pull/1761) - * Naming of semantic conventions has changed from uppercase constants, - like `SemanticConventions::SERVICE_NAME`, - to camel case, like `SemanticConventions::kServiceName`. - This is necessary to avoid collisions with macros in general, - which breaks the build on some platforms. - * Semantic conventions are flagged as experimental, - which is why this change is done in this release. - -## [1.7.0] 2022-10-28 - -* [METRICS SDK] Validate Instrument meta data (name, unit, description) [#1713](https://github.com/open-telemetry/opentelemetry-cpp/pull/1713) -* [DOCS] Document libthrift 0.12.0 doesn't work with Jaeger exporter [#1714](https://github.com/open-telemetry/opentelemetry-cpp/pull/1714) -* [Metrics SDK] Add Monotonic Property to Sum Aggregation, and -unit tests for Up Down Counter [#1675](https://github.com/open-telemetry/opentelemetry-cpp/pull/1675) -* [Metrics SDK] Move Metrics Exemplar processing behind feature flag [#1710](https://github.com/open-telemetry/opentelemetry-cpp/pull/1710) -* [Metrics API/SDK] Change Meter API/SDK to return nostd::unique_ptr - for Sync Instruments [#1707](https://github.com/open-telemetry/opentelemetry-cpp/pull/1707) -which includes breaking change in the Metrics api and sdk. -* [BUILD] Add e2e test to asan & tsan CI [#1670](https://github.com/open-telemetry/opentelemetry-cpp/pull/1670) -* [BUILD] Add otlp-grpc example bazel [#1708](https://github.com/open-telemetry/opentelemetry-cpp/pull/1708) -* [TRACE SDK] Fix debug log of OTLP HTTP exporter and ES log exporter [#1703](https://github.com/open-telemetry/opentelemetry-cpp/pull/1703) -* [METRICS SDK] Fix a potential precision loss on integer in -ReservoirCellIndexFor [#1696](https://github.com/open-telemetry/opentelemetry-cpp/pull/1696) -* [METRICS SDK] Fix Histogram crash [#1685](https://github.com/open-telemetry/opentelemetry-cpp/pull/1685) -* [METRICS SDK] Fix:1676 Segfault when short export period is used for metrics [#1682](https://github.com/open-telemetry/opentelemetry-cpp/pull/1682) -* [METRICS SDK] Add timeout support to MeterContext::ForceFlush [#1673](https://github.com/open-telemetry/opentelemetry-cpp/pull/1673) -* [DOCS] - Minor updates to OStream Metrics exporter documentation [#1679](https://github.com/open-telemetry/opentelemetry-cpp/pull/1679) -* [DOCS] Fix:#1575 API Documentation for Metrics SDK and API [#1678](https://github.com/open-telemetry/opentelemetry-cpp/pull/1678) -* [BUILD] Fixed compiler warnings [#1677](https://github.com/open-telemetry/opentelemetry-cpp/pull/1677) -* [METRICS SDK] Fix threading issue between Meter::RegisterSyncMetricStorage - and Meter::Collect [#1666](https://github.com/open-telemetry/opentelemetry-cpp/pull/1666) -* [METRICS SDK] Fix data race on MeterContext::meters_ [#1668](https://github.com/open-telemetry/opentelemetry-cpp/pull/1668) -* [METRICS SDK] Fix observable Gauge metrics generation [#1651](https://github.com/open-telemetry/opentelemetry-cpp/pull/1651) -* [BUILD] Detect ARCH=sparc in CMake [#1660](https://github.com/open-telemetry/opentelemetry-cpp/pull/1660) -* [SDK] Add user agent for OTLP http/grpc client [#1657](https://github.com/open-telemetry/opentelemetry-cpp/pull/1657) -* [BUILD] Fix clang and gcc warnings [#1658](https://github.com/open-telemetry/opentelemetry-cpp/pull/1658) -* [Metrics SDK] Add Metrics ExemplarFilter and ExemplarReservoir [#1584](https://github.com/open-telemetry/opentelemetry-cpp/pull/1584) -* [LOGS SDK] Rename OnReceive to OnEmit [#1652](https://github.com/open-telemetry/opentelemetry-cpp/pull/1652) -* [METRICS SDK] Fix Observable Gauge does not reflect updated values, -and send the old value always [#1641](https://github.com/open-telemetry/opentelemetry-cpp/pull/1641) -* [Metrics SDK] Change boundary type to double for Explicit Bucket Histogram Aggregation, -and change default bucket range [#1626](https://github.com/open-telemetry/opentelemetry-cpp/pull/1626) -* [METRICS SDK] Fix occasional Segfault with LongCounter instrument [#1638](https://github.com/open-telemetry/opentelemetry-cpp/pull/1638) -* [BUILD] Bump vcpk to 2022.08.15 [#1633](https://github.com/open-telemetry/opentelemetry-cpp/pull/1633) -* [BUILD] Bump gRPC to v1.48.1 for CMake Linux CI [#1608](https://github.com/open-telemetry/opentelemetry-cpp/pull/1608) -* [Metrics] Switch to explicit 64 bit integers [#1686](https://github.com/open-telemetry/opentelemetry-cpp/pull/1686) - which includes breaking change in the Metrics api and sdk. -* [Metrics SDK] Add support for Pull Metric Exporter [#1701](https://github.com/open-telemetry/opentelemetry-cpp/pull/1701) - which includes breaking change in the Metrics api. -* [BUILD] Add CMake OTELCPP_MAINTAINER_MODE [#1650](https://github.com/open-telemetry/opentelemetry-cpp/pull/1650) -* [SEMANTIC CONVENTIONS] Upgrade to version 1.14.0 [#1697](https://github.com/open-telemetry/opentelemetry-cpp/pull/1697) - -Notes: - -Metrics API/SDK GA release includes PRs [#1686](https://github.com/open-telemetry/opentelemetry-cpp/pull/1686), -[#1701](https://github.com/open-telemetry/opentelemetry-cpp/pull/1701), and -[#1707](https://github.com/open-telemetry/opentelemetry-cpp/pull/1707) -with breaking changes in the Metrics API and SDK. - -## [1.6.1] 2022-09-22 - -* [BUILD] Upgrade opentelemetry-proto to v0.19.0 [#1579](https://github.com/open-telemetry/opentelemetry-cpp/pull/1579) -* [METRICS EXPORTER] Add `OtlpGrpcMetricExporterFactory` and `OtlpHttpMetricExporterFactory`. - [#1606](https://github.com/open-telemetry/opentelemetry-cpp/pull/1606) -* [SEMANTIC CONVENTIONS] Upgrade to version 1.13.0 [#1624](https://github.com/open-telemetry/opentelemetry-cpp/pull/1624) -* [BUILD] Fixes span creation benchmark issue. [#1622](https://github.com/open-telemetry/opentelemetry-cpp/pull/1622) -* [BUILD] Fix more build warnings (#1616) [#1620](https://github.com/open-telemetry/opentelemetry-cpp/pull/1620) -* [SDK gRPC]: Fix out-of-bounds access of string_view in GrpcClientCarrier in - the example - [#1619](https://github.com/open-telemetry/opentelemetry-cpp/pull/1619) -* [EXPORTER ETW] Add Trace flags in SpanContext [#1618](https://github.com/open-telemetry/opentelemetry-cpp/pull/1618) -* [SDK] resource sdk: Update Resource::Merge function docs [#1615](https://github.com/open-telemetry/opentelemetry-cpp/pull/1615) -* [BUILD] Fix build warnings [#1613](https://github.com/open-telemetry/opentelemetry-cpp/pull/1613) -* [API BUILD] Fix header only api singletons (#1520) [#1604](https://github.com/open-telemetry/opentelemetry-cpp/pull/1604) -* [METRICS SDK] Fix default value of - `OtlpHttpMetricExporterOptions::aggregation_temporality`. - [#1601](https://github.com/open-telemetry/opentelemetry-cpp/pull/1601) -* [METRICS EXAMPLE] Example for OTLP gRPC exporter for Metrics. [#1598](https://github.com/open-telemetry/opentelemetry-cpp/pull/1598) -* [SDK] Fix `LoggerContext::Shutdown` and tsan of `OtlpHttpClient` [#1592](https://github.com/open-telemetry/opentelemetry-cpp/pull/1592) -* [METRICS SDK] Fix 1585 - Multiple cumulative metric collections without - measurement recording. - [#1586](https://github.com/open-telemetry/opentelemetry-cpp/pull/1586) -* [BUILD] metrics warnings [#1583](https://github.com/open-telemetry/opentelemetry-cpp/pull/1583) -* [METRICS SDK] Fix ObservableInstrument::RemoveCallback [#1582](https://github.com/open-telemetry/opentelemetry-cpp/pull/1582) -* [SDK] Add error log when getting a http error code [#1581](https://github.com/open-telemetry/opentelemetry-cpp/pull/1581) -* [EXPORTER] ETW Exporter - Add support for Sampler and ID Generator [#1547](https://github.com/open-telemetry/opentelemetry-cpp/pull/1547) - -Notes: - -While [OpenTelemetry semantic -convention](https://github.com/open-telemetry/opentelemetry-specification/tree/main/semantic_conventions) -is still in experimental state, PR -[#1624](https://github.com/open-telemetry/opentelemetry-cpp/pull/1624) upgraded -it from 1.12.0 to 1.13.0 which **MAY** break the instrumentation library. Please -update the semantic convention in instrumentation library is needed. - -## [1.6.0] 2022-08-15 - -* [METRICS SDK] Calling Observable Instruments callback during metrics - collection - [#1554](https://github.com/open-telemetry/opentelemetry-cpp/pull/1554) -* [METRICS CI] Add CI jobs for new and deprecated metrics [#1531](https://github.com/open-telemetry/opentelemetry-cpp/pull/1531) -* [METRICS BUILD] Fix metrics asan and tsan CI [#1562](https://github.com/open-telemetry/opentelemetry-cpp/pull/1562) -* [METRICS SDK] remove throw check from metrics with noexcept [#1560](https://github.com/open-telemetry/opentelemetry-cpp/pull/1560) -* [METRICS SDK] fix metrics race condition [#1552](https://github.com/open-telemetry/opentelemetry-cpp/pull/1552) -* [METRICS SDK] Fix metrics context circular reference [#1535](https://github.com/open-telemetry/opentelemetry-cpp/pull/1535) -* [METRICS EXPORTER] Improve scope/instrument names in metrics ostream exporter [#1544](https://github.com/open-telemetry/opentelemetry-cpp/pull/1544) -* [METRICS BUILD] fix IWYU error in instruments.h [#1555](https://github.com/open-telemetry/opentelemetry-cpp/pull/1555) -* [EXPORTER] Prometheus exporter support Gauge Type [#1553](https://github.com/open-telemetry/opentelemetry-cpp/pull/1553) -* [METRICS SDK] Fix default Metric view name [#1515](https://github.com/open-telemetry/opentelemetry-cpp/pull/1515) -* [SDK] Fix infinitely waiting when shutdown with more than one running http - sessions. - [#1549](https://github.com/open-telemetry/opentelemetry-cpp/pull/1549) -* [METRICS SDK] Fix OTLP gRPC Metrics env variables [#1543](https://github.com/open-telemetry/opentelemetry-cpp/pull/1543) -* [METRICS SDK] Metric aggregation temporality controls [#1541](https://github.com/open-telemetry/opentelemetry-cpp/pull/1541) -* [METRICS SDK] Histogram min/max support [#1540](https://github.com/open-telemetry/opentelemetry-cpp/pull/1540) -* [METRICS EXPORTER] ostream exporter should print out resource attributes [#1523](https://github.com/open-telemetry/opentelemetry-cpp/pull/1523) -* [METRICS SDK] Support multiple async callbacks [#1495](https://github.com/open-telemetry/opentelemetry-cpp/pull/1495) -* [BUILD] Fix code scanning alert [#1530](https://github.com/open-telemetry/opentelemetry-cpp/pull/1530) -* [BUILD] Fix several compiling/linking errors [#1539](https://github.com/open-telemetry/opentelemetry-cpp/pull/1539) -* [TRACE SDK] Add SpanData getter for Span Recordable [#1508](https://github.com/open-telemetry/opentelemetry-cpp/pull/1508) -* [LOG SDK] Fix log sdk builder (#1486) [#1524](https://github.com/open-telemetry/opentelemetry-cpp/pull/1524) -* [METRICS SDK] Add configuration options for Aggregation creation [#1513](https://github.com/open-telemetry/opentelemetry-cpp/pull/1513) -* [METRICS TEST] Fix metrics unit test memory leack [#1533](https://github.com/open-telemetry/opentelemetry-cpp/pull/1533) -* [LOG SDK] Add log sdk builders (#1486) [#1524](https://github.com/open-telemetry/opentelemetry-cpp/pull/1524) - -## [1.5.0] 2022-07-29 - -* [EXPORTER BUILD] Add resources to dep list of prometheus exporter test [#1527](https://github.com/open-telemetry/opentelemetry-cpp/pull/1527) -* [BUILD] Don't require applications using jaeger exporter to know about libcurl - [#1518](https://github.com/open-telemetry/opentelemetry-cpp/pull/1518) -* [EXPORTER] Inline print_value() in ostream exporter [#1512](https://github.com/open-telemetry/opentelemetry-cpp/pull/1512) -* [SDK] fix: urlPaser will incorrect parsing url like `http://abc.com/xxx@xxx/a/b` - [#1511](https://github.com/open-telemetry/opentelemetry-cpp/pull/1511) -* [SDK] Rename `InstrumentationLibrary` to `InstrumentationScope` [#1507](https://github.com/open-telemetry/opentelemetry-cpp/pull/1507) -* [BUILD] Try to build nlohmann-json only it's depended. [#1505](https://github.com/open-telemetry/opentelemetry-cpp/pull/1505) -* [EXPORTER BUILD] Link opentelemetry_api to ETW exporter test [#1503](https://github.com/open-telemetry/opentelemetry-cpp/pull/1503) -* [SDK] Add automatically semantic conventions from the spec (#873) [#1497](https://github.com/open-telemetry/opentelemetry-cpp/pull/1497) -* [SDK] Use template class for in-memory data. [#1496](https://github.com/open-telemetry/opentelemetry-cpp/pull/1496) -* [SDK] fix compiler warnings [#1499](https://github.com/open-telemetry/opentelemetry-cpp/pull/1499) -* [TRACE SDK] Add trace sdk builders (#1393) [#1471](https://github.com/open-telemetry/opentelemetry-cpp/pull/1471) -* [METRICS BUILD] Enable bazel build for metrics proto files [#1489](https://github.com/open-telemetry/opentelemetry-cpp/pull/1489) -* [METRICS EXPORTER] Add metrics OTLP/HTTP exporter [#1487](https://github.com/open-telemetry/opentelemetry-cpp/pull/1487) -* [EXPORTER] fix otlp grpc exporter naming [#1488](https://github.com/open-telemetry/opentelemetry-cpp/pull/1488) -* [BUILD] Remove `--config Debug` when installing. [#1480](https://github.com/open-telemetry/opentelemetry-cpp/pull/1480) -* [EXPORTER] Fix endpoint in otlp grpc exporter [#1474](https://github.com/open-telemetry/opentelemetry-cpp/pull/1474) -* [EXAMPLE] Fix memory ownership of InMemorySpanExporter (#1473) [#1471](https://github.com/open-telemetry/opentelemetry-cpp/pull/1471) -* [EXPORTER TESTS] Prometheus unit test [#1461](https://github.com/open-telemetry/opentelemetry-cpp/pull/1461) -* [DOCS] Update docs to use relative code links. [#1447](https://github.com/open-telemetry/opentelemetry-cpp/pull/1447) -* [SDK] Remove reference to deprecated InstrumentationLibrary in OTLP [#1469](https://github.com/open-telemetry/opentelemetry-cpp/pull/1469) -* [SDK] Fix trace kIsSampled flag set incorrectly [#1465](https://github.com/open-telemetry/opentelemetry-cpp/pull/1465) -* [METRICS EXPORTER] OTLP gRPC Metrics Exporter [#1454](https://github.com/open-telemetry/opentelemetry-cpp/pull/1454) -* [EXPORTER] fix prometheus exporter failure type [#1460](https://github.com/open-telemetry/opentelemetry-cpp/pull/1460) -* [SDK] Fix build warnings about missing aggregates. [#1368](https://github.com/open-telemetry/opentelemetry-cpp/pull/1368) -* [EXT] `curl::HttpClient` use `curl_multi_handle` instead of creating a thread - for every request and it's able to reuse connections now. ([#1317](https://github.com/open-telemetry/opentelemetry-cpp/pull/1317)) -* [SEMANTIC CONVENTIONS] Upgrade to version 1.12.0 [#873](https://github.com/open-telemetry/opentelemetry-cpp/pull/873) - -## [1.4.1] 2022-06-19 - -* [METRICS SDK] Fix variables inizialization [#1430](https://github.com/open-telemetry/opentelemetry-cpp/pull/1430) -* [DOCS] Fixed broken link to OpenTelemetry.io (#1445) [#1446](https://github.com/open-telemetry/opentelemetry-cpp/pull/1446) -* [BUILD] Upgrade nlohmann_json to 3.10.5 (#1438) [#1441](https://github.com/open-telemetry/opentelemetry-cpp/pull/1441) -* [METRICS SDK] fix histogram [#1440](https://github.com/open-telemetry/opentelemetry-cpp/pull/1440) -* [DOCS] Fix GettingStarted documentation for Jaeger HTTP exporter (#1347) [#1439](https://github.com/open-telemetry/opentelemetry-cpp/pull/1439) -* [BUILD] install sdk-config.h [#1419](https://github.com/open-telemetry/opentelemetry-cpp/pull/1419) -* [EXAMPLE] Log current timestamp instead of epoch time [#1434](https://github.com/open-telemetry/opentelemetry-cpp/pull/1434) -* [METRICS SDK] Add attributes/dimensions to metrics ostream exporter [#1400](https://github.com/open-telemetry/opentelemetry-cpp/pull/1400) -* [SDK] Fix global log handle symbols when using dlopen [#1420](https://github.com/open-telemetry/opentelemetry-cpp/pull/1420) -* [METRICS] Only record non-negative / finite / Non-NAN histogram values([#1427](https://github.com/open-telemetry/opentelemetry-cpp/pull/1427)) -* [ETW EXPORTER] Fix ETW log exporter header inclusion [#1426](https://github.com/open-telemetry/opentelemetry-cpp/pull/1426) -* [ETW EXPORTER] Copy string_view passed to ETW exporter in PropertyVariant [#1425](https://github.com/open-telemetry/opentelemetry-cpp/pull/1425) -* [METRICS API/SDK] Pass state to async callback function. [#1408](https://github.com/open-telemetry/opentelemetry-cpp/pull/1408) -* [BUILD] fix nlohmann_json's (third party) include dir [#1415](https://github.com/open-telemetry/opentelemetry-cpp/pull/1415) -* [SDK] fix: WaitOnSocket select error when sockfd above FD_SETSIZE [#1410](https://github.com/open-telemetry/opentelemetry-cpp/pull/1410) -* [SDK] fix OTEL_INTERNAL_LOG_INFO [#1407](https://github.com/open-telemetry/opentelemetry-cpp/pull/1407) -* [DOCS] Document Getting Started with Prometheus and Grafana [#1396](https://github.com/open-telemetry/opentelemetry-cpp/pull/1396) - -## [1.4.0] 2022-05-17 - -* [API SDK] Upgrade proto to v0.17.0, update log data model ([#1383](https://github.com/open-telemetry/opentelemetry-cpp/pull/1383)) -* [BUILD] Alpine image ([#1382](https://github.com/open-telemetry/opentelemetry-cpp/pull/1382)) -* [LOGS SDK] Get span_id from context when Logger::Log received invalid span_id - ([#1398](https://github.com/open-telemetry/opentelemetry-cpp/pull/1398)) -* [METRICS SDK] Connect async storage with async instruments ([#1388](https://github.com/open-telemetry/opentelemetry-cpp/pull/1388)) -* [DOCS] Getting started document using ostream exporter ([#1394](https://github.com/open-telemetry/opentelemetry-cpp/pull/1394)) -* [BUILD] Fix missing link to nlohmann_json ([#1390](https://github.com/open-telemetry/opentelemetry-cpp/pull/1390)) -* [SDK] Fix sharing resource in batched exported spans ([#1386](https://github.com/open-telemetry/opentelemetry-cpp/pull/1386)) -* [PROTOCOL \& LOGS] Upgrade proto to v0.17.0, update log data model ([#1383](https://github.com/open-telemetry/opentelemetry-cpp/pull/1383)) -* [METRICS SDK] Remove un-necessary files. ([#1379](https://github.com/open-telemetry/opentelemetry-cpp/pull/1379)) -* [EXPORTER] Prometheus exporter meters and instrument name ([#1378](https://github.com/open-telemetry/opentelemetry-cpp/pull/1378)) -* [API] Add noexcept/const qualifier at missing places for Trace API. ([#1374](https://github.com/open-telemetry/opentelemetry-cpp/pull/1374)) -* [SDK] Fix empty tracestate header propagation ([#1373](https://github.com/open-telemetry/opentelemetry-cpp/pull/1373)) -* [METRICS SDK] Reuse temporal metric storage for sync storage ([#1369](https://github.com/open-telemetry/opentelemetry-cpp/pull/1369)) -* [SDK] Fix baggage propagation for empty/invalid baggage context ([#1367](https://github.com/open-telemetry/opentelemetry-cpp/pull/1367)) -* [BUILD] Export opentelemetry_otlp_recordable ([#1365](https://github.com/open-telemetry/opentelemetry-cpp/pull/1365)) -* [TESTS] Disable test on prometheus-cpp which not need ([#1363](https://github.com/open-telemetry/opentelemetry-cpp/pull/1363)) -* [METRICS] Fix class member initialization order ([#1360](https://github.com/open-telemetry/opentelemetry-cpp/pull/1360)) -* [METRICS SDK] Simplify SDK Configuration: Use View with default aggregation if - no matching View is configured - ([#1358](https://github.com/open-telemetry/opentelemetry-cpp/pull/1358)) -* [BUILD] Add missing include guard ([#1357](https://github.com/open-telemetry/opentelemetry-cpp/pull/1357)) -* [ETW EXPORTER] Fix scalar delete against array ([#1356](https://github.com/open-telemetry/opentelemetry-cpp/pull/1356)) -* [ETW EXPORTER] Conditional include for codecvt header ([#1355](https://github.com/open-telemetry/opentelemetry-cpp/pull/1355)) -* [BUILD] Use latest TraceLoggingDynamic.h ([#1354](https://github.com/open-telemetry/opentelemetry-cpp/pull/1354)) -* [SDK] Add explicit type cast in baggage UrlDecode ([#1353](https://github.com/open-telemetry/opentelemetry-cpp/pull/1353)) -* [METRICS SDK] Remove exporter registration to meter provider ([#1350](https://github.com/open-telemetry/opentelemetry-cpp/pull/1350)) -* [METRICS SDK] Fix output time in metrics OStream exporter ([#1346](https://github.com/open-telemetry/opentelemetry-cpp/pull/1346)) -* [BUILD] ostream metrics cmake ([#1344](https://github.com/open-telemetry/opentelemetry-cpp/pull/1344)) -* [BUILD] Link `opentelemetry_ext` with `opentelemetry_api` ([#1336](https://github.com/open-telemetry/opentelemetry-cpp/pull/1336)) -* [METRICS SDK] Enable metric collection for Async Instruments - Delta and - Cumulative - ([#1334](https://github.com/open-telemetry/opentelemetry-cpp/pull/1334)) -* [BUILD] Dependencies image as artifact ([#1333](https://github.com/open-telemetry/opentelemetry-cpp/pull/1333)) -* [EXAMPLE] Prometheus example ([#1332](https://github.com/open-telemetry/opentelemetry-cpp/pull/1332)) -* [METRICS EXPORTER] Prometheus exporter ([#1331](https://github.com/open-telemetry/opentelemetry-cpp/pull/1331)) -* [METRICS] Metrics histogram example ([#1330](https://github.com/open-telemetry/opentelemetry-cpp/pull/1330)) -* [TESTS] Replace deprecated googletest API ([#1327](https://github.com/open-telemetry/opentelemetry-cpp/pull/1327)) -* [BUILD] Fix Ninja path ([#1326](https://github.com/open-telemetry/opentelemetry-cpp/pull/1326)) -* [API] Update yield logic for ARM processor ([#1325](https://github.com/open-telemetry/opentelemetry-cpp/pull/1325)) -* [BUILD] Fix metrics compiler warnings ([#1328](https://github.com/open-telemetry/opentelemetry-cpp/pull/1328)) -* [METRICS SDK] Implement Merge and Diff operation for Histogram Aggregation ([#1303](https://github.com/open-telemetry/opentelemetry-cpp/pull/1303)) - -Notes: - -While opentelemetry-cpp Logs are still in experimental stage, -[#1383](https://github.com/open-telemetry/opentelemetry-cpp/pull/1383) updated -opentelemetry-proto to 0.17.0, which includes some breaking change in the -protocol, like -[this](https://github.com/open-telemetry/opentelemetry-proto/pull/373). This -makes `name` parameter for our log API unnecessary. However, this parameter is -marked deprecated instead of being removed in this release, and it will be -removed in future release. - -## [1.3.0] 2022-04-11 - -* [ETW EXPORTER] ETW provider handle cleanup ([#1322](https://github.com/open-telemetry/opentelemetry-cpp/pull/1322)) -* [BUILD] Move public definitions into `opentelemetry_api`. ([#1314](https://github.com/open-telemetry/opentelemetry-cpp/pull/1314)) -* [METRICS] OStream example ([#1312](https://github.com/open-telemetry/opentelemetry-cpp/pull/1312)) -* [BUILD] Rename `http_client_curl` to `opentelemetry_http_client_curl` ([#1301](https://github.com/open-telemetry/opentelemetry-cpp/pull/1301)) -* [METRICS SDK] Add InstrumentationInfo and Resource to the metrics data to be - exported. - ([#1299](https://github.com/open-telemetry/opentelemetry-cpp/pull/1299)) -* [TESTS] Add building test without RTTI ([#1294](https://github.com/open-telemetry/opentelemetry-cpp/pull/1294)) -* [METRICS SDK] Implement periodic exporting metric reader ([#1286](https://github.com/open-telemetry/opentelemetry-cpp/pull/1286)) -* [SDK] Bugfix: span SetAttribute crash ([#1283](https://github.com/open-telemetry/opentelemetry-cpp/pull/1283)) -* [BUG] Remove implicitly deleted default constructor ([#1267](https://github.com/open-telemetry/opentelemetry-cpp/pull/1267)) -* [METRICS SDK] Synchronous Metric collection (Delta , Cumulative) ([#1265](https://github.com/open-telemetry/opentelemetry-cpp/pull/1265)) -* [METRICS SDK] Metrics exemplar round 1 ([#1264](https://github.com/open-telemetry/opentelemetry-cpp/pull/1264)) -* [EXPORTER] Fix: use CURLOPT_TIMEOUT_MS to config OtlpHttpExporter's timeout - instead of CURLOPT_TIMEOUT - ([#1261](https://github.com/open-telemetry/opentelemetry-cpp/pull/1261)) -* [EXPORTER] Jaeger Exporter - Populate Span Links ([#1251](https://github.com/open-telemetry/opentelemetry-cpp/pull/1251)) -* [SDK] Reorder the destructor of members in LoggerProvider and TracerProvider ([#1245](https://github.com/open-telemetry/opentelemetry-cpp/pull/1245)) -* [METRICS SDK] Enable metric collection from MetricReader ([#1241](https://github.com/open-telemetry/opentelemetry-cpp/pull/1241)) -* [METRICS SDK] Asynchronous Aggregation storage ([#1232](https://github.com/open-telemetry/opentelemetry-cpp/pull/1232)) -* [METRICS SDK] Synchronous Instruments - Aggregation Storage(s) creation for - configured views - ([#1219](https://github.com/open-telemetry/opentelemetry-cpp/pull/1219)) -* [BUILD] Added s390x arch into CMake build. ([#1216](https://github.com/open-telemetry/opentelemetry-cpp/pull/1216)) -* [API] Allow extension of the lifetime of ContextStorage. ([#1214](https://github.com/open-telemetry/opentelemetry-cpp/pull/1214)) -* [METRICS SDK] Add Aggregation storage ([#1213](https://github.com/open-telemetry/opentelemetry-cpp/pull/1213)) -* [TESTS] Fix ostream_log_test Mac ([#1208](https://github.com/open-telemetry/opentelemetry-cpp/pull/1208)) -* [BUILD] Update grpc to v1.43.2 to support VS2022/MSVC 19.30 and bazel 5.0 ([#1207](https://github.com/open-telemetry/opentelemetry-cpp/pull/1207)) -* [DOCS] Benchmark documentation ([#1205](https://github.com/open-telemetry/opentelemetry-cpp/pull/1205)) -* [DOCS] Fix errors in SDK documentation ([#1201](https://github.com/open-telemetry/opentelemetry-cpp/pull/1201)) -* [METRICS EXPORTER] Ostream metric exporter ([#1196](https://github.com/open-telemetry/opentelemetry-cpp/pull/1196)) -* [Metrics SDK] Filtering metrics attributes ([#1191](https://github.com/open-telemetry/opentelemetry-cpp/pull/1191)) -* [Metrics SDK] Sync and Async Instruments SDK ([#1184](https://github.com/open-telemetry/opentelemetry-cpp/pull/1184)) -* [Metrics SDK] Add Aggregation as part of metrics SDK. ([#1178](https://github.com/open-telemetry/opentelemetry-cpp/pull/1178)) -* [BUILD] Cmake: thrift requires boost headers, include them as - Boost_INCLUDE_DIRS - ([#1100](https://github.com/open-telemetry/opentelemetry-cpp/pull/1100)) - -Notes: - -[#1301](https://github.com/open-telemetry/opentelemetry-cpp/pull/1301) added -`opentelemetry_` as prefix to http_client_curl library for resolving potential -naming conflict, this could break existing cmake build if http_client_curl is -listed as explicit dependency in user's cmake file. - -## [1.2.0] 2022-01-31 - -* [CI] Continuous benchmark tests as part of the CI ([#1174](https://github.com/open-telemetry/opentelemetry-cpp/pull/1174)) -* [API] Allow to use external abseil for bazel targets ([#1172](https://github.com/open-telemetry/opentelemetry-cpp/pull/1172)) -* [EXPORTER] Importing gsl::span if std::span is not available ([#1167](https://github.com/open-telemetry/opentelemetry-cpp/pull/1167)) -* [EXPORTER] Synchronized calls to Exporter::Export & Shutdown ([#1164](https://github.com/open-telemetry/opentelemetry-cpp/pull/1164)) -* [EXPORTER] OTLP http exporter block thread ([#1163](https://github.com/open-telemetry/opentelemetry-cpp/pull/1163)) -* [TESTS] Jaeger: ThriftSender unit test ([#1162](https://github.com/open-telemetry/opentelemetry-cpp/pull/1162)) -* [EXPORTER] InMemorySpanExporter shutdown fix ([#1161](https://github.com/open-telemetry/opentelemetry-cpp/pull/1161)) -* [EXPORTER] Fix leak in Jaeger exporter ([#1160](https://github.com/open-telemetry/opentelemetry-cpp/pull/1160)) -* [TESTS] ZipkinExporter unit-tests ([#1155](https://github.com/open-telemetry/opentelemetry-cpp/pull/1155)) -* [SDK] Logger: propagating resources through LoggerProvider ([#1154](https://github.com/open-telemetry/opentelemetry-cpp/pull/1154)) -* [SDK] Logger: support for instrumentation library ([#1149](https://github.com/open-telemetry/opentelemetry-cpp/pull/1149)) -* [SDK] Add log level for internal log of sdk ([#1147](https://github.com/open-telemetry/opentelemetry-cpp/pull/1147)) -* [METRICS] Metrics SDK: View API ([#1110](https://github.com/open-telemetry/opentelemetry-cpp/pull/1110)) - -Notes on experimental features: - -[#1149](https://github.com/open-telemetry/opentelemetry-cpp/pull/1149) and -[#1154](https://github.com/open-telemetry/opentelemetry-cpp/pull/1154) from -above CHANGELOG introduced API changes which are not backward compatible with -previous logs, please update API package to this release if -`ENABLE_LOGS_PREVIEW` is turned on (it is turned off by default). - -## [1.1.1] 2021-12-20 - -* [SDK] Rename OTEL_CPP_GET_ATTR macro, and define it using fully qualified attr - function - ([#1140](https://github.com/open-telemetry/opentelemetry-cpp/pull/1140)) -* [SDK] Default resource attributes and attributes in OTEL_RESOURCE_ATTRIBUTES - are missing when using Otlp*LogExporter - ([#1082](https://github.com/open-telemetry/opentelemetry-cpp/pull/1082)) -* [METRICS] Add Meter and MeterProvider in the SDK - ([#1078](https://github.com/open-telemetry/opentelemetry-cpp/pull/1078)) -* [EXPORTER] ZipkinExporter shutdown - ([#1153](https://github.com/open-telemetry/opentelemetry-cpp/pull/1153)) -* [EXPORTER] Jaeger exporter shutdown - ([#1150](https://github.com/open-telemetry/opentelemetry-cpp/pull/1150)) -* [EXPORTER] Bugfix: `jaeger::TUDPTransport::write` crash when `getaddrinfo` - returns error - ([#1116](https://github.com/open-telemetry/opentelemetry-cpp/pull/1116)) -* [EXPORTER] Bugfix: Jaeger exporter: extend supported attributes types - ([#1106](https://github.com/open-telemetry/opentelemetry-cpp/pull/1106)) -* [EXPORTER] Fix otlp generates null span ids - ([#1113](https://github.com/open-telemetry/opentelemetry-cpp/pull/1113)) -* [EXPORTER] Jaeger bazel (Linux only) - ([#1077](https://github.com/open-telemetry/opentelemetry-cpp/pull/1077)) -* [DOCS] Add note on DLL support - ([#1137](https://github.com/open-telemetry/opentelemetry-cpp/pull/1137)) -* [DOCS] Improve the instructions for Bazel build - ([#1136](https://github.com/open-telemetry/opentelemetry-cpp/pull/1136)) -* [DOCS] Document dependencies - ([#1119](https://github.com/open-telemetry/opentelemetry-cpp/pull/1119)) -* [DOCS] Dockerfile for quick demo/troubleshooting purpose - ([#905](https://github.com/open-telemetry/opentelemetry-cpp/pull/905)) -* [TESTS] Fix data race in BM_ThreadYieldSpinLockThrashing - ([#1099](https://github.com/open-telemetry/opentelemetry-cpp/pull/1099)) -* [EXAMPLE] Otlp gRPC log example - ([#1083](https://github.com/open-telemetry/opentelemetry-cpp/pull/1083)) -* [BUILD] C++20 not Building with VS2019 - ([#1144](https://github.com/open-telemetry/opentelemetry-cpp/pull/1144)) -* [BUILD] Mark tags to bazel - targets([#1075](https://github.com/open-telemetry/opentelemetry-cpp/pull/1075)) - -## [1.1.0] 2021-11-19 - -* [BUILD] build release tarball when nlohmann-json not installed - ([#1074](https://github.com/open-telemetry/opentelemetry-cpp/pull/1074)) -* [SDK] Bugfix: regex is neither working on GCC 4.9.x - ([#1069](https://github.com/open-telemetry/opentelemetry-cpp/pull/1069)) -* [SDK] Improvement: span_id should not break strict aliasing. - ([#1068](https://github.com/open-telemetry/opentelemetry-cpp/pull/1068)) -* [EXAMPLE] OTLP HTTP log example - ([#1062](https://github.com/open-telemetry/opentelemetry-cpp/pull/1062)) -* [SDK] OTLP gRPC log export should fail after shutdown - ([#1064](https://github.com/open-telemetry/opentelemetry-cpp/pull/1064)) -* [BUILD] Building otlp exporter from the release tarball - ([#1056](https://github.com/open-telemetry/opentelemetry-cpp/pull/1056)) -* [METRICS] Move old metrics implementation to different directory, and rename - targets to \_deprecated - ([#1053](https://github.com/open-telemetry/opentelemetry-cpp/pull/1053)) -* [EXPORTER] Add OTLP/gRPC Log Exporter - ([#1048](https://github.com/open-telemetry/opentelemetry-cpp/pull/1048)) -* [EXPORTER] Prometheus Exporter - ([#1031](https://github.com/open-telemetry/opentelemetry-cpp/pull/1031)) -* [EXPORTER] Add OTLP/HTTP Log Exporter - ([#1030](https://github.com/open-telemetry/opentelemetry-cpp/pull/1030)) -* [SDK] fix: issue 368- consistent namespace scope resolution - ([#1008](https://github.com/open-telemetry/opentelemetry-cpp/pull/1008)) - -## [1.0.1] 2021-10-21 - -* [EXPORTER] Exports span attributes to ETW - ([#1021](https://github.com/open-telemetry/opentelemetry-cpp/pull/1021)) -* [BUILD] cmake: add FindThrift.cmake find module method for thrift - ([#1020](https://github.com/open-telemetry/opentelemetry-cpp/pull/1020)) -* [BUILD] Fix nlohmann_json package dependency - ([#1017](https://github.com/open-telemetry/opentelemetry-cpp/pull/1017)) -* [EXPORTER] Change OTLP/HTTP default port from 4317 to 4318 - ([#1018](https://github.com/open-telemetry/opentelemetry-cpp/pull/1018)) -* [EXPORTER] ETW Log Exporter - ([#1006](https://github.com/open-telemetry/opentelemetry-cpp/pull/1006)) -* [API] Adding new Logger:log() method - ([#1005](https://github.com/open-telemetry/opentelemetry-cpp/pull/1005)) -* [EXPORTER] Remove scheme from OTLP endpoint before passing to gRPC - ([#988](https://github.com/open-telemetry/opentelemetry-cpp/pull/988)) -* [BUILD] Update opentelemetry-proto for bazel build to 0.9.0 - ([#984](https://github.com/open-telemetry/opentelemetry-cpp/pull/984)) -* [BUILD] Cross compling grpc_cpp_plugin not found bug - ([#982](https://github.com/open-telemetry/opentelemetry-cpp/pull/982)) -* [EXPORTER] Support environment variables for both `OtlpGrpcExporter` and - `OtlpHttpExporter` - ([#983](https://github.com/open-telemetry/opentelemetry-cpp/pull/983)) -* [API/SDK] Add schema_url support to both Resource and InstrumentationLibrary - ([#979](https://github.com/open-telemetry/opentelemetry-cpp/pull/979)) -* [BUILD] Fix build issue where _memcpy_ was not declared in scope - ([#985](https://github.com/open-telemetry/opentelemetry-cpp/issues/985)) - -## [1.0.0] 2021-09-16 - -### API - -* Document DefaultSpan, remove DefaultTracer - ([#959](https://github.com/open-telemetry/opentelemetry-cpp/pull/959)) -* Separate baggage<->Context api from Baggage Propagator - ([#963](https://github.com/open-telemetry/opentelemetry-cpp/pull/963)) -* Remove unused public API to_span_ptr - ([#964](https://github.com/open-telemetry/opentelemetry-cpp/pull/964)) -* :collision: Make span context management public - ([#967](https://github.com/open-telemetry/opentelemetry-cpp/pull/967)) -* Support determining parent span from Context while creating new Span - ([#969](https://github.com/open-telemetry/opentelemetry-cpp/pull/969)) -* :collision: Traces: Add note on experimental semantic convention - implementation, prefix semantics headers with experimental tag - ([#970](https://github.com/open-telemetry/opentelemetry-cpp/pull/970)) -* Increment OPENTELEMETRY_ABI_VERSION_NO to 1 - ([#980](https://github.com/open-telemetry/opentelemetry-cpp/pull/980)) - -### SDK - -* Clean up `GetEnvironmentVariable` and remove unused variable under `NO_GETENV` - ([#976](https://github.com/open-telemetry/opentelemetry-cpp/pull/976)) -* :collision: Resources: Add note on experimental semantic convention - implementation, prefix semantics headers with experimental tag - ([#970](https://github.com/open-telemetry/opentelemetry-cpp/pull/970)) - -### OTLP Exporter - -* :bug: Ignore status description if status code is not Error - ([#962](https://github.com/open-telemetry/opentelemetry-cpp/pull/962)) -* :collision: Make Otlp exporter configuration environment variables - specs-compliant - ([#974](https://github.com/open-telemetry/opentelemetry-cpp/pull/974)) - -### Zipkin Exporter - -* :bug: Don't set parentId in case parentId is empty - ([#943](https://github.com/open-telemetry/opentelemetry-cpp/pull/943)) -* :rocket: Extend zipkin exporter with ability to provide headers - ([#951](https://github.com/open-telemetry/opentelemetry-cpp/pull/951)) - -### DOCS - -* :book: Add getting-started documentation for SDK: - ([#942](https://github.com/open-telemetry/opentelemetry-cpp/pull/942)) -* :book: Remove unnecessary spaces and spelling of gRPC in README - ([#965](https://github.com/open-telemetry/opentelemetry-cpp/pull/965)) - -### BUILD - -* Disable bazel build for gcc 4.8, upgrade versions for grpc(v1.39.1) and - bazel(4.2.0), document bazel support - ([#953](https://github.com/open-telemetry/opentelemetry-cpp/pull/953)) -* Move CMake config template to cmake folder - ([#958](https://github.com/open-telemetry/opentelemetry-cpp/pull/958)) -* Enable CMake to search the new package variable `_ROOT` - ([#975](https://github.com/open-telemetry/opentelemetry-cpp/pull/975)) -* :bug: Do not override CMAKE_CXX_STANDARD - ([#977](https://github.com/open-telemetry/opentelemetry-cpp/pull/977)) - -### :construction: Experiemental Features (Will change in future) - -* Semantic Conventions for traces - As the specs is still experimental, the - implementation will change in future. -* Semantic Convention for resource - As the specs is still experimental, the - implementation will change in future. -* Logs and Metrics API & SDK - These are not compliant, and are behind feature - flag. Not recommended to use for now. - -## [1.0.0-rc4] 2021-08-04 - -* [EXPORTER] `BREAKING CHANGE` Fix default HTTP port for OTLP HTTP Exporter - ([#939](https://github.com/open-telemetry/opentelemetry-cpp/pull/939)) -* [API] Fix timeout calculation for Tracer::Flush() and Tracer::Close() - ([#937](https://github.com/open-telemetry/opentelemetry-cpp/pull/937)) -* [API] Fix for Stack::Resize that new_capacity is not assigned to capacity_ - ([#934](https://github.com/open-telemetry/opentelemetry-cpp/pull/934)) -* [SDK] Fix race condition in circular buffer simulation test - ([#931](https://github.com/open-telemetry/opentelemetry-cpp/pull/931)) -* [EXPORTER] Fix error logging in Jaeger Exporter - ([#930](https://github.com/open-telemetry/opentelemetry-cpp/pull/930)) -* [BUILD] Use latest grpc version (v1.39.0) for cmake build of otlp exporter - ([#927](https://github.com/open-telemetry/opentelemetry-cpp/pull/927)) -* [EXPORTER] Add Jaeger Thrift HTTP exporter - ([#926](https://github.com/open-telemetry/opentelemetry-cpp/pull/926)) -* [SDK] Move env-var read logic to common dir, and optional reading of env-var - ([#924](https://github.com/open-telemetry/opentelemetry-cpp/pull/924)) -* [EXPORTER] Remove recordable header from CMake install rules for exporters - ([#923](https://github.com/open-telemetry/opentelemetry-cpp/pull/923)) -* [EXPORTER] `BREAKING CHANGE` Rename Recordable to JaegerRecordable in Jaeger - exporter - ([#919](https://github.com/open-telemetry/opentelemetry-cpp/pull/919)) -* [EXPORTER] `BREAKING CHANGE` Rename Jaeger exporter target - ([#918](https://github.com/open-telemetry/opentelemetry-cpp/pull/918)) -* [EXPORTER] Add Zipkin exporter example - ([#917](https://github.com/open-telemetry/opentelemetry-cpp/pull/917)) -* [EXPORTER] Bazel build for Zipkin exorter - ([#916](https://github.com/open-telemetry/opentelemetry-cpp/pull/916)) -* [BUILD] Allow to use local GSL - ([#915](https://github.com/open-telemetry/opentelemetry-cpp/pull/915)) -* [DOCS] Document vcpkg toolchain configuration - ([#913](https://github.com/open-telemetry/opentelemetry-cpp/pull/913)) -* [SDK] Fix for resource deletion after tracer provider shutdown - ([#911](https://github.com/open-telemetry/opentelemetry-cpp/pull/911)) -* [BUILD] Add bazel build for grpc example - ([#910](https://github.com/open-telemetry/opentelemetry-cpp/pull/910)) -* [EXPORTER] Add resource and instrumentation library support for - OStreamSpanExporter - ([#906](https://github.com/open-telemetry/opentelemetry-cpp/pull/906)) -* [API] Adding semantic-convention attributes for trace - ([#868](https://github.com/open-telemetry/opentelemetry-cpp/pull/868)) - -## [1.0.0-rc3] 2021-07-12 - -* [DOCS] Add doxygen reference docs for SDK - ([#902](https://github.com/open-telemetry/opentelemetry-cpp/pull/902)) -* [EXPORTER] Jaeger Exporter - Populate resource attributes into process tags in - Jaeger ([#897](https://github.com/open-telemetry/opentelemetry-cpp/pull/897)) -* [EXPORTER] Zipkin Exporter - Report Event timestamp into microseconds - ([#896](https://github.com/open-telemetry/opentelemetry-cpp/pull/896)) -* [EXPORTER] Jaeger Exporter - Handle span events - ([#895](https://github.com/open-telemetry/opentelemetry-cpp/pull/895)) -* [DOCS] Fix API docs for Scope object - ([#894](https://github.com/open-telemetry/opentelemetry-cpp/pull/894)) -* [BUILD] Fix Linking error for libcurl on some macOS environments - ([#893](https://github.com/open-telemetry/opentelemetry-cpp/pull/893)) -* [API] Context cleanup from Runtime Storage - ([#885](https://github.com/open-telemetry/opentelemetry-cpp/pull/885)) -* [DOCS] Document strategy to avoid conflict between two different versions of - Abseil ([#883](https://github.com/open-telemetry/opentelemetry-cpp/pull/883/)) -* [EXPORTER] ETW Exporter - Document example for ETW Exporter - ([#882](https://github.com/open-telemetry/opentelemetry-cpp/pull/882)) -* [SDK] Create Span with Valid spanId and traceId irrespective of Sampling - decision - ([#879](https://github.com/open-telemetry/opentelemetry-cpp/pull/879)) -* [EXPORTER] Jaeger Exporter - Rename bswap macros to avoid clash on some - systems ([#876](https://github.com/open-telemetry/opentelemetry-cpp/pull/876)) -* [API] Add Semantics Conventions attributes for Resources - ([#872](https://github.com/open-telemetry/opentelemetry-cpp/pull/872)) -* [BUILD] Use nlohmann-json from submodules if not already installed - ([#870](https://github.com/open-telemetry/opentelemetry-cpp/pull/870)) - -## [1.0.0-rc2] 2021-06-18 - -* [EXPORTER] Jaeger Exporter - Support for Instrumentation Library - ([#864](https://github.com/open-telemetry/opentelemetry-cpp/pull/864)) -* [TESTS] Adding benchmark tests for baggage api - ([#861](https://github.com/open-telemetry/opentelemetry-cpp/pull/861)) -* [BUILD] Fix for GCC9/C++20 Support for using STL for modern C++ features - ([#860](https://github.com/open-telemetry/opentelemetry-cpp/pull/860)) -* [TESTS] Adding benchmark tests for span create api - ([#856](https://github.com/open-telemetry/opentelemetry-cpp/pull/856)) -* [BUILD] Fix for using Abseil library for modern C++ features - ([#850](https://github.com/open-telemetry/opentelemetry-cpp/pull/850)) -* [BUILD] Fix issues with win32/x86 compilation - ([#847](https://github.com/open-telemetry/opentelemetry-cpp/pull/847)) -* [DOCS] Document OSS dependencies and their licenses - ([#844](https://github.com/open-telemetry/opentelemetry-cpp/pull/844)) -* [BUILD] Various fixes to build with Visual Studio 2015 - ([#840](https://github.com/open-telemetry/opentelemetry-cpp/pull/840)) -* [INSTRUMENTATION] HTTPClient: Change support for full URL argument - ([#833](https://github.com/open-telemetry/opentelemetry-cpp/pull/833)) -* [EXPORTER] Jaeger Exporter - fix endianness of Jaeger IDs for transmission - ([#832](https://github.com/open-telemetry/opentelemetry-cpp/pull/832)) -* [INSTRUMENTATION] fix protobuf compilation warning in gRPC example - ([#830](https://github.com/open-telemetry/opentelemetry-cpp/pull/830)) -* [EXPORTER] `BREAKING CHANGE` - Add OTLP/HTTP+JSON Protocol exporter; Rename - `OtlpExporter` to `OtlpGrpcExporter` - ([#810](https://github.com/open-telemetry/opentelemetry-cpp/pull/810)) - -## [1.0.0-rc1] 2021-06-04 - -* [BUILD] Enable Jaeger exporter build in Windows - ([#815](https://github.com/open-telemetry/opentelemetry-cpp/pull/815)) -* [DOCS] Versioning doc update to clarify release and versioning policy - ([#811](https://github.com/open-telemetry/opentelemetry-cpp/pull/811)) -* [LOGS] Move Logging implementation under feature-flag - ([#807](https://github.com/open-telemetry/opentelemetry-cpp/pull/807)) -* [BUILD] Filter metric headers files from `opentelemetry-api` and - `opentelemetry-sdk` targets if metrics feature-flag is disabled - ([#806](https://github.com/open-telemetry/opentelemetry-cpp/pull/806)) -* [BUILD] Fix install rule for ostream exporter, Jaeger, ETW, ElasticSearch - ([#805](Fix install rule for header files of ostream exporter)) -* [API/SDK] Switch from mpark::variant to absl::variant as default - ([#771](https://github.com/open-telemetry/opentelemetry-cpp/pull/771)) -* [API/SDK] Support `const char *` as acceptable data type for attributes and - resources - ([#771](https://github.com/open-telemetry/opentelemetry-cpp/pull/771)) -* [EXAMPLE] gRPC instrumentation example with context propagation - ([#729](https://github.com/open-telemetry/opentelemetry-cpp/pull/729)) - -## [0.7.0] 2021-05-26 - -* [METRICS] Move metrics api/sdk under preview feature flag - ([#745](https://github.com/open-telemetry/opentelemetry-cpp/pull/745)) -* [DOCS] Add instructions to build using Bazel - ([#747](https://github.com/open-telemetry/opentelemetry-cpp/pull/747)) -* [DOCS] Update copyright headers - ([#754](https://github.com/open-telemetry/opentelemetry-cpp/pull/754)) -* [EXPORTER] Populate resource to OTLP proto data - ([#758](https://github.com/open-telemetry/opentelemetry-cpp/pull/758)) -* [CI] Add CodeQL security scan CI workflow - ([#770](https://github.com/open-telemetry/opentelemetry-cpp/pull/770)) -* [BUILD] Enable building API only CMake Project - ([#778](https://github.com/open-telemetry/opentelemetry-cpp/pull/778)) -* [SDK] Fix for sampling of root span - ([#784](https://github.com/open-telemetry/opentelemetry-cpp/pull/784)) -* [CI] Add Jaeger exporter to CMake CI build - ([#786](https://github.com/open-telemetry/opentelemetry-cpp/pull/786)) -* [API] `BREAKING CHANGE` - Tracer::WithActiveSpan() to return Scope object - intead of unique_ptr - ([#788](https://github.com/open-telemetry/opentelemetry-cpp/pull/788)) -* [DOCS] Add docs for nested spans and context propagation in readthedocs - ([#792](https://github.com/open-telemetry/opentelemetry-cpp/pull/792)) -* [CI] Output verbose error for failed unit-test in CI - ([#796](https://github.com/open-telemetry/opentelemetry-cpp/pull/796)) - -## [0.6.0] 2021-05-11 - -* [EXPORTER] Add Jaeger exporter - ([#534](https://github.com/open-telemetry/opentelemetry-cpp/pull/534)) -* [SDK] Support multiple processors - ([#692](https://github.com/open-telemetry/opentelemetry-cpp/pull/692)) -* [SDK] Add instrumentation library and multiple tracer support - ([#693](https://github.com/open-telemetry/opentelemetry-cpp/pull/693)) -* [SDK] Resource integration with Exporters - ([#706](https://github.com/open-telemetry/opentelemetry-cpp/pull/706)) -* [EXAMPLE] Enhance existing http example with propagation - ([#727](https://github.com/open-telemetry/opentelemetry-cpp/pull/727)) - -## [0.5.0] 2021-04-26 - -* [SDK] Support custom span-id and trace-id generator - ([#681](https://github.com/open-telemetry/opentelemetry-cpp/pull/681)) -* [SDK] Add SpanContext (and TraceState) to Recordable - ([#667](https://github.com/open-telemetry/opentelemetry-cpp/pull/667)) -* [SDK] Global Propagator - ([#668](https://github.com/open-telemetry/opentelemetry-cpp/pull/668)) -* [SDK] Create SharedContext for updating span pipeline - ([#650](https://github.com/open-telemetry/opentelemetry-cpp/pull/650)) -* [API] Baggage implementation - ([#676](https://github.com/open-telemetry/opentelemetry-cpp/pull/676)) -* [API] Move class from opentelemetry::core namespace to opentelemetry::common - namespace - ([#686](https://github.com/open-telemetry/opentelemetry-cpp/pull/686)) - -## [0.4.0] 2021-04-12 - -* [EXPORTER] ETW Exporter enhancements - ([#519](https://github.com/open-telemetry/opentelemetry-cpp/pull/519)) -* [EXPORTER] Read Zipkin endpoint from environment variable. - ([#624](https://github.com/open-telemetry/opentelemetry-cpp/pull/624)) -* [EXPORTER] Split Zpages webserver hosting from Exporter - ([#626](https://github.com/open-telemetry/opentelemetry-cpp/pull/626)) -* [EXPORTER] ETW Exporter Usage Instructions - ([#628](https://github.com/open-telemetry/opentelemetry-cpp/pull/628)) -* [INSTRUMENTATION] HTTP Client/Server Instrumentation example - ([#632](https://github.com/open-telemetry/opentelemetry-cpp/pull/632)) -* [EXPORTER] Enable tls authentication for otlp grpc exporter ([#635](Enable tls - authentication for otlp grpc exporter)) -* [API] Refactoring trace_state to reuse common functionality in baggage - ([#638](https://github.com/open-telemetry/opentelemetry-cpp/pull/638/files)) - -## [0.3.0] 2021-03-19 - -* [EXPORTER] Added Zipkin Exporter. - ([#471](https://github.com/open-telemetry/opentelemetry-cpp/pull/471)) -* [API] Added Jaeger propagator. - ([#599](https://github.com/open-telemetry/opentelemetry-cpp/pull/599)) -* [PROPAGATOR] Added Composite Propagator - ([#597](https://github.com/open-telemetry/opentelemetry-cpp/pull/597)) -* [API] Propagate traceflag from parent - ([#603](https://github.com/open-telemetry/opentelemetry-cpp/pull/603)) -* [DOCS] Add sphinx support for api doc generation - ([595](https://github.com/open-telemetry/opentelemetry-cpp/pull/595)) -* [SDK] Add service.name if missing in Resource - ([#616](https://github.com/open-telemetry/opentelemetry-cpp/pull/616)) - -## [0.2.0] 2021-03-02 - -* [SDK] Added `ForceFlush` to `TracerProvider`. - ([#588](https://github.com/open-telemetry/opentelemetry-cpp/pull/588)). -* [SDK] Added Resource API. - ([#502](https://github.com/open-telemetry/opentelemetry-cpp/pull/502)) -* [API] Modified TraceState support for w3c trace context as per specs. -* [SDK] TraceState implementation as per spec - ([#551](https://github.com/open-telemetry/opentelemetry-cpp/pull/551)) -* [API] Added B3 Propagator. - ([#523](https://github.com/open-telemetry/opentelemetry-cpp/pull/523)) -* [Exporter] Added ETW Exporter. - ([#376](https://github.com/open-telemetry/opentelemetry-cpp/pull/376)) -* [CI] Enable cache for Bazel for faster builds. - ([#505](https://github.com/open-telemetry/opentelemetry-cpp/pull/505)) - -## [0.0.1] 2020-12-16 - -### Added - -* Trace API and SDK experimental -* OTLP Exporter - -### Changed - -### Removed diff --git a/ext/opentelemetry-cpp-1.21.0/CMakeLists.txt b/ext/opentelemetry-cpp-1.21.0/CMakeLists.txt deleted file mode 100644 index 4e65f0493..000000000 --- a/ext/opentelemetry-cpp-1.21.0/CMakeLists.txt +++ /dev/null @@ -1,927 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.14) - -# See https://cmake.org/cmake/help/latest/policy/CMP0074.html required by -# certain version of zlib which CURL depends on. -if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12") - cmake_policy(SET CMP0074 NEW) -endif() - -# Allow to use normal variable for option() -if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13") - cmake_policy(SET CMP0077 NEW) -endif() - -# Prefer CMAKE_MSVC_RUNTIME_LIBRARY if possible -if(POLICY CMP0091) - cmake_policy(SET CMP0091 NEW) -endif() - -if(POLICY CMP0092) - # https://cmake.org/cmake/help/latest/policy/CMP0092.html#policy:CMP0092 Make - # sure the /W3 is not removed from CMAKE_CXX_FLAGS since CMake 3.15 - cmake_policy(SET CMP0092 OLD) -endif() - -# MSVC RTTI flag /GR should not be not added to CMAKE_CXX_FLAGS by default. @see -# https://cmake.org/cmake/help/latest/policy/CMP0117.html -if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.20.0") - cmake_policy(SET CMP0117 NEW) -endif() - -project(opentelemetry-cpp) - -# Mark variables as used so cmake doesn't complain about them -mark_as_advanced(CMAKE_TOOLCHAIN_FILE) - -# Note: CMAKE_FIND_PACKAGE_PREFER_CONFIG requires cmake 3.15. Prefer cmake -# CONFIG search mode to find dependencies. This is important to properly find -# protobuf versions 3.22.0 and above due to the abseil-cpp dependency. -set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) - -# Don't use customized cmake modules if vcpkg is used to resolve dependence. -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) - list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/") -endif() - -if(EXISTS "${CMAKE_SOURCE_DIR}/third_party_release") - file(STRINGS "${CMAKE_SOURCE_DIR}/third_party_release" third_party_tags) - foreach(third_party ${third_party_tags}) - string(REGEX REPLACE "^[ ]+" "" third_party ${third_party}) - string(REGEX MATCH "^[^=]+" third_party_name ${third_party}) - string(REPLACE "${third_party_name}=" "" third_party_tag ${third_party}) - set(${third_party_name} "${third_party_tag}") - endforeach() -endif() - -if(DEFINED ENV{ARCH}) - # Architecture may be specified via ARCH environment variable - set(ARCH $ENV{ARCH}) -else() - # Autodetection logic that populates ARCH variable - if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*") - # Windows may report AMD64 even if target is 32-bit - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(ARCH x64) - elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) - set(ARCH x86) - endif() - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*") - # Windows may report x86 even if target is 64-bit - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(ARCH x64) - elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) - set(ARCH x86) - endif() - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "powerpc") - # AIX will report the processor as 'powerpc' even if building in 64-bit mode - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(ARCH ppc64) - else() - set(ARCH ppc32) - endif() - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES - "^(aarch64.*|AARCH64.*|arm64.*|ARM64.*)") - set(ARCH arm64) - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)") - set(ARCH arm) - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le") - set(ARCH ppc64le) - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64") - set(ARCH ppc64) - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(mips.*|MIPS.*)") - set(ARCH mips) - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(riscv.*|RISCV.*)") - set(ARCH riscv) - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x.*|S390X.*)") - set(ARCH s390x) - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(sparc.*|SPARC.*)") - set(ARCH sparc) - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(loongarch.*|LOONGARCH.*)") - set(ARCH loongarch) - else() - message( - FATAL_ERROR - "opentelemetry-cpp: unrecognized target processor ${CMAKE_SYSTEM_PROCESSOR} configuration!" - ) - endif() -endif() -message(STATUS "Building for architecture ARCH=${ARCH}") - -# Autodetect vcpkg toolchain -if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE) - set(CMAKE_TOOLCHAIN_FILE - "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" - CACHE STRING "") -endif() - -if(VCPKG_CHAINLOAD_TOOLCHAIN_FILE) - include("${VCPKG_CHAINLOAD_TOOLCHAIN_FILE}") -endif() - -option(WITH_ABI_VERSION_1 "ABI version 1" ON) -option(WITH_ABI_VERSION_2 "EXPERIMENTAL: ABI version 2 preview" OFF) - -file(READ "${CMAKE_CURRENT_LIST_DIR}/api/include/opentelemetry/version.h" - OPENTELEMETRY_CPP_HEADER_VERSION_H) - -# -# We do not want to have WITH_ABI_VERSION = "1" or "2", and instead prefer two -# distinct flags, WITH_ABI_VERSION_1 and WITH_ABI_VERSION_2. -# -# This allows: -# -# * to have a specific option description for each ABI -# * to mark experimental/stable/deprecated on flags, for clarity -# * to search for exact abi usage move easily, discouraging: -# -# * cmake -DWITH_ABI_VERSION=${ARG} -# -# While not supported, having distinct WITH_ABI_VERSION_1 and WITH_ABI_VERSION_2 -# flags also opens the possibility to support multiple ABI concurrently, should -# that become necessary. -# -if(WITH_ABI_VERSION_1 AND WITH_ABI_VERSION_2) - # - # Only one ABI is supported in a build. - # - message( - FATAL_ERROR "Set either WITH_ABI_VERSION_1 or WITH_ABI_VERSION_2, not both") -endif() - -if(WITH_ABI_VERSION_2) - set(OPENTELEMETRY_ABI_VERSION_NO "2") -elseif(WITH_ABI_VERSION_1) - set(OPENTELEMETRY_ABI_VERSION_NO "1") -else() - if(OPENTELEMETRY_CPP_HEADER_VERSION_H MATCHES - "OPENTELEMETRY_ABI_VERSION_NO[ \t\r\n]+\"?([0-9]+)\"?") - math(EXPR OPENTELEMETRY_ABI_VERSION_NO ${CMAKE_MATCH_1}) - else() - message( - FATAL_ERROR - "OPENTELEMETRY_ABI_VERSION_NO not found on ${CMAKE_CURRENT_LIST_DIR}/api/include/opentelemetry/version.h" - ) - endif() -endif() - -message(STATUS "OPENTELEMETRY_ABI_VERSION_NO=${OPENTELEMETRY_ABI_VERSION_NO}") - -if(OPENTELEMETRY_CPP_HEADER_VERSION_H MATCHES - "OPENTELEMETRY_VERSION[ \t\r\n]+\"?([^\"]+)\"?") - set(OPENTELEMETRY_VERSION ${CMAKE_MATCH_1}) -else() - message( - FATAL_ERROR - "OPENTELEMETRY_VERSION not found on ${CMAKE_CURRENT_LIST_DIR}/api/include/opentelemetry/version.h" - ) -endif() - -message(STATUS "OPENTELEMETRY_VERSION=${OPENTELEMETRY_VERSION}") - -option(WITH_NO_DEPRECATED_CODE "Do not include deprecated code" OFF) - -set(WITH_STL - "OFF" - CACHE STRING "Which version of the Standard Library for C++ to use") - -option(WITH_GSL - "Whether to use Guidelines Support Library for C++ latest features" OFF) - -set(OPENTELEMETRY_INSTALL_default ON) -if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - set(OPENTELEMETRY_INSTALL_default OFF) -endif() -option(OPENTELEMETRY_INSTALL "Whether to install opentelemetry targets" - ${OPENTELEMETRY_INSTALL_default}) - -include("${PROJECT_SOURCE_DIR}/cmake/tools.cmake") - -if(NOT WITH_STL STREQUAL "OFF") - # These definitions are needed for test projects that do not link against - # opentelemetry-api library directly. We ensure that variant implementation - # (absl::variant or std::variant) in variant unit test code is consistent with - # the global project build definitions. Optimize for speed to reduce the hops - if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - if(CMAKE_BUILD_TYPE MATCHES Debug) - # Turn off optimizations for DEBUG - set(MSVC_CXX_OPT_FLAG "/Od") - else() - string(REGEX MATCH "\/O" result ${CMAKE_CXX_FLAGS}) - if(NOT ${result} MATCHES "\/O") - set(MSVC_CXX_OPT_FLAG "/O2") - endif() - endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MSVC_CXX_OPT_FLAG}") - endif() -endif() - -option(WITH_OTLP_RETRY_PREVIEW - "Whether to enable experimental retry functionality" OFF) - -option(WITH_OTLP_GRPC_SSL_MTLS_PREVIEW - "Whether to enable mTLS support fro gRPC" OFF) - -option(WITH_OTLP_GRPC "Whether to include the OTLP gRPC exporter in the SDK" - OFF) - -option(WITH_OTLP_HTTP "Whether to include the OTLP http exporter in the SDK" - OFF) - -option(WITH_OTLP_FILE "Whether to include the OTLP file exporter in the SDK" - OFF) - -option( - WITH_OTLP_HTTP_COMPRESSION - "Whether to include gzip compression for the OTLP http exporter in the SDK" - OFF) - -option(WITH_CURL_LOGGING "Whether to enable select CURL verbosity in OTel logs" - OFF) - -option(WITH_ZIPKIN "Whether to include the Zipkin exporter in the SDK" OFF) - -option(WITH_PROMETHEUS "Whether to include the Prometheus Client in the SDK" - OFF) - -option(WITH_ELASTICSEARCH - "Whether to include the Elasticsearch Client in the SDK" OFF) - -option(WITH_NO_GETENV "Whether the platform supports environment variables" OFF) - -option(BUILD_TESTING "Whether to enable tests" ON) - -option(WITH_BENCHMARK "Whether to build benchmark program" ON) - -option(BUILD_W3CTRACECONTEXT_TEST "Whether to build w3c trace context" OFF) - -option(OTELCPP_MAINTAINER_MODE "Build in maintainer mode (-Wall -Werror)" OFF) - -option(WITH_OPENTRACING "Whether to include the Opentracing shim" OFF) - -option(OTELCPP_VERSIONED_LIBS "Whether to generate the versioned shared libs" - OFF) - -# -# This option is experimental, subject to change in the spec: -# -# * https://github.com/open-telemetry/opentelemetry-specification/issues/2232 -# -option(WITH_REMOVE_METER_PREVIEW - "EXPERIMENTAL, ABI BREAKING: Allow to remove a meter" OFF) - -if(OTELCPP_VERSIONED_LIBS AND NOT BUILD_SHARED_LIBS) - message(FATAL_ERROR "OTELCPP_VERSIONED_LIBS=ON requires BUILD_SHARED_LIBS=ON") -endif() - -if(WIN32) - option(WITH_ETW "Whether to include the ETW Exporter in the SDK" ON) -else() - if(DEFINED (WITH_ETW)) - message(FATAL_ERROR "WITH_ETW is only supported on Windows") - endif() -endif(WIN32) - -# Do not convert deprecated message to error -if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") - add_compile_options(-Wno-error=deprecated-declarations) -endif() - -option( - WITH_API_ONLY - "Only build the API (use as a header-only library). Overrides WITH_EXAMPLES and all options to enable exporters" - OFF) -option(WITH_EXAMPLES "Whether to build examples" ON) - -# This requires CURL, OFF by default. -option( - WITH_EXAMPLES_HTTP - "Whether to build http client/server examples. Requires WITH_EXAMPLES and CURL" - OFF) - -option(WITH_FUNC_TESTS "Whether to build functional tests" ON) - -option(WITH_ASYNC_EXPORT_PREVIEW "Whether to enable async export" OFF) - -# Exemplar specs status is experimental, so behind feature flag by default -option(WITH_METRICS_EXEMPLAR_PREVIEW - "Whether to enable exemplar within metrics" OFF) - -# Experimental, so behind feature flag by default -option(WITH_THREAD_INSTRUMENTATION_PREVIEW - "Whether to enable thread instrumentation" OFF) - -option(OPENTELEMETRY_SKIP_DYNAMIC_LOADING_TESTS - "Whether to build test libraries that are always linked as shared libs" - OFF) - -# -# Verify options dependencies -# - -if(WITH_EXAMPLES_HTTP AND NOT WITH_EXAMPLES) - message(FATAL_ERROR "WITH_EXAMPLES_HTTP=ON requires WITH_EXAMPLES=ON") -endif() - -find_package(Threads) - -function(install_windows_deps) - # Bootstrap vcpkg from CMake and auto-install deps in case if we are missing - # deps on Windows. Respect the target architecture variable. - set(VCPKG_TARGET_ARCHITECTURE - ${ARCH} - PARENT_SCOPE) - message(STATUS "Installing build tools and dependencies...") - set(ENV{ARCH} ${ARCH}) - execute_process( - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/setup-buildtools.cmd) - set(CMAKE_TOOLCHAIN_FILE - ${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/scripts/buildsystems/vcpkg.cmake - CACHE FILEPATH "") - message( - STATUS - "Make sure that vcpkg.cmake is set as the CMAKE_TOOLCHAIN_FILE at the START of the cmake build process! - Can be command-line arg (cmake -DCMAKE_TOOLCHAIN_FILE=...) or set in your editor of choice." - ) - -endfunction() - -function(set_target_version target_name) - if(OTELCPP_VERSIONED_LIBS) - set_target_properties( - ${target_name} PROPERTIES VERSION ${OPENTELEMETRY_VERSION} - SOVERSION ${OPENTELEMETRY_ABI_VERSION_NO}) - endif() -endfunction() - -if(MSVC) - # Options for Visual C++ compiler: /Zc:__cplusplus - report an updated value - # for recent C++ language standards. Without this option MSVC returns the - # value of __cplusplus="199711L" - if(MSVC_VERSION GREATER 1900) - # __cplusplus flag is not supported by Visual Studio 2015 - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus") - endif() -endif() - -# include GNUInstallDirs before include cmake/opentelemetry-proto.cmake because -# opentelemetry-proto installs targets to the location variables defined in -# GNUInstallDirs. -include(GNUInstallDirs) - -if(WITH_PROMETHEUS) - find_package(prometheus-cpp CONFIG QUIET) - if(NOT prometheus-cpp_FOUND) - message(STATUS "Trying to use local prometheus-cpp from submodule") - if(EXISTS ${PROJECT_SOURCE_DIR}/third_party/prometheus-cpp/.git) - set(SAVED_ENABLE_TESTING ${ENABLE_TESTING}) - set(SAVED_CMAKE_CXX_CLANG_TIDY ${CMAKE_CXX_CLANG_TIDY}) - set(SAVED_CMAKE_CXX_INCLUDE_WHAT_YOU_USE - ${CMAKE_CXX_INCLUDE_WHAT_YOU_USE}) - set(ENABLE_TESTING OFF) - set(CMAKE_CXX_CLANG_TIDY "") - set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "") - add_subdirectory(third_party/prometheus-cpp) - set(ENABLE_TESTING ${SAVED_ENABLE_TESTING}) - set(CMAKE_CXX_CLANG_TIDY ${SAVED_CMAKE_CXX_CLANG_TIDY}) - set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE - ${SAVED_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}) - - # Get the version of the prometheus-cpp submodule - find_package(Git QUIET) - if(Git_FOUND) - execute_process( - COMMAND ${GIT_EXECUTABLE} describe --tags --always - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/third_party/prometheus-cpp - OUTPUT_VARIABLE prometheus-cpp_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE) - string(REGEX REPLACE "^v" "" prometheus-cpp_VERSION - "${prometheus-cpp_VERSION}") - endif() - - message( - STATUS - "Using local prometheus-cpp from submodule. Version = ${prometheus-cpp_VERSION}" - ) - else() - message( - FATAL_ERROR - "\nprometheus-cpp package was not found. Please either provide it manually or clone with submodules. " - "To initialize, fetch and checkout any nested submodules, you can use the following command:\n" - "git submodule update --init --recursive") - endif() - else() - message(STATUS "Using external prometheus-cpp") - endif() -endif() - -if(WITH_OTLP_GRPC - OR WITH_OTLP_HTTP - OR WITH_OTLP_FILE) - - # Including the CMakeFindDependencyMacro resolves an error from - # gRPCConfig.cmake on some grpc versions. See - # https://github.com/grpc/grpc/pull/33361 for more details. - include(CMakeFindDependencyMacro) - - # Protobuf 3.22+ depends on abseil-cpp and must be found using the cmake - # find_package CONFIG search mode. The following attempts to find Protobuf - # using the CONFIG mode first, and if not found, falls back to the MODULE - # mode. See https://gitlab.kitware.com/cmake/cmake/-/issues/24321 for more - # details. - find_package(Protobuf CONFIG) - if(NOT Protobuf_FOUND) - find_package(Protobuf MODULE) - if(Protobuf_FOUND AND Protobuf_VERSION VERSION_GREATER_EQUAL "3.22.0") - message( - WARNING - "Found Protobuf version ${Protobuf_VERSION} using MODULE mode. " - "Linking errors may occur. Protobuf 3.22+ depends on abseil-cpp " - "and should be found using the CONFIG mode.") - endif() - endif() - - if(WITH_OTLP_GRPC) - find_package(gRPC CONFIG) - endif() - if((NOT Protobuf_FOUND) OR (WITH_OTLP_GRPC AND NOT gRPC_FOUND)) - if(WIN32 AND (NOT DEFINED CMAKE_TOOLCHAIN_FILE)) - install_windows_deps() - endif() - - if(WIN32 AND (NOT DEFINED CMAKE_TOOLCHAIN_FILE)) - message(FATAL_ERROR "Windows dependency installation failed!") - endif() - if(WIN32) - include(${CMAKE_TOOLCHAIN_FILE}) - endif() - - if(NOT Protobuf_FOUND) - find_package(Protobuf CONFIG REQUIRED) - endif() - if(NOT gRPC_FOUND AND WITH_OTLP_GRPC) - find_package(gRPC CONFIG) - endif() - if(WIN32) - # Always use x64 protoc.exe - if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") - set(Protobuf_PROTOC_EXECUTABLE - ${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/packages/protobuf_x64-windows/tools/protobuf/protoc.exe - ) - endif() - endif() - endif() - # Latest Protobuf imported targets and without legacy module support - if(TARGET protobuf::protoc) - if(CMAKE_CROSSCOMPILING AND Protobuf_PROTOC_EXECUTABLE) - set(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE}) - else() - project_build_tools_get_imported_location(PROTOBUF_PROTOC_EXECUTABLE - protobuf::protoc) - # If protobuf::protoc is not a imported target, then we use the target - # directly for fallback - if(NOT PROTOBUF_PROTOC_EXECUTABLE) - set(PROTOBUF_PROTOC_EXECUTABLE protobuf::protoc) - endif() - endif() - elseif(Protobuf_PROTOC_EXECUTABLE) - # Some versions of FindProtobuf.cmake uses mixed case instead of uppercase - set(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE}) - endif() - include(CMakeDependentOption) - - message(STATUS "PROTOBUF_PROTOC_EXECUTABLE=${PROTOBUF_PROTOC_EXECUTABLE}") - set(SAVED_CMAKE_CXX_CLANG_TIDY ${CMAKE_CXX_CLANG_TIDY}) - set(CMAKE_CXX_CLANG_TIDY "") - include(cmake/opentelemetry-proto.cmake) - set(CMAKE_CXX_CLANG_TIDY ${SAVED_CMAKE_CXX_CLANG_TIDY}) -endif() - -# -# Do we need HTTP CLIENT CURL ? -# - -if(WITH_OTLP_HTTP - OR WITH_ELASTICSEARCH - OR WITH_ZIPKIN - OR BUILD_W3CTRACECONTEXT_TEST - OR WITH_EXAMPLES_HTTP) - set(WITH_HTTP_CLIENT_CURL ON) -else() - set(WITH_HTTP_CLIENT_CURL OFF) -endif() - -# -# Do we need CURL ? -# - -if((NOT WITH_API_ONLY) AND WITH_HTTP_CLIENT_CURL) - # No specific version required. - find_package(CURL REQUIRED) - # Set the CURL_VERSION from the legacy CURL_VERSION_STRING Required for CMake - # versions below 4.0 - if(NOT DEFINED CURL_VERSION AND DEFINED CURL_VERSION_STRING) - set(CURL_VERSION ${CURL_VERSION_STRING}) - endif() -endif() - -# -# Do we need ZLIB ? -# - -if((NOT WITH_API_ONLY) - AND WITH_HTTP_CLIENT_CURL - AND WITH_OTLP_HTTP_COMPRESSION) - # No specific version required. - find_package(ZLIB REQUIRED) - # Set the ZLIB_VERSION from the legacy ZLIB_VERSION_STRING Required for CMake - # versions below 3.26 - if(NOT DEFINED ZLIB_VERSION AND DEFINED ZLIB_VERSION_STRING) - set(ZLIB_VERSION ${ZLIB_VERSION_STRING}) - endif() -endif() - -# -# Do we need NLOHMANN_JSON ? -# - -if(WITH_ELASTICSEARCH - OR WITH_ZIPKIN - OR WITH_OTLP_HTTP - OR WITH_OTLP_FILE - OR BUILD_W3CTRACECONTEXT_TEST - OR WITH_ETW) - set(USE_NLOHMANN_JSON ON) -else() - set(USE_NLOHMANN_JSON OFF) -endif() - -if((NOT WITH_API_ONLY) AND USE_NLOHMANN_JSON) - include(cmake/nlohmann-json.cmake) -endif() - -if(OTELCPP_MAINTAINER_MODE) - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - message(STATUS "Building with gcc in maintainer mode.") - - add_compile_options(-Wall) - add_compile_options(-Werror) - add_compile_options(-Wextra) - - # Tested with GCC 9.4 on github. - if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9.4) - message(STATUS "Building with additional warnings for gcc.") - - # Relaxed warnings - - # Enforced warnings - - # C++ options only - add_compile_options($<$,CXX>:-Wextra-semi>) - add_compile_options( - $<$,CXX>:-Woverloaded-virtual>) - add_compile_options( - $<$,CXX>:-Wsuggest-override>) - add_compile_options( - $<$,CXX>:-Wold-style-cast>) - - # C and C++ - add_compile_options(-Wcast-qual) - add_compile_options(-Wformat-security) - add_compile_options(-Wlogical-op) - add_compile_options(-Wmissing-include-dirs) - add_compile_options(-Wstringop-truncation) - add_compile_options(-Wundef) - add_compile_options(-Wvla) - endif() - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - message(STATUS "Building with clang in maintainer mode.") - - add_compile_options(-Wall) - add_compile_options(-Werror) - add_compile_options(-Wextra) - - # Tested with Clang 11.0 on github. - if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0) - message(STATUS "Building with additional warnings for clang.") - - # Relaxed warnings - add_compile_options(-Wno-error=unused-private-field) - - # Enforced warnings - add_compile_options(-Wcast-qual) - add_compile_options(-Wconditional-uninitialized) - add_compile_options(-Wextra-semi) - add_compile_options(-Wformat-security) - add_compile_options(-Wheader-hygiene) - add_compile_options(-Winconsistent-missing-destructor-override) - add_compile_options(-Winconsistent-missing-override) - add_compile_options(-Wnewline-eof) - add_compile_options(-Wnon-virtual-dtor) - add_compile_options(-Woverloaded-virtual) - add_compile_options(-Wrange-loop-analysis) - add_compile_options(-Wundef) - add_compile_options(-Wundefined-reinterpret-cast) - add_compile_options(-Wvla) - add_compile_options(-Wold-style-cast) - endif() - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - message(STATUS "Building with msvc in maintainer mode.") - - add_compile_options(/WX) - add_compile_options(/W4) - - # Relaxed warnings - add_compile_options(/wd4100) - add_compile_options(/wd4125) - add_compile_options(/wd4566) - add_compile_options(/wd4127) - add_compile_options(/wd4512) - add_compile_options(/wd4267) - add_compile_options(/wd4996) - - # Enforced warnings - add_compile_options(/we4265) # 'class': class has virtual functions, but - # destructor is not virtual - add_compile_options(/we5204) # A class with virtual functions has - # non-virtual trivial destructor. - - elseif() - message(FATAL_ERROR "Building with unknown compiler in maintainer mode.") - endif() -endif(OTELCPP_MAINTAINER_MODE) - -list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}") - -include(CTest) -if(BUILD_TESTING) - if(EXISTS ${CMAKE_BINARY_DIR}/lib/libgtest.a) - # Prefer GTest from build tree. GTest is not always working with - # CMAKE_PREFIX_PATH - set(GTEST_INCLUDE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googletest/include - ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googlemock/include) - if(TARGET gtest) - set(GTEST_BOTH_LIBRARIES gtest gtest_main) - else() - set(GTEST_BOTH_LIBRARIES ${CMAKE_BINARY_DIR}/lib/libgtest.a - ${CMAKE_BINARY_DIR}/lib/libgtest_main.a) - endif() - elseif(WIN32) - # Make sure we are always bootsrapped with vcpkg on Windows - find_package(GTest) - if(NOT (GTEST_FOUND OR GTest_FOUND)) - if(DEFINED CMAKE_TOOLCHAIN_FILE) - message( - FATAL_ERROR - "Pleaes install GTest with the CMAKE_TOOLCHAIN_FILE at ${CMAKE_TOOLCHAIN_FILE}" - ) - else() - install_windows_deps() - include(${CMAKE_TOOLCHAIN_FILE}) - find_package(GTest REQUIRED) - endif() - endif() - else() - # Prefer GTest installed by OS distro, brew or vcpkg package manager - find_package(GTest REQUIRED) - endif() - if(NOT GTEST_BOTH_LIBRARIES) - # New GTest package names - if(TARGET GTest::gtest) - set(GTEST_BOTH_LIBRARIES GTest::gtest GTest::gtest_main) - elseif(TARGET GTest::GTest) - set(GTEST_BOTH_LIBRARIES GTest::GTest GTest::Main) - endif() - endif() - if(GTEST_INCLUDE_DIRS) - include_directories(SYSTEM ${GTEST_INCLUDE_DIRS}) - endif() - message(STATUS "GTEST_INCLUDE_DIRS = ${GTEST_INCLUDE_DIRS}") - message(STATUS "GTEST_BOTH_LIBRARIES = ${GTEST_BOTH_LIBRARIES}") - - # Try to find gmock - if(NOT GMOCK_LIB AND TARGET GTest::gmock) - set(GMOCK_LIB GTest::gmock) - elseif(MSVC) - # Explicitly specify that we consume GTest from shared library. The rest of - # code logic below determines whether we link Release or Debug flavor of the - # library. These flavors have different prefix on Windows, gmock and gmockd - # respectively. - add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY=1) - if(GMOCK_LIB) - # unset GMOCK_LIB to force find_library to redo the lookup, as the cached - # entry could cause linking to incorrect flavor of gmock and leading to - # runtime error. - unset(GMOCK_LIB CACHE) - endif() - endif() - if(NOT GMOCK_LIB) - if(MSVC AND CMAKE_BUILD_TYPE STREQUAL "Debug") - find_library(GMOCK_LIB gmockd PATH_SUFFIXES lib) - else() - find_library(GMOCK_LIB gmock PATH_SUFFIXES lib) - endif() - # Reset GMOCK_LIB if it was not found, or some target may link - # GMOCK_LIB-NOTFOUND - if(NOT GMOCK_LIB) - unset(GMOCK_LIB) - unset(GMOCK_LIB CACHE) - endif() - endif() - - enable_testing() - if(WITH_BENCHMARK) - # Benchmark respects the CMAKE_PREFIX_PATH - find_package(benchmark CONFIG REQUIRED) - endif() -endif() - -# Record build config and versions -message(STATUS "---------------------------------------------") -message(STATUS "build settings") -message(STATUS "---------------------------------------------") -message(STATUS "OpenTelemetry: ${OPENTELEMETRY_VERSION}") -message(STATUS "OpenTelemetry ABI: ${OPENTELEMETRY_ABI_VERSION_NO}") -message(STATUS "ARCH: ${ARCH}") -message(STATUS "CXX: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") -message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") -message(STATUS "CXXFLAGS: ${CMAKE_CXX_FLAGS}") -message(STATUS "CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}") -message(STATUS "CMAKE_TOOLCHAIN_FILE: ${CMAKE_TOOLCHAIN_FILE}") -message(STATUS "BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}") - -message(STATUS "---------------------------------------------") -message(STATUS "opentelemetry-cpp build options") -message(STATUS "---------------------------------------------") -message(STATUS "WITH_API_ONLY: ${WITH_API_ONLY}") -message(STATUS "WITH_NO_DEPRECATED_CODE: ${WITH_NO_DEPRECATED_CODE}") -message(STATUS "WITH_ABI_VERSION_1: ${WITH_ABI_VERSION_1}") -message(STATUS "WITH_ABI_VERSION_2: ${WITH_ABI_VERSION_2}") -message(STATUS "OTELCPP_VERSIONED_LIBS: ${OTELCPP_VERSIONED_LIBS}") -message(STATUS "OTELCPP_MAINTAINER_MODE: ${OTELCPP_MAINTAINER_MODE}") -message(STATUS "WITH_STL: ${WITH_STL}") -message(STATUS "WITH_GSL: ${WITH_GSL}") -message(STATUS "WITH_NO_GETENV: ${WITH_NO_GETENV}") - -message(STATUS "---------------------------------------------") -message(STATUS "opentelemetry-cpp cmake component options") -message(STATUS "---------------------------------------------") -message(STATUS "WITH_OTLP_GRPC: ${WITH_OTLP_GRPC}") -message(STATUS "WITH_OTLP_HTTP: ${WITH_OTLP_HTTP}") -message(STATUS "WITH_OTLP_FILE: ${WITH_OTLP_FILE}") -message(STATUS "WITH_HTTP_CLIENT_CURL: ${WITH_HTTP_CLIENT_CURL}") -message(STATUS "WITH_ZIPKIN: ${WITH_ZIPKIN}") -message(STATUS "WITH_PROMETHEUS: ${WITH_PROMETHEUS}") -message(STATUS "WITH_ELASTICSEARCH: ${WITH_ELASTICSEARCH}") -message(STATUS "WITH_OPENTRACING: ${WITH_OPENTRACING}") -message(STATUS "WITH_ETW: ${WITH_ETW}") -message(STATUS "OPENTELEMETRY_BUILD_DLL: ${OPENTELEMETRY_BUILD_DLL}") - -message(STATUS "---------------------------------------------") -message(STATUS "feature preview options") -message(STATUS "---------------------------------------------") -message(STATUS "WITH_ASYNC_EXPORT_PREVIEW: ${WITH_ASYNC_EXPORT_PREVIEW}") -message( - STATUS - "WITH_THREAD_INSTRUMENTATION_PREVIEW: ${WITH_THREAD_INSTRUMENTATION_PREVIEW}" -) -message( - STATUS "WITH_METRICS_EXEMPLAR_PREVIEW: ${WITH_METRICS_EXEMPLAR_PREVIEW}") -message(STATUS "WITH_REMOVE_METER_PREVIEW: ${WITH_REMOVE_METER_PREVIEW}") -message( - STATUS "WITH_OTLP_GRPC_SSL_MTLS_PREVIEW: ${WITH_OTLP_GRPC_SSL_MTLS_PREVIEW}") -message(STATUS "WITH_OTLP_RETRY_PREVIEW: ${WITH_OTLP_RETRY_PREVIEW}") -message(STATUS "---------------------------------------------") -message(STATUS "third-party options") -message(STATUS "---------------------------------------------") -message(STATUS "WITH_NLOHMANN_JSON: ${USE_NLOHMANN_JSON}") -message(STATUS "WITH_CURL_LOGGING: ${WITH_CURL_LOGGING}") -message(STATUS "WITH_OTLP_HTTP_COMPRESSION: ${WITH_OTLP_HTTP_COMPRESSION}") -message(STATUS "---------------------------------------------") -message(STATUS "examples and test options") -message(STATUS "---------------------------------------------") -message(STATUS "WITH_BENCHMARK: ${WITH_BENCHMARK}") -message(STATUS "WITH_EXAMPLES: ${WITH_EXAMPLES}") -message(STATUS "WITH_EXAMPLES_HTTP: ${WITH_EXAMPLES_HTTP}") -message(STATUS "WITH_FUNC_TESTS: ${WITH_FUNC_TESTS}") -message(STATUS "BUILD_W3CTRACECONTEXT_TEST: ${BUILD_W3CTRACECONTEXT_TEST}") -message(STATUS "BUILD_TESTING: ${BUILD_TESTING}") -message(STATUS "---------------------------------------------") -message(STATUS "versions") -message(STATUS "---------------------------------------------") -message(STATUS "CMake: ${CMAKE_VERSION}") -message(STATUS "GTest: ${GTest_VERSION}") -message(STATUS "benchmark: ${benchmark_VERSION}") -if(WITH_GSL) - message(STATUS "GSL: ${GSL_VERSION}") -endif() -if(absl_FOUND) - message(STATUS "Abseil: ${absl_VERSION}") -endif() -if(Protobuf_FOUND) - message(STATUS "Protobuf: ${Protobuf_VERSION}") -endif() -if(gRPC_FOUND) - message(STATUS "gRPC: ${gRPC_VERSION}") -endif() -if(CURL_FOUND) - message(STATUS "CURL: ${CURL_VERSION}") -endif() -if(ZLIB_FOUND) - message(STATUS "ZLIB: ${ZLIB_VERSION}") -endif() -if(USE_NLOHMANN_JSON) - message(STATUS "nlohmann-json: ${nlohmann_json_VERSION}") -endif() -if(prometheus-cpp_FOUND) - message(STATUS "prometheus-cpp: ${prometheus-cpp_VERSION}") -endif() -message(STATUS "---------------------------------------------") - -include("${PROJECT_SOURCE_DIR}/cmake/otel-install-functions.cmake") - -include(CMakePackageConfigHelpers) - -if(DEFINED OPENTELEMETRY_BUILD_DLL) - if(NOT WIN32) - message(FATAL_ERROR "Build DLL is only supported on Windows!") - endif() - if(NOT MSVC) - message(WARNING "Build DLL is supposed to work with MSVC!") - endif() - if(WITH_STL) - message( - WARNING "Build DLL with C++ STL could cause binary incompatibility!") - endif() - add_definitions(-DOPENTELEMETRY_BUILD_EXPORT_DLL) -endif() - -add_subdirectory(api) - -if(WITH_OPENTRACING) - find_package(OpenTracing CONFIG QUIET) - if(NOT OpenTracing_FOUND) - set(OPENTRACING_DIR "third_party/opentracing-cpp") - message(STATUS "Trying to use local ${OPENTRACING_DIR} from submodule") - if(EXISTS "${PROJECT_SOURCE_DIR}/${OPENTRACING_DIR}/.git") - set(SAVED_BUILD_TESTING ${BUILD_TESTING}) - set(BUILD_TESTING OFF) - set(SAVED_CMAKE_CXX_INCLUDE_WHAT_YOU_USE - ${CMAKE_CXX_INCLUDE_WHAT_YOU_USE}) - set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "") - add_subdirectory(${OPENTRACING_DIR}) - set(BUILD_TESTING ${SAVED_BUILD_TESTING}) - set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE - ${SAVED_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}) - else() - message( - FATAL_ERROR - "\nopentracing-cpp package was not found. Please either provide it manually or clone with submodules. " - "To initialize, fetch and checkout any nested submodules, you can use the following command:\n" - "git submodule update --init --recursive") - endif() - else() - message(STATUS "Using external opentracing-cpp") - endif() - add_subdirectory(opentracing-shim) -endif() - -if(NOT WITH_API_ONLY) - set(BUILD_TESTING ${BUILD_TESTING}) - - add_subdirectory(sdk) - add_subdirectory(ext) - add_subdirectory(exporters) - - if(BUILD_TESTING) - add_subdirectory(test_common) - endif() - if(WITH_EXAMPLES) - add_subdirectory(examples) - endif() - if(WITH_FUNC_TESTS) - add_subdirectory(functional) - endif() -endif() - -include(cmake/opentelemetry-build-external-component.cmake) -include(cmake/patch-imported-config.cmake) - -if(OPENTELEMETRY_INSTALL) - # Install the cmake config and version files - otel_install_cmake_config() - - # Install the components and associated files - otel_install_components() - - # Install the thirdparty dependency definition file - otel_install_thirdparty_definitions() - - if(BUILD_PACKAGE) - include(cmake/package.cmake) - include(CPack) - endif() -endif() diff --git a/ext/opentelemetry-cpp-1.21.0/CMakeSettings.json b/ext/opentelemetry-cpp-1.21.0/CMakeSettings.json deleted file mode 100644 index 02d068a3a..000000000 --- a/ext/opentelemetry-cpp-1.21.0/CMakeSettings.json +++ /dev/null @@ -1,126 +0,0 @@ -{ - "configurations": [ - { - "name": "nostd-x64-Debug", - "generator": "Ninja", - "configurationType": "Debug", - "inheritEnvironments": [ - "msvc_x64_x64" - ], - "buildRoot": "${projectDir}\\out\\vs2019\\${name}", - "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "variables": [ - { - "name": "WITH_OTLP_GRPC", - "value": "True", - "type": "BOOL" - }, - { - "name": "WITH_EXAMPLES", - "value": "true", - "type": "BOOL" - } - ] - }, - { - "name": "nostd-x64-Release", - "generator": "Ninja", - "configurationType": "Release", - "inheritEnvironments": [ - "msvc_x64_x64" - ], - "buildRoot": "${projectDir}\\out\\vs2019\\${name}", - "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "cmakeToolchain": "", - "variables": [ - { - "name": "WITH_OTLP_GRPC", - "value": "True", - "type": "BOOL" - }, - { - "name": "WITH_EXAMPLES", - "value": "true", - "type": "BOOL" - } - ] - }, - { - "name": "stdlib-x64-Debug", - "generator": "Ninja", - "configurationType": "Debug", - "inheritEnvironments": [ - "msvc_x64_x64" - ], - "buildRoot": "${projectDir}\\out\\vs2019\\${name}", - "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "variables": [ - { - "name": "WITH_STL", - "value": "True", - "type": "BOOL" - }, - { - "name": "WITH_OTLP_GRPC", - "value": "True", - "type": "BOOL" - }, - { - "name": "WITH_EXAMPLES", - "value": "true", - "type": "BOOL" - }, - { - "name": "WITH_PROMETHEUS", - "value": "True", - "type": "BOOL" - } - ] - }, - { - "name": "stdlib-x64-Release", - "generator": "Ninja", - "configurationType": "Release", - "inheritEnvironments": [ - "msvc_x64_x64" - ], - "buildRoot": "${projectDir}\\out\\vs2019\\${name}", - "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "cmakeToolchain": "", - "variables": [ - { - "name": "WITH_STL", - "value": "True", - "type": "BOOL" - }, - { - "name": "WITH_OTLP_GRPC", - "value": "True", - "type": "BOOL" - }, - { - "name": "WITH_EXAMPLES", - "value": "true", - "type": "BOOL" - }, - { - "name": "WITH_PROMETHEUS", - "value": "True", - "type": "BOOL" - } - ] - } - ] -} diff --git a/ext/opentelemetry-cpp-1.21.0/CODE_OF_CONDUCT.md b/ext/opentelemetry-cpp-1.21.0/CODE_OF_CONDUCT.md deleted file mode 100644 index fee94ae58..000000000 --- a/ext/opentelemetry-cpp-1.21.0/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenTelemetry Community Code of Conduct - -OpenTelemetry follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). diff --git a/ext/opentelemetry-cpp-1.21.0/CONTRIBUTING.md b/ext/opentelemetry-cpp-1.21.0/CONTRIBUTING.md deleted file mode 100644 index fda99e097..000000000 --- a/ext/opentelemetry-cpp-1.21.0/CONTRIBUTING.md +++ /dev/null @@ -1,322 +0,0 @@ -# Contributing to opentelemetry-cpp - -The OpenTelemetry C/C++ special interest group (SIG) meets regularly. See the -OpenTelemetry [community](https://github.com/open-telemetry/community#cc-sdk) -repo for information on this and other language SIGs. - -See the [public meeting -notes](https://docs.google.com/document/d/1i1E4-_y4uJ083lCutKGDhkpi3n4_e774SBLi9hPLocw/edit) -for a summary description of past meetings. To request edit access, join the -meeting or get in touch on -[Slack](https://cloud-native.slack.com/archives/C01N3AT62SJ). - -See the [community membership -document](https://github.com/open-telemetry/community/blob/main/community-membership.md) -on how to become a -[**Member**](https://github.com/open-telemetry/community/blob/main/community-membership.md#member), -[**Approver**](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver) -and -[**Maintainer**](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer). - -## Development - -OpenTelemetry C++ uses the [Google naming -convention](https://google.github.io/styleguide/cppguide.html#Naming). - -Code is formatted automatically and enforced by CI. - -### Build and Run Code Examples - -Note: these instructions apply to examples configured with Bazel, see -example-specific documentation for other build automation tools. - -Install the latest bazel version by following the steps listed -[here](https://docs.bazel.build/versions/master/install.html). - -Select an example of interest from the [examples -folder](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/examples). -Inside each example directory is a `BUILD` file containing instructions for -Bazel. Find the binary name of your example by inspecting the contents of this -`BUILD` file. - -Build the example from the root of the opentelemetry-cpp directory using Bazel. -Replace `` with the identifier found in the previous step: - -```sh -bazel build //examples/: -``` - -Run the resulting executable to see telemetry from the application as it calls -the instrumented library: - -```sh -bazel-bin/examples// -``` - -For instance, building and running the `simple` example can be done as follows: - -```sh -bazel build //examples/simple:example_simple -bazel-bin/examples/simple/example_simple -``` - -### DevContainer Setup for Project - -This guide provides instructions on how to set up and use the development -container (`devcontainer`) environment to streamline testing and development -for this project. With the DevContainer, you can work in a consistent environment -configured with all the necessary dependencies and tools. - -#### Prerequisites - -Before getting started, ensure you have the following installed: - -* **Docker**: DevContainers require Docker for containerization. -* **Visual Studio Code (VSCode)** with the **Remote - Containers** extension. - -#### Getting Started - -* **Open the Project in DevContainer**: - - Open the project in VSCode. When prompted to "Reopen in Container," select - this option. If you’re not prompted, you can manually open the container by - selecting **Remote-Containers: Reopen in Container** from the command palette - (`F1` or `Ctrl+Shift+P`). - -* **Container Setup**: - - The DevContainer environment will automatically build based on the configuration - files provided (e.g., `.devcontainer/devcontainer.json`). This setup will install - required dependencies, tools, and environment variables needed for the project. - -* **Container Customization**: - See `.devcontainer/README.md` for devcontainer configuration options. - -#### Available Commands - -Once inside the DevContainer, you can use the following commands to run tests -and CI workflows. - -##### 1. Run Tests with Bazelisk - -To run tests with Bazelisk using specific compilation options, use: - -```bash -bazelisk-linux-amd64 test --copt=-DENABLE_LOGS_PREVIEW ---test_output=errors --cache_test_results=no --copt=-DENABLE_TEST //exporters/otlp/... -``` - -###### Command Breakdown - -* `--copt=-DENABLE_LOGS_PREVIEW`: Enables preview logs. -* `--test_output=errors`: Shows only the errors in the test output. -* `--cache_test_results=no`: Forces Bazel to re-run tests without caching. -* `--copt=-DENABLE_TEST`: Enables testing capabilities for the target code. -* `//exporters/otlp/...`: Specifies the test target path. - -##### 2. Run CI Script - -You can also run the CI script provided to perform testing with the -following command as an -example: - -```bash -bash ci/do_ci.sh cmake.exporter.otprotocol.test -``` - -This command initiates the CI pipeline, executing tests specifically for the -**cmake.exporter.otprotocol** module. - -#### Troubleshooting - -If you encounter issues: - -* **Rebuild the DevContainer**: From the command palette, run - **Remote-Containers: Rebuild Container** to reinitialize the environment. -* **Check Bazelisk and CI Script Logs**: Inspect logs for any configuration or - dependency issues. - -#### Additional Notes - -* You can adjust compiler options (`--copt`) as needed to test additional flags - or enable/disable specific features. -* The test results will be displayed in the terminal within the DevContainer for - easy debugging. - -#### Resources - -* **Bazelisk Documentation**: [https://github.com/bazelbuild/bazelisk](https://github.com/bazelbuild/bazelisk) -* **VSCode DevContainer Documentation**: [https://code.visualstudio.com/docs/remote/containers](https://code.visualstudio.com/docs/remote/containers) - -### Docker Development Image - -The `.devcontainer/Dockerfile.dev` -dockerfile can be built directly with the following command. - -```sh - docker build -t opentelemetry-cpp-dev -f ./.devcontainer/Dockerfile.dev . -``` - -You can customize the image using build arguments - to match permissions with the host user. - -```sh - docker build -t opentelemetry-cpp-dev \ - --build-arg USER_UID="$(id -u)" \ - --build-arg USER_GID="$(id -g)" \ - -f ./.devcontainer/Dockerfile.dev . - -``` - -Run an interactive bash session binding your host - opentelemetry-cpp directory to the container's workspace: - -```sh -docker run -it -v "$PWD:/workspaces/opentelemetry-cpp" opentelemetry-cpp-dev bash -``` - -## Pull Requests - -### How to Send Pull Requests - -Everyone is welcome to contribute code to `opentelemetry-cpp` via GitHub pull -requests (PRs). - -To create a new PR, fork the project in GitHub and clone the upstream repo: - -```sh -git clone --recursive https://github.com/open-telemetry/opentelemetry-cpp.git -``` - -Add your fork as a remote: - -```sh -git remote add fork https://github.com/YOUR_GITHUB_USERNAME/opentelemetry-cpp.git -``` - -If you haven't, make sure you are loading the submodules required to build -OpenTelemetry - -```sh -git submodule init -git submodule update -``` - -The source code is automatically formatted using clang-format. - -The output can vary between versions, so make sure to install `clang-format` -version `10.0`, and have `clang-format-10` in your execution path, -so that the helper script `tools/format.sh` can find it. - -Check out a new branch, make modifications and push the branch to your fork: - -```sh -git checkout -b feature -# edit files -tools/format.sh -git commit -git push fork feature -``` - -If you made changes to the Markdown documents (`*.md` files), install the latest -[`markdownlint-cli`](https://github.com/igorshubovych/markdownlint-cli) and run: - -```sh -markdownlint . -``` - -If you modified shell scripts (`*.sh` files), install `shellcheck` and run: - -```sh -shellcheck --severity=error .sh -``` - -Open a pull request against the main `opentelemetry-cpp` repo. - -To run tests locally, please read the [CI instructions](ci/README.md). - -### How to Receive Comments - -* If the PR is not ready for review, please put `[WIP]` in the title, tag it as - `work-in-progress`, or mark it as - [`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/). -* Make sure [CLA](https://identity.linuxfoundation.org/projects/cncf) is signed - and CI is clear. -* For non-trivial changes, please update the [CHANGELOG](./CHANGELOG.md). - -### How to Get PRs Merged - -A PR is considered to be **ready to merge** when: - -* It has received two approvals with at least one approval from - [Approver](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver) - / - [Maintainer](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer) - (at different company). -* A pull request opened by an Approver / Maintainer can be merged with only one - approval from Approver / Maintainer (at different company). -* Major feedback items/points are resolved. -* It has been open for review for at least one working day. This gives people - reasonable time to review. -* Trivial changes (typo, cosmetic, doc, etc.) don't have to wait for one day. -* Urgent fixes can take exceptions as long as it has been actively communicated. - -Any Maintainer can merge the PR once it is **ready to merge**. Maintainer can -make conscious judgement to merge pull requests which have not strictly met -above mentioned requirements. - -If a PR has been stuck (e.g. there are lots of debates and people couldn't agree -on each other), the owner should try to get people aligned by: - -* Consolidating the perspectives and putting a summary in the PR. It is - recommended to add a link into the PR description, which points to a comment - with a summary in the PR conversation -* Stepping back to see if it makes sense to narrow down the scope of the PR or - split it up. - -If none of the above worked and the PR has been stuck for more than 2 weeks, the -owner should bring it to the OpenTelemetry C++ SIG meeting. See -[README.md](README.md#contributing) for the meeting link. - -## Design Choices - -As with other OpenTelemetry clients, opentelemetry-cpp follows the -[opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification). - -It's especially valuable to read through the [library -guidelines](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/library-guidelines.md). - -## Useful Resources - -Hi! If you’re looking at this document, these resources will provide you the -knowledge to get started as a newcomer to the OpenTelemetry project. They will -help you understand the OpenTelemetry Project, its components, and specifically -the C++ repository. - -### Reading Resources - -* Medium - [article](https://medium.com/opentelemetry/how-to-start-contributing-to-opentelemetry-b23991ad91f4) - (October 2019) on how to start contributing to the OpenTelemetry project. -* Medium - [article](https://medium.com/opentelemetry/opentelemetry-beyond-getting-started-5ac43cd0fe26) - (January 2020) describing the overarching goals and use cases for - OpenTelemetry. - -### Relevant Documentation - -* [OpenTelemetry - Specification](https://github.com/open-telemetry/opentelemetry-specification) -* The OpenTelemetry Specification describes the requirements and expectations - of for all OpenTelemetry implementations. - -* Read through the OpenTelemetry C++ documentation -* The - [API](https://opentelemetry-cpp.readthedocs.io/en/latest/api/api.html) - and - [SDK](https://opentelemetry-cpp.readthedocs.io/en/latest/sdk/sdk.html) - documentation provides a lot of information on what the classes and their - functions are used for. - -Please contribute! You’re welcome to add more information if you come across any -helpful resources. diff --git a/ext/opentelemetry-cpp-1.21.0/DEPRECATED.md b/ext/opentelemetry-cpp-1.21.0/DEPRECATED.md deleted file mode 100644 index ec97f420f..000000000 --- a/ext/opentelemetry-cpp-1.21.0/DEPRECATED.md +++ /dev/null @@ -1,139 +0,0 @@ -# Deprecated - -This document lists all the items currently deprecated in opentelemetry-cpp. - -Deprecated items will be removed in the future. - -## Guidelines - -### Maintainer guidelines - -See the [deprecation-process](./docs/deprecation-process.md) - -## [TEMPLATE] - -### New Deprecation Title (Template) - -#### Announcement (Template) - -#### Motivation (Template) - -#### Scope (Template) - -#### Mitigation (Template) - -#### Planned removal (Template) - -## [Platforms] - -N/A - -## [Compilers] - -N/A - -## [Third party dependencies] - -N/A - -## [Build tools] - -N/A - -## [Build scripts] - -N/A - -## [opentelemetry-cpp API] - -N/A - -## [opentelemetry-cpp SDK] - -N/A - -## [opentelemetry-cpp Exporter] - -N/A - -## [Documentation] - -N/A - -## Semantic conventions - -### Header files "semantic_conventions.h" - -#### Announcement (semantic_conventions.h) - -Deprecation is announced as part of the migration to weaver: - -* `Version:` release following opentelemetry-cpp 1.17.0 -* `Date:` Nov 9, 2024 -* `PR:` [PR 3105](https://github.com/open-telemetry/opentelemetry-cpp/pull/3105) - -#### Motivation (semantic_conventions.h) - -The header files for semantic conventions are generated automatically. -The tooling to generate these files is changing: - -* before, the build-tool repository was used -* now, the weaver repository is used - -Changes in tooling allows to generate code that is better organized, -with dedicated header files per group of semantic conventions, -instead of a single header file for everything. - -#### Scope (semantic_conventions.h) - -The following files: - -* `api/include/opentelemetry/trace/semantic_conventions.h` -* `sdk/include/opentelemetry/sdk/resource/semantic_conventions.h` - -are now deprecated. - -They correspond to semantic conventions v1.27.0, -and will no longer be maintained up to date. - -These files will be removed in the future. - -#### Mitigation (semantic_conventions.h) - -Two things have changed: - -* the header file to use -* the symbol name to use. - -Before, the semantic convention for `url.full` was: - -* declared in file `semantic_conventions.h` -* declared as symbol `SemanticConventions::kUrlFull` - -Now, the `url.full` convention, which is part or the `url` group, is: - -* declared in file `semconv/url_attributes.h` -* declared as symbol `semconv::url::kUrlFull` - -Application code that uses semantic conventions must be adjusted -accordingly. - -In addition, semantic conventions that are not marked as stable -are generated in a different header file, placed under directory -`incubating`, to better separate stable and non stable code. - -For example, file `semconv/incubating/url_attributes.h` -defines `semconv::url::kUrlDomain`, -which is not marked as stable in semconv v1.27.0 - -#### Planned removal (semantic_conventions.h) - -The following files: - -* `api/include/opentelemetry/trace/semantic_conventions.h` -* `sdk/include/opentelemetry/sdk/resource/semantic_conventions.h` - -will be removed. - -The removal date is planned for July 1, 2025. -This allows more than six months for applications to adjust. diff --git a/ext/opentelemetry-cpp-1.21.0/INSTALL.md b/ext/opentelemetry-cpp-1.21.0/INSTALL.md deleted file mode 100644 index 296a61c44..000000000 --- a/ext/opentelemetry-cpp-1.21.0/INSTALL.md +++ /dev/null @@ -1,452 +0,0 @@ -# Building opentelemetry-cpp - -[CMake](https://cmake.org/) and [Bazel](https://bazel.build) are the official -build systems for opentelemetry-cpp. - -## Dependencies - -You can link OpenTelemetry C++ SDK with libraries provided in -[dependencies.md](https://github.com/open-telemetry/opentelemetry-cpp/blob/main/docs/dependencies.md) -(complete list of libraries with versions used in our CI can be found -[here](https://github.com/open-telemetry/opentelemetry-cpp/blob/main/third_party_release)). - -## Build instructions using CMake - -### Prerequisites for CMake build - -- A supported platform (e.g. Windows, macOS or Linux). Refer to [Platforms - Supported](./README.md#supported-development-platforms) for more information. -- A compatible C++ compiler supporting at least C++14. Major compilers are - supported. Refer to [Supported Compilers](./README.md#supported-c-versions) - for more information. -- [Git](https://git-scm.com/) for fetching opentelemetry-cpp source code from - repository. To install Git, consult the [Set up - Git](https://help.github.com/articles/set-up-git/) guide on GitHub. -- [CMake](https://cmake.org/) for building opentelemetry-cpp API, SDK with their - unittests. The minimum CMake version is 3.14. - CMake 3.15+ is recommended on Windows due to known CI test failures with 3.14. - To install CMake, - consult the [Installing CMake](https://cmake.org/install/) guide. -- [GoogleTest](https://github.com/google/googletest) framework to build and run - the unittests. Refer to - [third_party_release](https://github.com/open-telemetry/opentelemetry-cpp/blob/main/third_party_release#L5) - for version of GoogleTest used in CI. To install GoogleTest, consult the - [GoogleTest Build - Instructions](https://github.com/google/googletest/blob/master/googletest/README.md#generic-build-instructions). -- [Google Benchmark](https://github.com/google/benchmark) framework to build and - run benchmark tests. Refer to - [third_party_release](https://github.com/open-telemetry/opentelemetry-cpp/blob/main/third_party_release#L4) - for version of Benchmark used in CI. To install Benchmark, consult the - [GoogleBenchmark Build - Instructions](https://github.com/google/benchmark#installation). -- Apart from above core requirements, the Exporters and Propagators have their - build dependencies. - -### Building dependencies for the OTLP exporters - -The opentelemetry-cpp OTLP exporters depend on Protobuf and gRPC - (in the case of the otlp grpc exporters). -Protobuf (since version 3.22.0) and gRPC depend on Abseil. -For cmake builds, it is best practice to build and install Abseil -, Protobuf, and gPRC as independent packages - -configuring cmake for Protobuf and gRPC to build against - the installed packages instead of using their submodule option. - -If building and installing Protobuf and gRPC manually with cmake the - recommended approach is: - -1. Choose the desired tag version of grpc. Find the compatible versions of abseil - and protobuf by inspecting the submodules of grpc at that tag. -2. Build and install the required version of abseil -3. Build and install the required version of protobuf - - Set the cmake option of Protobuf to build against the installed - package of Abseil (`protobuf_ABSL_PROVIDER=package`) -4. Build and install the required version of grpc - - Set the cmake option of grpc to build against the installed packages - of Abseil and Protobuf (cmake options - `gRPC_ABSL_PROVIDER=package` and `gRPC_PROTOBUF_PROVIDER=package`) - -### Building as standalone CMake Project - -1. Getting the opentelemetry-cpp source with its submodules: - - ```console - # Change to the directory where you want to create the code repository - $ cd ~ - $ mkdir source && cd source && git clone --recurse-submodules https://github.com/open-telemetry/opentelemetry-cpp - Cloning into 'opentelemetry-cpp'... - ... - Resolving deltas: 100% (3225/3225), done. - $ - ``` - -2. Navigate to the repository cloned above, and create the `CMake` build - configuration. - - ```console - $ cd opentelemetry-cpp - $ mkdir build && cd build && cmake .. - -- The C compiler identification is GNU 9.3.0 - -- The CXX compiler identification is GNU 9.3.0 - ... - -- Configuring done - -- Generating done - -- Build files have been written to: /home//source/opentelemetry-cpp/build - $ - ``` - - Some of the available cmake build variables we can use during cmake - configuration: - - - `-DCMAKE_POSITION_INDEPENDENT_CODE=ON` : Please note that with default - configuration, the code is compiled without `-fpic` option, so it is not - suitable for inclusion in shared libraries. To enable the code for - inclusion in shared libraries, this variable is used. - - `-DBUILD_SHARED_LIBS=ON` : To build shared libraries for the targets. - Please refer to note [below](#building-shared-libs-for-windows) for - Windows DLL support. - - `-DWITH_OTLP_GRPC=ON` : To enable building OTLP GRPC exporter. - - `-DWITH_OTLP_HTTP=ON` : To enable building OTLP HTTP exporter. - - `-DWITH_PROMETHEUS=ON` : To enable building prometheus exporter. - - `-DOPENTELEMETRY_INSTALL=ON`: To install `otel-cpp` library needed - for external code linking. - -3. Once the build configuration is created, build the CMake targets - this - includes building SDKs and unittests for API and SDK. Note that since API is - header only library, no separate build is triggered for it. - - ```console - $ cmake --build . --target all - Scanning dependencies of target timestamp_test - [ 0%] Building CXX object api/test/core/CMakeFiles/timestamp_test.dir/timestamp_test.cc.o - [ 1%] Linking CXX executable timestamp_test - ... - Scanning dependencies of target w3c_tracecontext_test - [ 99%] Building CXX object ext/test/w3c_tracecontext_test/CMakeFiles/w3c_tracecontext_test.dir/main.cc.o - [100%] Linking CXX executable w3c_tracecontext_test - [100%] Built target w3c_tracecontext_test - $ - ``` - -4. Once CMake tests are built, run them with `ctest` command - - ```console - $ ctest - Test project /tmp/opentelemetry-cpp/build - Start 1: trace.SystemTimestampTest.Construction - ... - Start 380: ext.http.urlparser.UrlParserTests.BasicTests - ... - 100% tests passed, 0 tests failed out of 380 - $ - ``` - -5. Optionally install the header files for API, and generated targets and header - files for SDK at custom/default install location. - - ```console - $ cmake --install . --prefix // - -- Installing: //lib/cmake/opentelemetry-cpp/opentelemetry-cpp-config.cmake - -- Installing: //lib/cmake/opentelemetry-cpp/opentelemetry-cpp-config-version.cmake - ... - $ - ``` - -### Incorporating into an external CMake Project - -There are two approaches to incoporate `opentelemetry-cpp` into - an external CMake project: - -1. Build and install `opentelemetry-cpp` then use `find_package` - to import its targets - - ```cmake - # Find all installed components and link all imported targets - find_package(opentelemetry-cpp CONFIG REQUIRED) - ... - target_include_directories(foo PRIVATE ${OPENTELEMETRY_CPP_INCLUDE_DIRS}) - target_link_libraries(foo PRIVATE ${OPENTELEMETRY_CPP_LIBRARIES}) - ``` - - ```cmake - # Find a specific component and link its imported target(s) - find_package(opentelemetry-cpp CONFIG REQUIRED COMPONENTS api) - ... - target_link_libraries(foo PRIVATE opentelemetry-cpp::api) - ``` - -2. Use CMake's [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) - module to fetch and build `opentelemetry-cpp` then make its targets available - - ```cmake - # Fetch from an existing clone and build - include(FetchContent) - FetchContent_Declare(opentelemetry-cpp SOURCE_DIR "") - FetchContent_MakeAvailable(opentelemetry-cpp) - ... - target_link_libraries(foo PRIVATE opentelemetry-cpp::api) - ``` - - ```cmake - # Clone and build opentelemetry-cpp from a git tag - include(FetchContent) - FetchContent_Declare( - opentelemetry-cpp - GIT_REPOSITORY https://github.com/open-telemetry/opentelemetry-cpp.git - GIT_TAG v1.20.0) - FetchContent_MakeAvailable(opentelemetry-cpp) - ... - target_link_libraries(foo PRIVATE opentelemetry-cpp::api) - ``` - -In both cases the project's built or imported CMake targets will be - available in the `opentelemetry-cpp` namespace (ie: `opentelemetry-cpp::api`) - -#### Using opentelemetry-cpp package components - -> **Note:** `opentelemetry-cpp` CMake package components were introduced in `v1.21.0` - -The `opentelemetry-cpp` package supports using the `COMPONENTS` argument to -`find_package`. The following example illustrates using this feature to include -and link the `api` header only target to an instrumented `foo_lib` while only including -and linking the `sdk` and `otlp_grpc_exporter` targets to the `foo_app`. - -```cmake -# foo_lib/CMakeLists.txt -find_package(opentelemetry-cpp CONFIG REQUIRED COMPONENTS api) -add_library(foo_lib foo.cpp) -target_link_libraries(foo_lib PRIVATE opentelemetry-cpp::api) -``` - -```cmake -# foo_app/CMakeLists.txt -find_package(opentelemetry-cpp CONFIG REQUIRED COMPONENTS api sdk exporters_otlp_grpc) -add_executable(foo_app main.cpp) -target_link_libraries(foo_app PRIVATE foo_lib opentelemetry-cpp::api opentelemetry-cpp::trace opentelemetry-cpp::otlp_grpc_exporter ) -``` - -The following table provides the mapping between components and targets. Components -and targets available in the installation depends on the opentelemetry-cpp package -build configuration. - -> **Note:** components `exporters_elasticsearch` and `exporters_etw` - may be moved out of the core package and to `opentelemetry-cpp-contrib` - in a future release - -| Component | Targets | -|----------------------------|--------------------------------------------------------------------------------------------------| -| **api** | opentelemetry-cpp::api | -| **sdk** | opentelemetry-cpp::sdk | -| | opentelemetry-cpp::version | -| | opentelemetry-cpp::common | -| | opentelemetry-cpp::resources | -| | opentelemetry-cpp::trace | -| | opentelemetry-cpp::metrics | -| | opentelemetry-cpp::logs | -| **ext_common** | opentelemetry-cpp::ext | -| **ext_http_curl** | opentelemetry-cpp::http_client_curl | -| **ext_dll** | opentelemetry-cpp::opentelemetry_cpp | -| **exporters_in_memory** | opentelemetry-cpp::in_memory_span_exporter | -| | opentelemetry-cpp::in_memory_metric_exporter | -| **exporters_ostream** | opentelemetry-cpp::ostream_log_record_exporter | -| | opentelemetry-cpp::ostream_metrics_exporter | -| | opentelemetry-cpp::ostream_span_exporter | -| **exporters_otlp_common** | opentelemetry-cpp::proto | -| | opentelemetry-cpp::otlp_recordable | -| **exporters_otlp_file** | opentelemetry-cpp::otlp_file_client | -| | opentelemetry-cpp::otlp_file_exporter | -| | opentelemetry-cpp::otlp_file_log_record_exporter | -| | opentelemetry-cpp::otlp_file_metric_exporter | -| **exporters_otlp_grpc** | opentelemetry-cpp::proto_grpc | -| | opentelemetry-cpp::otlp_grpc_client | -| | opentelemetry-cpp::otlp_grpc_exporter | -| | opentelemetry-cpp::otlp_grpc_log_record_exporter | -| | opentelemetry-cpp::otlp_grpc_metrics_exporter | -| **exporters_otlp_http** | opentelemetry-cpp::otlp_http_client | -| | opentelemetry-cpp::otlp_http_exporter | -| | opentelemetry-cpp::otlp_http_log_record_exporter | -| | opentelemetry-cpp::otlp_http_metric_exporter | -| **exporters_prometheus** | opentelemetry-cpp::prometheus_exporter | -| **exporters_elasticsearch**| opentelemetry-cpp::elasticsearch_log_record_exporter | -| **exporters_etw** | opentelemetry-cpp::etw_exporter | -| **exporters_zipkin** | opentelemetry-cpp::zipkin_trace_exporter | -| **shims_opentracing** | opentelemetry-cpp::opentracing_shim | - -## Build instructions using Bazel - -NOTE: Experimental, and not supported for all the components. Make sure the -[GoogleTest](https://github.com/google/googletest) installation may fail if -there is a different version of googletest already installed in system-defined -path. - -### Prerequisites for Bazel build - -- A supported platform (e.g. Windows, macOS or Linux). Refer to [Platforms -Supported](./README.md#supported-development-platforms) for more information. -- A compatible C++ compiler supporting at least C++14. Major compilers are -supported. Refer to [Supported Compilers](./README.md#supported-c-versions) for -more information. -- [Git](https://git-scm.com/) for fetching opentelemetry-cpp source code from -repository. To install Git, consult the [Set up -Git](https://help.github.com/articles/set-up-git/) guide on GitHub. -- [Bazel](https://www.bazel.build/) for building opentelemetry-cpp API, SDK with -their unittests. We use 3.7.2 in our build system. - -To install Bazel, consult the [Installing -Bazel](https://docs.bazel.build/versions/3.7.0/install.html) guide. - -### Building as standalone Bazel Project - -1. Getting the opentelemetry-cpp source: - - ```console - # Change to the directory where you want to create the code repository - $ cd ~ - $ mkdir source && cd source - $ git clone https://github.com/open-telemetry/opentelemetry-cpp - Cloning into 'opentelemetry-cpp'... - ... - Resolving deltas: 100% (3225/3225), done. - $ - ``` - -2. Navigate to the repository cloned above, download the dependencies and build - the source code: - - ```console - $ cd opentelemetry-cpp - $ bazel build //... - bazel build -- //... -//exporters/otlp/... -//exporters/prometheus/... - Extracting Bazel installation... - Starting local Bazel server and connecting to it... - INFO: Analyzed 121 targets (98 packages loaded, 3815 targets configured). - INFO: Found 121 targets... - INFO: From Compiling sdk/src/trace/tracer_context.cc: - ... - - ``` - -3. Once Bazel tests are built, run them with `bazel test //...` command - - ```console - $ bazel test //... - .. - $ - ``` - -4. The build artifacts will be located under `bazel-bin` - -### Incorporating into an existing Bazel Project - -- WORKSPACE file: - -```console -http_archive( - name = "io_opentelemetry_cpp", - sha256 = "", - strip_prefix = "opentelemetry-cpp-1.0.1", - urls = [ - "https://github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.0.1.tar.gz" - ], -) - -# Load OpenTelemetry dependencies after load. -load("@io_opentelemetry_cpp//bazel:repository.bzl", "opentelemetry_cpp_deps") - -opentelemetry_cpp_deps() - -# (required after v1.8.0) Load extra dependencies required for OpenTelemetry -load("@io_opentelemetry_cpp//bazel:extra_deps.bzl", "opentelemetry_extra_deps") - -opentelemetry_extra_deps() - -# Load gRPC dependencies after load. -load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps") - -grpc_deps() - -# Load extra gRPC dependencies due to https://github.com/grpc/grpc/issues/20511 -load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps") - -grpc_extra_deps() - -``` - -- Component level BUILD file: - -```console -cc_library( - name = "" - ... - deps = [ - "@io_opentelemetry_cpp//api", - "@io_opentelemetry_cpp//exporters/otlp:otlp_exporter", - "@io_opentelemetry_cpp//sdk/src/trace", - ... - ], - ... -) -``` - -## Building shared libs for Windows - -Windows DLL build is supported under **preview**. Please check the -[doc](./docs/build-as-dll.md) for more details. - -## Generating binary packages - -OpenTelemetry C++ supports generating platform specific binary packages from CMake -configuration. The packages generated through this mayn't be production ready, -and user may have to customize it further before using it as distribution. - -- Linux : deb, rpm, tgz -- MacOS : tgz -- Windows : NuGet, zip - -This requires platform specific package generators already installed. The package -generation can subsequently be enabled by using BUILD_PACKAGE option during cmake -configuration - - ```console - $ cd opentelemetry-cpp - $ mkdir build && cd build && cmake -DBUILD_PACKAGE=ON .. - - -- Package name: opentelemetry-cpp-1.8.1-ubuntu-20.04-x86_64.deb - -- Configuring done - -- Generating done - ... - $ - ``` - -Once build is complete as specified in [standalone build section](#building-as-standalone-cmake-project), -the package can be generated as below. - - ```console - $ cpack -C debug - CPack: Create package using DEB - ... - CPack: - package: /home//opentelemetry-cpp/build/opentelemetry-cpp-1.8.1-ubuntu-20.04-x86_64.deb generated. - $ - ``` - -## Using Package Managers - -If you are using [Conan](https://www.conan.io/) to manage your dependencies, add -[`opentelemetry-cpp/x.y.z`](https://conan.io/center/opentelemetry-cpp) to your -`conanfile`'s requires, where `x.y.z` is the release version you want to use. -Please file issues [here](https://github.com/conan-io/conan-center-index/issues) -if you experience problems with the packages. - -If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project -for external dependencies, then you can install the [opentelemetry-cpp -package](https://github.com/microsoft/vcpkg/tree/master/ports/opentelemetry-cpp) -with `vcpkg install opentelemetry-cpp` and follow the then displayed -descriptions. Please see the vcpkg project for any issues regarding the -packaging. - -If you are using [alpine linux](https://www.alpinelinux.org/) you can install -the [opentelemetry-cpp packages](https://pkgs.alpinelinux.org/packages?name=opentelemetry-cpp-*) -with `apk add -X http://dl-cdn.alpinelinux.org/alpine/edge/testing opentelemetry-cpp-dev`. - -Please note, these packages are not officially provided and maintained by -OpenTelemetry C++ project, and are just listed here to consolidate all such -efforts for ease of developers. diff --git a/ext/opentelemetry-cpp-1.21.0/LICENSE b/ext/opentelemetry-cpp-1.21.0/LICENSE deleted file mode 100644 index 261eeb9e9..000000000 --- a/ext/opentelemetry-cpp-1.21.0/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/ext/opentelemetry-cpp-1.21.0/MODULE.bazel b/ext/opentelemetry-cpp-1.21.0/MODULE.bazel deleted file mode 100644 index 59d844090..000000000 --- a/ext/opentelemetry-cpp-1.21.0/MODULE.bazel +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -module( - name = "opentelemetry-cpp", - version = "1.21.0", - compatibility_level = 0, - repo_name = "io_opentelemetry_cpp", -) - -bazel_dep(name = "abseil-cpp", version = "20240116.1", repo_name = "com_google_absl") -bazel_dep(name = "bazel_skylib", version = "1.5.0") -bazel_dep(name = "curl", version = "8.8.0") -bazel_dep(name = "grpc", version = "1.63.1.bcr.1", repo_name = "com_github_grpc_grpc") -bazel_dep(name = "nlohmann_json", version = "3.12.0", repo_name = "github_nlohmann_json") -bazel_dep(name = "opentelemetry-proto", version = "1.6.0", repo_name = "com_github_opentelemetry_proto") -bazel_dep(name = "opentracing-cpp", version = "1.6.0", repo_name = "com_github_opentracing") -bazel_dep(name = "platforms", version = "0.0.8") -bazel_dep(name = "prometheus-cpp", version = "1.3.0", repo_name = "com_github_jupp0r_prometheus_cpp") -bazel_dep(name = "protobuf", version = "26.0", repo_name = "com_google_protobuf") -bazel_dep(name = "rules_proto", version = "5.3.0-21.7") -bazel_dep(name = "zlib", version = "1.3.1.bcr.1") - -bazel_dep(name = "google_benchmark", version = "1.8.3", dev_dependency = True, repo_name = "com_github_google_benchmark") -bazel_dep(name = "googletest", version = "1.14.0.bcr.1", dev_dependency = True, repo_name = "com_google_googletest") diff --git a/ext/opentelemetry-cpp-1.21.0/README.md b/ext/opentelemetry-cpp-1.21.0/README.md deleted file mode 100644 index 01645aa8c..000000000 --- a/ext/opentelemetry-cpp-1.21.0/README.md +++ /dev/null @@ -1,127 +0,0 @@ -# OpenTelemetry C++ - -[![Slack](https://img.shields.io/badge/slack-@cncf/otel/cpp-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C01N3AT62SJ) -[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-cpp/branch/main/graphs/badge.svg?)](https://codecov.io/gh/open-telemetry/opentelemetry-cpp/) -[![Build -Status](https://github.com/open-telemetry/opentelemetry-cpp/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/open-telemetry/opentelemetry-cpp/actions) -[![Release](https://img.shields.io/github/v/release/open-telemetry/opentelemetry-cpp?include_prereleases&style=)](https://github.com/open-telemetry/opentelemetry-cpp/releases/) -[![FOSSA License Status](https://app.fossa.com/api/projects/custom%2B162%2Fgithub.com%2Fopen-telemetry%2Fopentelemetry-cpp.svg?type=shield&issueType=license)](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fopen-telemetry%2Fopentelemetry-cpp?ref=badge_shield&issueType=license) -[![FOSSA Security Status](https://app.fossa.com/api/projects/custom%2B162%2Fgithub.com%2Fopen-telemetry%2Fopentelemetry-cpp.svg?type=shield&issueType=security)](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fopen-telemetry%2Fopentelemetry-cpp?ref=badge_shield&issueType=security) - -The C++ [OpenTelemetry](https://opentelemetry.io/) client. - -## Project Status - -**Stable** across all 3 signals i.e. `Logs`, `Metrics`, and `Traces`. - -See [Spec Compliance -Matrix](https://github.com/open-telemetry/opentelemetry-specification/blob/main/spec-compliance-matrix.md) -to understand which portions of the specification has been implemented in this -repo. - -## Supported C++ Versions - -Code shipped from this repository generally supports the following versions of -C++ standards: - -* ISO/IEC 14882:2014 (C++14) -* ISO/IEC 14882:2017 (C++17) -* ISO/IEC 14882:2020 (C++20) - -Any exceptions to this are noted in the individual `README.md` files. - -Please note that supporting the [C Programming -Language](https://en.wikipedia.org/wiki/C_(programming_language)) is not a goal -of the current project. - -## Supported Development Platforms - - Our CI pipeline builds and tests on following `x86-64` platforms: - -| Platform | Build type | -|---------------------------------------------------------------------|---------------| -| ubuntu-22.04 (GCC 10, GCC 12, Clang 14) | CMake, Bazel | -| ubuntu-20.04 (GCC 9.4.0 - default compiler) | CMake, Bazel | -| ubuntu-20.04 (GCC 9.4.0 with -std=c++14/17/20 flags) | CMake, Bazel | -| macOS 12.7 (Xcode 14.2) | Bazel | -| Windows Server 2019 (Visual Studio Enterprise 2019) | CMake, Bazel | -| Windows Server 2022 (Visual Studio Enterprise 2022) | CMake | - -In general, the code shipped from this repository should build on all platforms -having C++ compiler with [supported C++ standards](#supported-c-versions). - -## Dependencies - -Please refer to [Dependencies.md](docs/dependencies.md) for OSS Dependencies and -license requirements. - -## Installation - -Please refer to [INSTALL.md](./INSTALL.md). - -## Getting Started - -As an application owner or the library author, you can find the getting started -guide and reference documentation on -[opentelemetry-cpp.readthedocs.io](https://opentelemetry-cpp.readthedocs.io/en/latest/) - -The `examples/simple` directory contains a minimal program demonstrating how to -instrument a small library using a simple `processor` and console `exporter`, -along with build files for CMake and Bazel. - -## Contributing - -See [CONTRIBUTING.md](CONTRIBUTING.md) - -We meet weekly, and the time of the meeting alternates between Monday at 13:00 -PT and Wednesday at 9:00 PT. The meeting is subject to change depending on -contributors' availability. Check the [OpenTelemetry community -calendar](https://github.com/open-telemetry/community#calendar) -for specific dates and Zoom meeting links. - -Meeting notes are available as a public [Google -doc](https://docs.google.com/document/d/1i1E4-_y4uJ083lCutKGDhkpi3n4_e774SBLi9hPLocw/edit?usp=sharing). -For edit access, get in touch on -[Slack](https://cloud-native.slack.com/archives/C01N3AT62SJ). - -[Maintainers](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer) -([@open-telemetry/cpp-maintainers](https://github.com/orgs/open-telemetry/teams/cpp-maintainers)): - -* [Ehsan Saei](https://github.com/esigo) -* [Lalit Kumar Bhasin](https://github.com/lalitb), Microsoft -* [Marc Alff](https://github.com/marcalff), Oracle -* [Tom Tan](https://github.com/ThomsonTan), Microsoft - -[Approvers](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver) -([@open-telemetry/cpp-approvers](https://github.com/orgs/open-telemetry/teams/cpp-approvers)): - -* [Doug Barker](https://github.com/dbarker) -* [Josh Suereth](https://github.com/jsuereth), Google -* [Pranav Sharma](https://github.com/psx95), Google -* [WenTao Ou](https://github.com/owent), Tencent - -[Emeritus -Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/community-membership.md#emeritus-maintainerapprovertriager): - -* [Alolita Sharma](https://github.com/alolita) -* [Emil Mikulic](https://github.com/g-easy) -* [Jodee Varney](https://github.com/jodeev) -* [Johannes Tax](https://github.com/pyohannes) -* [Max Golovanov](https://github.com/maxgolov) -* [Reiley Yang](https://github.com/reyang) -* [Ryan Burn](https://github.com/rnburn) - -### Thanks to all the people who have contributed - -[![contributors](https://contributors-img.web.app/image?repo=open-telemetry/opentelemetry-cpp)](https://github.com/open-telemetry/opentelemetry-cpp/graphs/contributors) - -## Release Schedule - -See the [release -notes](https://github.com/open-telemetry/opentelemetry-cpp/releases) for -existing releases. - -See the [project -milestones](https://github.com/open-telemetry/opentelemetry-cpp/milestones) for -details on upcoming releases. The dates and features described in issues and -milestones are estimates, and subject to change. diff --git a/ext/opentelemetry-cpp-1.21.0/RELEASING.md b/ext/opentelemetry-cpp-1.21.0/RELEASING.md deleted file mode 100644 index 852332e82..000000000 --- a/ext/opentelemetry-cpp-1.21.0/RELEASING.md +++ /dev/null @@ -1,96 +0,0 @@ -# Release Process - -## Pre Release - -1: Upgrade to latest [dependencies](docs/maintaining-dependencies.md) -if required. - -2: Make sure all relevant changes for this release are included under -`Unreleased` section in `CHANGELOG.md` and are in language that non-contributors -to the project can understand. - -3: Run the pre-release script. It creates a branch `pre_release_` and -updates `CHANGELOG.md` with the ``: - -```sh -./buildscripts/pre_release.sh -t -``` - -4: Verify that CHANGELOG.md is updated properly: - -```sh -git diff main -``` - -5: Push the changes to upstream and create a Pull Request on GitHub. Be sure to -include the curated changes from the [Changelog](./CHANGELOG.md) in the -description. - -## Tag - -Once the above Pull Request has been approved and merged it is time to tag the -merged commit. - -***IMPORTANT***: It is critical you use the same tag that you used in the -Pre-Release step! Failure to do so will leave things in a broken state. - -1: Note down the commit hash of the master branch after above PR request is -merged: `` - -```sh -git show -s --format=%H -``` - -2: Create a github tag on this commit hash: - -```sh -git tag -a "" -s -m "Version " "" -``` - -3: Push tag to upstream remote - -```sh -git push upstream -``` - -## Versioning - -Once tag is created, it's time to use that tag for Runtime Versioning - -1: Create a new brach for updating version information in -`./sdk/src/version.cc`. - -```sh -git checkout -b update_version_${tag} master -``` - -2: Run the pre-commit script to update the version: - -```sh -./buildscripts/pre-commit -``` - -3: Check if any changes made since last release broke ABI compatibility. If yes, -update `OPENTELEMETRY_ABI_VERSION_NO` in -[version.h](api/include/opentelemetry/version.h). - -4: Push the changes to upstream and create a Pull Request on GitHub. - -5: Once changes are merged, move the tag created earlier to the new commit hash -from step 4. - -```sh -git tag -f -git push --tags --force -``` - -## Release - -Finally create a Release for the new `` on GitHub. The release body -should include all the release notes from the Changelog for this release. - -## Post Release - -Update the OpenTelemetry.io document -[here](https://github.com/open-telemetry/opentelemetry.io/tree/main/content/en/docs/instrumentation/cpp) -by sending a Pull Request. diff --git a/ext/opentelemetry-cpp-1.21.0/Versioning.md b/ext/opentelemetry-cpp-1.21.0/Versioning.md deleted file mode 100644 index b6cbe490e..000000000 --- a/ext/opentelemetry-cpp-1.21.0/Versioning.md +++ /dev/null @@ -1,107 +0,0 @@ -# Versioning - -This document describes the versioning policy for this repository. - -## Goals - -### API and SDK Compatibility - -Once the API for a given signal (spans, logs, metrics, baggage) has been -officially released, that API module will function with any SDK that has the -same MAJOR version and equal or greater MINOR or PATCH version. For example, -application compiled with API v1.1 is compatible with SDK v1.1.2, v1.2.0, etc. - -For example, libraries that are instrumented with `opentelemetry 1.0.1` will -function in applications using `opentelemetry 1.11.33` or `opentelemetry 1.3.4`, -buy may not work in applications using `opentelemetry 2.0.0`. - -### ABI Stability - -Refer to the [ABI Policy](./docs/abi-policy.md) for more details. To summarise: - -* The API is header only, and uses ABI compliant interfaces. However, ABI - stability is not guaranteed for SDK. -* In case of ABI breaking changes, a new `inline namespace` version will be - introduced, and the existing linked applications can continue using the older - version unless they relink with newer version. - -## Release Policy - -* Release versions will follow [SemVer 2.0](https://semver.org/). -* Only a single source package containing the API, SDK, and exporters which are - required by the specification would be released. All these components are - always versioned and released together. For example, any changes in one of the - exporter would result in version update of the entire source package even - though there is no changes in API, SDK and other exporters. -* Experimental releases: New (unstable) telemetry signals and features will be - introduced behind feature flag protected by a preprocessor macro. - - ```cpp - #ifdef FEATURE_FLAG - - #endif - ``` - - As we deliver the package in source form, and the user is responsible to build - it for their platform, the user must be aware of these feature flags - (documented in the [CHANGELOG.md](CHANGELOG.md) file). The user must enable - them explicitly through their build system (CMake, Bazel or others) to use any - preview features. - - The guidelines in creating feature flag would be: - - * Naming: - * `ENABLE__PREVIEW` : For experimental release of signal api/sdks - eg, `METRICS_PREVIEW`, `LOGS_PREVIEW`, - * `ENABLE___PREVIEW` : For experimental release for - any feature within stable signal. For example, `TRACING_JAEGER_PREVIEW` to - release the experimental Jaeger exporter for tracing. - * Cleanup: It is good practice to keep feature-flags as shortlived as - possible. And, also important to keep the number of them low. They should be - used such that it is easy to remove/cleanup them once the experimental - feature is stable. - -* New signals will be stabilized via a **minor version bump**, and are not - allowed to break existing stable interfaces. Feature flags will be removed - once we have a stable implementation for the signal. - -* As an exception, small experimental features in otherwise stable - signals/components mayn't necessarily be released under feature flag. These - would be flagged as experimental by adding a `NOTE` in it's header file - - either at the beginning of file, or as the comment for the experimental API - methods. Also, if the complete header is experimental, it would be prefixed as - `experimental_`. As an example, the semantic conventions for trace signal is - experimental at the time of the writing and is within - `experimental_semantic_conventions.h` - -* Code under the "*::detail" namespace implements internal details, and is NOT - part of public interface. Also, any API not documented in the [public - documentation](https://opentelemetry-cpp.readthedocs.io/en/latest/) is NOT - part of the public interface. - -* GitHub releases will be made for all released versions. - -## Example Versioning Lifecycle - -Purely for illustration purposes, not intended to represent actual releases: - -* v0.0.1 release: - * Contains experimental API and SDK of trace (without feature flag) - * No API and SDK of logging and metrics available -* v1.0.0-rc1 release: - * Pre-release, no API/ABI guarantees, but more stable than alpha/beta. - * Contains pre-release API and SDK of trace, baggage and resource - * experimental metrics and logging API/SDK behind feature flag -* v1.0.0: ( with traces ) - * Contains stable API and SDK of trace, baggage and resource - * experimental metrics and logging API/SDK behind feature flag -* v1.5.0 release (with metrics) - * Contains stable API and SDK of metrics, trace, baggage, resource. - * experimental logging API/SDK behind feature flag -* v1.10.0 release (with logging) - * Contains stable API and SDK of logging, metrics, trace, baggage, resource. - -### Before moving to version 1.0.0 - -* Major version zero (0.y.z) is for initial development. Anything MAY change at - any time. The public API SHOULD NOT be considered stable. diff --git a/ext/opentelemetry-cpp-1.21.0/WORKSPACE b/ext/opentelemetry-cpp-1.21.0/WORKSPACE deleted file mode 100644 index a52788ece..000000000 --- a/ext/opentelemetry-cpp-1.21.0/WORKSPACE +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -workspace(name = "io_opentelemetry_cpp") - -# Load our direct dependencies. -load("//bazel:repository.bzl", "opentelemetry_cpp_deps") - -opentelemetry_cpp_deps() - -load("//bazel:extra_deps.bzl", "opentelemetry_extra_deps") - -opentelemetry_extra_deps() - -# Load gRPC dependencies after load. -load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps") - -grpc_deps() - -# Load extra gRPC dependencies due to https://github.com/grpc/grpc/issues/20511 -load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps") - -grpc_extra_deps() diff --git a/ext/opentelemetry-cpp-1.21.0/WORKSPACE.bzlmod b/ext/opentelemetry-cpp-1.21.0/WORKSPACE.bzlmod deleted file mode 100644 index 0db1b0462..000000000 --- a/ext/opentelemetry-cpp-1.21.0/WORKSPACE.bzlmod +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# Disables the default WORKSPACE when using bzlmod diff --git a/ext/opentelemetry-cpp-1.21.0/api/BUILD b/ext/opentelemetry-cpp-1.21.0/api/BUILD deleted file mode 100644 index fb3139356..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/BUILD +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "int_flag", "string_flag") - -package(default_visibility = ["//visibility:public"]) - -CPP_STDLIBS = [ - "none", - "best", - "2014", - "2017", - "2020", - "2023", -] - -string_flag( - name = "with_cxx_stdlib", - build_setting_default = "best", - values = CPP_STDLIBS, -) - -cc_library( - name = "api", - hdrs = glob(["include/**/*.h"]), - defines = select({ - ":set_cxx_stdlib_none": [], - ### automatic selection - ":set_cxx_stdlib_best": ["OPENTELEMETRY_STL_VERSION=(__cplusplus/100)"], - # See https://learn.microsoft.com/en-us/cpp/build/reference/zc-cplusplus - ":set_cxx_stdlib_best_and_msvc": ["OPENTELEMETRY_STL_VERSION=(_MSVC_LANG/100)"], - ### manual selection - ":set_cxx_stdlib_2014": ["OPENTELEMETRY_STL_VERSION=2014"], - ":set_cxx_stdlib_2017": ["OPENTELEMETRY_STL_VERSION=2017"], - ":set_cxx_stdlib_2020": ["OPENTELEMETRY_STL_VERSION=2020"], - ":set_cxx_stdlib_2023": ["OPENTELEMETRY_STL_VERSION=2023"], - "//conditions:default": [], - }) + select({ - ":abi_version_no_1": ["OPENTELEMETRY_ABI_VERSION_NO=1"], - ":abi_version_no_2": ["OPENTELEMETRY_ABI_VERSION_NO=2"], - }), - strip_include_prefix = "include", - tags = ["api"], - deps = [ - "@com_google_absl//absl/base", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/types:variant", - ], -) - -[config_setting( - name = "set_cxx_stdlib_%s" % v, - flag_values = {":with_cxx_stdlib": v}, -) for v in CPP_STDLIBS] - -config_setting( - name = "set_cxx_stdlib_best_and_msvc", - constraint_values = ["@bazel_tools//tools/cpp:msvc"], - flag_values = {":with_cxx_stdlib": "best"}, -) - -bool_flag( - name = "with_abseil", - build_setting_default = False, - deprecation = "The value of this flag is ignored. Bazel builds always depend on Abseil for its pre-adopted `std::` types. You should remove this flag from your build command.", -) - -int_flag( - name = "abi_version_no", - build_setting_default = 1, -) - -config_setting( - name = "abi_version_no_1", - flag_values = {":abi_version_no": "1"}, -) - -config_setting( - name = "abi_version_no_2", - flag_values = {":abi_version_no": "2"}, -) diff --git a/ext/opentelemetry-cpp-1.21.0/api/CMakeLists.txt b/ext/opentelemetry-cpp-1.21.0/api/CMakeLists.txt deleted file mode 100644 index 0707464b3..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/CMakeLists.txt +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -add_library(opentelemetry_api INTERFACE) -target_include_directories( - opentelemetry_api - INTERFACE "$" - "$") - -set_target_properties(opentelemetry_api PROPERTIES EXPORT_NAME api) - -otel_add_component( - COMPONENT - api - TARGETS - opentelemetry_api - FILES_DIRECTORY - "include/opentelemetry" - FILES_DESTINATION - "include" - FILES_MATCHING - PATTERN - "*.h") - -if(OPENTELEMETRY_INSTALL) - unset(TARGET_DEPS) -endif() - -if(BUILD_TESTING) - add_subdirectory(test) -endif() - -if(WITH_NO_DEPRECATED_CODE) - target_compile_definitions(opentelemetry_api - INTERFACE OPENTELEMETRY_NO_DEPRECATED_CODE) -endif() - -if(WITH_STL STREQUAL "OFF") - message(STATUS "Building WITH_STL=OFF") -elseif(WITH_STL STREQUAL "CXX11") - message(STATUS "Building WITH_STL=CXX11") - target_compile_definitions(opentelemetry_api - INTERFACE OPENTELEMETRY_STL_VERSION=2011) -elseif(WITH_STL STREQUAL "CXX14") - message(STATUS "Building WITH_STL=CXX14") - target_compile_definitions(opentelemetry_api - INTERFACE OPENTELEMETRY_STL_VERSION=2014) -elseif(WITH_STL STREQUAL "CXX17") - message(STATUS "Building WITH_STL=CXX17") - target_compile_definitions(opentelemetry_api - INTERFACE OPENTELEMETRY_STL_VERSION=2017) -elseif(WITH_STL STREQUAL "CXX20") - message(STATUS "Building WITH_STL=CXX20") - target_compile_definitions(opentelemetry_api - INTERFACE OPENTELEMETRY_STL_VERSION=2020) -elseif(WITH_STL STREQUAL "CXX23") - message(STATUS "Building WITH_STL=CXX23") - target_compile_definitions(opentelemetry_api - INTERFACE OPENTELEMETRY_STL_VERSION=2023) -elseif(WITH_STL STREQUAL "ON") - message(STATUS "Building WITH_STL=ON") - # "ON" corresponds to "CXX23" at this time. - target_compile_definitions(opentelemetry_api - INTERFACE OPENTELEMETRY_STL_VERSION=2023) -else() - message( - FATAL_ERROR "WITH_STL must be ON, OFF, CXX11, CXX14, CXX17, CXX20 or CXX23") -endif() - -if(WITH_GSL) - target_compile_definitions(opentelemetry_api INTERFACE HAVE_GSL) - - # Guidelines Support Library path. Used if we are not on not get C++20. - # - find_package(Microsoft.GSL QUIET) - if(TARGET Microsoft.GSL::GSL) - target_link_libraries(opentelemetry_api INTERFACE Microsoft.GSL::GSL) - list(APPEND TARGET_DEPS "gsl") - else() - set(GSL_DIR third_party/ms-gsl) - target_include_directories( - opentelemetry_api INTERFACE "$") - endif() -endif() - -if(WITH_NO_GETENV) - target_compile_definitions(opentelemetry_api INTERFACE NO_GETENV) -endif() - -if(WIN32) - if(WITH_ETW) - target_compile_definitions(opentelemetry_api INTERFACE HAVE_MSGPACK) - endif() -endif() - -if(WITH_ASYNC_EXPORT_PREVIEW) - target_compile_definitions(opentelemetry_api INTERFACE ENABLE_ASYNC_EXPORT) -endif() - -target_compile_definitions( - opentelemetry_api - INTERFACE OPENTELEMETRY_ABI_VERSION_NO=${OPENTELEMETRY_ABI_VERSION_NO}) - -if(WITH_OTLP_RETRY_PREVIEW) - target_compile_definitions(opentelemetry_api - INTERFACE ENABLE_OTLP_RETRY_PREVIEW) -endif() - -if(WITH_OTLP_GRPC_SSL_MTLS_PREVIEW) - target_compile_definitions(opentelemetry_api - INTERFACE ENABLE_OTLP_GRPC_SSL_MTLS_PREVIEW) -endif() - -if(WITH_METRICS_EXEMPLAR_PREVIEW) - target_compile_definitions(opentelemetry_api - INTERFACE ENABLE_METRICS_EXEMPLAR_PREVIEW) -endif() - -if(WITH_THREAD_INSTRUMENTATION_PREVIEW) - target_compile_definitions(opentelemetry_api - INTERFACE ENABLE_THREAD_INSTRUMENTATION_PREVIEW) -endif() - -if(WITH_OTLP_HTTP_COMPRESSION) - target_compile_definitions(opentelemetry_api - INTERFACE ENABLE_OTLP_COMPRESSION_PREVIEW) -endif() - -if(APPLE) - target_link_libraries(opentelemetry_api INTERFACE "-framework CoreFoundation") -endif() - -include(${PROJECT_SOURCE_DIR}/cmake/pkgconfig.cmake) - -if(OPENTELEMETRY_INSTALL) - opentelemetry_add_pkgconfig( - api "OpenTelemetry API" - "A header-only library to support instrumentation with OpenTelemetry." - "${TARGET_DEPS}") -endif() diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/baggage/baggage.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/baggage/baggage.h deleted file mode 100644 index 6c799cda2..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/baggage/baggage.h +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/common/kv_properties.h" -#include "opentelemetry/common/macros.h" -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE - -namespace baggage -{ - -class OPENTELEMETRY_EXPORT Baggage -{ -public: - static constexpr size_t kMaxKeyValuePairs = 180; - static constexpr size_t kMaxKeyValueSize = 4096; - static constexpr size_t kMaxSize = 8192; - static constexpr char kKeyValueSeparator = '='; - static constexpr char kMembersSeparator = ','; - static constexpr char kMetadataSeparator = ';'; - - Baggage() noexcept : kv_properties_(new common::KeyValueProperties()) {} - Baggage(size_t size) noexcept : kv_properties_(new common::KeyValueProperties(size)) {} - - template - Baggage(const T &keys_and_values) noexcept - : kv_properties_(new common::KeyValueProperties(keys_and_values)) - {} - - OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr GetDefault() - { - static nostd::shared_ptr baggage{new Baggage()}; - return baggage; - } - - /* Get value for key in the baggage - @returns true if key is found, false otherwise - */ - bool GetValue(nostd::string_view key, std::string &value) const noexcept - { - return kv_properties_->GetValue(key, value); - } - - /* Returns shared_ptr of new baggage object which contains new key-value pair. If key or value is - invalid, copy of current baggage is returned - */ - nostd::shared_ptr Set(const nostd::string_view &key, - const nostd::string_view &value) noexcept - { - - nostd::shared_ptr baggage(new Baggage(kv_properties_->Size() + 1)); - const bool valid_kv = IsValidKey(key) && IsValidValue(value); - - if (valid_kv) - { - baggage->kv_properties_->AddEntry(key, value); - } - - // add rest of the fields. - kv_properties_->GetAllEntries( - [&baggage, &key, &valid_kv](nostd::string_view e_key, nostd::string_view e_value) { - // if key or value was not valid, add all the entries. Add only remaining entries - // otherwise. - if (!valid_kv || key != e_key) - { - baggage->kv_properties_->AddEntry(e_key, e_value); - } - - return true; - }); - - return baggage; - } - - // @return all key-values entries by repeatedly invoking the function reference passed as argument - // for each entry - bool GetAllEntries( - nostd::function_ref callback) const noexcept - { - return kv_properties_->GetAllEntries(callback); - } - - // delete key from the baggage if it exists. Returns shared_ptr of new baggage object. - // if key does not exist, copy of current baggage is returned. - // Validity of key is not checked as invalid keys should never be populated in baggage in the - // first place. - nostd::shared_ptr Delete(nostd::string_view key) noexcept - { - // keeping size of baggage same as key might not be found in it - nostd::shared_ptr baggage(new Baggage(kv_properties_->Size())); - kv_properties_->GetAllEntries( - [&baggage, &key](nostd::string_view e_key, nostd::string_view e_value) { - if (key != e_key) - baggage->kv_properties_->AddEntry(e_key, e_value); - return true; - }); - return baggage; - } - - // Returns shared_ptr of baggage after extracting key-value pairs from header - static nostd::shared_ptr FromHeader(nostd::string_view header) noexcept - { - if (header.size() > kMaxSize) - { - // header size exceeds maximum threshold, return empty baggage - return GetDefault(); - } - - common::KeyValueStringTokenizer kv_str_tokenizer(header); - size_t cnt = kv_str_tokenizer.NumTokens(); // upper bound on number of kv pairs - if (cnt > kMaxKeyValuePairs) - { - cnt = kMaxKeyValuePairs; - } - - nostd::shared_ptr baggage(new Baggage(cnt)); - bool kv_valid; - nostd::string_view key, value; - - while (kv_str_tokenizer.next(kv_valid, key, value) && baggage->kv_properties_->Size() < cnt) - { - if (!kv_valid || (key.size() + value.size() > kMaxKeyValueSize)) - { - // if kv pair is not valid, skip it - continue; - } - - // NOTE : metadata is kept as part of value only as it does not have any semantic meaning. - // but, we need to extract it (else Decode on value will return error) - nostd::string_view metadata; - auto metadata_separator = value.find(kMetadataSeparator); - if (metadata_separator != std::string::npos) - { - metadata = value.substr(metadata_separator); - value = value.substr(0, metadata_separator); - } - - bool err = 0; - auto key_str = UrlDecode(common::StringUtil::Trim(key), err); - auto value_str = UrlDecode(common::StringUtil::Trim(value), err); - - if (err == false && IsValidKey(key_str) && IsValidValue(value_str)) - { - if (!metadata.empty()) - { - value_str.append(metadata.data(), metadata.size()); - } - baggage->kv_properties_->AddEntry(key_str, value_str); - } - } - - return baggage; - } - - // Creates string from baggage object. - std::string ToHeader() const noexcept - { - std::string header_s; - bool first = true; - kv_properties_->GetAllEntries([&](nostd::string_view key, nostd::string_view value) { - if (!first) - { - header_s.push_back(kMembersSeparator); - } - else - { - first = false; - } - header_s.append(UrlEncode(key)); - header_s.push_back(kKeyValueSeparator); - - // extracting metadata from value. We do not encode metadata - auto metadata_separator = value.find(kMetadataSeparator); - if (metadata_separator != std::string::npos) - { - header_s.append(UrlEncode(value.substr(0, metadata_separator))); - auto metadata = value.substr(metadata_separator); - header_s.append(std::string(metadata.data(), metadata.size())); - } - else - { - header_s.append(UrlEncode(value)); - } - return true; - }); - return header_s; - } - -private: - static bool IsPrintableString(nostd::string_view str) - { - for (const auto ch : str) - { - if (ch < ' ' || ch > '~') - { - return false; - } - } - - return true; - } - - static bool IsValidKey(nostd::string_view key) { return key.size() && IsPrintableString(key); } - - static bool IsValidValue(nostd::string_view value) { return IsPrintableString(value); } - - // Uri encode key value pairs before injecting into header - // Implementation inspired from : https://golang.org/src/net/url/url.go?s=7851:7884#L264 - static std::string UrlEncode(nostd::string_view str) - { - auto to_hex = [](char c) -> char { - static const char *hex = "0123456789ABCDEF"; - return hex[c & 15]; - }; - - std::string ret; - - for (auto c : str) - { - if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') - { - ret.push_back(c); - } - else if (c == ' ') - { - ret.push_back('+'); - } - else - { - ret.push_back('%'); - ret.push_back(to_hex(c >> 4)); - ret.push_back(to_hex(c & 15)); - } - } - - return ret; - } - - // Uri decode key value pairs after extracting from header - static std::string UrlDecode(nostd::string_view str, bool &err) - { - auto IsHex = [](char c) { - return std::isdigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); - }; - - auto from_hex = [](char c) -> char { - // c - '0' produces integer type which could trigger error/warning when casting to char, - // but the cast is safe here. - return static_cast(std::isdigit(c) ? c - '0' : std::toupper(c) - 'A' + 10); - }; - - std::string ret; - - for (size_t i = 0; i < str.size(); i++) - { - if (str[i] == '%') - { - if (i + 2 >= str.size() || !IsHex(str[i + 1]) || !IsHex(str[i + 2])) - { - err = 1; - return ""; - } - ret.push_back(from_hex(str[i + 1]) << 4 | from_hex(str[i + 2])); - i += 2; - } - else if (str[i] == '+') - { - ret.push_back(' '); - } - else if (std::isalnum(str[i]) || str[i] == '-' || str[i] == '_' || str[i] == '.' || - str[i] == '~') - { - ret.push_back(str[i]); - } - else - { - err = 1; - return ""; - } - } - - return ret; - } - -private: - // Store entries in a C-style array to avoid using std::array or std::vector. - nostd::unique_ptr kv_properties_; -}; - -} // namespace baggage - -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/baggage/baggage_context.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/baggage/baggage_context.h deleted file mode 100644 index a0016353b..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/baggage/baggage_context.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/baggage/baggage.h" -#include "opentelemetry/context/context.h" -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE - -namespace baggage -{ - -static const std::string kBaggageHeader = "baggage"; - -inline nostd::shared_ptr GetBaggage(const context::Context &context) noexcept -{ - context::ContextValue context_value = context.GetValue(kBaggageHeader); - if (nostd::holds_alternative>(context_value)) - { - return nostd::get>(context_value); - } - static nostd::shared_ptr empty_baggage{new Baggage()}; - return empty_baggage; -} - -inline context::Context SetBaggage(context::Context &context, - const nostd::shared_ptr &baggage) noexcept -{ - return context.SetValue(kBaggageHeader, baggage); -} - -} // namespace baggage -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/baggage/propagation/baggage_propagator.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/baggage/propagation/baggage_propagator.h deleted file mode 100644 index d75409ed6..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/baggage/propagation/baggage_propagator.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include "opentelemetry/baggage/baggage.h" -#include "opentelemetry/baggage/baggage_context.h" -#include "opentelemetry/context/context.h" -#include "opentelemetry/context/propagation/text_map_propagator.h" -#include "opentelemetry/nostd/function_ref.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace baggage -{ -namespace propagation -{ - -class BaggagePropagator : public context::propagation::TextMapPropagator -{ -public: - void Inject(context::propagation::TextMapCarrier &carrier, - const context::Context &context) noexcept override - { - auto baggage = baggage::GetBaggage(context); - auto header = baggage->ToHeader(); - if (header.size()) - { - carrier.Set(kBaggageHeader, header); - } - } - - context::Context Extract(const context::propagation::TextMapCarrier &carrier, - context::Context &context) noexcept override - { - nostd::string_view baggage_str = carrier.Get(baggage::kBaggageHeader); - auto baggage = baggage::Baggage::FromHeader(baggage_str); - - if (baggage->ToHeader().size()) - { - return baggage::SetBaggage(context, baggage); - } - else - { - return context; - } - } - - bool Fields(nostd::function_ref callback) const noexcept override - { - return callback(kBaggageHeader); - } -}; -} // namespace propagation -} // namespace baggage -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/attribute_value.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/attribute_value.h deleted file mode 100644 index af4cc83d4..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/attribute_value.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/nostd/span.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/variant.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace common -{ -/// OpenTelemetry signals can be enriched by adding attributes. The -/// \c AttributeValue type is defined as a variant of all attribute value -/// types the OpenTelemetry C++ API supports. -/// -/// The following attribute value types are supported by the OpenTelemetry -/// specification: -/// - Primitive types: string, boolean, double precision floating point -/// (IEEE 754-1985) or signed 64 bit integer. -/// - Homogenous arrays of primitive type values. -/// -/// \warning -/// \parblock The OpenTelemetry C++ API currently supports several attribute -/// value types that are not covered by the OpenTelemetry specification: -/// - \c uint64_t -/// - \c nostd::span -/// - \c nostd::span -/// -/// Those types are reserved for future use and currently should not be -/// used. There are no guarantees around how those values are handled by -/// exporters. -/// \endparblock -using AttributeValue = - nostd::variant, - nostd::span, - nostd::span, - nostd::span, - nostd::span, - nostd::span, - // Not currently supported by the specification, but reserved for future use. - // Added to provide support for all primitive C++ types. - uint64_t, - // Not currently supported by the specification, but reserved for future use. - // Added to provide support for all primitive C++ types. - nostd::span, - // Not currently supported by the specification, but reserved for future use. - // See https://github.com/open-telemetry/opentelemetry-specification/issues/780 - nostd::span>; - -enum AttributeType -{ - kTypeBool, - kTypeInt, - kTypeInt64, - kTypeUInt, - kTypeDouble, - kTypeCString, - kTypeString, - kTypeSpanBool, - kTypeSpanInt, - kTypeSpanInt64, - kTypeSpanUInt, - kTypeSpanDouble, - kTypeSpanString, - kTypeUInt64, - kTypeSpanUInt64, - kTypeSpanByte -}; - -} // namespace common -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/key_value_iterable.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/key_value_iterable.h deleted file mode 100644 index 9d43e1571..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/key_value_iterable.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/common/attribute_value.h" -#include "opentelemetry/nostd/function_ref.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace common -{ -/** - * Supports internal iteration over a collection of key-value pairs. - */ -class KeyValueIterable -{ -public: - virtual ~KeyValueIterable() = default; - - /** - * Iterate over key-value pairs - * @param callback a callback to invoke for each key-value. If the callback returns false, - * the iteration is aborted. - * @return true if every key-value pair was iterated over - */ - virtual bool ForEachKeyValue(nostd::function_ref - callback) const noexcept = 0; - - /** - * @return the number of key-value pairs - */ - virtual size_t size() const noexcept = 0; -}; - -/** - * Supports internal iteration over a collection of key-value pairs. - */ -class NoopKeyValueIterable : public KeyValueIterable -{ -public: - ~NoopKeyValueIterable() override = default; - - /** - * Iterate over key-value pairs - * @param callback a callback to invoke for each key-value. If the callback returns false, - * the iteration is aborted. - * @return true if every key-value pair was iterated over - */ - bool ForEachKeyValue( - nostd::function_ref) const noexcept override - { - return true; - } - - /** - * @return the number of key-value pairs - */ - size_t size() const noexcept override { return 0; } -}; - -} // namespace common -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/key_value_iterable_view.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/key_value_iterable_view.h deleted file mode 100644 index e22fb6f06..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/key_value_iterable_view.h +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "opentelemetry/common/attribute_value.h" -#include "opentelemetry/common/key_value_iterable.h" -#include "opentelemetry/nostd/function_ref.h" -#include "opentelemetry/nostd/span.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/type_traits.h" -#include "opentelemetry/nostd/utility.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace common -{ -// NOTE - code within `detail` namespace implements internal details, and not part -// of the public interface. -namespace detail -{ -inline void take_key_value(nostd::string_view, common::AttributeValue) {} - -template -auto is_key_value_iterable_impl(T iterable) - -> decltype(take_key_value(std::begin(iterable)->first, std::begin(iterable)->second), - nostd::size(iterable), - std::true_type{}); - -std::false_type is_key_value_iterable_impl(...); - -template -struct is_key_value_iterable -{ - static const bool value = decltype(detail::is_key_value_iterable_impl(std::declval()))::value; -}; -} // namespace detail - -/** - * @brief Container for key-value pairs that can transform every value in it to one of types - * listed in common::AttributeValue. It may contain value types that are not directly map'able - * to primitive value types. In that case the `ForEachKeyValue` method acts as a transform to - * convert the value type to one listed under AtributeValue (bool, int32_t, int64_t, uint32_t, - * uint64_t, double, nostd::string_view, or arrays of primite types). For example, if UUID, - * GUID, or UTF-16 string type is passed as one of values stored inside this container, the - * container itself may provide a custom implementation of `ForEachKeyValue` to transform the - * 'non-standard' type to one of the standard types. - */ -template -class KeyValueIterableView final : public KeyValueIterable -{ - -public: - explicit KeyValueIterableView(const T &container) noexcept : container_{&container} {} - - // KeyValueIterable - bool ForEachKeyValue(nostd::function_ref - callback) const noexcept override - { - auto iter = std::begin(*container_); - auto last = std::end(*container_); - for (; iter != last; ++iter) - { - if (!callback(iter->first, iter->second)) - { - return false; - } - } - return true; - } - - size_t size() const noexcept override { return nostd::size(*container_); } - -private: - const T *container_; -}; - -template ::value> * = nullptr> -KeyValueIterableView MakeKeyValueIterableView(const T &container) noexcept -{ - return KeyValueIterableView(container); -} - -/** - * Utility function to help to make a attribute view from initializer_list - * - * @param attributes - * @return nostd::span> - */ -inline static nostd::span> -MakeAttributes(std::initializer_list> - attributes) noexcept -{ - return nostd::span>{ - attributes.begin(), attributes.end()}; -} - -/** - * Utility function to help to make a attribute view from a span - * - * @param attributes - * @return nostd::span> - */ -inline static nostd::span> -MakeAttributes( - nostd::span> attributes) noexcept -{ - return attributes; -} - -/** - * Utility function to help to make a attribute view from a KeyValueIterable - * - * @param attributes - * @return common::KeyValueIterable - */ -inline static const common::KeyValueIterable &MakeAttributes( - const common::KeyValueIterable &attributes) noexcept -{ - return attributes; -} - -/** - * Utility function to help to make a attribute view from a key-value iterable object - * - * @param attributes - * @return nostd::span> - */ -template < - class ArgumentType, - nostd::enable_if_t::value> * = nullptr> -inline static common::KeyValueIterableView MakeAttributes( - const ArgumentType &arg) noexcept -{ - return common::KeyValueIterableView(arg); -} - -} // namespace common -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/kv_properties.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/kv_properties.h deleted file mode 100644 index b5accab40..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/kv_properties.h +++ /dev/null @@ -1,272 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/common/key_value_iterable_view.h" -#include "opentelemetry/common/string_util.h" -#include "opentelemetry/nostd/function_ref.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/unique_ptr.h" -#include "opentelemetry/version.h" - -#include -#include -#include - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace common -{ - -// Constructor parameter for KeyValueStringTokenizer -struct KeyValueStringTokenizerOptions -{ - char member_separator = ','; - char key_value_separator = '='; - bool ignore_empty_members = true; -}; - -// Tokenizer for key-value headers -class KeyValueStringTokenizer -{ -public: - KeyValueStringTokenizer( - nostd::string_view str, - const KeyValueStringTokenizerOptions &opts = KeyValueStringTokenizerOptions()) noexcept - : str_(str), opts_(opts), index_(0) - {} - - static nostd::string_view GetDefaultKeyOrValue() - { - static std::string default_str = ""; - return default_str; - } - - // Returns next key value in the string header - // @param valid_kv : if the found kv pair is valid or not - // @param key : key in kv pair - // @param key : value in kv pair - // @returns true if next kv pair was found, false otherwise. - bool next(bool &valid_kv, nostd::string_view &key, nostd::string_view &value) noexcept - { - valid_kv = true; - while (index_ < str_.size()) - { - bool is_empty_pair = false; - size_t end = str_.find(opts_.member_separator, index_); - if (end == std::string::npos) - { - end = str_.size() - 1; - } - else if (end == index_) // empty pair. do not update end - { - is_empty_pair = true; - } - else - { - end--; - } - - auto list_member = StringUtil::Trim(str_, index_, end); - if (list_member.size() == 0 || is_empty_pair) - { - // empty list member - index_ = end + 2 - is_empty_pair; - if (opts_.ignore_empty_members) - { - continue; - } - - valid_kv = true; - key = GetDefaultKeyOrValue(); - value = GetDefaultKeyOrValue(); - return true; - } - - auto key_end_pos = list_member.find(opts_.key_value_separator); - if (key_end_pos == std::string::npos) - { - // invalid member - valid_kv = false; - } - else - { - key = list_member.substr(0, key_end_pos); - value = list_member.substr(key_end_pos + 1); - } - - index_ = end + 2; - - return true; - } - - // no more entries remaining - return false; - } - - // Returns total number of tokens in header string - size_t NumTokens() const noexcept - { - size_t cnt = 0, begin = 0; - while (begin < str_.size()) - { - ++cnt; - size_t end = str_.find(opts_.member_separator, begin); - if (end == std::string::npos) - { - break; - } - - begin = end + 1; - } - - return cnt; - } - - // Resets the iterator - void reset() noexcept { index_ = 0; } - -private: - nostd::string_view str_; - KeyValueStringTokenizerOptions opts_; - size_t index_; -}; - -// Class to store fixed size array of key-value pairs of string type -class KeyValueProperties -{ - // Class to store key-value pairs of string types -public: - class Entry - { - public: - Entry() : key_(nullptr), value_(nullptr) {} - - // Copy constructor - Entry(const Entry ©) - { - key_ = CopyStringToPointer(copy.key_.get()); - value_ = CopyStringToPointer(copy.value_.get()); - } - - // Copy assignment operator - Entry &operator=(Entry &other) - { - key_ = CopyStringToPointer(other.key_.get()); - value_ = CopyStringToPointer(other.value_.get()); - return *this; - } - - // Move contructor and assignment operator - Entry(Entry &&other) = default; - Entry &operator=(Entry &&other) = default; - - // Creates an Entry for a given key-value pair. - Entry(nostd::string_view key, nostd::string_view value) - { - key_ = CopyStringToPointer(key); - value_ = CopyStringToPointer(value); - } - - // Gets the key associated with this entry. - nostd::string_view GetKey() const noexcept { return key_.get(); } - - // Gets the value associated with this entry. - nostd::string_view GetValue() const noexcept { return value_.get(); } - - // Sets the value for this entry. This overrides the previous value. - void SetValue(nostd::string_view value) noexcept { value_ = CopyStringToPointer(value); } - - private: - // Store key and value as raw char pointers to avoid using std::string. - nostd::unique_ptr key_; - nostd::unique_ptr value_; - - // Copies string into a buffer and returns a unique_ptr to the buffer. - // This is a workaround for the fact that memcpy doesn't accept a const destination. - nostd::unique_ptr CopyStringToPointer(nostd::string_view str) - { - char *temp = new char[str.size() + 1]; - memcpy(temp, str.data(), str.size()); - temp[str.size()] = '\0'; - return nostd::unique_ptr(temp); - } - }; - - // Maintain the number of entries in entries_. - size_t num_entries_; - - // Max size of allocated array - size_t max_num_entries_; - - // Store entries in a C-style array to avoid using std::array or std::vector. - nostd::unique_ptr entries_; - -public: - // Create Key-value list of given size - // @param size : Size of list. - KeyValueProperties(size_t size) noexcept - : num_entries_(0), max_num_entries_(size), entries_(new Entry[size]) - {} - - // Create Empty Key-Value list - KeyValueProperties() noexcept : num_entries_(0), max_num_entries_(0), entries_(nullptr) {} - - template ::value>::type> - KeyValueProperties(const T &keys_and_values) noexcept - : num_entries_(0), - max_num_entries_(keys_and_values.size()), - entries_(new Entry[max_num_entries_]) - { - for (auto &e : keys_and_values) - { - Entry entry(e.first, e.second); - (entries_.get())[num_entries_++] = std::move(entry); - } - } - - // Adds new kv pair into kv properties - void AddEntry(nostd::string_view key, nostd::string_view value) noexcept - { - if (num_entries_ < max_num_entries_) - { - Entry entry(key, value); - (entries_.get())[num_entries_++] = std::move(entry); - } - } - - // Returns all kv pair entries - bool GetAllEntries( - nostd::function_ref callback) const noexcept - { - for (size_t i = 0; i < num_entries_; i++) - { - auto &entry = (entries_.get())[i]; - if (!callback(entry.GetKey(), entry.GetValue())) - { - return false; - } - } - return true; - } - - // Return value for key if exists, return false otherwise - bool GetValue(nostd::string_view key, std::string &value) const noexcept - { - for (size_t i = 0; i < num_entries_; i++) - { - auto &entry = (entries_.get())[i]; - if (entry.GetKey() == key) - { - const auto &entry_value = entry.GetValue(); - value = std::string(entry_value.data(), entry_value.size()); - return true; - } - } - return false; - } - - size_t Size() const noexcept { return num_entries_; } -}; -} // namespace common -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/macros.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/macros.h deleted file mode 100644 index 71d12a57b..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/macros.h +++ /dev/null @@ -1,523 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -/* - OPENTELEMETRY_HAVE_BUILTIN&OPENTELEMETRY_HAVE_FEATURE - - Checks whether the compiler supports a Clang Feature Checking Macro, and if - so, checks whether it supports the provided builtin function "x" where x - is one of the functions noted in - https://clang.llvm.org/docs/LanguageExtensions.html - - Note: Use this macro to avoid an extra level of #ifdef __has_builtin check. - http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html -*/ -#if !defined(OPENTELEMETRY_HAVE_BUILTIN) -# ifdef __has_builtin -# define OPENTELEMETRY_HAVE_BUILTIN(x) __has_builtin(x) -# else -# define OPENTELEMETRY_HAVE_BUILTIN(x) 0 -# endif -#endif - -#if !defined(OPENTELEMETRY_HAVE_FEATURE) -# ifdef __has_feature -# define OPENTELEMETRY_HAVE_FEATURE(f) __has_feature(f) -# else -# define OPENTELEMETRY_HAVE_FEATURE(f) 0 -# endif -#endif - -/* - has feature - - OPENTELEMETRY_HAVE_ATTRIBUTE - - A function-like feature checking macro that is a wrapper around - `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a - nonzero constant integer if the attribute is supported or 0 if not. - - It evaluates to zero if `__has_attribute` is not defined by the compiler. - - GCC: https://gcc.gnu.org/gcc-5/changes.html - Clang: https://clang.llvm.org/docs/LanguageExtensions.html -*/ -#if !defined(OPENTELEMETRY_HAVE_ATTRIBUTE) -# ifdef __has_attribute -# define OPENTELEMETRY_HAVE_ATTRIBUTE(x) __has_attribute(x) -# else -# define OPENTELEMETRY_HAVE_ATTRIBUTE(x) 0 -# endif -#endif - -/* - OPENTELEMETRY_HAVE_CPP_ATTRIBUTE - - A function-like feature checking macro that accepts C++11 style attributes. - It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6 - (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't - find `__has_cpp_attribute`, will evaluate to 0. -*/ -#if !defined(OPENTELEMETRY_HAVE_CPP_ATTRIBUTE) -# if defined(__cplusplus) && defined(__has_cpp_attribute) -// NOTE: requiring __cplusplus above should not be necessary, but -// works around https://bugs.llvm.org/show_bug.cgi?id=23435. -# define OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) -# else -# define OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(x) 0 -# endif -#endif - -/* - Expected usage pattern: - - if OPENTELEMETRY_LIKELY_CONDITION (ptr != nullptr) - { - do_something_likely(); - } else { - do_something_unlikely(); - } - - This pattern works with gcc/clang and __builtin_expect(), - as well as with C++20. - It is unclear if __builtin_expect() will be deprecated - in favor of C++20 [[likely]] or not. - - OPENTELEMETRY_LIKELY_CONDITION is preferred over OPENTELEMETRY_LIKELY, - to be revisited when C++20 is required. -*/ - -#if !defined(OPENTELEMETRY_LIKELY_CONDITION) && defined(__cplusplus) -// Only use likely with C++20 -# if __cplusplus >= 202002L -// GCC 9 has likely attribute but do not support declare it at the beginning of statement -# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9) -# if __has_cpp_attribute(likely) -# define OPENTELEMETRY_LIKELY_CONDITION(C) (C) [[likely]] -# endif -# endif -# endif -#endif -#if !defined(OPENTELEMETRY_LIKELY_CONDITION) && (defined(__clang__) || defined(__GNUC__)) -// Only use if supported by the compiler -# define OPENTELEMETRY_LIKELY_CONDITION(C) (__builtin_expect(!!(C), true)) -#endif -#ifndef OPENTELEMETRY_LIKELY_CONDITION -// Do not use likely annotations -# define OPENTELEMETRY_LIKELY_CONDITION(C) (C) -#endif - -#if !defined(OPENTELEMETRY_UNLIKELY_CONDITION) && defined(__cplusplus) -// Only use unlikely with C++20 -# if __cplusplus >= 202002L -// GCC 9 has unlikely attribute but do not support declare it at the beginning of statement -# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9) -# if __has_cpp_attribute(unlikely) -# define OPENTELEMETRY_UNLIKELY_CONDITION(C) (C) [[unlikely]] -# endif -# endif -# endif -#endif -#if !defined(OPENTELEMETRY_UNLIKELY_CONDITION) && (defined(__clang__) || defined(__GNUC__)) -// Only use if supported by the compiler -# define OPENTELEMETRY_UNLIKELY_CONDITION(C) (__builtin_expect(!!(C), false)) -#endif -#ifndef OPENTELEMETRY_UNLIKELY_CONDITION -// Do not use unlikely annotations -# define OPENTELEMETRY_UNLIKELY_CONDITION(C) (C) -#endif - -/* - Expected usage pattern: - - if (ptr != nullptr) - OPENTELEMETRY_LIKELY - { - do_something_likely(); - } else { - do_something_unlikely(); - } - - This pattern works starting with C++20. - See https://en.cppreference.com/w/cpp/language/attributes/likely - - Please use OPENTELEMETRY_LIKELY_CONDITION instead for now. -*/ - -#if !defined(OPENTELEMETRY_LIKELY) && defined(__cplusplus) -// Only use likely with C++20 -# if __cplusplus >= 202002L -// GCC 9 has likely attribute but do not support declare it at the beginning of statement -# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9) -# if __has_cpp_attribute(likely) -# define OPENTELEMETRY_LIKELY [[likely]] -# endif -# endif -# endif -#endif - -#ifndef OPENTELEMETRY_LIKELY -# define OPENTELEMETRY_LIKELY -#endif - -#if !defined(OPENTELEMETRY_UNLIKELY) && defined(__cplusplus) -// Only use unlikely with C++20 -# if __cplusplus >= 202002L -// GCC 9 has unlikely attribute but do not support declare it at the beginning of statement -# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9) -# if __has_cpp_attribute(unlikely) -# define OPENTELEMETRY_UNLIKELY [[unlikely]] -# endif -# endif -# endif -#endif - -#ifndef OPENTELEMETRY_UNLIKELY -# define OPENTELEMETRY_UNLIKELY -#endif - -/// \brief Declare variable as maybe unused -/// usage: -/// OPENTELEMETRY_MAYBE_UNUSED int a; -/// class OPENTELEMETRY_MAYBE_UNUSED a; -/// OPENTELEMETRY_MAYBE_UNUSED int a(); -/// -#if defined(__cplusplus) && __cplusplus >= 201703L -# define OPENTELEMETRY_MAYBE_UNUSED [[maybe_unused]] -#elif defined(__clang__) -# define OPENTELEMETRY_MAYBE_UNUSED __attribute__((unused)) -#elif defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) -# define OPENTELEMETRY_MAYBE_UNUSED __attribute__((unused)) -#elif (defined(_MSC_VER) && _MSC_VER >= 1910) && (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -# define OPENTELEMETRY_MAYBE_UNUSED [[maybe_unused]] -#else -# define OPENTELEMETRY_MAYBE_UNUSED -#endif - -#ifndef OPENTELEMETRY_RTTI_ENABLED -# if defined(__clang__) -# if __has_feature(cxx_rtti) -# define OPENTELEMETRY_RTTI_ENABLED -# endif -# elif defined(__GNUG__) -# if defined(__GXX_RTTI) -# define OPENTELEMETRY_RTTI_ENABLED -# endif -# elif defined(_MSC_VER) -# if defined(_CPPRTTI) -# define OPENTELEMETRY_RTTI_ENABLED -# endif -# endif -#endif - -#if defined(__cplusplus) && __cplusplus >= 201402L -# define OPENTELEMETRY_DEPRECATED [[deprecated]] -#elif defined(__clang__) -# define OPENTELEMETRY_DEPRECATED __attribute__((deprecated)) -#elif defined(__GNUC__) -# define OPENTELEMETRY_DEPRECATED __attribute__((deprecated)) -#elif defined(_MSC_VER) -# if _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L -# define OPENTELEMETRY_DEPRECATED [[deprecated]] -# else -# define OPENTELEMETRY_DEPRECATED __declspec(deprecated) -# endif -#else -# define OPENTELEMETRY_DEPRECATED -#endif - -#if defined(__cplusplus) && __cplusplus >= 201402L -# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]] -#elif defined(__clang__) -# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __attribute__((deprecated(msg))) -#elif defined(__GNUC__) -# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __attribute__((deprecated(msg))) -#elif defined(_MSC_VER) -# if _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L -# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]] -# else -# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __declspec(deprecated(msg)) -# endif -#else -# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) -#endif - -// Regex support -#if (__GNUC__ == 4 && (__GNUC_MINOR__ == 8 || __GNUC_MINOR__ == 9)) -# define OPENTELEMETRY_HAVE_WORKING_REGEX 0 -#else -# define OPENTELEMETRY_HAVE_WORKING_REGEX 1 -#endif - -/* clang-format off */ - -/** - @page HEADER_ONLY_SINGLETON Header only singleton. - - @section ELF_SINGLETON - - For clang and gcc, the desired coding pattern is as follows. - - @verbatim - class Foo - { - // (a) - __attribute__((visibility("default"))) - // (b) - T& get_singleton() - { - // (c) - static T singleton; - return singleton; - } - }; - @endverbatim - - (a) is needed when the code is build with - @code -fvisibility="hidden" @endcode - to ensure that all instances of (b) are visible to the linker. - - What is duplicated in the binary is @em code, in (b). - - The linker will make sure only one instance - of all the (b) methods is used. - - (c) is a singleton implemented inside a method. - - This is very desirable, because: - - - the C++ compiler guarantees that construction - of the variable (c) is thread safe. - - - constructors for (c) singletons are executed in code path order, - or not at all if the singleton is never used. - - @section OTHER_SINGLETON - - For other platforms, header only singletons are not supported at this -point. - - @section CODING_PATTERN - - The coding pattern to use in the source code is as follows - - @verbatim - class Foo - { - OPENTELEMETRY_API_SINGLETON - T& get_singleton() - { - static T singleton; - return singleton; - } - }; - @endverbatim -*/ - -/* clang-format on */ - -#if defined(__clang__) - -# define OPENTELEMETRY_API_SINGLETON __attribute__((visibility("default"))) -# define OPENTELEMETRY_LOCAL_SYMBOL __attribute__((visibility("hidden"))) - -#elif defined(__GNUC__) - -# define OPENTELEMETRY_API_SINGLETON __attribute__((visibility("default"))) -# define OPENTELEMETRY_LOCAL_SYMBOL __attribute__((visibility("hidden"))) - -#else - -/* Add support for other compilers here. */ - -# define OPENTELEMETRY_API_SINGLETON -# define OPENTELEMETRY_LOCAL_SYMBOL - -#endif - -// -// Atomic wrappers based on compiler intrinsics for memory read/write. -// The tailing number is read/write length in bits. -// -// N.B. Compiler intrinsic is used because the usage of C++ standard library is restricted in the -// OpenTelemetry C++ API. -// -#if defined(__GNUC__) - -# define OPENTELEMETRY_ATOMIC_READ_8(ptr) __atomic_load_n(ptr, __ATOMIC_SEQ_CST) -# define OPENTELEMETRY_ATOMIC_WRITE_8(ptr, value) __atomic_store_n(ptr, value, __ATOMIC_SEQ_CST) - -#elif defined(_MSC_VER) - -# include - -# define OPENTELEMETRY_ATOMIC_READ_8(ptr) \ - static_cast(_InterlockedCompareExchange8(reinterpret_cast(ptr), 0, 0)) -# define OPENTELEMETRY_ATOMIC_WRITE_8(ptr, value) \ - _InterlockedExchange8(reinterpret_cast(ptr), static_cast(value)) - -#else -# error port atomics read/write for the current platform -#endif - -/* clang-format on */ -// -// The if/elif order matters here. If both OPENTELEMETRY_BUILD_IMPORT_DLL and -// OPENTELEMETRY_BUILD_EXPORT_DLL are defined, the former takes precedence. -// -// TODO: consider define OPENTELEMETRY_EXPORT for cygwin/gcc, see below link. -// https://gcc.gnu.org/wiki/Visibility#How_to_use_the_new_C.2B-.2B-_visibility_support -// -#if defined(_MSC_VER) && defined(OPENTELEMETRY_BUILD_IMPORT_DLL) - -# define OPENTELEMETRY_EXPORT __declspec(dllimport) - -#elif defined(_MSC_VER) && defined(OPENTELEMETRY_BUILD_EXPORT_DLL) - -# define OPENTELEMETRY_EXPORT __declspec(dllexport) - -#else - -// -// build OpenTelemetry as static library or not on Windows. -// -# define OPENTELEMETRY_EXPORT - -#endif - -// OPENTELEMETRY_HAVE_EXCEPTIONS -// -// Checks whether the compiler both supports and enables exceptions. Many -// compilers support a "no exceptions" mode that disables exceptions. -// -// Generally, when OPENTELEMETRY_HAVE_EXCEPTIONS is not defined: -// -// * Code using `throw` and `try` may not compile. -// * The `noexcept` specifier will still compile and behave as normal. -// * The `noexcept` operator may still return `false`. -// -// For further details, consult the compiler's documentation. -#ifndef OPENTELEMETRY_HAVE_EXCEPTIONS -# if defined(__clang__) && ((__clang_major__ * 100) + __clang_minor__) < 306 -// Clang < 3.6 -// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro -# if defined(__EXCEPTIONS) && OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions) -# define OPENTELEMETRY_HAVE_EXCEPTIONS 1 -# endif // defined(__EXCEPTIONS) && OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions) -# elif OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions) -# define OPENTELEMETRY_HAVE_EXCEPTIONS 1 -// Handle remaining special cases and default to exceptions being supported. -# elif !(defined(__GNUC__) && !defined(__EXCEPTIONS) && !defined(__cpp_exceptions)) && \ - !(defined(_MSC_VER) && !defined(_CPPUNWIND)) -# define OPENTELEMETRY_HAVE_EXCEPTIONS 1 -# endif -#endif -#ifndef OPENTELEMETRY_HAVE_EXCEPTIONS -# define OPENTELEMETRY_HAVE_EXCEPTIONS 0 -#endif - -/* - OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function - parameter or implicit object parameter is retained by the return value of the - annotated function (or, for a parameter of a constructor, in the value of the - constructed object). This attribute causes warnings to be produced if a - temporary object does not live long enough. - - When applied to a reference parameter, the referenced object is assumed to be - retained by the return value of the function. When applied to a non-reference - parameter (for example, a pointer or a class type), all temporaries - referenced by the parameter are assumed to be retained by the return value of - the function. - - See also the upstream documentation: - https://clang.llvm.org/docs/AttributeReference.html#lifetimebound -*/ -#ifndef OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND -# if OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(clang::lifetimebound) -# define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]] -# elif OPENTELEMETRY_HAVE_ATTRIBUTE(lifetimebound) -# define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound)) -# else -# define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND -# endif -#endif - -// OPENTELEMETRY_HAVE_MEMORY_SANITIZER -// -// MemorySanitizer (MSan) is a detector of uninitialized reads. It consists of -// a compiler instrumentation module and a run-time library. -#ifndef OPENTELEMETRY_HAVE_MEMORY_SANITIZER -# if !defined(__native_client__) && OPENTELEMETRY_HAVE_FEATURE(memory_sanitizer) -# define OPENTELEMETRY_HAVE_MEMORY_SANITIZER 1 -# else -# define OPENTELEMETRY_HAVE_MEMORY_SANITIZER 0 -# endif -#endif - -#if OPENTELEMETRY_HAVE_MEMORY_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_memory) -# define OPENTELEMETRY_SANITIZER_NO_MEMORY \ - __attribute__((no_sanitize_memory)) // __attribute__((no_sanitize("memory"))) -#else -# define OPENTELEMETRY_SANITIZER_NO_MEMORY -#endif - -// OPENTELEMETRY_HAVE_THREAD_SANITIZER -// -// ThreadSanitizer (TSan) is a fast data race detector. -#ifndef OPENTELEMETRY_HAVE_THREAD_SANITIZER -# if defined(__SANITIZE_THREAD__) -# define OPENTELEMETRY_HAVE_THREAD_SANITIZER 1 -# elif OPENTELEMETRY_HAVE_FEATURE(thread_sanitizer) -# define OPENTELEMETRY_HAVE_THREAD_SANITIZER 1 -# else -# define OPENTELEMETRY_HAVE_THREAD_SANITIZER 0 -# endif -#endif - -#if OPENTELEMETRY_HAVE_THREAD_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_thread) -# define OPENTELEMETRY_SANITIZER_NO_THREAD \ - __attribute__((no_sanitize_thread)) // __attribute__((no_sanitize("thread"))) -#else -# define OPENTELEMETRY_SANITIZER_NO_THREAD -#endif - -// OPENTELEMETRY_HAVE_ADDRESS_SANITIZER -// -// AddressSanitizer (ASan) is a fast memory error detector. -#ifndef OPENTELEMETRY_HAVE_ADDRESS_SANITIZER -# if defined(__SANITIZE_ADDRESS__) -# define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 1 -# elif OPENTELEMETRY_HAVE_FEATURE(address_sanitizer) -# define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 1 -# else -# define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 0 -# endif -#endif - -// OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER -// -// Hardware-Assisted AddressSanitizer (or HWASAN) is even faster than asan -// memory error detector which can use CPU features like ARM TBI, Intel LAM or -// AMD UAI. -#ifndef OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER -# if defined(__SANITIZE_HWADDRESS__) -# define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 1 -# elif OPENTELEMETRY_HAVE_FEATURE(hwaddress_sanitizer) -# define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 1 -# else -# define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 0 -# endif -#endif - -#if OPENTELEMETRY_HAVE_ADDRESS_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_address) -# define OPENTELEMETRY_SANITIZER_NO_ADDRESS \ - __attribute__((no_sanitize_address)) // __attribute__((no_sanitize("address"))) -#elif OPENTELEMETRY_HAVE_ADDRESS_SANITIZER && defined(_MSC_VER) && _MSC_VER >= 1928 -# define OPENTELEMETRY_SANITIZER_NO_ADDRESS __declspec(no_sanitize_address) -#elif OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize) -# define OPENTELEMETRY_SANITIZER_NO_ADDRESS __attribute__((no_sanitize("hwaddress"))) -#else -# define OPENTELEMETRY_SANITIZER_NO_ADDRESS -#endif diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/spin_lock_mutex.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/spin_lock_mutex.h deleted file mode 100644 index 7031fa4d2..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/spin_lock_mutex.h +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include - -#include "opentelemetry/version.h" - -#if defined(_MSC_VER) -# define _WINSOCKAPI_ // stops including winsock.h -# include -#elif defined(__i386__) || defined(__x86_64__) -# if defined(__clang__) -# include -# elif defined(__INTEL_COMPILER) -# include -# endif -#endif - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace common -{ - -constexpr int SPINLOCK_FAST_ITERATIONS = 100; -constexpr int SPINLOCK_SLEEP_MS = 1; - -/** - * A Mutex which uses atomic flags and spin-locks instead of halting threads. - * - * This mutex uses an incremental back-off strategy with the following phases: - * 1. A tight spin-lock loop (pending: using hardware PAUSE/YIELD instructions) - * 2. A loop where the current thread yields control after checking the lock. - * 3. Issuing a thread-sleep call before starting back in phase 1. - * - * This is meant to give a good balance of perofrmance and CPU consumption in - * practice. - * - * This mutex uses an incremental back-off strategy with the following phases: - * 1. A tight spin-lock loop (pending: using hardware PAUSE/YIELD instructions) - * 2. A loop where the current thread yields control after checking the lock. - * 3. Issuing a thread-sleep call before starting back in phase 1. - * - * This is meant to give a good balance of perofrmance and CPU consumption in - * practice. - * - * This class implements the `BasicLockable` specification: - * https://en.cppreference.com/w/cpp/named_req/BasicLockable - */ -class SpinLockMutex -{ -public: - SpinLockMutex() noexcept {} - ~SpinLockMutex() noexcept = default; - SpinLockMutex(const SpinLockMutex &) = delete; - SpinLockMutex &operator=(const SpinLockMutex &) = delete; - - static inline void fast_yield() noexcept - { -// Issue a Pause/Yield instruction while spinning. -#if defined(_MSC_VER) - YieldProcessor(); -#elif defined(__i386__) || defined(__x86_64__) -# if defined(__clang__) || defined(__INTEL_COMPILER) - _mm_pause(); -# else - __builtin_ia32_pause(); -# endif -#elif defined(__armel__) || defined(__ARMEL__) - asm volatile("nop" ::: "memory"); -#elif defined(__arm__) || defined(__aarch64__) // arm big endian / arm64 - __asm__ __volatile__("yield" ::: "memory"); -#else - // TODO: Issue PAGE/YIELD on other architectures. -#endif - } - - /** - * Attempts to lock the mutex. Return immediately with `true` (success) or `false` (failure). - */ - bool try_lock() noexcept - { - return !flag_.load(std::memory_order_relaxed) && - !flag_.exchange(true, std::memory_order_acquire); - } - - /** - * Blocks until a lock can be obtained for the current thread. - * - * This mutex will spin the current CPU waiting for the lock to be available. This can have - * decent performance in scenarios where there is low lock contention and lock-holders achieve - * their work quickly. It degrades in scenarios where locked tasks take a long time. - */ - void lock() noexcept - { - for (;;) - { - // Try once - if (!flag_.exchange(true, std::memory_order_acquire)) - { - return; - } - // Spin-Fast (goal ~10ns) - for (std::size_t i = 0; i < SPINLOCK_FAST_ITERATIONS; ++i) - { - if (try_lock()) - { - return; - } - fast_yield(); - } - // Yield then try again (goal ~100ns) - std::this_thread::yield(); - if (try_lock()) - { - return; - } - // Sleep and then start the whole process again. (goal ~1000ns) - std::this_thread::sleep_for(std::chrono::milliseconds(SPINLOCK_SLEEP_MS)); - } - return; - } - /** Releases the lock held by the execution agent. Throws no exceptions. */ - void unlock() noexcept { flag_.store(false, std::memory_order_release); } - -private: - std::atomic flag_{false}; -}; - -} // namespace common -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/string_util.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/string_util.h deleted file mode 100644 index 273a65272..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/string_util.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace common -{ - -class StringUtil -{ -public: - static nostd::string_view Trim(nostd::string_view str, size_t left, size_t right) noexcept - { - while (left <= right && isspace(str[left])) - { - left++; - } - while (left <= right && isspace(str[right])) - { - right--; - } - return str.substr(left, 1 + right - left); - } - - static nostd::string_view Trim(nostd::string_view str) noexcept - { - if (str.empty()) - { - return str; - } - - return Trim(str, 0, str.size() - 1); - } -}; - -} // namespace common - -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/timestamp.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/timestamp.h deleted file mode 100644 index f7c79b8b5..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/common/timestamp.h +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace common -{ -/** - * @brief A timepoint relative to the system clock epoch. - * - * This is used for marking the beginning and end of an operation. - */ -class SystemTimestamp -{ -public: - /** - * @brief Initializes a system timestamp pointing to the start of the epoch. - */ - SystemTimestamp() noexcept : nanos_since_epoch_{0} {} - - /** - * @brief Initializes a system timestamp from a duration. - * - * @param time_since_epoch Time elapsed since the beginning of the epoch. - */ - template - explicit SystemTimestamp(const std::chrono::duration &time_since_epoch) noexcept - : nanos_since_epoch_{static_cast( - std::chrono::duration_cast(time_since_epoch).count())} - {} - - /** - * @brief Initializes a system timestamp based on a point in time. - * - * @param time_point A point in time. - */ - /*implicit*/ SystemTimestamp(const std::chrono::system_clock::time_point &time_point) noexcept - : SystemTimestamp{time_point.time_since_epoch()} - {} - - /** - * @brief Returns a time point for the time stamp. - * - * @return A time point corresponding to the time stamp. - */ - operator std::chrono::system_clock::time_point() const noexcept - { - return std::chrono::system_clock::time_point{ - std::chrono::duration_cast( - std::chrono::nanoseconds{nanos_since_epoch_})}; - } - - /** - * @brief Returns the nanoseconds since the beginning of the epoch. - * - * @return Elapsed nanoseconds since the beginning of the epoch for this timestamp. - */ - std::chrono::nanoseconds time_since_epoch() const noexcept - { - return std::chrono::nanoseconds{nanos_since_epoch_}; - } - - /** - * @brief Compare two steady time stamps. - * - * @return true if the two time stamps are equal. - */ - bool operator==(const SystemTimestamp &other) const noexcept - { - return nanos_since_epoch_ == other.nanos_since_epoch_; - } - - /** - * @brief Compare two steady time stamps for inequality. - * - * @return true if the two time stamps are not equal. - */ - bool operator!=(const SystemTimestamp &other) const noexcept - { - return nanos_since_epoch_ != other.nanos_since_epoch_; - } - -private: - int64_t nanos_since_epoch_; -}; - -/** - * @brief A timepoint relative to the monotonic clock epoch - * - * This is used for calculating the duration of an operation. - */ -class SteadyTimestamp -{ -public: - /** - * @brief Initializes a monotonic timestamp pointing to the start of the epoch. - */ - SteadyTimestamp() noexcept : nanos_since_epoch_{0} {} - - /** - * @brief Initializes a monotonic timestamp from a duration. - * - * @param time_since_epoch Time elapsed since the beginning of the epoch. - */ - template - explicit SteadyTimestamp(const std::chrono::duration &time_since_epoch) noexcept - : nanos_since_epoch_{static_cast( - std::chrono::duration_cast(time_since_epoch).count())} - {} - - /** - * @brief Initializes a monotonic timestamp based on a point in time. - * - * @param time_point A point in time. - */ - /*implicit*/ SteadyTimestamp(const std::chrono::steady_clock::time_point &time_point) noexcept - : SteadyTimestamp{time_point.time_since_epoch()} - {} - - /** - * @brief Returns a time point for the time stamp. - * - * @return A time point corresponding to the time stamp. - */ - operator std::chrono::steady_clock::time_point() const noexcept - { - return std::chrono::steady_clock::time_point{ - std::chrono::duration_cast( - std::chrono::nanoseconds{nanos_since_epoch_})}; - } - - /** - * @brief Returns the nanoseconds since the beginning of the epoch. - * - * @return Elapsed nanoseconds since the beginning of the epoch for this timestamp. - */ - std::chrono::nanoseconds time_since_epoch() const noexcept - { - return std::chrono::nanoseconds{nanos_since_epoch_}; - } - - /** - * @brief Compare two steady time stamps. - * - * @return true if the two time stamps are equal. - */ - bool operator==(const SteadyTimestamp &other) const noexcept - { - return nanos_since_epoch_ == other.nanos_since_epoch_; - } - - /** - * @brief Compare two steady time stamps for inequality. - * - * @return true if the two time stamps are not equal. - */ - bool operator!=(const SteadyTimestamp &other) const noexcept - { - return nanos_since_epoch_ != other.nanos_since_epoch_; - } - -private: - int64_t nanos_since_epoch_; -}; - -class DurationUtil -{ -public: - template - static std::chrono::duration AdjustWaitForTimeout( - std::chrono::duration timeout, - std::chrono::duration indefinite_value) noexcept - { - // Do not call now() when this duration is max value, now() may have a expensive cost. - if (timeout == (std::chrono::duration::max)()) - { - return indefinite_value; - } - - // std::future::wait_for, std::this_thread::sleep_for, and std::condition_variable::wait_for - // may use steady_clock or system_clock.We need make sure now() + timeout do not overflow. - auto max_timeout = std::chrono::duration_cast>( - (std::chrono::steady_clock::time_point::max)() - std::chrono::steady_clock::now()); - if (timeout >= max_timeout) - { - return indefinite_value; - } - max_timeout = std::chrono::duration_cast>( - (std::chrono::system_clock::time_point::max)() - std::chrono::system_clock::now()); - if (timeout >= max_timeout) - { - return indefinite_value; - } - - return timeout; - } -}; - -} // namespace common -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/config.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/config.h deleted file mode 100644 index cb52f3b5d..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/config.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include // IWYU pragma: keep - -#if defined(OPENTELEMETRY_ABI_VERSION_NO) && OPENTELEMETRY_ABI_VERSION_NO >= 2 -# error \ - "opentelemetry/config.h is removed in ABI version 2 and later. Please use opentelemetry/version.h instead." -#else -# if defined(__clang__) || defined(__GNUC__) -# pragma GCC warning \ - "opentelemetry/config.h is deprecated. Please use opentelemetry/version.h instead." -# elif defined(_MSC_VER) -# pragma message( \ - "[WARNING]: opentelemetry/config.h is deprecated. Please use opentelemetry/version.h instead.") -# endif -#endif diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/context.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/context.h deleted file mode 100644 index 924036efa..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/context.h +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include "opentelemetry/context/context_value.h" -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/variant.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace context -{ - -// The context class provides a context identifier. Is built as a linked list -// of DataList nodes and each context holds a shared_ptr to a place within -// the list that determines which keys and values it has access to. All that -// come before and none that come after. -class Context -{ - -public: - Context() = default; - // Creates a context object from a map of keys and identifiers, this will - // hold a shared_ptr to the head of the DataList linked list - template - Context(const T &keys_and_values) noexcept - : head_{nostd::shared_ptr{new DataList(keys_and_values)}} - {} - - // Creates a context object from a key and value, this will - // hold a shared_ptr to the head of the DataList linked list - Context(nostd::string_view key, ContextValue value) noexcept - : head_{nostd::shared_ptr{new DataList(key, value)}} - {} - - // Accepts a new iterable and then returns a new context that - // contains the new key and value data. It attaches the - // exisiting list to the end of the new list. - template - Context SetValues(T &values) noexcept - { - Context context = Context(values); - nostd::shared_ptr last = context.head_; - while (last->next_ != nullptr) - { - last = last->next_; - } - last->next_ = head_; - return context; - } - - // Accepts a new iterable and then returns a new context that - // contains the new key and value data. It attaches the - // exisiting list to the end of the new list. - Context SetValue(nostd::string_view key, ContextValue value) noexcept - { - Context context = Context(key, value); - context.head_->next_ = head_; - return context; - } - - // Returns the value associated with the passed in key. - context::ContextValue GetValue(const nostd::string_view key) const noexcept - { - for (DataList *data = head_.get(); data != nullptr; data = data->next_.get()) - { - if (key.size() == data->key_length_) - { - if (std::memcmp(key.data(), data->key_, data->key_length_) == 0) - { - return data->value_; - } - } - } - return ContextValue{}; - } - - // Checks for key and returns true if found - bool HasKey(const nostd::string_view key) const noexcept - { - return !nostd::holds_alternative(GetValue(key)); - } - - bool operator==(const Context &other) const noexcept { return (head_ == other.head_); } - -private: - // A linked list to contain the keys and values of this context node - struct DataList - { - char *key_ = nullptr; - - nostd::shared_ptr next_{nullptr}; - - size_t key_length_ = 0UL; - - ContextValue value_; - - DataList() = default; - - // Builds a data list off of a key and value iterable and returns the head - template - DataList(const T &keys_and_vals) - { - bool first = true; - auto *node = this; - for (auto &iter : keys_and_vals) - { - if (first) - { - *node = DataList(iter.first, iter.second); - first = false; - } - else - { - node->next_ = nostd::shared_ptr(new DataList(iter.first, iter.second)); - node = node->next_.get(); - } - } - } - - // Builds a data list with just a key and value, so it will just be the head - // and returns that head. - DataList(nostd::string_view key, const ContextValue &value) - { - key_ = new char[key.size()]; - key_length_ = key.size(); - std::memcpy(key_, key.data(), key.size() * sizeof(char)); - next_ = nostd::shared_ptr{nullptr}; - value_ = value; - } - - DataList(const DataList &other) - : key_(new char[other.key_length_]), - next_(other.next_), - key_length_(other.key_length_), - value_(other.value_) - { - std::memcpy(key_, other.key_, other.key_length_ * sizeof(char)); - } - - DataList &operator=(DataList &&other) noexcept - { - key_length_ = other.key_length_; - value_ = std::move(other.value_); - next_ = std::move(other.next_); - - key_ = other.key_; - other.key_ = nullptr; - - return *this; - } - - ~DataList() - { - if (key_ != nullptr) - { - delete[] key_; - } - } - }; - - // Head of the list which holds the keys and values of this context - nostd::shared_ptr head_; -}; -} // namespace context -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/context_value.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/context_value.h deleted file mode 100644 index 27bd40fb0..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/context_value.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/nostd/variant.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace baggage -{ -class Baggage; -} // namespace baggage - -namespace trace -{ -class Span; -class SpanContext; -} // namespace trace - -namespace context -{ -using ContextValue = nostd::variant, - nostd::shared_ptr, - nostd::shared_ptr>; -} // namespace context -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/propagation/composite_propagator.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/propagation/composite_propagator.h deleted file mode 100644 index f7afe23bf..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/propagation/composite_propagator.h +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include "opentelemetry/context/propagation/text_map_propagator.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace context -{ -namespace propagation -{ - -class CompositePropagator : public TextMapPropagator -{ -public: - CompositePropagator(std::vector> propagators) - : propagators_(std::move(propagators)) - {} - - /** - * Run each of the configured propagators with the given context and carrier. - * Propagators are run in the order they are configured, so if multiple - * propagators write the same carrier key, the propagator later in the list - * will "win". - * - * @param carrier Carrier into which context will be injected - * @param context Context to inject - * - */ - - void Inject(TextMapCarrier &carrier, const context::Context &context) noexcept override - { - for (auto &p : propagators_) - { - p->Inject(carrier, context); - } - } - - /** - * Run each of the configured propagators with the given context and carrier. - * Propagators are run in the order they are configured, so if multiple - * propagators write the same context key, the propagator later in the list - * will "win". - * - * @param carrier Carrier from which to extract context - * @param context Context to add values to - */ - context::Context Extract(const TextMapCarrier &carrier, - context::Context &context) noexcept override - { - auto first = true; - context::Context tmp_context; - for (auto &p : propagators_) - { - if (first) - { - tmp_context = p->Extract(carrier, context); - first = false; - } - else - { - tmp_context = p->Extract(carrier, tmp_context); - } - } - return propagators_.size() ? tmp_context : context; - } - - /** - * Invoke callback with fields set to carrier by `inject` method for all the - * configured propagators - * Returns true if all invocation return true - */ - bool Fields(nostd::function_ref callback) const noexcept override - { - bool status = true; - for (auto &p : propagators_) - { - status = status && p->Fields(callback); - } - return status; - } - -private: - std::vector> propagators_; -}; -} // namespace propagation -} // namespace context -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/propagation/global_propagator.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/propagation/global_propagator.h deleted file mode 100644 index 85293202f..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/propagation/global_propagator.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/context/propagation/noop_propagator.h" - -#include "opentelemetry/common/macros.h" -#include "opentelemetry/common/spin_lock_mutex.h" -#include "opentelemetry/nostd/shared_ptr.h" - -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace context -{ -namespace propagation -{ - -class TextMapPropagator; - -/* Stores the singleton TextMapPropagator */ - -class OPENTELEMETRY_EXPORT GlobalTextMapPropagator -{ -public: - static nostd::shared_ptr GetGlobalPropagator() noexcept - { - std::lock_guard guard(GetLock()); - return nostd::shared_ptr(GetPropagator()); - } - - static void SetGlobalPropagator(const nostd::shared_ptr &prop) noexcept - { - std::lock_guard guard(GetLock()); - GetPropagator() = prop; - } - -private: - OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr &GetPropagator() noexcept - { - static nostd::shared_ptr propagator(new NoOpPropagator()); - return propagator; - } - - OPENTELEMETRY_API_SINGLETON static common::SpinLockMutex &GetLock() noexcept - { - static common::SpinLockMutex lock; - return lock; - } -}; - -} // namespace propagation -} // namespace context -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/propagation/noop_propagator.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/propagation/noop_propagator.h deleted file mode 100644 index 4e1b30c17..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/propagation/noop_propagator.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/context/propagation/text_map_propagator.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace context -{ -namespace propagation -{ - -/** - * No-op implementation TextMapPropagator - */ -class NoOpPropagator : public TextMapPropagator -{ -public: - /** Noop extract function does nothing and returns the input context */ - context::Context Extract(const TextMapCarrier & /*carrier*/, - context::Context &context) noexcept override - { - return context; - } - - /** Noop inject function does nothing */ - void Inject(TextMapCarrier & /*carrier*/, - const context::Context & /* context */) noexcept override - {} - - bool Fields(nostd::function_ref /* callback */) const noexcept override - { - return true; - } -}; -} // namespace propagation -} // namespace context -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/propagation/text_map_propagator.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/propagation/text_map_propagator.h deleted file mode 100644 index 21bc29361..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/propagation/text_map_propagator.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/context/context.h" -#include "opentelemetry/nostd/function_ref.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace context -{ -namespace propagation -{ - -// TextMapCarrier is the storage medium used by TextMapPropagator. -class TextMapCarrier -{ -public: - // returns the value associated with the passed key. - virtual nostd::string_view Get(nostd::string_view key) const noexcept = 0; - - // stores the key-value pair. - virtual void Set(nostd::string_view key, nostd::string_view value) noexcept = 0; - - /* list of all the keys in the carrier. - By default, it returns true without invoking callback */ - virtual bool Keys(nostd::function_ref /* callback */) const noexcept - { - return true; - } - virtual ~TextMapCarrier() = default; -}; - -// The TextMapPropagator class provides an interface that enables extracting and injecting -// context into carriers that travel in-band across process boundaries. HTTP frameworks and clients -// can integrate with TextMapPropagator by providing the object containing the -// headers, and a getter and setter function for the extraction and -// injection of values, respectively. - -class TextMapPropagator -{ -public: - // Returns the context that is stored in the carrier with the TextMapCarrier as extractor. - virtual context::Context Extract(const TextMapCarrier &carrier, - context::Context &context) noexcept = 0; - - // Sets the context for carrier with self defined rules. - virtual void Inject(TextMapCarrier &carrier, const context::Context &context) noexcept = 0; - - // Gets the fields set in the carrier by the `inject` method - virtual bool Fields(nostd::function_ref callback) const noexcept = 0; - - virtual ~TextMapPropagator() = default; -}; -} // namespace propagation -} // namespace context -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/runtime_context.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/runtime_context.h deleted file mode 100644 index e3f88254c..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/context/runtime_context.h +++ /dev/null @@ -1,340 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include "opentelemetry/common/macros.h" -#include "opentelemetry/context/context.h" -#include "opentelemetry/context/context_value.h" -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/unique_ptr.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace context -{ -// The Token object provides is returned when attaching objects to the -// RuntimeContext object and is associated with a context object, and -// can be provided to the RuntimeContext Detach method to remove the -// associated context from the RuntimeContext. -class Token -{ -public: - bool operator==(const Context &other) const noexcept { return context_ == other; } - - ~Token() noexcept; - -private: - friend class RuntimeContextStorage; - - // A constructor that sets the token's Context object to the - // one that was passed in. - Token(const Context &context) : context_(context) {} - - const Context context_; -}; - -/** - * RuntimeContextStorage is used by RuntimeContext to store Context frames. - * - * Custom context management strategies can be implemented by deriving from - * this class and passing an initialized RuntimeContextStorage object to - * RuntimeContext::SetRuntimeContextStorage. - */ -class OPENTELEMETRY_EXPORT RuntimeContextStorage -{ -public: - /** - * Return the current context. - * @return the current context - */ - virtual Context GetCurrent() noexcept = 0; - - /** - * Set the current context. - * @param the new current context - * @return a token for the new current context. This never returns a nullptr. - */ - virtual nostd::unique_ptr Attach(const Context &context) noexcept = 0; - - /** - * Detach the context related to the given token. - * @param token a token related to a context - * @return true if the context could be detached - */ - virtual bool Detach(Token &token) noexcept = 0; - - virtual ~RuntimeContextStorage() {} - -protected: - nostd::unique_ptr CreateToken(const Context &context) noexcept - { - return nostd::unique_ptr(new Token(context)); - } -}; - -/** - * Construct and return the default RuntimeContextStorage - * @return a ThreadLocalContextStorage - */ -static RuntimeContextStorage *GetDefaultStorage() noexcept; - -// Provides a wrapper for propagating the context object globally. -// -// By default, a thread-local runtime context storage is used. -class OPENTELEMETRY_EXPORT RuntimeContext -{ -public: - // Return the current context. - static Context GetCurrent() noexcept { return GetRuntimeContextStorage()->GetCurrent(); } - - // Sets the current 'Context' object. Returns a token - // that can be used to reset to the previous Context. - static nostd::unique_ptr Attach(const Context &context) noexcept - { - return GetRuntimeContextStorage()->Attach(context); - } - - // Resets the context to a previous value stored in the - // passed in token. Returns true if successful, false otherwise - static bool Detach(Token &token) noexcept { return GetRuntimeContextStorage()->Detach(token); } - - // Sets the Key and Value into the passed in context or if a context is not - // passed in, the RuntimeContext. - // Should be used to SetValues to the current RuntimeContext, is essentially - // equivalent to RuntimeContext::GetCurrent().SetValue(key,value). Keep in - // mind that the current RuntimeContext will not be changed, and the new - // context will be returned. - static Context SetValue(nostd::string_view key, - const ContextValue &value, - Context *context = nullptr) noexcept - { - Context temp_context; - if (context == nullptr) - { - temp_context = GetCurrent(); - } - else - { - temp_context = *context; - } - return temp_context.SetValue(key, value); - } - - // Returns the value associated with the passed in key and either the - // passed in context* or the runtime context if a context is not passed in. - // Should be used to get values from the current RuntimeContext, is - // essentially equivalent to RuntimeContext::GetCurrent().GetValue(key). - static ContextValue GetValue(nostd::string_view key, Context *context = nullptr) noexcept - { - Context temp_context; - if (context == nullptr) - { - temp_context = GetCurrent(); - } - else - { - temp_context = *context; - } - return temp_context.GetValue(key); - } - - /** - * Provide a custom runtime context storage. - * - * This provides a possibility to override the default thread-local runtime - * context storage. This has to be set before any spans are created by the - * application, otherwise the behavior is undefined. - * - * @param storage a custom runtime context storage - */ - static void SetRuntimeContextStorage( - const nostd::shared_ptr &storage) noexcept - { - GetStorage() = storage; - } - - /** - * Provide a pointer to const runtime context storage. - * - * The returned pointer can only be used for extending the lifetime of the runtime context - * storage. - * - */ - static nostd::shared_ptr GetConstRuntimeContextStorage() noexcept - { - return GetRuntimeContextStorage(); - } - -private: - static nostd::shared_ptr GetRuntimeContextStorage() noexcept - { - return GetStorage(); - } - - OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr &GetStorage() noexcept - { - static nostd::shared_ptr context(GetDefaultStorage()); - return context; - } -}; - -inline Token::~Token() noexcept -{ - context::RuntimeContext::Detach(*this); -} - -// The ThreadLocalContextStorage class is a derived class from -// RuntimeContextStorage and provides a wrapper for propagating context through -// cpp thread locally. This file must be included to use the RuntimeContext -// class if another implementation has not been registered. -class ThreadLocalContextStorage : public RuntimeContextStorage -{ -public: - ThreadLocalContextStorage() noexcept = default; - - // Return the current context. - Context GetCurrent() noexcept override { return GetStack().Top(); } - - // Resets the context to the value previous to the passed in token. This will - // also detach all child contexts of the passed in token. - // Returns true if successful, false otherwise. - bool Detach(Token &token) noexcept override - { - // In most cases, the context to be detached is on the top of the stack. - if (token == GetStack().Top()) - { - GetStack().Pop(); - return true; - } - - if (!GetStack().Contains(token)) - { - return false; - } - - while (!(token == GetStack().Top())) - { - GetStack().Pop(); - } - - GetStack().Pop(); - - return true; - } - - // Sets the current 'Context' object. Returns a token - // that can be used to reset to the previous Context. - nostd::unique_ptr Attach(const Context &context) noexcept override - { - GetStack().Push(context); - return CreateToken(context); - } - -private: - // A nested class to store the attached contexts in a stack. - class Stack - { - friend class ThreadLocalContextStorage; - - Stack() noexcept : size_(0), capacity_(0), base_(nullptr) {} - - // Pops the top Context off the stack. - void Pop() noexcept - { - if (size_ == 0) - { - return; - } - // Store empty Context before decrementing `size`, to ensure - // the shared_ptr object (if stored in prev context object ) are released. - // The stack is not resized, and the unused memory would be reutilised - // for subsequent context storage. - base_[size_ - 1] = Context(); - size_ -= 1; - } - - bool Contains(const Token &token) const noexcept - { - for (size_t pos = size_; pos > 0; --pos) - { - if (token == base_[pos - 1]) - { - return true; - } - } - - return false; - } - - // Returns the Context at the top of the stack. - Context Top() const noexcept - { - if (size_ == 0) - { - return Context(); - } - return base_[size_ - 1]; - } - - // Pushes the passed in context pointer to the top of the stack - // and resizes if necessary. - void Push(const Context &context) noexcept - { - size_++; - if (size_ > capacity_) - { - Resize(size_ * 2); - } - base_[size_ - 1] = context; - } - - // Reallocates the storage array to the pass in new capacity size. - void Resize(size_t new_capacity) noexcept - { - size_t old_size = size_ - 1; - if (new_capacity == 0) - { - new_capacity = 2; - } - Context *temp = new Context[new_capacity]; - if (base_ != nullptr) - { - // vs2015 does not like this construct considering it unsafe: - // - std::copy(base_, base_ + old_size, temp); - // Ref. - // https://stackoverflow.com/questions/12270224/xutility2227-warning-c4996-std-copy-impl - for (size_t i = 0; i < (std::min)(old_size, new_capacity); i++) - { - temp[i] = base_[i]; - } - delete[] base_; - } - base_ = temp; - capacity_ = new_capacity; - } - - ~Stack() noexcept { delete[] base_; } - - size_t size_; - size_t capacity_; - Context *base_; - }; - - OPENTELEMETRY_API_SINGLETON Stack &GetStack() - { - static thread_local Stack stack_ = Stack(); - return stack_; - } -}; - -static RuntimeContextStorage *GetDefaultStorage() noexcept -{ - return new ThreadLocalContextStorage(); -} -} // namespace context -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/detail/preprocessor.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/detail/preprocessor.h deleted file mode 100644 index acdf02eb0..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/detail/preprocessor.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -// NOTE - code within detail namespace implements internal details, and not part -// of the public interface. - -#pragma once - -#define OPENTELEMETRY_STRINGIFY(S) OPENTELEMETRY_STRINGIFY_(S) -#define OPENTELEMETRY_STRINGIFY_(S) #S - -#define OPENTELEMETRY_CONCAT(A, B) OPENTELEMETRY_CONCAT_(A, B) -#define OPENTELEMETRY_CONCAT_(A, B) A##B - -// Import the C++20 feature-test macros -#ifdef __has_include -# if __has_include() -# include -# endif -#elif defined(_MSC_VER) && ((defined(__cplusplus) && __cplusplus >= 202002L) || \ - (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)) -# if _MSC_VER >= 1922 -# include -# endif -#endif diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/event_id.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/event_id.h deleted file mode 100644 index 65306ef79..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/event_id.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/unique_ptr.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace logs -{ - -/** - * EventId class which acts the Id of the event with an optional name. - */ -class EventId -{ -public: - EventId(int64_t id, nostd::string_view name) noexcept - : id_{id}, name_{nostd::unique_ptr{new char[name.length() + 1]}} - { - std::copy(name.begin(), name.end(), name_.get()); - name_.get()[name.length()] = 0; - } - - EventId(int64_t id) noexcept : id_{id}, name_{nullptr} {} - -public: - int64_t id_; - nostd::unique_ptr name_; -}; - -} // namespace logs -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/event_logger.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/event_logger.h deleted file mode 100644 index bcc103562..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/event_logger.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/logs/log_record.h" -#include "opentelemetry/logs/logger.h" -#include "opentelemetry/logs/logger_type_traits.h" -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/unique_ptr.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace logs -{ -#if OPENTELEMETRY_ABI_VERSION_NO < 2 -/** - * Handles event log record creation. - **/ -class OPENTELEMETRY_DEPRECATED EventLogger -{ -public: - virtual ~EventLogger() = default; - - /* Returns the name of the logger */ - virtual const nostd::string_view GetName() noexcept = 0; - - /* Returns the delegate logger of this event logger */ - virtual nostd::shared_ptr GetDelegateLogger() noexcept = 0; - - /** - * Emit a event Log Record object - * - * @param event_name Event name - * @param log_record Log record - */ - virtual void EmitEvent(nostd::string_view event_name, - nostd::unique_ptr &&log_record) noexcept = 0; - - /** - * Emit a event Log Record object with arguments - * - * @param event_name Event name - * @tparam args Arguments which can be used to set data of log record by type. - * Severity -> severity, severity_text - * string_view -> body - * AttributeValue -> body - * SpanContext -> span_id,tace_id and trace_flags - * SpanId -> span_id - * TraceId -> tace_id - * TraceFlags -> trace_flags - * SystemTimestamp -> timestamp - * system_clock::time_point -> timestamp - * KeyValueIterable -> attributes - * Key value iterable container -> attributes - * span> -> attributes(return type of MakeAttributes) - */ - template - void EmitEvent(nostd::string_view event_name, ArgumentType &&...args) - { - nostd::shared_ptr delegate_logger = GetDelegateLogger(); - if (!delegate_logger) - { - return; - } - nostd::unique_ptr log_record = delegate_logger->CreateLogRecord(); - - IgnoreTraitResult(detail::LogRecordSetterTrait::type>::Set( - log_record.get(), std::forward(args))...); - - EmitEvent(event_name, std::move(log_record)); - } - -private: - template - void IgnoreTraitResult(ValueType &&...) - {} -}; -#endif -} // namespace logs -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/event_logger_provider.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/event_logger_provider.h deleted file mode 100644 index 9eea0ca23..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/event_logger_provider.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace logs -{ - -class EventLogger; -class Logger; - -#if OPENTELEMETRY_ABI_VERSION_NO < 2 -/** - * Creates new EventLogger instances. - */ -class OPENTELEMETRY_DEPRECATED EventLoggerProvider -{ -public: - virtual ~EventLoggerProvider() = default; - - /** - * Creates a named EventLogger instance. - * - */ - - virtual nostd::shared_ptr CreateEventLogger( - nostd::shared_ptr delegate_logger, - nostd::string_view event_domain) noexcept = 0; -}; -#endif -} // namespace logs -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/log_record.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/log_record.h deleted file mode 100644 index 81dec568e..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/log_record.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/common/attribute_value.h" -#include "opentelemetry/common/timestamp.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace trace -{ -class SpanId; -class TraceId; -class TraceFlags; -} // namespace trace - -namespace logs -{ - -enum class Severity : uint8_t; - -/** - * Maintains a representation of a log in a format that can be processed by a recorder. - * - * This class is thread-compatible. - */ -class LogRecord -{ -public: - virtual ~LogRecord() = default; - - /** - * Set the timestamp for this log. - * @param timestamp the timestamp to set - */ - virtual void SetTimestamp(common::SystemTimestamp timestamp) noexcept = 0; - - /** - * Set the observed timestamp for this log. - * @param timestamp the timestamp to set - */ - virtual void SetObservedTimestamp(common::SystemTimestamp timestamp) noexcept = 0; - - /** - * Set the severity for this log. - * @param severity the severity of the event - */ - virtual void SetSeverity(logs::Severity severity) noexcept = 0; - - /** - * Set body field for this log. - * @param message the body to set - */ - virtual void SetBody(const common::AttributeValue &message) noexcept = 0; - - /** - * Set an attribute of a log. - * @param key the name of the attribute - * @param value the attribute value - */ - virtual void SetAttribute(nostd::string_view key, - const common::AttributeValue &value) noexcept = 0; - - /** - * Set the Event Id. - * @param id The event id to set - * @param name Optional event name to set - */ - // TODO: mark this as pure virtual once all exporters have been updated - virtual void SetEventId(int64_t id, nostd::string_view name = {}) noexcept = 0; - - /** - * Set the trace id for this log. - * @param trace_id the trace id to set - */ - virtual void SetTraceId(const trace::TraceId &trace_id) noexcept = 0; - - /** - * Set the span id for this log. - * @param span_id the span id to set - */ - virtual void SetSpanId(const trace::SpanId &span_id) noexcept = 0; - - /** - * Inject trace_flags for this log. - * @param trace_flags the trace flags to set - */ - virtual void SetTraceFlags(const trace::TraceFlags &trace_flags) noexcept = 0; -}; -} // namespace logs -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/logger.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/logger.h deleted file mode 100644 index 52f403b0a..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/logger.h +++ /dev/null @@ -1,492 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/logs/logger_type_traits.h" -#include "opentelemetry/logs/severity.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/unique_ptr.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace common -{ -class KeyValueIterable; -} // namespace common - -namespace logs -{ - -class EventId; -class LogRecord; - -/** - * Handles log record creation. - **/ -class Logger -{ -public: - virtual ~Logger() = default; - - /* Returns the name of the logger */ - virtual const nostd::string_view GetName() noexcept = 0; - - /** - * Create a Log Record object - * - * @return nostd::unique_ptr - */ - virtual nostd::unique_ptr CreateLogRecord() noexcept = 0; - - /** - * Emit a Log Record object - * - * @param log_record Log record - */ - virtual void EmitLogRecord(nostd::unique_ptr &&log_record) noexcept = 0; - - /** - * Emit a Log Record object with arguments - * - * @param log_record Log record - * @param args Arguments which can be used to set data of log record by type. - * Severity -> severity, severity_text - * string_view -> body - * AttributeValue -> body - * SpanContext -> span_id,trace_id and trace_flags - * SpanId -> span_id - * TraceId -> trace_id - * TraceFlags -> trace_flags - * SystemTimestamp -> timestamp - * system_clock::time_point -> timestamp - * KeyValueIterable -> attributes - * Key value iterable container -> attributes - * span> -> attributes(return type of MakeAttributes) - */ - template - void EmitLogRecord(nostd::unique_ptr &&log_record, ArgumentType &&...args) - { - if (!log_record) - { - return; - } - - // - // Keep the parameter pack unpacking order from left to right because left - // ones are usually more important like severity and event_id than the - // attributes. The left to right unpack order could pass the more important - // data to processors to avoid caching and memory allocating. - // -#if __cplusplus <= 201402L - // C++14 does not support fold expressions for parameter pack expansion. - int dummy[] = {(detail::LogRecordSetterTrait::type>::Set( - log_record.get(), std::forward(args)), - 0)...}; - IgnoreTraitResult(dummy); -#else - IgnoreTraitResult((detail::LogRecordSetterTrait::type>::Set( - log_record.get(), std::forward(args)), - ...)); -#endif - - EmitLogRecord(std::move(log_record)); - } - - /** - * Emit a Log Record object with arguments - * - * @param args Arguments which can be used to set data of log record by type. - * Severity -> severity, severity_text - * string_view -> body - * AttributeValue -> body - * SpanContext -> span_id,trace_id and trace_flags - * SpanId -> span_id - * TraceId -> trace_id - * TraceFlags -> trace_flags - * SystemTimestamp -> timestamp - * system_clock::time_point -> timestamp - * KeyValueIterable -> attributes - * Key value iterable container -> attributes - * span> -> attributes(return type of MakeAttributes) - */ - template - void EmitLogRecord(ArgumentType &&...args) - { - nostd::unique_ptr log_record = CreateLogRecord(); - - EmitLogRecord(std::move(log_record), std::forward(args)...); - } - - /** - * Writes a log with a severity of trace. - * @param args Arguments which can be used to set data of log record by type. - * string_view -> body - * AttributeValue -> body - * SpanContext -> span_id,trace_id and trace_flags - * SpanId -> span_id - * TraceId -> trace_id - * TraceFlags -> trace_flags - * SystemTimestamp -> timestamp - * system_clock::time_point -> timestamp - * KeyValueIterable -> attributes - * Key value iterable container -> attributes - * span> -> attributes(return type of MakeAttributes) - */ - template - void Trace(ArgumentType &&...args) noexcept - { - static_assert( - !detail::LogRecordHasType::type...>::value, - "Severity is already set."); - this->EmitLogRecord(Severity::kTrace, std::forward(args)...); - } - - /** - * Writes a log with a severity of debug. - * @param args Arguments which can be used to set data of log record by type. - * string_view -> body - * AttributeValue -> body - * SpanContext -> span_id,trace_id and trace_flags - * SpanId -> span_id - * TraceId -> trace_id - * TraceFlags -> trace_flags - * SystemTimestamp -> timestamp - * system_clock::time_point -> timestamp - * KeyValueIterable -> attributes - * Key value iterable container -> attributes - * span> -> attributes(return type of MakeAttributes) - */ - template - void Debug(ArgumentType &&...args) noexcept - { - static_assert( - !detail::LogRecordHasType::type...>::value, - "Severity is already set."); - this->EmitLogRecord(Severity::kDebug, std::forward(args)...); - } - - /** - * Writes a log with a severity of info. - * @param args Arguments which can be used to set data of log record by type. - * string_view -> body - * AttributeValue -> body - * SpanContext -> span_id,trace_id and trace_flags - * SpanId -> span_id - * TraceId -> trace_id - * TraceFlags -> trace_flags - * SystemTimestamp -> timestamp - * system_clock::time_point -> timestamp - * KeyValueIterable -> attributes - * Key value iterable container -> attributes - * span> -> attributes(return type of MakeAttributes) - */ - template - void Info(ArgumentType &&...args) noexcept - { - static_assert( - !detail::LogRecordHasType::type...>::value, - "Severity is already set."); - this->EmitLogRecord(Severity::kInfo, std::forward(args)...); - } - - /** - * Writes a log with a severity of warn. - * @param args Arguments which can be used to set data of log record by type. - * string_view -> body - * AttributeValue -> body - * SpanContext -> span_id,trace_id and trace_flags - * SpanId -> span_id - * TraceId -> trace_id - * TraceFlags -> trace_flags - * SystemTimestamp -> timestamp - * system_clock::time_point -> timestamp - * KeyValueIterable -> attributes - * Key value iterable container -> attributes - * span> -> attributes(return type of MakeAttributes) - */ - template - void Warn(ArgumentType &&...args) noexcept - { - static_assert( - !detail::LogRecordHasType::type...>::value, - "Severity is already set."); - this->EmitLogRecord(Severity::kWarn, std::forward(args)...); - } - - /** - * Writes a log with a severity of error. - * @param args Arguments which can be used to set data of log record by type. - * string_view -> body - * AttributeValue -> body - * SpanContext -> span_id,trace_id and trace_flags - * SpanId -> span_id - * TraceId -> trace_id - * TraceFlags -> trace_flags - * SystemTimestamp -> timestamp - * system_clock::time_point -> timestamp - * KeyValueIterable -> attributes - * Key value iterable container -> attributes - * span> -> attributes(return type of MakeAttributes) - */ - template - void Error(ArgumentType &&...args) noexcept - { - static_assert( - !detail::LogRecordHasType::type...>::value, - "Severity is already set."); - this->EmitLogRecord(Severity::kError, std::forward(args)...); - } - - /** - * Writes a log with a severity of fatal. - * @param args Arguments which can be used to set data of log record by type. - * string_view -> body - * AttributeValue -> body - * SpanContext -> span_id,trace_id and trace_flags - * SpanId -> span_id - * TraceId -> trace_id - * TraceFlags -> trace_flags - * SystemTimestamp -> timestamp - * system_clock::time_point -> timestamp - * KeyValueIterable -> attributes - * Key value iterable container -> attributes - * span> -> attributes(return type of MakeAttributes) - */ - template - void Fatal(ArgumentType &&...args) noexcept - { - static_assert( - !detail::LogRecordHasType::type...>::value, - "Severity is already set."); - this->EmitLogRecord(Severity::kFatal, std::forward(args)...); - } - - // - // OpenTelemetry C++ user-facing Logs API - // - - inline bool Enabled(Severity severity, const EventId &event_id) const noexcept - { - if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity)) - { - return false; - } - return EnabledImplementation(severity, event_id); - } - - inline bool Enabled(Severity severity, int64_t event_id) const noexcept - { - if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity)) - { - return false; - } - return EnabledImplementation(severity, event_id); - } - - inline bool Enabled(Severity severity) const noexcept - { - return static_cast(severity) >= OPENTELEMETRY_ATOMIC_READ_8(&minimum_severity_); - } - - /** - * Log an event - * - * @severity severity of the log - * @event_id event identifier of the log - * @format an utf-8 string following https://messagetemplates.org/ - * @attributes key value pairs of the log - */ - virtual void Log(Severity severity, - const EventId &event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->EmitLogRecord(severity, event_id, format, attributes); - } - - virtual void Log(Severity severity, - int64_t event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->EmitLogRecord(severity, EventId{event_id}, format, attributes); - } - - virtual void Log(Severity severity, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->EmitLogRecord(severity, format, attributes); - } - - virtual void Log(Severity severity, nostd::string_view message) noexcept - { - this->EmitLogRecord(severity, message); - } - - // Convenient wrappers based on virtual methods Log(). - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber - - inline void Trace(const EventId &event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kTrace, event_id, format, attributes); - } - - inline void Trace(int64_t event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kTrace, EventId{event_id}, format, attributes); - } - - inline void Trace(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kTrace, format, attributes); - } - - inline void Trace(nostd::string_view message) noexcept { this->Log(Severity::kTrace, message); } - - inline void Debug(const EventId &event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kDebug, event_id, format, attributes); - } - - inline void Debug(int64_t event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kDebug, EventId{event_id}, format, attributes); - } - - inline void Debug(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kDebug, format, attributes); - } - - inline void Debug(nostd::string_view message) noexcept { this->Log(Severity::kDebug, message); } - - inline void Info(const EventId &event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kInfo, event_id, format, attributes); - } - - inline void Info(int64_t event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kInfo, EventId{event_id}, format, attributes); - } - - inline void Info(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kInfo, format, attributes); - } - - inline void Info(nostd::string_view message) noexcept { this->Log(Severity::kInfo, message); } - - inline void Warn(const EventId &event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kWarn, event_id, format, attributes); - } - - inline void Warn(int64_t event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kWarn, EventId{event_id}, format, attributes); - } - - inline void Warn(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kWarn, format, attributes); - } - - inline void Warn(nostd::string_view message) noexcept { this->Log(Severity::kWarn, message); } - - inline void Error(const EventId &event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kError, event_id, format, attributes); - } - - inline void Error(int64_t event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kError, EventId{event_id}, format, attributes); - } - - inline void Error(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kError, format, attributes); - } - - inline void Error(nostd::string_view message) noexcept { this->Log(Severity::kError, message); } - - inline void Fatal(const EventId &event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kFatal, event_id, format, attributes); - } - - inline void Fatal(int64_t event_id, - nostd::string_view format, - const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kFatal, EventId{event_id}, format, attributes); - } - - inline void Fatal(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept - { - this->Log(Severity::kFatal, format, attributes); - } - - inline void Fatal(nostd::string_view message) noexcept { this->Log(Severity::kFatal, message); } - - // - // End of OpenTelemetry C++ user-facing Log API. - // - -protected: - // TODO: discuss with community about naming for internal methods. - virtual bool EnabledImplementation(Severity /*severity*/, - const EventId & /*event_id*/) const noexcept - { - return false; - } - - virtual bool EnabledImplementation(Severity /*severity*/, int64_t /*event_id*/) const noexcept - { - return false; - } - - void SetMinimumSeverity(uint8_t severity_or_max) noexcept - { - OPENTELEMETRY_ATOMIC_WRITE_8(&minimum_severity_, severity_or_max); - } - -private: - template - void IgnoreTraitResult(ValueType &&...) - {} - - // - // minimum_severity_ can be updated concurrently by multiple threads/cores, so race condition on - // read/write should be handled. And std::atomic can not be used here because it is not ABI - // compatible for OpenTelemetry C++ API. - // - mutable uint8_t minimum_severity_{kMaxSeverity}; -}; -} // namespace logs -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/logger_provider.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/logger_provider.h deleted file mode 100644 index ab1493c5c..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/logger_provider.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/common/key_value_iterable.h" -#include "opentelemetry/common/key_value_iterable_view.h" -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/nostd/span.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/type_traits.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace logs -{ - -class Logger; - -/** - * Creates new Logger instances. - */ -class OPENTELEMETRY_EXPORT LoggerProvider -{ -public: - virtual ~LoggerProvider() = default; - - /** - * Gets or creates a named Logger instance. - * - * Optionally a version can be passed to create a named and versioned Logger - * instance. - * - * Optionally a configuration file name can be passed to create a configuration for - * the Logger instance. - * - */ - - virtual nostd::shared_ptr GetLogger( - nostd::string_view logger_name, - nostd::string_view library_name = "", - nostd::string_view library_version = "", - nostd::string_view schema_url = "", - const common::KeyValueIterable &attributes = common::NoopKeyValueIterable()) = 0; - - nostd::shared_ptr GetLogger( - nostd::string_view logger_name, - nostd::string_view library_name, - nostd::string_view library_version, - nostd::string_view schema_url, - std::initializer_list> attributes) - { - return GetLogger(logger_name, library_name, library_version, schema_url, - nostd::span>{ - attributes.begin(), attributes.end()}); - } - - template ::value> * = nullptr> - nostd::shared_ptr GetLogger(nostd::string_view logger_name, - nostd::string_view library_name, - nostd::string_view library_version, - nostd::string_view schema_url, - const T &attributes) - { - return GetLogger(logger_name, library_name, library_version, schema_url, - common::KeyValueIterableView(attributes)); - } -}; -} // namespace logs -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/logger_type_traits.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/logger_type_traits.h deleted file mode 100644 index d88a6ffbd..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/logger_type_traits.h +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include - -#include "opentelemetry/common/attribute_value.h" -#include "opentelemetry/common/key_value_iterable.h" -#include "opentelemetry/common/timestamp.h" -#include "opentelemetry/logs/event_id.h" -#include "opentelemetry/logs/log_record.h" -#include "opentelemetry/logs/severity.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/type_traits.h" -#include "opentelemetry/trace/span_context.h" -#include "opentelemetry/trace/span_id.h" -#include "opentelemetry/trace/trace_flags.h" -#include "opentelemetry/trace/trace_id.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace logs -{ -namespace detail -{ -template -struct LogRecordSetterTrait; - -template <> -struct LogRecordSetterTrait -{ - template - inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept - { - log_record->SetSeverity(std::forward(arg)); - - return log_record; - } -}; - -template <> -struct LogRecordSetterTrait -{ - template - inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept - { - log_record->SetEventId(arg.id_, nostd::string_view{arg.name_.get()}); - - return log_record; - } -}; - -template <> -struct LogRecordSetterTrait -{ - template - inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept - { - log_record->SetSpanId(arg.span_id()); - log_record->SetTraceId(arg.trace_id()); - log_record->SetTraceFlags(arg.trace_flags()); - - return log_record; - } -}; - -template <> -struct LogRecordSetterTrait -{ - template - inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept - { - log_record->SetSpanId(std::forward(arg)); - - return log_record; - } -}; - -template <> -struct LogRecordSetterTrait -{ - template - inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept - { - log_record->SetTraceId(std::forward(arg)); - - return log_record; - } -}; - -template <> -struct LogRecordSetterTrait -{ - template - inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept - { - log_record->SetTraceFlags(std::forward(arg)); - - return log_record; - } -}; - -template <> -struct LogRecordSetterTrait -{ - template - inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept - { - log_record->SetTimestamp(std::forward(arg)); - - return log_record; - } -}; - -template <> -struct LogRecordSetterTrait -{ - template - inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept - { - log_record->SetTimestamp(common::SystemTimestamp(std::forward(arg))); - - return log_record; - } -}; - -template <> -struct LogRecordSetterTrait -{ - template - inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept - { - arg.ForEachKeyValue( - [&log_record](nostd::string_view key, common::AttributeValue value) noexcept { - log_record->SetAttribute(key, value); - return true; - }); - - return log_record; - } -}; - -template -struct LogRecordSetterTrait -{ - static_assert(!std::is_same, ValueType>::value && - !std::is_same, ValueType>::value, - "unique_ptr is not allowed, please use std::move()"); - - template ::value || - std::is_convertible::value, - void> * = nullptr> - inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept - { - log_record->SetBody(std::forward(arg)); - - return log_record; - } - - template ::value, bool> - * = nullptr> - inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept - { - return LogRecordSetterTrait::Set(log_record, - std::forward(arg)); - } - - template ::value, int> * = - nullptr> - inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept - { - for (auto &argv : arg) - { - log_record->SetAttribute(argv.first, argv.second); - } - - return log_record; - } -}; - -template -struct LogRecordHasType; - -template -struct LogRecordHasType : public std::false_type -{}; - -template -struct LogRecordHasType - : public std::conditional::value, - std::true_type, - LogRecordHasType>::type -{}; - -} // namespace detail - -} // namespace logs -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/noop.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/noop.h deleted file mode 100644 index 24312f061..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/noop.h +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -// Please refer to provider.h for documentation on how to obtain a Logger object. -// -// This file is part of the internal implementation of OpenTelemetry. Nothing in this file should be -// used directly. Please refer to logger.h for documentation on these interfaces. - -#include "opentelemetry/logs/event_logger.h" -#include "opentelemetry/logs/event_logger_provider.h" -#include "opentelemetry/logs/logger.h" -#include "opentelemetry/logs/logger_provider.h" -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/unique_ptr.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace common -{ -class KeyValueIterable; -} // namespace common - -namespace logs -{ -/** - * No-op implementation of Logger. This class should not be used directly. It should only be - * instantiated using a LoggerProvider's GetLogger() call. - */ -class NoopLogger final : public Logger -{ -public: - const nostd::string_view GetName() noexcept override { return "noop logger"; } - - nostd::unique_ptr CreateLogRecord() noexcept override - { - /* - * Do not return memory shared between threads, - * a `new` + `delete` for each noop record can not be avoided, - * due to the semantic of unique_ptr. - */ - return nostd::unique_ptr(new NoopLogRecord()); - } - - using Logger::EmitLogRecord; - - void EmitLogRecord(nostd::unique_ptr &&) noexcept override {} - -private: - class NoopLogRecord : public LogRecord - { - public: - NoopLogRecord() = default; - ~NoopLogRecord() override = default; - - void SetTimestamp(common::SystemTimestamp /* timestamp */) noexcept override {} - void SetObservedTimestamp(common::SystemTimestamp /* timestamp */) noexcept override {} - void SetSeverity(logs::Severity /* severity */) noexcept override {} - void SetBody(const common::AttributeValue & /* message */) noexcept override {} - void SetAttribute(nostd::string_view /* key */, - const common::AttributeValue & /* value */) noexcept override - {} - void SetEventId(int64_t /* id */, nostd::string_view /* name */) noexcept override {} - void SetTraceId(const trace::TraceId & /* trace_id */) noexcept override {} - void SetSpanId(const trace::SpanId & /* span_id */) noexcept override {} - void SetTraceFlags(const trace::TraceFlags & /* trace_flags */) noexcept override {} - }; -}; - -/** - * No-op implementation of a LoggerProvider. - */ -class NoopLoggerProvider final : public LoggerProvider -{ -public: - NoopLoggerProvider() : logger_{nostd::shared_ptr(new NoopLogger())} {} - - nostd::shared_ptr GetLogger(nostd::string_view /* logger_name */, - nostd::string_view /* library_name */, - nostd::string_view /* library_version */, - nostd::string_view /* schema_url */, - const common::KeyValueIterable & /* attributes */) override - { - return logger_; - } - -private: - nostd::shared_ptr logger_; -}; - -#if OPENTELEMETRY_ABI_VERSION_NO < 2 -class NoopEventLogger final : public EventLogger -{ -public: - NoopEventLogger() : logger_{nostd::shared_ptr(new NoopLogger())} {} - - const nostd::string_view GetName() noexcept override { return "noop event logger"; } - - nostd::shared_ptr GetDelegateLogger() noexcept override { return logger_; } - - void EmitEvent(nostd::string_view, nostd::unique_ptr &&) noexcept override {} - -private: - nostd::shared_ptr logger_; -}; - -/** - * No-op implementation of a EventLoggerProvider. - */ -class NoopEventLoggerProvider final : public EventLoggerProvider -{ -public: - NoopEventLoggerProvider() : event_logger_{nostd::shared_ptr(new NoopEventLogger())} - {} - - nostd::shared_ptr CreateEventLogger( - nostd::shared_ptr /*delegate_logger*/, - nostd::string_view /*event_domain*/) noexcept override - { - return event_logger_; - } - -private: - nostd::shared_ptr event_logger_; -}; -#endif - -} // namespace logs -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/provider.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/provider.h deleted file mode 100644 index 0c1b4deea..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/provider.h +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/common/macros.h" -#include "opentelemetry/common/spin_lock_mutex.h" -#include "opentelemetry/logs/noop.h" -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace logs -{ - -#if OPENTELEMETRY_ABI_VERSION_NO < 2 -class EventLoggerProvider; -#endif -class LoggerProvider; - -/** - * Stores the singleton global LoggerProvider. - */ -class OPENTELEMETRY_EXPORT Provider -{ -public: - /** - * Returns the singleton LoggerProvider. - * - * By default, a no-op LoggerProvider is returned. This will never return a - * nullptr LoggerProvider. - */ - static nostd::shared_ptr GetLoggerProvider() noexcept - { - std::lock_guard guard(GetLock()); - return nostd::shared_ptr(GetProvider()); - } - - /** - * Changes the singleton LoggerProvider. - */ - static void SetLoggerProvider(const nostd::shared_ptr &tp) noexcept - { - std::lock_guard guard(GetLock()); - GetProvider() = tp; - } - -#if OPENTELEMETRY_ABI_VERSION_NO < 2 - /** - * Returns the singleton EventLoggerProvider. - * - * By default, a no-op EventLoggerProvider is returned. This will never return a - * nullptr EventLoggerProvider. - */ - OPENTELEMETRY_DEPRECATED static nostd::shared_ptr - GetEventLoggerProvider() noexcept - { - std::lock_guard guard(GetLock()); - return nostd::shared_ptr(GetEventProvider()); - } - - /** - * Changes the singleton EventLoggerProvider. - */ - OPENTELEMETRY_DEPRECATED static void SetEventLoggerProvider( - const nostd::shared_ptr &tp) noexcept - { - std::lock_guard guard(GetLock()); - GetEventProvider() = tp; - } -#endif - -private: - OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr &GetProvider() noexcept - { - static nostd::shared_ptr provider(new NoopLoggerProvider); - return provider; - } - -#if OPENTELEMETRY_ABI_VERSION_NO < 2 - OPENTELEMETRY_DEPRECATED - OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr & - GetEventProvider() noexcept - { - static nostd::shared_ptr provider(new NoopEventLoggerProvider); - return provider; - } -#endif - - OPENTELEMETRY_API_SINGLETON static common::SpinLockMutex &GetLock() noexcept - { - static common::SpinLockMutex lock; - return lock; - } -}; - -} // namespace logs -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/severity.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/severity.h deleted file mode 100644 index f4d961615..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/logs/severity.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace logs -{ - -/** - * Severity Levels assigned to log events, based on Log Data Model, - * with the addition of kInvalid (mapped to a severity number of 0). - * - * See - * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber - */ -enum class Severity : uint8_t -{ - kInvalid = 0, - kTrace = 1, - kTrace2 = 2, - kTrace3 = 3, - kTrace4 = 4, - kDebug = 5, - kDebug2 = 6, - kDebug3 = 7, - kDebug4 = 8, - kInfo = 9, - kInfo2 = 10, - kInfo3 = 11, - kInfo4 = 12, - kWarn = 13, - kWarn2 = 14, - kWarn3 = 15, - kWarn4 = 16, - kError = 17, - kError2 = 18, - kError3 = 19, - kError4 = 20, - kFatal = 21, - kFatal2 = 22, - kFatal3 = 23, - kFatal4 = 24 -}; - -const uint8_t kMaxSeverity = 255; - -/** - * Mapping of the severity enum above, to a severity text string (in all caps). - * This severity text can be printed out by exporters. Capital letters follow the - * spec naming convention. - * - * Included to follow the specification's recommendation to print both - * severity number and text in each log record. - */ -const nostd::string_view SeverityNumToText[25] = { - "INVALID", "TRACE", "TRACE2", "TRACE3", "TRACE4", "DEBUG", "DEBUG2", "DEBUG3", "DEBUG4", - "INFO", "INFO2", "INFO3", "INFO4", "WARN", "WARN2", "WARN3", "WARN4", "ERROR", - "ERROR2", "ERROR3", "ERROR4", "FATAL", "FATAL2", "FATAL3", "FATAL4"}; - -} // namespace logs -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/async_instruments.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/async_instruments.h deleted file mode 100644 index f73eb2f51..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/async_instruments.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/metrics/observer_result.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace metrics -{ - -using ObservableCallbackPtr = void (*)(ObserverResult, void *); - -class ObservableInstrument -{ -public: - ObservableInstrument() = default; - virtual ~ObservableInstrument() = default; - - /** - * Sets up a function that will be called whenever a metric collection is initiated. - */ - virtual void AddCallback(ObservableCallbackPtr, void *state) noexcept = 0; - - /** - * Remove a function that was configured to be called whenever a metric collection is initiated. - */ - virtual void RemoveCallback(ObservableCallbackPtr, void *state) noexcept = 0; -}; - -} // namespace metrics -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/meter.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/meter.h deleted file mode 100644 index 59cfb8782..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/meter.h +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/unique_ptr.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace metrics -{ - -template -class Counter; - -template -class Histogram; - -template -class UpDownCounter; - -template -class Gauge; - -class ObservableInstrument; - -/** - * Handles instrument creation and provides a facility for batch recording. - * - * This class provides methods to create new metric instruments, record a - * batch of values to a specified set of instruments, and collect - * measurements from all instruments. - * - */ -class Meter -{ -public: - virtual ~Meter() = default; - - /** - * Creates a Counter with the passed characteristics and returns a unique_ptr to that Counter. - * - * @param name the name of the new Counter. - * @param description a brief description of what the Counter is used for. - * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. - * @return a shared pointer to the created Counter. - */ - - virtual nostd::unique_ptr> CreateUInt64Counter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; - - virtual nostd::unique_ptr> CreateDoubleCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; - - /** - * Creates a Asynchronous (Observable) counter with the passed characteristics and returns a - * shared_ptr to that Observable Counter - * - * @param name the name of the new Observable Counter. - * @param description a brief description of what the Observable Counter is used for. - * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. - */ - virtual nostd::shared_ptr CreateInt64ObservableCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; - - virtual nostd::shared_ptr CreateDoubleObservableCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; - - /** - * Creates a Histogram with the passed characteristics and returns a unique_ptr to that Histogram. - * - * @param name the name of the new Histogram. - * @param description a brief description of what the Histogram is used for. - * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. - * @return a shared pointer to the created Histogram. - */ - virtual nostd::unique_ptr> CreateUInt64Histogram( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; - - virtual nostd::unique_ptr> CreateDoubleHistogram( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; - -#if OPENTELEMETRY_ABI_VERSION_NO >= 2 - /** - * Creates a Gauge with the passed characteristics and returns a unique_ptr to that Gauge. - * - * @param name the name of the new Gauge. - * @param description a brief description of what the Gauge is used for. - * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. - * @return a unique pointer to the created Gauge. - */ - - virtual nostd::unique_ptr> CreateInt64Gauge( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; - - virtual nostd::unique_ptr> CreateDoubleGauge( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; -#endif - - /** - * Creates a Asynchronous (Observable) Gauge with the passed characteristics and returns a - * shared_ptr to that Observable Gauge - * - * @param name the name of the new Observable Gauge. - * @param description a brief description of what the Observable Gauge is used for. - * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. - */ - virtual nostd::shared_ptr CreateInt64ObservableGauge( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; - - virtual nostd::shared_ptr CreateDoubleObservableGauge( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; - - /** - * Creates an UpDownCounter with the passed characteristics and returns a unique_ptr to that - * UpDownCounter. - * - * @param name the name of the new UpDownCounter. - * @param description a brief description of what the UpDownCounter is used for. - * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. - * @return a shared pointer to the created UpDownCounter. - */ - virtual nostd::unique_ptr> CreateInt64UpDownCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; - - virtual nostd::unique_ptr> CreateDoubleUpDownCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; - - /** - * Creates a Asynchronous (Observable) UpDownCounter with the passed characteristics and returns - * a shared_ptr to that Observable UpDownCounter - * - * @param name the name of the new Observable UpDownCounter. - * @param description a brief description of what the Observable UpDownCounter is used for. - * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. - */ - virtual nostd::shared_ptr CreateInt64ObservableUpDownCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; - - virtual nostd::shared_ptr CreateDoubleObservableUpDownCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; -}; -} // namespace metrics -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/meter_provider.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/meter_provider.h deleted file mode 100644 index fca960bb8..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/meter_provider.h +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/common/key_value_iterable.h" -#include "opentelemetry/common/key_value_iterable_view.h" -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/type_traits.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace metrics -{ - -class Meter; - -/** - * Creates new Meter instances. - */ -class MeterProvider -{ -public: - virtual ~MeterProvider() = default; - -#if OPENTELEMETRY_ABI_VERSION_NO >= 2 - - /** - * Gets or creates a named Meter instance (ABI). - * - * @since ABI_VERSION 2 - * - * @param[in] name Meter instrumentation scope - * @param[in] version Instrumentation scope version - * @param[in] schema_url Instrumentation scope schema URL - * @param[in] attributes Instrumentation scope attributes (optional, may be nullptr) - */ - virtual nostd::shared_ptr GetMeter( - nostd::string_view name, - nostd::string_view version, - nostd::string_view schema_url, - const common::KeyValueIterable *attributes) noexcept = 0; - - /** - * Gets or creates a named Meter instance (API helper). - * - * @since ABI_VERSION 2 - * - * @param[in] name Meter instrumentation scope - * @param[in] version Instrumentation scope version, optional - * @param[in] schema_url Instrumentation scope schema URL, optional - */ - nostd::shared_ptr GetMeter(nostd::string_view name, - nostd::string_view version = "", - nostd::string_view schema_url = "") - { - return GetMeter(name, version, schema_url, nullptr); - } - - /** - * Gets or creates a named Meter instance (API helper). - * - * @since ABI_VERSION 2 - * - * @param[in] name Meter instrumentation scope - * @param[in] version Instrumentation scope version - * @param[in] schema_url Instrumentation scope schema URL - * @param[in] attributes Instrumentation scope attributes - */ - nostd::shared_ptr GetMeter( - nostd::string_view name, - nostd::string_view version, - nostd::string_view schema_url, - std::initializer_list> attributes) - { - /* Build a container from std::initializer_list. */ - nostd::span> attributes_span{ - attributes.begin(), attributes.end()}; - - /* Build a view on the container. */ - common::KeyValueIterableView< - nostd::span>> - iterable_attributes{attributes_span}; - - /* Add attributes using the view. */ - return GetMeter(name, version, schema_url, &iterable_attributes); - } - - /** - * Gets or creates a named Meter instance (API helper). - * - * @since ABI_VERSION 2 - * - * @param[in] name Meter instrumentation scope - * @param[in] version Instrumentation scope version - * @param[in] schema_url Instrumentation scope schema URL - * @param[in] attributes Instrumentation scope attributes container - */ - template ::value> * = nullptr> - nostd::shared_ptr GetMeter(nostd::string_view name, - nostd::string_view version, - nostd::string_view schema_url, - const T &attributes) - { - /* Build a view on the container. */ - common::KeyValueIterableView iterable_attributes(attributes); - - /* Add attributes using the view. */ - return GetMeter(name, version, schema_url, &iterable_attributes); - } - -#else - /** - * Gets or creates a named Meter instance (ABI) - * - * @since ABI_VERSION 1 - * - * @param[in] name Meter instrumentation scope - * @param[in] version Instrumentation scope version, optional - * @param[in] schema_url Instrumentation scope schema URL, optional - */ - virtual nostd::shared_ptr GetMeter(nostd::string_view name, - nostd::string_view version = "", - nostd::string_view schema_url = "") noexcept = 0; -#endif - -#if OPENTELEMETRY_ABI_VERSION_NO >= 2 - /** - * Remove a named Meter instance (ABI). - * - * This API is experimental, see - * https://github.com/open-telemetry/opentelemetry-specification/issues/2232 - * - * @since ABI_VERSION 2 - * - * @param[in] name Meter instrumentation scope - * @param[in] version Instrumentation scope version, optional - * @param[in] schema_url Instrumentation scope schema URL, optional - */ - virtual void RemoveMeter(nostd::string_view name, - nostd::string_view version = "", - nostd::string_view schema_url = "") noexcept = 0; -#endif -}; -} // namespace metrics -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/noop.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/noop.h deleted file mode 100644 index 1d508b938..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/noop.h +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/metrics/async_instruments.h" -#include "opentelemetry/metrics/meter.h" -#include "opentelemetry/metrics/meter_provider.h" -#include "opentelemetry/metrics/observer_result.h" -#include "opentelemetry/metrics/sync_instruments.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace metrics -{ - -template -class NoopCounter : public Counter -{ -public: - NoopCounter(nostd::string_view /* name */, - nostd::string_view /* description */, - nostd::string_view /* unit */) noexcept - {} - void Add(T /* value */) noexcept override {} - void Add(T /* value */, const context::Context & /* context */) noexcept override {} - void Add(T /* value */, const common::KeyValueIterable & /* attributes */) noexcept override {} - void Add(T /* value */, - const common::KeyValueIterable & /* attributes */, - const context::Context & /* context */) noexcept override - {} -}; - -template -class NoopHistogram : public Histogram -{ -public: - NoopHistogram(nostd::string_view /* name */, - nostd::string_view /* description */, - nostd::string_view /* unit */) noexcept - {} - void Record(T /* value */, const context::Context & /* context */) noexcept override {} - void Record(T /* value */, - const common::KeyValueIterable & /* attributes */, - const context::Context & /* context */) noexcept override - {} -#if OPENTELEMETRY_ABI_VERSION_NO >= 2 - void Record(T /*value*/, - const opentelemetry::common::KeyValueIterable & /*attributes*/) noexcept override - {} - - void Record(T /*value*/) noexcept override {} -#endif -}; - -template -class NoopUpDownCounter : public UpDownCounter -{ -public: - NoopUpDownCounter(nostd::string_view /* name */, - nostd::string_view /* description */, - nostd::string_view /* unit */) noexcept - {} - ~NoopUpDownCounter() override = default; - void Add(T /* value */) noexcept override {} - void Add(T /* value */, const context::Context & /* context */) noexcept override {} - void Add(T /* value */, const common::KeyValueIterable & /* attributes */) noexcept override {} - void Add(T /* value */, - const common::KeyValueIterable & /* attributes */, - const context::Context & /* context */) noexcept override - {} -}; - -#if OPENTELEMETRY_ABI_VERSION_NO >= 2 -template -class NoopGauge : public Gauge -{ -public: - NoopGauge(nostd::string_view /* name */, - nostd::string_view /* description */, - nostd::string_view /* unit */) noexcept - {} - ~NoopGauge() override = default; - void Record(T /* value */) noexcept override {} - void Record(T /* value */, const context::Context & /* context */) noexcept override {} - void Record(T /* value */, const common::KeyValueIterable & /* attributes */) noexcept override {} - void Record(T /* value */, - const common::KeyValueIterable & /* attributes */, - const context::Context & /* context */) noexcept override - {} -}; -#endif - -class NoopObservableInstrument : public ObservableInstrument -{ -public: - NoopObservableInstrument(nostd::string_view /* name */, - nostd::string_view /* description */, - nostd::string_view /* unit */) noexcept - {} - - void AddCallback(ObservableCallbackPtr, void * /* state */) noexcept override {} - void RemoveCallback(ObservableCallbackPtr, void * /* state */) noexcept override {} -}; - -/** - * No-op implementation of Meter. - */ -class NoopMeter final : public Meter -{ -public: - nostd::unique_ptr> CreateUInt64Counter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::unique_ptr>{new NoopCounter(name, description, unit)}; - } - - nostd::unique_ptr> CreateDoubleCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::unique_ptr>{new NoopCounter(name, description, unit)}; - } - - nostd::shared_ptr CreateInt64ObservableCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::shared_ptr( - new NoopObservableInstrument(name, description, unit)); - } - - nostd::shared_ptr CreateDoubleObservableCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::shared_ptr( - new NoopObservableInstrument(name, description, unit)); - } - - nostd::unique_ptr> CreateUInt64Histogram( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::unique_ptr>{ - new NoopHistogram(name, description, unit)}; - } - - nostd::unique_ptr> CreateDoubleHistogram( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::unique_ptr>{new NoopHistogram(name, description, unit)}; - } - -#if OPENTELEMETRY_ABI_VERSION_NO >= 2 - nostd::unique_ptr> CreateInt64Gauge(nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::unique_ptr>{new NoopGauge(name, description, unit)}; - } - - nostd::unique_ptr> CreateDoubleGauge(nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::unique_ptr>{new NoopGauge(name, description, unit)}; - } -#endif - - nostd::shared_ptr CreateInt64ObservableGauge( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::shared_ptr( - new NoopObservableInstrument(name, description, unit)); - } - - nostd::shared_ptr CreateDoubleObservableGauge( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::shared_ptr( - new NoopObservableInstrument(name, description, unit)); - } - - nostd::unique_ptr> CreateInt64UpDownCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::unique_ptr>{ - new NoopUpDownCounter(name, description, unit)}; - } - - nostd::unique_ptr> CreateDoubleUpDownCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::unique_ptr>{ - new NoopUpDownCounter(name, description, unit)}; - } - - nostd::shared_ptr CreateInt64ObservableUpDownCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::shared_ptr( - new NoopObservableInstrument(name, description, unit)); - } - - nostd::shared_ptr CreateDoubleObservableUpDownCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::shared_ptr( - new NoopObservableInstrument(name, description, unit)); - } -}; - -/** - * No-op implementation of a MeterProvider. - */ -class NoopMeterProvider final : public MeterProvider -{ -public: - NoopMeterProvider() : meter_{nostd::shared_ptr(new NoopMeter)} {} - -#if OPENTELEMETRY_ABI_VERSION_NO >= 2 - nostd::shared_ptr GetMeter( - nostd::string_view /* name */, - nostd::string_view /* version */, - nostd::string_view /* schema_url */, - const common::KeyValueIterable * /* attributes */) noexcept override - { - return meter_; - } -#else - nostd::shared_ptr GetMeter(nostd::string_view /* name */, - nostd::string_view /* version */, - nostd::string_view /* schema_url */) noexcept override - { - return meter_; - } -#endif - -#if OPENTELEMETRY_ABI_VERSION_NO >= 2 - void RemoveMeter(nostd::string_view /* name */, - nostd::string_view /* version */, - nostd::string_view /* schema_url */) noexcept override - {} -#endif - -private: - nostd::shared_ptr meter_; -}; -} // namespace metrics -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/observer_result.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/observer_result.h deleted file mode 100644 index 56c42bc20..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/observer_result.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/common/attribute_value.h" -#include "opentelemetry/common/key_value_iterable_view.h" -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/nostd/span.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/type_traits.h" -#include "opentelemetry/nostd/variant.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace metrics -{ - -/** - * ObserverResultT class is necessary for the callback recording asynchronous - * instrument use. - */ -template -class ObserverResultT -{ - -public: - virtual ~ObserverResultT() = default; - - virtual void Observe(T value) noexcept = 0; - - virtual void Observe(T value, const common::KeyValueIterable &attributes) noexcept = 0; - - template ::value> * = nullptr> - void Observe(T value, const U &attributes) noexcept - { - this->Observe(value, common::KeyValueIterableView{attributes}); - } - - void Observe(T value, - std::initializer_list> - attributes) noexcept - { - this->Observe(value, nostd::span>{ - attributes.begin(), attributes.end()}); - } -}; - -using ObserverResult = nostd::variant>, - nostd::shared_ptr>>; - -} // namespace metrics -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/provider.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/provider.h deleted file mode 100644 index 20a606a77..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/provider.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/common/spin_lock_mutex.h" -#include "opentelemetry/metrics/meter_provider.h" -#include "opentelemetry/metrics/noop.h" -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace metrics -{ - -/** - * Stores the singleton global MeterProvider. - */ -class Provider -{ -public: - /** - * Returns the singleton MeterProvider. - * - * By default, a no-op MeterProvider is returned. This will never return a - * nullptr MeterProvider. - */ - static nostd::shared_ptr GetMeterProvider() noexcept - { - std::lock_guard guard(GetLock()); - return nostd::shared_ptr(GetProvider()); - } - - /** - * Changes the singleton MeterProvider. - */ - static void SetMeterProvider(const nostd::shared_ptr &tp) noexcept - { - std::lock_guard guard(GetLock()); - GetProvider() = tp; - } - -private: - OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr &GetProvider() noexcept - { - static nostd::shared_ptr provider(new NoopMeterProvider); - return provider; - } - - OPENTELEMETRY_API_SINGLETON static common::SpinLockMutex &GetLock() noexcept - { - static common::SpinLockMutex lock; - return lock; - } -}; - -} // namespace metrics -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/sync_instruments.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/sync_instruments.h deleted file mode 100644 index 9eaec3352..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/metrics/sync_instruments.h +++ /dev/null @@ -1,328 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/common/attribute_value.h" -#include "opentelemetry/common/key_value_iterable_view.h" -#include "opentelemetry/context/context.h" -#include "opentelemetry/nostd/span.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/type_traits.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace metrics -{ - -class SynchronousInstrument -{ -public: - SynchronousInstrument() = default; - virtual ~SynchronousInstrument() = default; -}; - -/* A Counter instrument that adds values. */ -template -class Counter : public SynchronousInstrument -{ - -public: - /** - * Record a value - * - * @param value The increment amount. MUST be non-negative. - */ - virtual void Add(T value) noexcept = 0; - - /** - * Record a value - * - * @param value The increment amount. MUST be non-negative. - * @param context The explicit context to associate with this measurement. - */ - virtual void Add(T value, const context::Context &context) noexcept = 0; - - /** - * Record a value with a set of attributes. - * - * @param value The increment amount. MUST be non-negative. - * @param attributes A set of attributes to associate with the value. - */ - - virtual void Add(T value, const common::KeyValueIterable &attributes) noexcept = 0; - - /** - * Record a value with a set of attributes. - * - * @param value The increment amount. MUST be non-negative. - * @param attributes A set of attributes to associate with the value. - * @param context The explicit context to associate with this measurement. - */ - virtual void Add(T value, - const common::KeyValueIterable &attributes, - const context::Context &context) noexcept = 0; - - template ::value> * = nullptr> - void Add(T value, const U &attributes) noexcept - { - this->Add(value, common::KeyValueIterableView{attributes}); - } - - template ::value> * = nullptr> - void Add(T value, const U &attributes, const context::Context &context) noexcept - { - this->Add(value, common::KeyValueIterableView{attributes}, context); - } - - void Add(T value, - std::initializer_list> - attributes) noexcept - { - this->Add(value, nostd::span>{ - attributes.begin(), attributes.end()}); - } - - void Add(T value, - std::initializer_list> attributes, - const context::Context &context) noexcept - { - this->Add(value, - nostd::span>{ - attributes.begin(), attributes.end()}, - context); - } -}; - -/** A histogram instrument that records values. */ - -template -class Histogram : public SynchronousInstrument -{ -public: -#if OPENTELEMETRY_ABI_VERSION_NO >= 2 - /** - * @since ABI_VERSION 2 - * Records a value. - * - * @param value The measurement value. MUST be non-negative. - */ - virtual void Record(T value) noexcept = 0; - - /** - * @since ABI_VERSION 2 - * Records a value with a set of attributes. - * - * @param value The measurement value. MUST be non-negative. - * @param attribute A set of attributes to associate with the value. - */ - virtual void Record(T value, const common::KeyValueIterable &attribute) noexcept = 0; - - template ::value> * = nullptr> - void Record(T value, const U &attributes) noexcept - { - this->Record(value, common::KeyValueIterableView{attributes}); - } - - void Record(T value, - std::initializer_list> - attributes) noexcept - { - this->Record(value, nostd::span>{ - attributes.begin(), attributes.end()}); - } -#endif - - /** - * Records a value. - * - * @param value The measurement value. MUST be non-negative. - * @param context The explicit context to associate with this measurement. - */ - virtual void Record(T value, const context::Context &context) noexcept = 0; - - /** - * Records a value with a set of attributes. - * - * @param value The measurement value. MUST be non-negative. - * @param attributes A set of attributes to associate with the value.. - * @param context The explicit context to associate with this measurement. - */ - virtual void Record(T value, - const common::KeyValueIterable &attributes, - const context::Context &context) noexcept = 0; - - template ::value> * = nullptr> - void Record(T value, const U &attributes, const context::Context &context) noexcept - { - this->Record(value, common::KeyValueIterableView{attributes}, context); - } - - void Record( - T value, - std::initializer_list> attributes, - const context::Context &context) noexcept - { - this->Record(value, - nostd::span>{ - attributes.begin(), attributes.end()}, - context); - } -}; - -/** An up-down-counter instrument that adds or reduce values. */ - -template -class UpDownCounter : public SynchronousInstrument -{ -public: - /** - * Record a value. - * - * @param value The increment amount. May be positive, negative or zero. - */ - virtual void Add(T value) noexcept = 0; - - /** - * Record a value. - * - * @param value The increment amount. May be positive, negative or zero. - * @param context The explicit context to associate with this measurement. - */ - virtual void Add(T value, const context::Context &context) noexcept = 0; - - /** - * Record a value with a set of attributes. - * - * @param value The increment amount. May be positive, negative or zero. - * @param attributes A set of attributes to associate with the count. - */ - virtual void Add(T value, const common::KeyValueIterable &attributes) noexcept = 0; - - /** - * Record a value with a set of attributes. - * - * @param value The increment amount. May be positive, negative or zero. - * @param attributes A set of attributes to associate with the count. - * @param context The explicit context to associate with this measurement. - */ - virtual void Add(T value, - const common::KeyValueIterable &attributes, - const context::Context &context) noexcept = 0; - - template ::value> * = nullptr> - void Add(T value, const U &attributes) noexcept - { - this->Add(value, common::KeyValueIterableView{attributes}); - } - - template ::value> * = nullptr> - void Add(T value, const U &attributes, const context::Context &context) noexcept - { - this->Add(value, common::KeyValueIterableView{attributes}, context); - } - - void Add(T value, - std::initializer_list> - attributes) noexcept - { - this->Add(value, nostd::span>{ - attributes.begin(), attributes.end()}); - } - - void Add(T value, - std::initializer_list> attributes, - const context::Context &context) noexcept - { - this->Add(value, - nostd::span>{ - attributes.begin(), attributes.end()}, - context); - } -}; - -#if OPENTELEMETRY_ABI_VERSION_NO >= 2 -/* A Gauge instrument that records values. */ -template -class Gauge : public SynchronousInstrument -{ - -public: - /** - * Record a value - * - * @param value The measurement value. May be positive, negative or zero. - */ - virtual void Record(T value) noexcept = 0; - - /** - * Record a value - * - * @param value The measurement value. May be positive, negative or zero. - * @param context The explicit context to associate with this measurement. - */ - virtual void Record(T value, const context::Context &context) noexcept = 0; - - /** - * Record a value with a set of attributes. - * - * @param value The measurement value. May be positive, negative or zero. - * @param attributes A set of attributes to associate with the value. - */ - - virtual void Record(T value, const common::KeyValueIterable &attributes) noexcept = 0; - - /** - * Record a value with a set of attributes. - * - * @param value The measurement value. May be positive, negative or zero. - * @param attributes A set of attributes to associate with the value. - * @param context The explicit context to associate with this measurement. - */ - virtual void Record(T value, - const common::KeyValueIterable &attributes, - const context::Context &context) noexcept = 0; - - template ::value> * = nullptr> - void Record(T value, const U &attributes) noexcept - { - this->Record(value, common::KeyValueIterableView{attributes}); - } - - template ::value> * = nullptr> - void Record(T value, const U &attributes, const context::Context &context) noexcept - { - this->Record(value, common::KeyValueIterableView{attributes}, context); - } - - void Record(T value, - std::initializer_list> - attributes) noexcept - { - this->Record(value, nostd::span>{ - attributes.begin(), attributes.end()}); - } - - void Record( - T value, - std::initializer_list> attributes, - const context::Context &context) noexcept - { - this->Record(value, - nostd::span>{ - attributes.begin(), attributes.end()}, - context); - } -}; -#endif - -} // namespace metrics -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/all.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/all.h deleted file mode 100644 index deaf3ac6f..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/all.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/nostd/utility.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace nostd -{ -namespace detail -{ -template -using all = std::is_same, integer_sequence>; - -} // namespace detail -} // namespace nostd -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/decay.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/decay.h deleted file mode 100644 index a6cb11124..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/decay.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace nostd -{ -template -using decay_t = typename std::decay::type; -} // namespace nostd -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/dependent_type.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/dependent_type.h deleted file mode 100644 index 5bba09ff8..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/dependent_type.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace nostd -{ -namespace detail -{ -template -struct dependent_type : T -{}; -} // namespace detail -} // namespace nostd -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/functional.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/functional.h deleted file mode 100644 index 0da58dd18..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/functional.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/version.h" - -#define OPENTELEMETRY_RETURN(...) \ - noexcept(noexcept(__VA_ARGS__))->decltype(__VA_ARGS__) \ - { \ - return __VA_ARGS__; \ - } - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace nostd -{ -namespace detail -{ -struct equal_to -{ - template - inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const - OPENTELEMETRY_RETURN(std::forward(lhs) == std::forward(rhs)) -}; - -struct not_equal_to -{ - template - inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const - OPENTELEMETRY_RETURN(std::forward(lhs) != std::forward(rhs)) -}; - -struct less -{ - template - inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const - OPENTELEMETRY_RETURN(std::forward(lhs) < std::forward(rhs)) -}; - -struct greater -{ - template - inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const - OPENTELEMETRY_RETURN(std::forward(lhs) > std::forward(rhs)) -}; - -struct less_equal -{ - template - inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const - OPENTELEMETRY_RETURN(std::forward(lhs) <= std::forward(rhs)) -}; - -struct greater_equal -{ - template - inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const - OPENTELEMETRY_RETURN(std::forward(lhs) >= std::forward(rhs)) -}; -} // namespace detail -} // namespace nostd -OPENTELEMETRY_END_NAMESPACE - -#undef OPENTELEMETRY_RETURN diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/invoke.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/invoke.h deleted file mode 100644 index 55a943ed1..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/invoke.h +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include "opentelemetry/nostd/detail/decay.h" -#include "opentelemetry/nostd/detail/void.h" -#include "opentelemetry/version.h" - -#define OPENTELEMETRY_RETURN(...) \ - noexcept(noexcept(__VA_ARGS__))->decltype(__VA_ARGS__) \ - { \ - return __VA_ARGS__; \ - } - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace nostd -{ -namespace detail -{ - -template -struct is_reference_wrapper : std::false_type -{}; - -template -struct is_reference_wrapper> : std::true_type -{}; - -template -struct Invoke; - -template <> -struct Invoke -{ - template - inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&...args) - OPENTELEMETRY_RETURN((std::forward(arg).*pmf)(std::forward(args)...)) -}; - -template <> -struct Invoke -{ - template - inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&...args) - OPENTELEMETRY_RETURN((std::forward(arg).get().*pmf)(std::forward(args)...)) -}; - -template <> -struct Invoke -{ - template - inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&...args) - OPENTELEMETRY_RETURN(((*std::forward(arg)).*pmf)(std::forward(args)...)) -}; - -template <> -struct Invoke -{ - template - inline static constexpr auto invoke(R T::*pmo, Arg &&arg) - OPENTELEMETRY_RETURN(std::forward(arg).*pmo) -}; - -template <> -struct Invoke -{ - template - inline static constexpr auto invoke(R T::*pmo, Arg &&arg) - OPENTELEMETRY_RETURN(std::forward(arg).get().*pmo) -}; - -template <> -struct Invoke -{ - template - inline static constexpr auto invoke(R T::*pmo, Arg &&arg) - OPENTELEMETRY_RETURN((*std::forward(arg)).*pmo) -}; - -template -inline constexpr auto invoke_impl(R T::*f, Arg &&arg, Args &&...args) OPENTELEMETRY_RETURN( - Invoke::value, - (std::is_base_of>::value ? 0 - : is_reference_wrapper>::value ? 1 - : 2)>::invoke(f, - std::forward(arg), - std::forward(args)...)) - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4100) -#endif - template - inline constexpr auto invoke_impl(F &&f, Args &&...args) - OPENTELEMETRY_RETURN(std::forward(f)(std::forward(args)...)) -#ifdef _MSC_VER -# pragma warning(pop) -#endif -} // namespace detail - -/* clang-format off */ -template -inline constexpr auto invoke(F &&f, Args &&... args) - OPENTELEMETRY_RETURN(detail::invoke_impl(std::forward(f), std::forward(args)...)) - -namespace detail -/* clang-format on */ -{ - - template - struct invoke_result - {}; - - template - struct invoke_result(), std::declval()...))>, - F, Args...> - { - using type = decltype(nostd::invoke(std::declval(), std::declval()...)); - }; - -} // namespace detail - -template -using invoke_result = detail::invoke_result; - -template -using invoke_result_t = typename invoke_result::type; - -namespace detail -{ - -template -struct is_invocable : std::false_type -{}; - -template -struct is_invocable>, F, Args...> : std::true_type -{}; - -template -struct is_invocable_r : std::false_type -{}; - -template -struct is_invocable_r>, R, F, Args...> - : std::is_convertible, R> -{}; - -} // namespace detail - -template -using is_invocable = detail::is_invocable; - -template -using is_invocable_r = detail::is_invocable_r; -} // namespace nostd -OPENTELEMETRY_END_NAMESPACE - -#undef OPENTELEMETRY_RETURN diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/trait.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/trait.h deleted file mode 100644 index 8f76fdec8..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/trait.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/nostd/type_traits.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace nostd -{ -namespace detail -{ -enum class Trait -{ - TriviallyAvailable, - Available, - Unavailable -}; - -template - class IsTriviallyAvailable, - template - class IsAvailable> -inline constexpr Trait trait() -{ - return IsTriviallyAvailable::value ? Trait::TriviallyAvailable - : IsAvailable::value ? Trait::Available - : Trait::Unavailable; -} - -inline constexpr Trait common_trait_impl(Trait result) -{ - return result; -} - -template -inline constexpr Trait common_trait_impl(Trait result, Trait t, Traits... ts) -{ - return static_cast(t) > static_cast(result) ? common_trait_impl(t, ts...) - : common_trait_impl(result, ts...); -} - -template -inline constexpr Trait common_trait(Traits... ts) -{ - return common_trait_impl(Trait::TriviallyAvailable, ts...); -} - -template -struct traits -{ - static constexpr Trait copy_constructible_trait = - common_trait(trait()...); - - static constexpr Trait move_constructible_trait = - common_trait(trait()...); - - static constexpr Trait copy_assignable_trait = - common_trait(copy_constructible_trait, - trait()...); - - static constexpr Trait move_assignable_trait = - common_trait(move_constructible_trait, - trait()...); - - static constexpr Trait destructible_trait = - common_trait(trait()...); -}; -} // namespace detail -} // namespace nostd -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/type_pack_element.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/type_pack_element.h deleted file mode 100644 index 280d24e94..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/type_pack_element.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include "opentelemetry/nostd/utility.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace nostd -{ -namespace detail -{ -template -using size_constant = std::integral_constant; - -template -struct indexed_type : size_constant -{ - using type = T; -}; - -template -struct type_pack_element_impl -{ -private: - template - struct set; - - template - struct set> : indexed_type... - {}; - - template - inline static std::enable_if impl(indexed_type); - - inline static std::enable_if impl(...); - -public: - using type = decltype(impl(set>{})); -}; - -template -using type_pack_element = typename type_pack_element_impl::type; - -template -using type_pack_element_t = typename type_pack_element::type; -} // namespace detail -} // namespace nostd -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/valueless.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/valueless.h deleted file mode 100644 index 3b2ca7f7c..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/valueless.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace nostd -{ -struct valueless_t -{}; -} // namespace nostd -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/variant_alternative.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/variant_alternative.h deleted file mode 100644 index cc0da9c8c..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/variant_alternative.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/nostd/detail/type_pack_element.h" -#include "opentelemetry/nostd/detail/variant_fwd.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace nostd -{ -template -struct variant_alternative; - -template -using variant_alternative_t = typename variant_alternative::type; - -template -struct variant_alternative : std::add_const> -{}; - -template -struct variant_alternative : std::add_volatile> -{}; - -template -struct variant_alternative : std::add_cv> -{}; - -template -struct variant_alternative> -{ - static_assert(I < sizeof...(Ts), "index out of bounds in `std::variant_alternative<>`"); - using type = detail::type_pack_element_t; -}; -} // namespace nostd -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/variant_fwd.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/variant_fwd.h deleted file mode 100644 index 6bae9659e..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/variant_fwd.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace nostd -{ -template -class variant; -} // namespace nostd -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/variant_size.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/variant_size.h deleted file mode 100644 index d8986a222..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/variant_size.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include "opentelemetry/nostd/detail/variant_fwd.h" -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace nostd -{ -template -struct variant_size; - -template -struct variant_size : variant_size -{}; - -template -struct variant_size : variant_size -{}; - -template -struct variant_size : variant_size -{}; - -template -struct variant_size> : std::integral_constant -{}; -} // namespace nostd -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/void.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/void.h deleted file mode 100644 index 1b4c3b4f7..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/detail/void.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace nostd -{ -namespace detail -{ -template -struct voider -{ - using type = void; -}; -} // namespace detail - -/** - * Back port of std::void_t - * - * Note: voider workaround is required for gcc-4.8 to make SFINAE work - */ -template -using void_t = typename detail::voider::type; -} // namespace nostd -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/function_ref.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/function_ref.h deleted file mode 100644 index 6f0c2dd33..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/function_ref.h +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include // IWYU pragma: keep -#include -#include - -#include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace nostd -{ -template -class function_ref; // IWYU pragma: keep - -/** - * Non-owning function reference that can be used as a more performant - * replacement for std::function when ownership sematics aren't needed. - * - * See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0792r0.html - * - * Based off of https://stackoverflow.com/a/39087660/4447365 - */ -template -class function_ref -{ - void *callable_ = nullptr; - R (*invoker_)(void *, Args...) = nullptr; - - template - using FunctionPointer = decltype(std::addressof(std::declval())); - - template - void BindTo(F &f) noexcept - { - callable_ = static_cast(std::addressof(f)); - invoker_ = [](void *callable, Args... args) -> R { - return (*static_cast>(callable))(std::forward(args)...); - }; - } - - template - void BindTo(R_in (*f)(Args_in...)) noexcept - { - using F = decltype(f); - if (f == nullptr) - { - return BindTo(nullptr); - } - callable_ = reinterpret_cast(f); - invoker_ = [](void *callable, Args... args) -> R { - return (F(callable))(std::forward(args)...); - }; - } - - void BindTo(std::nullptr_t) noexcept - { - callable_ = nullptr; - invoker_ = nullptr; - } - -public: - template < - class F, - typename std::enable_if::type>::value, - int>::type = 0, - typename std::enable_if< -#if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && (_MSVC_LANG > 201402)) - // std::result_of deprecated in C++17, removed in C++20 - std::is_convertible::type, R>::value, -#else - // std::result_of since C++11 - std::is_convertible::type, R>::value, -#endif - int>::type = 0> - function_ref(F &&f) - { - BindTo(f); // not forward - } - - function_ref(std::nullptr_t) {} - - function_ref(const function_ref &) noexcept = default; - function_ref(function_ref &&) noexcept = default; - - R operator()(Args... args) const { return invoker_(callable_, std::forward(args)...); } - - explicit operator bool() const { return invoker_; } -}; -} // namespace nostd -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/.clang-format b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/.clang-format deleted file mode 100644 index 001170f7e..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/.clang-format +++ /dev/null @@ -1,3 +0,0 @@ -# Disable formatting for Google Abseil library snapshot -DisableFormat: true -SortIncludes: false diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/README.md b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/README.md deleted file mode 100644 index 5dd661971..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Notes on Abseil Variant implementation - -This is a snapshot of Abseil Variant -`absl::OTABSL_OPTION_NAMESPACE_NAME::variant` from Abseil `v2020-03-03#8`. diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/attributes.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/attributes.h deleted file mode 100644 index 72901a84c..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/attributes.h +++ /dev/null @@ -1,621 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// This header file defines macros for declaring attributes for functions, -// types, and variables. -// -// These macros are used within Abseil and allow the compiler to optimize, where -// applicable, certain function calls. -// -// This file is used for both C and C++! -// -// Most macros here are exposing GCC or Clang features, and are stubbed out for -// other compilers. -// -// GCC attributes documentation: -// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html -// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Variable-Attributes.html -// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Type-Attributes.html -// -// Most attributes in this file are already supported by GCC 4.7. However, some -// of them are not supported in older version of Clang. Thus, we check -// `__has_attribute()` first. If the check fails, we check if we are on GCC and -// assume the attribute exists on GCC (which is verified on GCC 4.7). -// -// ----------------------------------------------------------------------------- -// Sanitizer Attributes -// ----------------------------------------------------------------------------- -// -// Sanitizer-related attributes are not "defined" in this file (and indeed -// are not defined as such in any file). To utilize the following -// sanitizer-related attributes within your builds, define the following macros -// within your build using a `-D` flag, along with the given value for -// `-fsanitize`: -// -// * `ADDRESS_SANITIZER` + `-fsanitize=address` (Clang, GCC 4.8) -// * `MEMORY_SANITIZER` + `-fsanitize=memory` (Clang-only) -// * `THREAD_SANITIZER + `-fsanitize=thread` (Clang, GCC 4.8+) -// * `UNDEFINED_BEHAVIOR_SANITIZER` + `-fsanitize=undefined` (Clang, GCC 4.9+) -// * `CONTROL_FLOW_INTEGRITY` + -fsanitize=cfi (Clang-only) -// -// Example: -// -// // Enable branches in the Abseil code that are tagged for ASan: -// $ bazel build --copt=-DADDRESS_SANITIZER --copt=-fsanitize=address -// --linkopt=-fsanitize=address *target* -// -// Since these macro names are only supported by GCC and Clang, we only check -// for `__GNUC__` (GCC or Clang) and the above macros. -#ifndef OTABSL_BASE_ATTRIBUTES_H_ -#define OTABSL_BASE_ATTRIBUTES_H_ - -// OTABSL_HAVE_ATTRIBUTE -// -// A function-like feature checking macro that is a wrapper around -// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a -// nonzero constant integer if the attribute is supported or 0 if not. -// -// It evaluates to zero if `__has_attribute` is not defined by the compiler. -// -// GCC: https://gcc.gnu.org/gcc-5/changes.html -// Clang: https://clang.llvm.org/docs/LanguageExtensions.html -#ifdef __has_attribute -#define OTABSL_HAVE_ATTRIBUTE(x) __has_attribute(x) -#else -#define OTABSL_HAVE_ATTRIBUTE(x) 0 -#endif - -// OTABSL_HAVE_CPP_ATTRIBUTE -// -// A function-like feature checking macro that accepts C++11 style attributes. -// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6 -// (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't -// find `__has_cpp_attribute`, will evaluate to 0. -#if defined(__cplusplus) && defined(__has_cpp_attribute) -// NOTE: requiring __cplusplus above should not be necessary, but -// works around https://bugs.llvm.org/show_bug.cgi?id=23435. -#define OTABSL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) -#else -#define OTABSL_HAVE_CPP_ATTRIBUTE(x) 0 -#endif - -// ----------------------------------------------------------------------------- -// Function Attributes -// ----------------------------------------------------------------------------- -// -// GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html -// Clang: https://clang.llvm.org/docs/AttributeReference.html - -// OTABSL_PRINTF_ATTRIBUTE -// OTABSL_SCANF_ATTRIBUTE -// -// Tells the compiler to perform `printf` format string checking if the -// compiler supports it; see the 'format' attribute in -// . -// -// Note: As the GCC manual states, "[s]ince non-static C++ methods -// have an implicit 'this' argument, the arguments of such methods -// should be counted from two, not one." -#if OTABSL_HAVE_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__)) -#define OTABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) \ - __attribute__((__format__(__printf__, string_index, first_to_check))) -#define OTABSL_SCANF_ATTRIBUTE(string_index, first_to_check) \ - __attribute__((__format__(__scanf__, string_index, first_to_check))) -#else -#define OTABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) -#define OTABSL_SCANF_ATTRIBUTE(string_index, first_to_check) -#endif - -// OTABSL_ATTRIBUTE_ALWAYS_INLINE -// OTABSL_ATTRIBUTE_NOINLINE -// -// Forces functions to either inline or not inline. Introduced in gcc 3.1. -#if OTABSL_HAVE_ATTRIBUTE(always_inline) || \ - (defined(__GNUC__) && !defined(__clang__)) -#define OTABSL_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) -#define OTABSL_HAVE_ATTRIBUTE_ALWAYS_INLINE 1 -#else -#define OTABSL_ATTRIBUTE_ALWAYS_INLINE -#endif - -#if OTABSL_HAVE_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__)) -#define OTABSL_ATTRIBUTE_NOINLINE __attribute__((noinline)) -#define OTABSL_HAVE_ATTRIBUTE_NOINLINE 1 -#else -#define OTABSL_ATTRIBUTE_NOINLINE -#endif - -// OTABSL_ATTRIBUTE_NO_TAIL_CALL -// -// Prevents the compiler from optimizing away stack frames for functions which -// end in a call to another function. -#if OTABSL_HAVE_ATTRIBUTE(disable_tail_calls) -#define OTABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 -#define OTABSL_ATTRIBUTE_NO_TAIL_CALL __attribute__((disable_tail_calls)) -#elif defined(__GNUC__) && !defined(__clang__) -#define OTABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 -#define OTABSL_ATTRIBUTE_NO_TAIL_CALL \ - __attribute__((optimize("no-optimize-sibling-calls"))) -#else -#define OTABSL_ATTRIBUTE_NO_TAIL_CALL -#define OTABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 0 -#endif - -// OTABSL_ATTRIBUTE_WEAK -// -// Tags a function as weak for the purposes of compilation and linking. -// Weak attributes currently do not work properly in LLVM's Windows backend, -// so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598 -// for further information. -// The MinGW compiler doesn't complain about the weak attribute until the link -// step, presumably because Windows doesn't use ELF binaries. -#if (OTABSL_HAVE_ATTRIBUTE(weak) || \ - (defined(__GNUC__) && !defined(__clang__))) && \ - !(defined(__llvm__) && defined(_WIN32)) && !defined(__MINGW32__) -#undef OTABSL_ATTRIBUTE_WEAK -#define OTABSL_ATTRIBUTE_WEAK __attribute__((weak)) -#define OTABSL_HAVE_ATTRIBUTE_WEAK 1 -#else -#define OTABSL_ATTRIBUTE_WEAK -#define OTABSL_HAVE_ATTRIBUTE_WEAK 0 -#endif - -// OTABSL_ATTRIBUTE_NONNULL -// -// Tells the compiler either (a) that a particular function parameter -// should be a non-null pointer, or (b) that all pointer arguments should -// be non-null. -// -// Note: As the GCC manual states, "[s]ince non-static C++ methods -// have an implicit 'this' argument, the arguments of such methods -// should be counted from two, not one." -// -// Args are indexed starting at 1. -// -// For non-static class member functions, the implicit `this` argument -// is arg 1, and the first explicit argument is arg 2. For static class member -// functions, there is no implicit `this`, and the first explicit argument is -// arg 1. -// -// Example: -// -// /* arg_a cannot be null, but arg_b can */ -// void Function(void* arg_a, void* arg_b) OTABSL_ATTRIBUTE_NONNULL(1); -// -// class C { -// /* arg_a cannot be null, but arg_b can */ -// void Method(void* arg_a, void* arg_b) OTABSL_ATTRIBUTE_NONNULL(2); -// -// /* arg_a cannot be null, but arg_b can */ -// static void StaticMethod(void* arg_a, void* arg_b) -// OTABSL_ATTRIBUTE_NONNULL(1); -// }; -// -// If no arguments are provided, then all pointer arguments should be non-null. -// -// /* No pointer arguments may be null. */ -// void Function(void* arg_a, void* arg_b, int arg_c) OTABSL_ATTRIBUTE_NONNULL(); -// -// NOTE: The GCC nonnull attribute actually accepts a list of arguments, but -// OTABSL_ATTRIBUTE_NONNULL does not. -#if OTABSL_HAVE_ATTRIBUTE(nonnull) || (defined(__GNUC__) && !defined(__clang__)) -#define OTABSL_ATTRIBUTE_NONNULL(arg_index) __attribute__((nonnull(arg_index))) -#else -#define OTABSL_ATTRIBUTE_NONNULL(...) -#endif - -// OTABSL_ATTRIBUTE_NORETURN -// -// Tells the compiler that a given function never returns. -#if OTABSL_HAVE_ATTRIBUTE(noreturn) || (defined(__GNUC__) && !defined(__clang__)) -#define OTABSL_ATTRIBUTE_NORETURN __attribute__((noreturn)) -#elif defined(_MSC_VER) -#define OTABSL_ATTRIBUTE_NORETURN __declspec(noreturn) -#else -#define OTABSL_ATTRIBUTE_NORETURN -#endif - -// OTABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS -// -// Tells the AddressSanitizer (or other memory testing tools) to ignore a given -// function. Useful for cases when a function reads random locations on stack, -// calls _exit from a cloned subprocess, deliberately accesses buffer -// out of bounds or does other scary things with memory. -// NOTE: GCC supports AddressSanitizer(asan) since 4.8. -// https://gcc.gnu.org/gcc-4.8/changes.html -#if defined(__GNUC__) -#define OTABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) -#else -#define OTABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS -#endif - -// OTABSL_ATTRIBUTE_NO_SANITIZE_MEMORY -// -// Tells the MemorySanitizer to relax the handling of a given function. All -// "Use of uninitialized value" warnings from such functions will be suppressed, -// and all values loaded from memory will be considered fully initialized. -// This attribute is similar to the ADDRESS_SANITIZER attribute above, but deals -// with initialized-ness rather than addressability issues. -// NOTE: MemorySanitizer(msan) is supported by Clang but not GCC. -#if defined(__clang__) -#define OTABSL_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) -#else -#define OTABSL_ATTRIBUTE_NO_SANITIZE_MEMORY -#endif - -// OTABSL_ATTRIBUTE_NO_SANITIZE_THREAD -// -// Tells the ThreadSanitizer to not instrument a given function. -// NOTE: GCC supports ThreadSanitizer(tsan) since 4.8. -// https://gcc.gnu.org/gcc-4.8/changes.html -#if defined(__GNUC__) -#define OTABSL_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) -#else -#define OTABSL_ATTRIBUTE_NO_SANITIZE_THREAD -#endif - -// OTABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED -// -// Tells the UndefinedSanitizer to ignore a given function. Useful for cases -// where certain behavior (eg. division by zero) is being used intentionally. -// NOTE: GCC supports UndefinedBehaviorSanitizer(ubsan) since 4.9. -// https://gcc.gnu.org/gcc-4.9/changes.html -#if defined(__GNUC__) && \ - (defined(UNDEFINED_BEHAVIOR_SANITIZER) || defined(ADDRESS_SANITIZER)) -#define OTABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \ - __attribute__((no_sanitize("undefined"))) -#else -#define OTABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED -#endif - -// OTABSL_ATTRIBUTE_NO_SANITIZE_CFI -// -// Tells the ControlFlowIntegrity sanitizer to not instrument a given function. -// See https://clang.llvm.org/docs/ControlFlowIntegrity.html for details. -#if defined(__GNUC__) && defined(CONTROL_FLOW_INTEGRITY) -#define OTABSL_ATTRIBUTE_NO_SANITIZE_CFI __attribute__((no_sanitize("cfi"))) -#else -#define OTABSL_ATTRIBUTE_NO_SANITIZE_CFI -#endif - -// OTABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK -// -// Tells the SafeStack to not instrument a given function. -// See https://clang.llvm.org/docs/SafeStack.html for details. -#if defined(__GNUC__) && defined(SAFESTACK_SANITIZER) -#define OTABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK \ - __attribute__((no_sanitize("safe-stack"))) -#else -#define OTABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK -#endif - -// OTABSL_ATTRIBUTE_RETURNS_NONNULL -// -// Tells the compiler that a particular function never returns a null pointer. -#if OTABSL_HAVE_ATTRIBUTE(returns_nonnull) || \ - (defined(__GNUC__) && \ - (__GNUC__ > 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) && \ - !defined(__clang__)) -#define OTABSL_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) -#else -#define OTABSL_ATTRIBUTE_RETURNS_NONNULL -#endif - -// OTABSL_HAVE_ATTRIBUTE_SECTION -// -// Indicates whether labeled sections are supported. Weak symbol support is -// a prerequisite. Labeled sections are not supported on Darwin/iOS. -#ifdef OTABSL_HAVE_ATTRIBUTE_SECTION -#error OTABSL_HAVE_ATTRIBUTE_SECTION cannot be directly set -#elif (OTABSL_HAVE_ATTRIBUTE(section) || \ - (defined(__GNUC__) && !defined(__clang__))) && \ - !defined(__APPLE__) && OTABSL_HAVE_ATTRIBUTE_WEAK -#define OTABSL_HAVE_ATTRIBUTE_SECTION 1 - -// OTABSL_ATTRIBUTE_SECTION -// -// Tells the compiler/linker to put a given function into a section and define -// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. -// This functionality is supported by GNU linker. Any function annotated with -// `OTABSL_ATTRIBUTE_SECTION` must not be inlined, or it will be placed into -// whatever section its caller is placed into. -// -#ifndef OTABSL_ATTRIBUTE_SECTION -#define OTABSL_ATTRIBUTE_SECTION(name) \ - __attribute__((section(#name))) __attribute__((noinline)) -#endif - - -// OTABSL_ATTRIBUTE_SECTION_VARIABLE -// -// Tells the compiler/linker to put a given variable into a section and define -// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. -// This functionality is supported by GNU linker. -#ifndef OTABSL_ATTRIBUTE_SECTION_VARIABLE -#define OTABSL_ATTRIBUTE_SECTION_VARIABLE(name) __attribute__((section(#name))) -#endif - -// OTABSL_DECLARE_ATTRIBUTE_SECTION_VARS -// -// A weak section declaration to be used as a global declaration -// for OTABSL_ATTRIBUTE_SECTION_START|STOP(name) to compile and link -// even without functions with OTABSL_ATTRIBUTE_SECTION(name). -// OTABSL_DEFINE_ATTRIBUTE_SECTION should be in the exactly one file; it's -// a no-op on ELF but not on Mach-O. -// -#ifndef OTABSL_DECLARE_ATTRIBUTE_SECTION_VARS -#define OTABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) \ - extern char __start_##name[] OTABSL_ATTRIBUTE_WEAK; \ - extern char __stop_##name[] OTABSL_ATTRIBUTE_WEAK -#endif -#ifndef OTABSL_DEFINE_ATTRIBUTE_SECTION_VARS -#define OTABSL_INIT_ATTRIBUTE_SECTION_VARS(name) -#define OTABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) -#endif - -// OTABSL_ATTRIBUTE_SECTION_START -// -// Returns `void*` pointers to start/end of a section of code with -// functions having OTABSL_ATTRIBUTE_SECTION(name). -// Returns 0 if no such functions exist. -// One must OTABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) for this to compile and -// link. -// -#define OTABSL_ATTRIBUTE_SECTION_START(name) \ - (reinterpret_cast(__start_##name)) -#define OTABSL_ATTRIBUTE_SECTION_STOP(name) \ - (reinterpret_cast(__stop_##name)) - -#else // !OTABSL_HAVE_ATTRIBUTE_SECTION - -#define OTABSL_HAVE_ATTRIBUTE_SECTION 0 - -// provide dummy definitions -#define OTABSL_ATTRIBUTE_SECTION(name) -#define OTABSL_ATTRIBUTE_SECTION_VARIABLE(name) -#define OTABSL_INIT_ATTRIBUTE_SECTION_VARS(name) -#define OTABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) -#define OTABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) -#define OTABSL_ATTRIBUTE_SECTION_START(name) (reinterpret_cast(0)) -#define OTABSL_ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast(0)) - -#endif // OTABSL_ATTRIBUTE_SECTION - -// OTABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC -// -// Support for aligning the stack on 32-bit x86. -#if OTABSL_HAVE_ATTRIBUTE(force_align_arg_pointer) || \ - (defined(__GNUC__) && !defined(__clang__)) -#if defined(__i386__) -#define OTABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC \ - __attribute__((force_align_arg_pointer)) -#define OTABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) -#elif defined(__x86_64__) -#define OTABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (1) -#define OTABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC -#else // !__i386__ && !__x86_64 -#define OTABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) -#define OTABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC -#endif // __i386__ -#else -#define OTABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC -#define OTABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) -#endif - -// OTABSL_MUST_USE_RESULT -// -// Tells the compiler to warn about unused results. -// -// When annotating a function, it must appear as the first part of the -// declaration or definition. The compiler will warn if the return value from -// such a function is unused: -// -// OTABSL_MUST_USE_RESULT Sprocket* AllocateSprocket(); -// AllocateSprocket(); // Triggers a warning. -// -// When annotating a class, it is equivalent to annotating every function which -// returns an instance. -// -// class OTABSL_MUST_USE_RESULT Sprocket {}; -// Sprocket(); // Triggers a warning. -// -// Sprocket MakeSprocket(); -// MakeSprocket(); // Triggers a warning. -// -// Note that references and pointers are not instances: -// -// Sprocket* SprocketPointer(); -// SprocketPointer(); // Does *not* trigger a warning. -// -// OTABSL_MUST_USE_RESULT allows using cast-to-void to suppress the unused result -// warning. For that, warn_unused_result is used only for clang but not for gcc. -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 -// -// Note: past advice was to place the macro after the argument list. -#if OTABSL_HAVE_ATTRIBUTE(nodiscard) -#define OTABSL_MUST_USE_RESULT [[nodiscard]] -#elif defined(__clang__) && OTABSL_HAVE_ATTRIBUTE(warn_unused_result) -#define OTABSL_MUST_USE_RESULT __attribute__((warn_unused_result)) -#else -#define OTABSL_MUST_USE_RESULT -#endif - -// OTABSL_ATTRIBUTE_HOT, OTABSL_ATTRIBUTE_COLD -// -// Tells GCC that a function is hot or cold. GCC can use this information to -// improve static analysis, i.e. a conditional branch to a cold function -// is likely to be not-taken. -// This annotation is used for function declarations. -// -// Example: -// -// int foo() OTABSL_ATTRIBUTE_HOT; -#if OTABSL_HAVE_ATTRIBUTE(hot) || (defined(__GNUC__) && !defined(__clang__)) -#define OTABSL_ATTRIBUTE_HOT __attribute__((hot)) -#else -#define OTABSL_ATTRIBUTE_HOT -#endif - -#if OTABSL_HAVE_ATTRIBUTE(cold) || (defined(__GNUC__) && !defined(__clang__)) -#define OTABSL_ATTRIBUTE_COLD __attribute__((cold)) -#else -#define OTABSL_ATTRIBUTE_COLD -#endif - -// OTABSL_XRAY_ALWAYS_INSTRUMENT, OTABSL_XRAY_NEVER_INSTRUMENT, OTABSL_XRAY_LOG_ARGS -// -// We define the OTABSL_XRAY_ALWAYS_INSTRUMENT and OTABSL_XRAY_NEVER_INSTRUMENT -// macro used as an attribute to mark functions that must always or never be -// instrumented by XRay. Currently, this is only supported in Clang/LLVM. -// -// For reference on the LLVM XRay instrumentation, see -// http://llvm.org/docs/XRay.html. -// -// A function with the XRAY_ALWAYS_INSTRUMENT macro attribute in its declaration -// will always get the XRay instrumentation sleds. These sleds may introduce -// some binary size and runtime overhead and must be used sparingly. -// -// These attributes only take effect when the following conditions are met: -// -// * The file/target is built in at least C++11 mode, with a Clang compiler -// that supports XRay attributes. -// * The file/target is built with the -fxray-instrument flag set for the -// Clang/LLVM compiler. -// * The function is defined in the translation unit (the compiler honors the -// attribute in either the definition or the declaration, and must match). -// -// There are cases when, even when building with XRay instrumentation, users -// might want to control specifically which functions are instrumented for a -// particular build using special-case lists provided to the compiler. These -// special case lists are provided to Clang via the -// -fxray-always-instrument=... and -fxray-never-instrument=... flags. The -// attributes in source take precedence over these special-case lists. -// -// To disable the XRay attributes at build-time, users may define -// OTABSL_NO_XRAY_ATTRIBUTES. Do NOT define OTABSL_NO_XRAY_ATTRIBUTES on specific -// packages/targets, as this may lead to conflicting definitions of functions at -// link-time. -// -#if OTABSL_HAVE_CPP_ATTRIBUTE(clang::xray_always_instrument) && \ - !defined(OTABSL_NO_XRAY_ATTRIBUTES) -#define OTABSL_XRAY_ALWAYS_INSTRUMENT [[clang::xray_always_instrument]] -#define OTABSL_XRAY_NEVER_INSTRUMENT [[clang::xray_never_instrument]] -#if OTABSL_HAVE_CPP_ATTRIBUTE(clang::xray_log_args) -#define OTABSL_XRAY_LOG_ARGS(N) \ - [[clang::xray_always_instrument, clang::xray_log_args(N)]] -#else -#define OTABSL_XRAY_LOG_ARGS(N) [[clang::xray_always_instrument]] -#endif -#else -#define OTABSL_XRAY_ALWAYS_INSTRUMENT -#define OTABSL_XRAY_NEVER_INSTRUMENT -#define OTABSL_XRAY_LOG_ARGS(N) -#endif - -// OTABSL_ATTRIBUTE_REINITIALIZES -// -// Indicates that a member function reinitializes the entire object to a known -// state, independent of the previous state of the object. -// -// The clang-tidy check bugprone-use-after-move allows member functions marked -// with this attribute to be called on objects that have been moved from; -// without the attribute, this would result in a use-after-move warning. -#if OTABSL_HAVE_CPP_ATTRIBUTE(clang::reinitializes) -#define OTABSL_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]] -#else -#define OTABSL_ATTRIBUTE_REINITIALIZES -#endif - -// ----------------------------------------------------------------------------- -// Variable Attributes -// ----------------------------------------------------------------------------- - -// OTABSL_ATTRIBUTE_UNUSED -// -// Prevents the compiler from complaining about variables that appear unused. -#if OTABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__)) -#undef OTABSL_ATTRIBUTE_UNUSED -#define OTABSL_ATTRIBUTE_UNUSED __attribute__((__unused__)) -#else -#define OTABSL_ATTRIBUTE_UNUSED -#endif - -// OTABSL_ATTRIBUTE_INITIAL_EXEC -// -// Tells the compiler to use "initial-exec" mode for a thread-local variable. -// See http://people.redhat.com/drepper/tls.pdf for the gory details. -#if OTABSL_HAVE_ATTRIBUTE(tls_model) || (defined(__GNUC__) && !defined(__clang__)) -#define OTABSL_ATTRIBUTE_INITIAL_EXEC __attribute__((tls_model("initial-exec"))) -#else -#define OTABSL_ATTRIBUTE_INITIAL_EXEC -#endif - -// OTABSL_ATTRIBUTE_PACKED -// -// Instructs the compiler not to use natural alignment for a tagged data -// structure, but instead to reduce its alignment to 1. This attribute can -// either be applied to members of a structure or to a structure in its -// entirety. Applying this attribute (judiciously) to a structure in its -// entirety to optimize the memory footprint of very commonly-used structs is -// fine. Do not apply this attribute to a structure in its entirety if the -// purpose is to control the offsets of the members in the structure. Instead, -// apply this attribute only to structure members that need it. -// -// When applying OTABSL_ATTRIBUTE_PACKED only to specific structure members the -// natural alignment of structure members not annotated is preserved. Aligned -// member accesses are faster than non-aligned member accesses even if the -// targeted microprocessor supports non-aligned accesses. -#if OTABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__)) -#define OTABSL_ATTRIBUTE_PACKED __attribute__((__packed__)) -#else -#define OTABSL_ATTRIBUTE_PACKED -#endif - -// OTABSL_ATTRIBUTE_FUNC_ALIGN -// -// Tells the compiler to align the function start at least to certain -// alignment boundary -#if OTABSL_HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__)) -#define OTABSL_ATTRIBUTE_FUNC_ALIGN(bytes) __attribute__((aligned(bytes))) -#else -#define OTABSL_ATTRIBUTE_FUNC_ALIGN(bytes) -#endif - -// OTABSL_CONST_INIT -// -// A variable declaration annotated with the `OTABSL_CONST_INIT` attribute will -// not compile (on supported platforms) unless the variable has a constant -// initializer. This is useful for variables with static and thread storage -// duration, because it guarantees that they will not suffer from the so-called -// "static init order fiasco". Prefer to put this attribute on the most visible -// declaration of the variable, if there's more than one, because code that -// accesses the variable can then use the attribute for optimization. -// -// Example: -// -// class MyClass { -// public: -// OTABSL_CONST_INIT static MyType my_var; -// }; -// -// MyType MyClass::my_var = MakeMyType(...); -// -// Note that this attribute is redundant if the variable is declared constexpr. -#if OTABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) -#define OTABSL_CONST_INIT [[clang::require_constant_initialization]] -#else -#define OTABSL_CONST_INIT -#endif // OTABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) - -#endif // OTABSL_BASE_ATTRIBUTES_H_ diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/config.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/config.h deleted file mode 100644 index e0836b9b3..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/config.h +++ /dev/null @@ -1,671 +0,0 @@ -// -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ----------------------------------------------------------------------------- -// File: config.h -// ----------------------------------------------------------------------------- -// -// This header file defines a set of macros for checking the presence of -// important compiler and platform features. Such macros can be used to -// produce portable code by parameterizing compilation based on the presence or -// lack of a given feature. -// -// We define a "feature" as some interface we wish to program to: for example, -// a library function or system call. A value of `1` indicates support for -// that feature; any other value indicates the feature support is undefined. -// -// Example: -// -// Suppose a programmer wants to write a program that uses the 'mmap()' system -// call. The Abseil macro for that feature (`OTABSL_HAVE_MMAP`) allows you to -// selectively include the `mmap.h` header and bracket code using that feature -// in the macro: -// -// #include "absl/base/config.h" -// -// #ifdef OTABSL_HAVE_MMAP -// #include "sys/mman.h" -// #endif //OTABSL_HAVE_MMAP -// -// ... -// #ifdef OTABSL_HAVE_MMAP -// void *ptr = mmap(...); -// ... -// #endif // OTABSL_HAVE_MMAP - -#ifndef OTABSL_BASE_CONFIG_H_ -#define OTABSL_BASE_CONFIG_H_ - -// Included for the __GLIBC__ macro (or similar macros on other systems). -#include - -#ifdef __cplusplus -// Included for __GLIBCXX__, _LIBCPP_VERSION -#include -#endif // __cplusplus - -#if defined(__APPLE__) -// Included for TARGET_OS_IPHONE, __IPHONE_OS_VERSION_MIN_REQUIRED, -// __IPHONE_8_0. -#include -#include -#endif - -#include "options.h" -#include "policy_checks.h" - -// Helper macro to convert a CPP variable to a string literal. -#define OTABSL_INTERNAL_DO_TOKEN_STR(x) #x -#define OTABSL_INTERNAL_TOKEN_STR(x) OTABSL_INTERNAL_DO_TOKEN_STR(x) - -// ----------------------------------------------------------------------------- -// Abseil namespace annotations -// ----------------------------------------------------------------------------- - -// OTABSL_NAMESPACE_BEGIN/OTABSL_NAMESPACE_END -// -// An annotation placed at the beginning/end of each `namespace absl` scope. -// This is used to inject an inline namespace. -// -// The proper way to write Abseil code in the `absl` namespace is: -// -// namespace absl { -// OTABSL_NAMESPACE_BEGIN -// -// void Foo(); // absl::OTABSL_OPTION_NAMESPACE_NAME::Foo(). -// -// OTABSL_NAMESPACE_END -// } // namespace absl -// -// Users of Abseil should not use these macros, because users of Abseil should -// not write `namespace absl {` in their own code for any reason. (Abseil does -// not support forward declarations of its own types, nor does it support -// user-provided specialization of Abseil templates. Code that violates these -// rules may be broken without warning.) -#if !defined(OTABSL_OPTION_NAMESPACE_NAME) -#error options.h is misconfigured. -#endif - -// Check that OTABSL_OPTION_NAMESPACE_NAME is neither "head" nor "" -#if defined(__cplusplus) - -#define OTABSL_INTERNAL_INLINE_NAMESPACE_STR \ - OTABSL_INTERNAL_TOKEN_STR(OTABSL_OPTION_NAMESPACE_NAME) - -static_assert(OTABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != '\0', - "options.h misconfigured: OTABSL_OPTION_NAMESPACE_NAME must " - "not be empty."); -static_assert(OTABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || - OTABSL_INTERNAL_INLINE_NAMESPACE_STR[1] != 'e' || - OTABSL_INTERNAL_INLINE_NAMESPACE_STR[2] != 'a' || - OTABSL_INTERNAL_INLINE_NAMESPACE_STR[3] != 'd' || - OTABSL_INTERNAL_INLINE_NAMESPACE_STR[4] != '\0', - "options.h misconfigured: OTABSL_OPTION_NAMESPACE_NAME must " - "be changed to a new, unique identifier name."); - -#endif - - -#define OTABSL_NAMESPACE_BEGIN namespace OTABSL_OPTION_NAMESPACE_NAME { -#define OTABSL_NAMESPACE_END } - -// ----------------------------------------------------------------------------- -// Compiler Feature Checks -// ----------------------------------------------------------------------------- - -// OTABSL_HAVE_BUILTIN() -// -// Checks whether the compiler supports a Clang Feature Checking Macro, and if -// so, checks whether it supports the provided builtin function "x" where x -// is one of the functions noted in -// https://clang.llvm.org/docs/LanguageExtensions.html -// -// Note: Use this macro to avoid an extra level of #ifdef __has_builtin check. -// http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html -#ifdef __has_builtin -#define OTABSL_HAVE_BUILTIN(x) __has_builtin(x) -#else -#define OTABSL_HAVE_BUILTIN(x) 0 -#endif - -#if defined(__is_identifier) -#define OTABSL_INTERNAL_HAS_KEYWORD(x) !(__is_identifier(x)) -#else -#define OTABSL_INTERNAL_HAS_KEYWORD(x) 0 -#endif - -// OTABSL_HAVE_TLS is defined to 1 when __thread should be supported. -// We assume __thread is supported on Linux when compiled with Clang or compiled -// against libstdc++ with _GLIBCXX_HAVE_TLS defined. -#ifdef OTABSL_HAVE_TLS -#error OTABSL_HAVE_TLS cannot be directly set -#elif defined(__linux__) && (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS)) -#define OTABSL_HAVE_TLS 1 -#endif - -// OTABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE -// -// Checks whether `std::is_trivially_destructible` is supported. -// -// Notes: All supported compilers using libc++ support this feature, as does -// gcc >= 4.8.1 using libstdc++, and Visual Studio. -#ifdef OTABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE -#error OTABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set -#elif defined(_LIBCPP_VERSION) || \ - (defined(__clang__) && __clang_major__ >= 15) || \ - (!defined(__clang__) && defined(__GNUC__) && defined(__GLIBCXX__) && \ - (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \ - defined(_MSC_VER) -#define OTABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1 -#endif - -// OTABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE -// -// Checks whether `std::is_trivially_default_constructible` and -// `std::is_trivially_copy_constructible` are supported. - -// OTABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE -// -// Checks whether `std::is_trivially_copy_assignable` is supported. - -// Notes: Clang with libc++ supports these features, as does gcc >= 5.1 with -// either libc++ or libstdc++, and Visual Studio (but not NVCC). -#if defined(OTABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) -#error OTABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set -#elif defined(OTABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE) -#error OTABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot directly set -#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \ - (defined(__clang__) && __clang_major__ >= 15) || \ - (!defined(__clang__) && defined(__GNUC__) && \ - (__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ >= 4)) && \ - (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__))) || \ - (defined(_MSC_VER) && !defined(__NVCC__)) -#define OTABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1 -#define OTABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1 -#endif - -// OTABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE -// -// Checks whether `std::is_trivially_copyable` is supported. -// -// Notes: Clang 15+ with libc++ supports these features, GCC hasn't been tested. -#if defined(OTABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE) -#error OTABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE cannot be directly set -#elif defined(__clang__) && (__clang_major__ >= 15) -#define OTABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE 1 -#endif - -// OTABSL_HAVE_SOURCE_LOCATION_CURRENT -// -// Indicates whether `absl::OTABSL_OPTION_NAMESPACE_NAME::SourceLocation::current()` will return useful -// information in some contexts. -#ifndef OTABSL_HAVE_SOURCE_LOCATION_CURRENT -#if OTABSL_INTERNAL_HAS_KEYWORD(__builtin_LINE) && \ - OTABSL_INTERNAL_HAS_KEYWORD(__builtin_FILE) -#define OTABSL_HAVE_SOURCE_LOCATION_CURRENT 1 -#endif -#endif - -// OTABSL_HAVE_THREAD_LOCAL -// -// Checks whether C++11's `thread_local` storage duration specifier is -// supported. -#ifdef OTABSL_HAVE_THREAD_LOCAL -#error OTABSL_HAVE_THREAD_LOCAL cannot be directly set -#elif defined(__APPLE__) -// Notes: -// * Xcode's clang did not support `thread_local` until version 8, and -// even then not for all iOS < 9.0. -// * Xcode 9.3 started disallowing `thread_local` for 32-bit iOS simulator -// targeting iOS 9.x. -// * Xcode 10 moves the deployment target check for iOS < 9.0 to link time -// making __has_feature unreliable there. -// -// Otherwise, `__has_feature` is only supported by Clang so it has be inside -// `defined(__APPLE__)` check. -#if __has_feature(cxx_thread_local) && \ - !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0) -#define OTABSL_HAVE_THREAD_LOCAL 1 -#endif -#else // !defined(__APPLE__) -#define OTABSL_HAVE_THREAD_LOCAL 1 -#endif - -// There are platforms for which TLS should not be used even though the compiler -// makes it seem like it's supported (Android NDK < r12b for example). -// This is primarily because of linker problems and toolchain misconfiguration: -// Abseil does not intend to support this indefinitely. Currently, the newest -// toolchain that we intend to support that requires this behavior is the -// r11 NDK - allowing for a 5 year support window on that means this option -// is likely to be removed around June of 2021. -// TLS isn't supported until NDK r12b per -// https://developer.android.com/ndk/downloads/revision_history.html -// Since NDK r16, `__NDK_MAJOR__` and `__NDK_MINOR__` are defined in -// . For NDK < r16, users should define these macros, -// e.g. `-D__NDK_MAJOR__=11 -D__NKD_MINOR__=0` for NDK r11. -#if defined(__ANDROID__) && defined(__clang__) -#if __has_include() -#include -#endif // __has_include() -#if defined(__ANDROID__) && defined(__clang__) && defined(__NDK_MAJOR__) && \ - defined(__NDK_MINOR__) && \ - ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1))) -#undef OTABSL_HAVE_TLS -#undef OTABSL_HAVE_THREAD_LOCAL -#endif -#endif // defined(__ANDROID__) && defined(__clang__) - -// Emscripten doesn't yet support `thread_local` or `__thread`. -// https://github.com/emscripten-core/emscripten/issues/3502 -#if defined(__EMSCRIPTEN__) -#undef OTABSL_HAVE_TLS -#undef OTABSL_HAVE_THREAD_LOCAL -#endif // defined(__EMSCRIPTEN__) - -// OTABSL_HAVE_INTRINSIC_INT128 -// -// Checks whether the __int128 compiler extension for a 128-bit integral type is -// supported. -// -// Note: __SIZEOF_INT128__ is defined by Clang and GCC when __int128 is -// supported, but we avoid using it in certain cases: -// * On Clang: -// * Building using Clang for Windows, where the Clang runtime library has -// 128-bit support only on LP64 architectures, but Windows is LLP64. -// * On Nvidia's nvcc: -// * nvcc also defines __GNUC__ and __SIZEOF_INT128__, but not all versions -// actually support __int128. -#ifdef OTABSL_HAVE_INTRINSIC_INT128 -#error OTABSL_HAVE_INTRINSIC_INT128 cannot be directly set -#elif defined(__SIZEOF_INT128__) -#if (defined(__clang__) && !defined(_WIN32)) || \ - (defined(__CUDACC__) && __CUDACC_VER_MAJOR__ >= 9) || \ - (defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__)) -#define OTABSL_HAVE_INTRINSIC_INT128 1 -#elif defined(__CUDACC__) -// __CUDACC_VER__ is a full version number before CUDA 9, and is defined to a -// string explaining that it has been removed starting with CUDA 9. We use -// nested #ifs because there is no short-circuiting in the preprocessor. -// NOTE: `__CUDACC__` could be undefined while `__CUDACC_VER__` is defined. -#if __CUDACC_VER__ >= 70000 -#define OTABSL_HAVE_INTRINSIC_INT128 1 -#endif // __CUDACC_VER__ >= 70000 -#endif // defined(__CUDACC__) -#endif // OTABSL_HAVE_INTRINSIC_INT128 - -// OTABSL_HAVE_EXCEPTIONS -// -// Checks whether the compiler both supports and enables exceptions. Many -// compilers support a "no exceptions" mode that disables exceptions. -// -// Generally, when OTABSL_HAVE_EXCEPTIONS is not defined: -// -// * Code using `throw` and `try` may not compile. -// * The `noexcept` specifier will still compile and behave as normal. -// * The `noexcept` operator may still return `false`. -// -// For further details, consult the compiler's documentation. -#ifdef OTABSL_HAVE_EXCEPTIONS -#error OTABSL_HAVE_EXCEPTIONS cannot be directly set. - -#elif defined(__clang__) - -#if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 6) -// Clang >= 3.6 -#if __has_feature(cxx_exceptions) -#define OTABSL_HAVE_EXCEPTIONS 1 -#endif // __has_feature(cxx_exceptions) -#else -// Clang < 3.6 -// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro -#if defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) -#define OTABSL_HAVE_EXCEPTIONS 1 -#endif // defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) -#endif // __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 6) - -// Handle remaining special cases and default to exceptions being supported. -#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \ - !(defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__cpp_exceptions)) && \ - !(defined(_MSC_VER) && !defined(_CPPUNWIND)) -#define OTABSL_HAVE_EXCEPTIONS 1 -#endif - -// ----------------------------------------------------------------------------- -// Platform Feature Checks -// ----------------------------------------------------------------------------- - -// Currently supported operating systems and associated preprocessor -// symbols: -// -// Linux and Linux-derived __linux__ -// Android __ANDROID__ (implies __linux__) -// Linux (non-Android) __linux__ && !__ANDROID__ -// Darwin (macOS and iOS) __APPLE__ -// Akaros (http://akaros.org) __ros__ -// Windows _WIN32 -// NaCL __native_client__ -// AsmJS __asmjs__ -// WebAssembly __wasm__ -// Fuchsia __Fuchsia__ -// -// Note that since Android defines both __ANDROID__ and __linux__, one -// may probe for either Linux or Android by simply testing for __linux__. - -// OTABSL_HAVE_MMAP -// -// Checks whether the platform has an mmap(2) implementation as defined in -// POSIX.1-2001. -#ifdef OTABSL_HAVE_MMAP -#error OTABSL_HAVE_MMAP cannot be directly set -#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ - defined(__ros__) || defined(__native_client__) || defined(__asmjs__) || \ - defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) || \ - defined(__ASYLO__) -#define OTABSL_HAVE_MMAP 1 -#endif - -// OTABSL_HAVE_PTHREAD_GETSCHEDPARAM -// -// Checks whether the platform implements the pthread_(get|set)schedparam(3) -// functions as defined in POSIX.1-2001. -#ifdef OTABSL_HAVE_PTHREAD_GETSCHEDPARAM -#error OTABSL_HAVE_PTHREAD_GETSCHEDPARAM cannot be directly set -#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ - defined(__ros__) -#define OTABSL_HAVE_PTHREAD_GETSCHEDPARAM 1 -#endif - -// OTABSL_HAVE_SCHED_YIELD -// -// Checks whether the platform implements sched_yield(2) as defined in -// POSIX.1-2001. -#ifdef OTABSL_HAVE_SCHED_YIELD -#error OTABSL_HAVE_SCHED_YIELD cannot be directly set -#elif defined(__linux__) || defined(__ros__) || defined(__native_client__) -#define OTABSL_HAVE_SCHED_YIELD 1 -#endif - -// OTABSL_HAVE_SEMAPHORE_H -// -// Checks whether the platform supports the header and sem_init(3) -// family of functions as standardized in POSIX.1-2001. -// -// Note: While Apple provides for both iOS and macOS, it is -// explicitly deprecated and will cause build failures if enabled for those -// platforms. We side-step the issue by not defining it here for Apple -// platforms. -#ifdef OTABSL_HAVE_SEMAPHORE_H -#error OTABSL_HAVE_SEMAPHORE_H cannot be directly set -#elif defined(__linux__) || defined(__ros__) -#define OTABSL_HAVE_SEMAPHORE_H 1 -#endif - -// OTABSL_HAVE_ALARM -// -// Checks whether the platform supports the header and alarm(2) -// function as standardized in POSIX.1-2001. -#ifdef OTABSL_HAVE_ALARM -#error OTABSL_HAVE_ALARM cannot be directly set -#elif defined(__GOOGLE_GRTE_VERSION__) -// feature tests for Google's GRTE -#define OTABSL_HAVE_ALARM 1 -#elif defined(__GLIBC__) -// feature test for glibc -#define OTABSL_HAVE_ALARM 1 -#elif defined(_MSC_VER) -// feature tests for Microsoft's library -#elif defined(__MINGW32__) -// mingw32 doesn't provide alarm(2): -// https://osdn.net/projects/mingw/scm/git/mingw-org-wsl/blobs/5.2-trunk/mingwrt/include/unistd.h -// mingw-w64 provides a no-op implementation: -// https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-crt/misc/alarm.c -#elif defined(__EMSCRIPTEN__) -// emscripten doesn't support signals -#elif defined(__Fuchsia__) -// Signals don't exist on fuchsia. -#elif defined(__native_client__) -#else -// other standard libraries -#define OTABSL_HAVE_ALARM 1 -#endif - -// OTABSL_IS_LITTLE_ENDIAN -// OTABSL_IS_BIG_ENDIAN -// -// Checks the endianness of the platform. -// -// Notes: uses the built in endian macros provided by GCC (since 4.6) and -// Clang (since 3.2); see -// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html. -// Otherwise, if _WIN32, assume little endian. Otherwise, bail with an error. -#if defined(OTABSL_IS_BIG_ENDIAN) -#error "OTABSL_IS_BIG_ENDIAN cannot be directly set." -#endif -#if defined(OTABSL_IS_LITTLE_ENDIAN) -#error "OTABSL_IS_LITTLE_ENDIAN cannot be directly set." -#endif - -#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ - __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define OTABSL_IS_LITTLE_ENDIAN 1 -#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ - __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -#define OTABSL_IS_BIG_ENDIAN 1 -#elif defined(_WIN32) -#define OTABSL_IS_LITTLE_ENDIAN 1 -#else -#error "absl endian detection needs to be set up for your compiler" -#endif - -// macOS 10.13 and iOS 10.11 don't let you use , , or -// even though the headers exist and are publicly noted to work. See -// https://github.com/abseil/abseil-cpp/issues/207 and -// https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes -// libc++ spells out the availability requirements in the file -// llvm-project/libcxx/include/__config via the #define -// _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS. -#if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \ - ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101400) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 120000) || \ - (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 120000) || \ - (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 50000)) -#define OTABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 1 -#else -#define OTABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 0 -#endif - -// OTABSL_HAVE_STD_ANY -// -// Checks whether C++17 std::any is available by checking whether exists. -#ifdef OTABSL_HAVE_STD_ANY -#error "OTABSL_HAVE_STD_ANY cannot be directly set." -#endif - -#ifdef __has_include -#if __has_include() && __cplusplus >= 201703L && \ - !OTABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE -#define OTABSL_HAVE_STD_ANY 1 -#endif -#endif - -// OTABSL_HAVE_STD_OPTIONAL -// -// Checks whether C++17 std::optional is available. -#ifdef OTABSL_HAVE_STD_OPTIONAL -#error "OTABSL_HAVE_STD_OPTIONAL cannot be directly set." -#endif - -#ifdef __has_include -#if __has_include() && __cplusplus >= 201703L && \ - !OTABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE -#define OTABSL_HAVE_STD_OPTIONAL 1 -#endif -#endif - -// OTABSL_HAVE_STD_VARIANT -// -// Checks whether C++17 std::variant is available. -#ifdef OTABSL_HAVE_STD_VARIANT -#error "OTABSL_HAVE_STD_VARIANT cannot be directly set." -#endif - -#ifdef __has_include -#if __has_include() && __cplusplus >= 201703L && \ - !OTABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE -#define OTABSL_HAVE_STD_VARIANT 1 -#endif -#endif - -// OTABSL_HAVE_STD_STRING_VIEW -// -// Checks whether C++17 std::string_view is available. -#ifdef OTABSL_HAVE_STD_STRING_VIEW -#error "OTABSL_HAVE_STD_STRING_VIEW cannot be directly set." -#endif - -#ifdef __has_include -#if __has_include() && __cplusplus >= 201703L -#define OTABSL_HAVE_STD_STRING_VIEW 1 -#endif -#endif - -// For MSVC, `__has_include` is supported in VS 2017 15.3, which is later than -// the support for , , , . So we use -// _MSC_VER to check whether we have VS 2017 RTM (when , , -// , is implemented) or higher. Also, `__cplusplus` is -// not correctly set by MSVC, so we use `_MSVC_LANG` to check the language -// version. -// TODO(zhangxy): fix tests before enabling aliasing for `std::any`. -#if defined(_MSC_VER) && _MSC_VER >= 1910 && \ - ((defined(_MSVC_LANG) && _MSVC_LANG > 201402) || __cplusplus > 201402) -// #define OTABSL_HAVE_STD_ANY 1 -#define OTABSL_HAVE_STD_OPTIONAL 1 -#define OTABSL_HAVE_STD_VARIANT 1 -#define OTABSL_HAVE_STD_STRING_VIEW 1 -#endif - -// OTABSL_USES_STD_ANY -// -// Indicates whether absl::OTABSL_OPTION_NAMESPACE_NAME::any is an alias for std::any. -#if !defined(OTABSL_OPTION_USE_STD_ANY) -#error options.h is misconfigured. -#elif OTABSL_OPTION_USE_STD_ANY == 0 || \ - (OTABSL_OPTION_USE_STD_ANY == 2 && !defined(OTABSL_HAVE_STD_ANY)) -#undef OTABSL_USES_STD_ANY -#elif OTABSL_OPTION_USE_STD_ANY == 1 || \ - (OTABSL_OPTION_USE_STD_ANY == 2 && defined(OTABSL_HAVE_STD_ANY)) -#define OTABSL_USES_STD_ANY 1 -#else -#error options.h is misconfigured. -#endif - -// OTABSL_USES_STD_OPTIONAL -// -// Indicates whether absl::OTABSL_OPTION_NAMESPACE_NAME::optional is an alias for std::optional. -#if !defined(OTABSL_OPTION_USE_STD_OPTIONAL) -#error options.h is misconfigured. -#elif OTABSL_OPTION_USE_STD_OPTIONAL == 0 || \ - (OTABSL_OPTION_USE_STD_OPTIONAL == 2 && !defined(OTABSL_HAVE_STD_OPTIONAL)) -#undef OTABSL_USES_STD_OPTIONAL -#elif OTABSL_OPTION_USE_STD_OPTIONAL == 1 || \ - (OTABSL_OPTION_USE_STD_OPTIONAL == 2 && defined(OTABSL_HAVE_STD_OPTIONAL)) -#define OTABSL_USES_STD_OPTIONAL 1 -#else -#error options.h is misconfigured. -#endif - -// OTABSL_USES_STD_VARIANT -// -// Indicates whether absl::OTABSL_OPTION_NAMESPACE_NAME::variant is an alias for std::variant. -#if !defined(OTABSL_OPTION_USE_STD_VARIANT) -#error options.h is misconfigured. -#elif OTABSL_OPTION_USE_STD_VARIANT == 0 || \ - (OTABSL_OPTION_USE_STD_VARIANT == 2 && !defined(OTABSL_HAVE_STD_VARIANT)) -#undef OTABSL_USES_STD_VARIANT -#elif OTABSL_OPTION_USE_STD_VARIANT == 1 || \ - (OTABSL_OPTION_USE_STD_VARIANT == 2 && defined(OTABSL_HAVE_STD_VARIANT)) -#define OTABSL_USES_STD_VARIANT 1 -#else -#error options.h is misconfigured. -#endif - -// OTABSL_USES_STD_STRING_VIEW -// -// Indicates whether absl::OTABSL_OPTION_NAMESPACE_NAME::string_view is an alias for std::string_view. -#if !defined(OTABSL_OPTION_USE_STD_STRING_VIEW) -#error options.h is misconfigured. -#elif OTABSL_OPTION_USE_STD_STRING_VIEW == 0 || \ - (OTABSL_OPTION_USE_STD_STRING_VIEW == 2 && \ - !defined(OTABSL_HAVE_STD_STRING_VIEW)) -#undef OTABSL_USES_STD_STRING_VIEW -#elif OTABSL_OPTION_USE_STD_STRING_VIEW == 1 || \ - (OTABSL_OPTION_USE_STD_STRING_VIEW == 2 && \ - defined(OTABSL_HAVE_STD_STRING_VIEW)) -#define OTABSL_USES_STD_STRING_VIEW 1 -#else -#error options.h is misconfigured. -#endif - -// In debug mode, MSVC 2017's std::variant throws a EXCEPTION_ACCESS_VIOLATION -// SEH exception from emplace for variant when constructing the -// struct can throw. This defeats some of variant_test and -// variant_exception_safety_test. -#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_DEBUG) -#define OTABSL_INTERNAL_MSVC_2017_DBG_MODE -#endif - -// OTABSL_INTERNAL_MANGLED_NS -// OTABSL_INTERNAL_MANGLED_BACKREFERENCE -// -// Internal macros for building up mangled names in our internal fork of CCTZ. -// This implementation detail is only needed and provided for the MSVC build. -// -// These macros both expand to string literals. OTABSL_INTERNAL_MANGLED_NS is -// the mangled spelling of the `absl` namespace, and -// OTABSL_INTERNAL_MANGLED_BACKREFERENCE is a back-reference integer representing -// the proper count to skip past the CCTZ fork namespace names. (This number -// is one larger when there is an inline namespace name to skip.) -#if defined(_MSC_VER) -#define OTABSL_INTERNAL_MANGLED_NS \ - OTABSL_INTERNAL_TOKEN_STR(OTABSL_OPTION_NAMESPACE_NAME) "@absl" -#define OTABSL_INTERNAL_MANGLED_BACKREFERENCE "6" -#endif - -#undef OTABSL_INTERNAL_HAS_KEYWORD - -// OTABSL_DLL -// -// When building Abseil as a DLL, this macro expands to `__declspec(dllexport)` -// so we can annotate symbols appropriately as being exported. When used in -// headers consuming a DLL, this macro expands to `__declspec(dllimport)` so -// that consumers know the symbol is defined inside the DLL. In all other cases, -// the macro expands to nothing. -#if defined(_MSC_VER) -#if defined(OTABSL_BUILD_DLL) -#define OTABSL_DLL __declspec(dllexport) -#elif 1 -#define OTABSL_DLL __declspec(dllimport) -#else -#define OTABSL_DLL -#endif -#else -#define OTABSL_DLL -#endif // defined(_MSC_VER) - -#endif // OTABSL_BASE_CONFIG_H_ diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/internal/identity.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/internal/identity.h deleted file mode 100644 index 4afba3179..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/internal/identity.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#ifndef OTABSL_BASE_INTERNAL_IDENTITY_H_ -#define OTABSL_BASE_INTERNAL_IDENTITY_H_ - -#include "../config.h" - -namespace absl { -OTABSL_NAMESPACE_BEGIN -namespace internal { - -template -struct identity { - typedef T type; -}; - -template -using identity_t = typename identity::type; - -} // namespace internal -OTABSL_NAMESPACE_END -} // namespace absl - -#endif // OTABSL_BASE_INTERNAL_IDENTITY_H_ diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/internal/inline_variable.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/internal/inline_variable.h deleted file mode 100644 index dd66e9f22..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/internal/inline_variable.h +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef OTABSL_BASE_INTERNAL_INLINE_VARIABLE_EMULATION_H_ -#define OTABSL_BASE_INTERNAL_INLINE_VARIABLE_EMULATION_H_ - -#include - -#include "identity.h" - -// File: -// This file define a macro that allows the creation of or emulation of C++17 -// inline variables based on whether or not the feature is supported. - -//////////////////////////////////////////////////////////////////////////////// -// Macro: OTABSL_INTERNAL_INLINE_CONSTEXPR(type, name, init) -// -// Description: -// Expands to the equivalent of an inline constexpr instance of the specified -// `type` and `name`, initialized to the value `init`. If the compiler being -// used is detected as supporting actual inline variables as a language -// feature, then the macro expands to an actual inline variable definition. -// -// Requires: -// `type` is a type that is usable in an extern variable declaration. -// -// Requires: `name` is a valid identifier -// -// Requires: -// `init` is an expression that can be used in the following definition: -// constexpr type name = init; -// -// Usage: -// -// // Equivalent to: `inline constexpr size_t variant_npos = -1;` -// OTABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, -1); -// -// Differences in implementation: -// For a direct, language-level inline variable, decltype(name) will be the -// type that was specified along with const qualification, whereas for -// emulated inline variables, decltype(name) may be different (in practice -// it will likely be a reference type). -//////////////////////////////////////////////////////////////////////////////// - -#ifdef __cpp_inline_variables - -// Clang's -Wmissing-variable-declarations option erroneously warned that -// inline constexpr objects need to be pre-declared. This has now been fixed, -// but we will need to support this workaround for people building with older -// versions of clang. -// -// Bug: https://bugs.llvm.org/show_bug.cgi?id=35862 -// -// Note: -// identity_t is used here so that the const and name are in the -// appropriate place for pointer types, reference types, function pointer -// types, etc.. -#if defined(__clang__) -#define OTABSL_INTERNAL_EXTERN_DECL(type, name) \ - extern const ::absl::OTABSL_OPTION_NAMESPACE_NAME::internal::identity_t name; -#else // Otherwise, just define the macro to do nothing. -#define OTABSL_INTERNAL_EXTERN_DECL(type, name) -#endif // defined(__clang__) - -// See above comment at top of file for details. -#define OTABSL_INTERNAL_INLINE_CONSTEXPR(type, name, init) \ - OTABSL_INTERNAL_EXTERN_DECL(type, name) \ - inline constexpr ::absl::OTABSL_OPTION_NAMESPACE_NAME::internal::identity_t name = init - -#else - -// See above comment at top of file for details. -// -// Note: -// identity_t is used here so that the const and name are in the -// appropriate place for pointer types, reference types, function pointer -// types, etc.. -#define OTABSL_INTERNAL_INLINE_CONSTEXPR(var_type, name, init) \ - template \ - struct AbslInternalInlineVariableHolder##name { \ - static constexpr ::absl::OTABSL_OPTION_NAMESPACE_NAME::internal::identity_t kInstance = init; \ - }; \ - \ - template \ - constexpr ::absl::OTABSL_OPTION_NAMESPACE_NAME::internal::identity_t \ - AbslInternalInlineVariableHolder##name::kInstance; \ - \ - static constexpr const ::absl::OTABSL_OPTION_NAMESPACE_NAME::internal::identity_t& \ - name = /* NOLINT */ \ - AbslInternalInlineVariableHolder##name<>::kInstance; \ - static_assert(sizeof(void (*)(decltype(name))) != 0, \ - "Silence unused variable warnings.") - -#endif // __cpp_inline_variables - -#endif // OTABSL_BASE_INTERNAL_INLINE_VARIABLE_EMULATION_H_ diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/internal/invoke.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/internal/invoke.h deleted file mode 100644 index c37f43cfc..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/internal/invoke.h +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// absl::OTABSL_OPTION_NAMESPACE_NAME::base_internal::Invoke(f, args...) is an implementation of -// INVOKE(f, args...) from section [func.require] of the C++ standard. -// -// [func.require] -// Define INVOKE (f, t1, t2, ..., tN) as follows: -// 1. (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T -// and t1 is an object of type T or a reference to an object of type T or a -// reference to an object of a type derived from T; -// 2. ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a -// class T and t1 is not one of the types described in the previous item; -// 3. t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is -// an object of type T or a reference to an object of type T or a reference -// to an object of a type derived from T; -// 4. (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 -// is not one of the types described in the previous item; -// 5. f(t1, t2, ..., tN) in all other cases. -// -// The implementation is SFINAE-friendly: substitution failure within Invoke() -// isn't an error. - -#ifndef OTABSL_BASE_INTERNAL_INVOKE_H_ -#define OTABSL_BASE_INTERNAL_INVOKE_H_ - -#include -#include -#include - -#include "../../meta/type_traits.h" - -// The following code is internal implementation detail. See the comment at the -// top of this file for the API documentation. - -namespace absl { -OTABSL_NAMESPACE_BEGIN -namespace base_internal { - -// The five classes below each implement one of the clauses from the definition -// of INVOKE. The inner class template Accept checks whether the -// clause is applicable; static function template Invoke(f, args...) does the -// invocation. -// -// By separating the clause selection logic from invocation we make sure that -// Invoke() does exactly what the standard says. - -template -struct StrippedAccept { - template - struct Accept : Derived::template AcceptImpl::type>::type...> {}; -}; - -// (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T -// and t1 is an object of type T or a reference to an object of type T or a -// reference to an object of a type derived from T. -struct MemFunAndRef : StrippedAccept { - template - struct AcceptImpl : std::false_type {}; - - template - struct AcceptImpl - : std::integral_constant::value && - absl::OTABSL_OPTION_NAMESPACE_NAME::is_function::value> { - }; - - template - static decltype((std::declval().* - std::declval())(std::declval()...)) - Invoke(MemFun&& mem_fun, Obj&& obj, Args&&... args) { - return (std::forward(obj).* - std::forward(mem_fun))(std::forward(args)...); - } -}; - -// ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a -// class T and t1 is not one of the types described in the previous item. -struct MemFunAndPtr : StrippedAccept { - template - struct AcceptImpl : std::false_type {}; - - template - struct AcceptImpl - : std::integral_constant::value && - absl::OTABSL_OPTION_NAMESPACE_NAME::is_function::value> { - }; - - template - static decltype(((*std::declval()).* - std::declval())(std::declval()...)) - Invoke(MemFun&& mem_fun, Ptr&& ptr, Args&&... args) { - return ((*std::forward(ptr)).* - std::forward(mem_fun))(std::forward(args)...); - } -}; - -// t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is -// an object of type T or a reference to an object of type T or a reference -// to an object of a type derived from T. -struct DataMemAndRef : StrippedAccept { - template - struct AcceptImpl : std::false_type {}; - - template - struct AcceptImpl - : std::integral_constant::value && - !absl::OTABSL_OPTION_NAMESPACE_NAME::is_function::value> {}; - - template - static decltype(std::declval().*std::declval()) Invoke( - DataMem&& data_mem, Ref&& ref) { - return std::forward(ref).*std::forward(data_mem); - } -}; - -// (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 -// is not one of the types described in the previous item. -struct DataMemAndPtr : StrippedAccept { - template - struct AcceptImpl : std::false_type {}; - - template - struct AcceptImpl - : std::integral_constant::value && - !absl::OTABSL_OPTION_NAMESPACE_NAME::is_function::value> {}; - - template - static decltype((*std::declval()).*std::declval()) Invoke( - DataMem&& data_mem, Ptr&& ptr) { - return (*std::forward(ptr)).*std::forward(data_mem); - } -}; - -// f(t1, t2, ..., tN) in all other cases. -struct Callable { - // Callable doesn't have Accept because it's the last clause that gets picked - // when none of the previous clauses are applicable. - template - static decltype(std::declval()(std::declval()...)) Invoke( - F&& f, Args&&... args) { - return std::forward(f)(std::forward(args)...); - } -}; - -// Resolves to the first matching clause. -template -struct Invoker { - typedef typename std::conditional< - MemFunAndRef::Accept::value, MemFunAndRef, - typename std::conditional< - MemFunAndPtr::Accept::value, MemFunAndPtr, - typename std::conditional< - DataMemAndRef::Accept::value, DataMemAndRef, - typename std::conditional::value, - DataMemAndPtr, Callable>::type>::type>:: - type>::type type; -}; - -// The result type of Invoke. -template -using InvokeT = decltype(Invoker::type::Invoke( - std::declval(), std::declval()...)); - -// Invoke(f, args...) is an implementation of INVOKE(f, args...) from section -// [func.require] of the C++ standard. -template -InvokeT Invoke(F&& f, Args&&... args) { - return Invoker::type::Invoke(std::forward(f), - std::forward(args)...); -} - -} // namespace base_internal -OTABSL_NAMESPACE_END -} // namespace absl - -#endif // OTABSL_BASE_INTERNAL_INVOKE_H_ diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/macros.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/macros.h deleted file mode 100644 index 707c375ed..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/macros.h +++ /dev/null @@ -1,220 +0,0 @@ -// -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ----------------------------------------------------------------------------- -// File: macros.h -// ----------------------------------------------------------------------------- -// -// This header file defines the set of language macros used within Abseil code. -// For the set of macros used to determine supported compilers and platforms, -// see absl/base/config.h instead. -// -// This code is compiled directly on many platforms, including client -// platforms like Windows, Mac, and embedded systems. Before making -// any changes here, make sure that you're not breaking any platforms. - -#ifndef OTABSL_BASE_MACROS_H_ -#define OTABSL_BASE_MACROS_H_ - -#include -#include - -#include "attributes.h" -#include "optimization.h" -#include "port.h" - -// OTABSL_ARRAYSIZE() -// -// Returns the number of elements in an array as a compile-time constant, which -// can be used in defining new arrays. If you use this macro on a pointer by -// mistake, you will get a compile-time error. -#define OTABSL_ARRAYSIZE(array) \ - (sizeof(::absl::OTABSL_OPTION_NAMESPACE_NAME::macros_internal::ArraySizeHelper(array))) - -namespace absl { -OTABSL_NAMESPACE_BEGIN -namespace macros_internal { -// Note: this internal template function declaration is used by OTABSL_ARRAYSIZE. -// The function doesn't need a definition, as we only use its type. -template -auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N]; -} // namespace macros_internal -OTABSL_NAMESPACE_END -} // namespace absl - -// kLinkerInitialized -// -// An enum used only as a constructor argument to indicate that a variable has -// static storage duration, and that the constructor should do nothing to its -// state. Use of this macro indicates to the reader that it is legal to -// declare a static instance of the class, provided the constructor is given -// the absl::OTABSL_OPTION_NAMESPACE_NAME::base_internal::kLinkerInitialized argument. -// -// Normally, it is unsafe to declare a static variable that has a constructor or -// a destructor because invocation order is undefined. However, if the type can -// be zero-initialized (which the loader does for static variables) into a valid -// state and the type's destructor does not affect storage, then a constructor -// for static initialization can be declared. -// -// Example: -// // Declaration -// explicit MyClass(absl::OTABSL_OPTION_NAMESPACE_NAME::base_internal:LinkerInitialized x) {} -// -// // Invocation -// static MyClass my_global(absl::OTABSL_OPTION_NAMESPACE_NAME::base_internal::kLinkerInitialized); -namespace absl { -OTABSL_NAMESPACE_BEGIN -namespace base_internal { -enum LinkerInitialized { - kLinkerInitialized = 0, -}; -} // namespace base_internal -OTABSL_NAMESPACE_END -} // namespace absl - -// OTABSL_FALLTHROUGH_INTENDED -// -// Annotates implicit fall-through between switch labels, allowing a case to -// indicate intentional fallthrough and turn off warnings about any lack of a -// `break` statement. The OTABSL_FALLTHROUGH_INTENDED macro should be followed by -// a semicolon and can be used in most places where `break` can, provided that -// no statements exist between it and the next switch label. -// -// Example: -// -// switch (x) { -// case 40: -// case 41: -// if (truth_is_out_there) { -// ++x; -// OTABSL_FALLTHROUGH_INTENDED; // Use instead of/along with annotations -// // in comments -// } else { -// return x; -// } -// case 42: -// ... -// -// Notes: when compiled with clang in C++11 mode, the OTABSL_FALLTHROUGH_INTENDED -// macro is expanded to the [[clang::fallthrough]] attribute, which is analysed -// when performing switch labels fall-through diagnostic -// (`-Wimplicit-fallthrough`). See clang documentation on language extensions -// for details: -// https://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough -// -// When used with unsupported compilers, the OTABSL_FALLTHROUGH_INTENDED macro -// has no effect on diagnostics. In any case this macro has no effect on runtime -// behavior and performance of code. -#ifdef OTABSL_FALLTHROUGH_INTENDED -#error "OTABSL_FALLTHROUGH_INTENDED should not be defined." -#endif - -// TODO(zhangxy): Use c++17 standard [[fallthrough]] macro, when supported. -#if defined(__clang__) && defined(__has_warning) -#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") -#define OTABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]] -#endif -#elif defined(__GNUC__) && __GNUC__ >= 7 -#define OTABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]] -#endif - -#ifndef OTABSL_FALLTHROUGH_INTENDED -#define OTABSL_FALLTHROUGH_INTENDED \ - do { \ - } while (0) -#endif - -// OTABSL_DEPRECATED() -// -// Marks a deprecated class, struct, enum, function, method and variable -// declarations. The macro argument is used as a custom diagnostic message (e.g. -// suggestion of a better alternative). -// -// Examples: -// -// class OTABSL_DEPRECATED("Use Bar instead") Foo {...}; -// -// OTABSL_DEPRECATED("Use Baz() instead") void Bar() {...} -// -// template -// OTABSL_DEPRECATED("Use DoThat() instead") -// void DoThis(); -// -// Every usage of a deprecated entity will trigger a warning when compiled with -// clang's `-Wdeprecated-declarations` option. This option is turned off by -// default, but the warnings will be reported by clang-tidy. -#if defined(__clang__) && __cplusplus >= 201103L -#define OTABSL_DEPRECATED(message) __attribute__((deprecated(message))) -#endif - -#ifndef OTABSL_DEPRECATED -#define OTABSL_DEPRECATED(message) -#endif - -// OTABSL_BAD_CALL_IF() -// -// Used on a function overload to trap bad calls: any call that matches the -// overload will cause a compile-time error. This macro uses a clang-specific -// "enable_if" attribute, as described at -// https://clang.llvm.org/docs/AttributeReference.html#enable-if -// -// Overloads which use this macro should be bracketed by -// `#ifdef OTABSL_BAD_CALL_IF`. -// -// Example: -// -// int isdigit(int c); -// #ifdef OTABSL_BAD_CALL_IF -// int isdigit(int c) -// OTABSL_BAD_CALL_IF(c <= -1 || c > 255, -// "'c' must have the value of an unsigned char or EOF"); -// #endif // OTABSL_BAD_CALL_IF -#if OTABSL_HAVE_ATTRIBUTE(enable_if) -#define OTABSL_BAD_CALL_IF(expr, msg) \ - __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg))) -#endif - -// OTABSL_ASSERT() -// -// In C++11, `assert` can't be used portably within constexpr functions. -// OTABSL_ASSERT functions as a runtime assert but works in C++11 constexpr -// functions. Example: -// -// constexpr double Divide(double a, double b) { -// return OTABSL_ASSERT(b != 0), a / b; -// } -// -// This macro is inspired by -// https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/ -#if defined(NDEBUG) -#define OTABSL_ASSERT(expr) \ - (false ? static_cast(expr) : static_cast(0)) -#else -#define OTABSL_ASSERT(expr) \ - (OTABSL_PREDICT_TRUE((expr)) ? static_cast(0) \ - : [] { assert(false && #expr); }()) // NOLINT -#endif - -#ifdef OTABSL_HAVE_EXCEPTIONS -#define OTABSL_INTERNAL_TRY try -#define OTABSL_INTERNAL_CATCH_ANY catch (...) -#define OTABSL_INTERNAL_RETHROW do { throw; } while (false) -#else // OTABSL_HAVE_EXCEPTIONS -#define OTABSL_INTERNAL_TRY if (true) -#define OTABSL_INTERNAL_CATCH_ANY else if (false) -#define OTABSL_INTERNAL_RETHROW do {} while (false) -#endif // OTABSL_HAVE_EXCEPTIONS - -#endif // OTABSL_BASE_MACROS_H_ diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/optimization.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/optimization.h deleted file mode 100644 index 69713654a..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/optimization.h +++ /dev/null @@ -1,181 +0,0 @@ -// -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ----------------------------------------------------------------------------- -// File: optimization.h -// ----------------------------------------------------------------------------- -// -// This header file defines portable macros for performance optimization. - -#ifndef OTABSL_BASE_OPTIMIZATION_H_ -#define OTABSL_BASE_OPTIMIZATION_H_ - -#include "config.h" - -// OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION -// -// Instructs the compiler to avoid optimizing tail-call recursion. Use of this -// macro is useful when you wish to preserve the existing function order within -// a stack trace for logging, debugging, or profiling purposes. -// -// Example: -// -// int f() { -// int result = g(); -// OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); -// return result; -// } -#if defined(__pnacl__) -#define OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } -#elif defined(__clang__) -// Clang will not tail call given inline volatile assembly. -#define OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") -#elif defined(__GNUC__) -// GCC will not tail call given inline volatile assembly. -#define OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") -#elif defined(_MSC_VER) -#include -// The __nop() intrinsic blocks the optimisation. -#define OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __nop() -#else -#define OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } -#endif - -// OTABSL_CACHELINE_SIZE -// -// Explicitly defines the size of the L1 cache for purposes of alignment. -// Setting the cacheline size allows you to specify that certain objects be -// aligned on a cacheline boundary with `OTABSL_CACHELINE_ALIGNED` declarations. -// (See below.) -// -// NOTE: this macro should be replaced with the following C++17 features, when -// those are generally available: -// -// * `std::hardware_constructive_interference_size` -// * `std::hardware_destructive_interference_size` -// -// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html -// for more information. -#if defined(__GNUC__) -// Cache line alignment -#if defined(__i386__) || defined(__x86_64__) -#define OTABSL_CACHELINE_SIZE 64 -#elif defined(__powerpc64__) -#define OTABSL_CACHELINE_SIZE 128 -#elif defined(__aarch64__) -// We would need to read special register ctr_el0 to find out L1 dcache size. -// This value is a good estimate based on a real aarch64 machine. -#define OTABSL_CACHELINE_SIZE 64 -#elif defined(__arm__) -// Cache line sizes for ARM: These values are not strictly correct since -// cache line sizes depend on implementations, not architectures. There -// are even implementations with cache line sizes configurable at boot -// time. -#if defined(__ARM_ARCH_5T__) -#define OTABSL_CACHELINE_SIZE 32 -#elif defined(__ARM_ARCH_7A__) -#define OTABSL_CACHELINE_SIZE 64 -#endif -#endif - -#ifndef OTABSL_CACHELINE_SIZE -// A reasonable default guess. Note that overestimates tend to waste more -// space, while underestimates tend to waste more time. -#define OTABSL_CACHELINE_SIZE 64 -#endif - -// OTABSL_CACHELINE_ALIGNED -// -// Indicates that the declared object be cache aligned using -// `OTABSL_CACHELINE_SIZE` (see above). Cacheline aligning objects allows you to -// load a set of related objects in the L1 cache for performance improvements. -// Cacheline aligning objects properly allows constructive memory sharing and -// prevents destructive (or "false") memory sharing. -// -// NOTE: this macro should be replaced with usage of `alignas()` using -// `std::hardware_constructive_interference_size` and/or -// `std::hardware_destructive_interference_size` when available within C++17. -// -// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html -// for more information. -// -// On some compilers, `OTABSL_CACHELINE_ALIGNED` expands to an `__attribute__` -// or `__declspec` attribute. For compilers where this is not known to work, -// the macro expands to nothing. -// -// No further guarantees are made here. The result of applying the macro -// to variables and types is always implementation-defined. -// -// WARNING: It is easy to use this attribute incorrectly, even to the point -// of causing bugs that are difficult to diagnose, crash, etc. It does not -// of itself guarantee that objects are aligned to a cache line. -// -// NOTE: Some compilers are picky about the locations of annotations such as -// this attribute, so prefer to put it at the beginning of your declaration. -// For example, -// -// OTABSL_CACHELINE_ALIGNED static Foo* foo = ... -// -// class OTABSL_CACHELINE_ALIGNED Bar { ... -// -// Recommendations: -// -// 1) Consult compiler documentation; this comment is not kept in sync as -// toolchains evolve. -// 2) Verify your use has the intended effect. This often requires inspecting -// the generated machine code. -// 3) Prefer applying this attribute to individual variables. Avoid -// applying it to types. This tends to localize the effect. -#define OTABSL_CACHELINE_ALIGNED __attribute__((aligned(OTABSL_CACHELINE_SIZE))) -#elif defined(_MSC_VER) -#define OTABSL_CACHELINE_SIZE 64 -#define OTABSL_CACHELINE_ALIGNED __declspec(align(OTABSL_CACHELINE_SIZE)) -#else -#define OTABSL_CACHELINE_SIZE 64 -#define OTABSL_CACHELINE_ALIGNED -#endif - -// OTABSL_PREDICT_TRUE, OTABSL_PREDICT_FALSE -// -// Enables the compiler to prioritize compilation using static analysis for -// likely paths within a boolean branch. -// -// Example: -// -// if (OTABSL_PREDICT_TRUE(expression)) { -// return result; // Faster if more likely -// } else { -// return 0; -// } -// -// Compilers can use the information that a certain branch is not likely to be -// taken (for instance, a CHECK failure) to optimize for the common case in -// the absence of better information (ie. compiling gcc with `-fprofile-arcs`). -// -// Recommendation: Modern CPUs dynamically predict branch execution paths, -// typically with accuracy greater than 97%. As a result, annotating every -// branch in a codebase is likely counterproductive; however, annotating -// specific branches that are both hot and consistently mispredicted is likely -// to yield performance improvements. -#if OTABSL_HAVE_BUILTIN(__builtin_expect) || \ - (defined(__GNUC__) && !defined(__clang__)) -#define OTABSL_PREDICT_FALSE(x) (__builtin_expect(x, 0)) -#define OTABSL_PREDICT_TRUE(x) (__builtin_expect(false || (x), true)) -#else -#define OTABSL_PREDICT_FALSE(x) (x) -#define OTABSL_PREDICT_TRUE(x) (x) -#endif - -#endif // OTABSL_BASE_OPTIMIZATION_H_ diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/options.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/options.h deleted file mode 100644 index c4b00a3d3..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/options.h +++ /dev/null @@ -1,216 +0,0 @@ -#ifndef OTABSL_BASE_OPTIONS_H_ -#define OTABSL_BASE_OPTIONS_H_ - -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ----------------------------------------------------------------------------- -// File: options.h -// ----------------------------------------------------------------------------- -// -// This file contains Abseil configuration options for setting specific -// implementations instead of letting Abseil determine which implementation to -// use at compile-time. Setting these options may be useful for package or build -// managers who wish to guarantee ABI stability within binary builds (which are -// otherwise difficult to enforce). -// -// *** IMPORTANT NOTICE FOR PACKAGE MANAGERS: It is important that -// maintainers of package managers who wish to package Abseil read and -// understand this file! *** -// -// Abseil contains a number of possible configuration endpoints, based on -// parameters such as the detected platform, language version, or command-line -// flags used to invoke the underlying binary. As is the case with all -// libraries, binaries which contain Abseil code must ensure that separate -// packages use the same compiled copy of Abseil to avoid a diamond dependency -// problem, which can occur if two packages built with different Abseil -// configuration settings are linked together. Diamond dependency problems in -// C++ may manifest as violations to the One Definition Rule (ODR) (resulting in -// linker errors), or undefined behavior (resulting in crashes). -// -// Diamond dependency problems can be avoided if all packages utilize the same -// exact version of Abseil. Building from source code with the same compilation -// parameters is the easiest way to avoid such dependency problems. However, for -// package managers who cannot control such compilation parameters, we are -// providing the file to allow you to inject ABI (Application Binary Interface) -// stability across builds. Settings options in this file will neither change -// API nor ABI, providing a stable copy of Abseil between packages. -// -// Care must be taken to keep options within these configurations isolated -// from any other dynamic settings, such as command-line flags which could alter -// these options. This file is provided specifically to help build and package -// managers provide a stable copy of Abseil within their libraries and binaries; -// other developers should not have need to alter the contents of this file. -// -// ----------------------------------------------------------------------------- -// Usage -// ----------------------------------------------------------------------------- -// -// For any particular package release, set the appropriate definitions within -// this file to whatever value makes the most sense for your package(s). Note -// that, by default, most of these options, at the moment, affect the -// implementation of types; future options may affect other implementation -// details. -// -// NOTE: the defaults within this file all assume that Abseil can select the -// proper Abseil implementation at compile-time, which will not be sufficient -// to guarantee ABI stability to package managers. - -// Include a standard library header to allow configuration based on the -// standard library in use. -// Using C++20 feature-test macros when possible, otherwise fall back to -// ciso646/iso646.h.There are warnings when including ciso646 in C++17 mode -#ifdef __has_include -# if __has_include() -# include -# endif -#elif defined(_MSC_VER) && \ - ((defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)) -# if _MSC_VER >= 1922 -# include -# endif -#else -# if defined(__GNUC__) && !defined(__clang__) && !defined(__apple_build_version__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wcpp" -# elif defined(__clang__) || defined(__apple_build_version__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wcpp" -# endif -# include -# if defined(__GNUC__) && !defined(__clang__) && !defined(__apple_build_version__) -# pragma GCC diagnostic pop -# elif defined(__clang__) || defined(__apple_build_version__) -# pragma clang diagnostic pop -# endif -#endif - -// ----------------------------------------------------------------------------- -// Type Compatibility Options -// ----------------------------------------------------------------------------- -// -// OTABSL_OPTION_USE_STD_ANY -// -// This option controls whether absl::OTABSL_OPTION_NAMESPACE_NAME::any is implemented as an alias to -// std::any, or as an independent implementation. -// -// A value of 0 means to use Abseil's implementation. This requires only C++11 -// support, and is expected to work on every toolchain we support. -// -// A value of 1 means to use an alias to std::any. This requires that all code -// using Abseil is built in C++17 mode or later. -// -// A value of 2 means to detect the C++ version being used to compile Abseil, -// and use an alias only if a working std::any is available. This option is -// useful when you are building your entire program, including all of its -// dependencies, from source. It should not be used otherwise -- for example, -// if you are distributing Abseil in a binary package manager -- since in -// mode 2, absl::OTABSL_OPTION_NAMESPACE_NAME::any will name a different type, with a different mangled name -// and binary layout, depending on the compiler flags passed by the end user. -// For more info, see https://abseil.io/about/design/dropin-types. -// -// User code should not inspect this macro. To check in the preprocessor if -// absl::OTABSL_OPTION_NAMESPACE_NAME::any is a typedef of std::any, use the feature macro OTABSL_USES_STD_ANY. - -#define OTABSL_OPTION_USE_STD_ANY 0 - - -// OTABSL_OPTION_USE_STD_OPTIONAL -// -// This option controls whether absl::OTABSL_OPTION_NAMESPACE_NAME::optional is implemented as an alias to -// std::optional, or as an independent implementation. -// -// A value of 0 means to use Abseil's implementation. This requires only C++11 -// support, and is expected to work on every toolchain we support. -// -// A value of 1 means to use an alias to std::optional. This requires that all -// code using Abseil is built in C++17 mode or later. -// -// A value of 2 means to detect the C++ version being used to compile Abseil, -// and use an alias only if a working std::optional is available. This option -// is useful when you are building your program from source. It should not be -// used otherwise -- for example, if you are distributing Abseil in a binary -// package manager -- since in mode 2, absl::OTABSL_OPTION_NAMESPACE_NAME::optional will name a different -// type, with a different mangled name and binary layout, depending on the -// compiler flags passed by the end user. For more info, see -// https://abseil.io/about/design/dropin-types. - -// User code should not inspect this macro. To check in the preprocessor if -// absl::OTABSL_OPTION_NAMESPACE_NAME::optional is a typedef of std::optional, use the feature macro -// OTABSL_USES_STD_OPTIONAL. - -#define OTABSL_OPTION_USE_STD_OPTIONAL 0 - - -// OTABSL_OPTION_USE_STD_STRING_VIEW -// -// This option controls whether absl::OTABSL_OPTION_NAMESPACE_NAME::string_view is implemented as an alias to -// std::string_view, or as an independent implementation. -// -// A value of 0 means to use Abseil's implementation. This requires only C++11 -// support, and is expected to work on every toolchain we support. -// -// A value of 1 means to use an alias to std::string_view. This requires that -// all code using Abseil is built in C++17 mode or later. -// -// A value of 2 means to detect the C++ version being used to compile Abseil, -// and use an alias only if a working std::string_view is available. This -// option is useful when you are building your program from source. It should -// not be used otherwise -- for example, if you are distributing Abseil in a -// binary package manager -- since in mode 2, absl::OTABSL_OPTION_NAMESPACE_NAME::string_view will name a -// different type, with a different mangled name and binary layout, depending on -// the compiler flags passed by the end user. For more info, see -// https://abseil.io/about/design/dropin-types. -// -// User code should not inspect this macro. To check in the preprocessor if -// absl::OTABSL_OPTION_NAMESPACE_NAME::string_view is a typedef of std::string_view, use the feature macro -// OTABSL_USES_STD_STRING_VIEW. - -#define OTABSL_OPTION_USE_STD_STRING_VIEW 0 - -// OTABSL_OPTION_USE_STD_VARIANT -// -// This option controls whether absl::OTABSL_OPTION_NAMESPACE_NAME::variant is implemented as an alias to -// std::variant, or as an independent implementation. -// -// A value of 0 means to use Abseil's implementation. This requires only C++11 -// support, and is expected to work on every toolchain we support. -// -// A value of 1 means to use an alias to std::variant. This requires that all -// code using Abseil is built in C++17 mode or later. -// -// A value of 2 means to detect the C++ version being used to compile Abseil, -// and use an alias only if a working std::variant is available. This option -// is useful when you are building your program from source. It should not be -// used otherwise -- for example, if you are distributing Abseil in a binary -// package manager -- since in mode 2, absl::OTABSL_OPTION_NAMESPACE_NAME::variant will name a different -// type, with a different mangled name and binary layout, depending on the -// compiler flags passed by the end user. For more info, see -// https://abseil.io/about/design/dropin-types. -// -// User code should not inspect this macro. To check in the preprocessor if -// absl::OTABSL_OPTION_NAMESPACE_NAME::variant is a typedef of std::variant, use the feature macro -// OTABSL_USES_STD_VARIANT. - -#define OTABSL_OPTION_USE_STD_VARIANT 0 - - -// OTABSL_OPTION_NAMESPACE_NAME -// -// All codes in otabsl are under OTABSL_OPTION_NAMESPACE_NAME, we do not use inline namespace to avoid -// conlict with external Abseil. - -#define OTABSL_OPTION_NAMESPACE_NAME otel_v1 - -#endif // OTABSL_BASE_OPTIONS_H_ diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/policy_checks.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/policy_checks.h deleted file mode 100644 index f86c264fc..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/policy_checks.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ----------------------------------------------------------------------------- -// File: policy_checks.h -// ----------------------------------------------------------------------------- -// -// This header enforces a minimum set of policies at build time, such as the -// supported compiler and library versions. Unsupported configurations are -// reported with `#error`. This enforcement is best effort, so successfully -// compiling this header does not guarantee a supported configuration. - -#ifndef OTABSL_BASE_POLICY_CHECKS_H_ -#define OTABSL_BASE_POLICY_CHECKS_H_ - -// Included for the __GLIBC_PREREQ macro used below. -#include - -// Included for the _STLPORT_VERSION macro used below. -#if defined(__cplusplus) -#include -#endif - -// ----------------------------------------------------------------------------- -// Operating System Check -// ----------------------------------------------------------------------------- - -#if defined(__CYGWIN__) -#error "Cygwin is not supported." -#endif - -// ----------------------------------------------------------------------------- -// Compiler Check -// ----------------------------------------------------------------------------- - -#if 0 /* FIXME: MG */ -// We support MSVC++ 14.0 update 2 and later. -// This minimum will go up. -#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023918 && !defined(__clang__) -#error "This package requires Visual Studio 2015 Update 2 or higher." -#endif -#endif - -// We support gcc 4.7 and later. -// This minimum will go up. -#if defined(__GNUC__) && !defined(__clang__) -#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) -#error "This package requires gcc 4.7 or higher." -#endif -#endif - -// We support Apple Xcode clang 4.2.1 (version 421.11.65) and later. -// This corresponds to Apple Xcode version 4.5. -// This minimum will go up. -#if defined(__apple_build_version__) && __apple_build_version__ < 4211165 -#error "This package requires __apple_build_version__ of 4211165 or higher." -#endif - -// ----------------------------------------------------------------------------- -// C++ Version Check -// ----------------------------------------------------------------------------- - -// Enforce C++11 as the minimum. -#if defined(_MSVC_LANG) -#if _MSVC_LANG < 201103L -#error "C++ versions less than C++11 are not supported." -#endif // _MSVC_LANG < 201103L -#elif defined(__cplusplus) -#if __cplusplus < 201103L -#error "C++ versions less than C++11 are not supported." -#endif // __cplusplus < 201103L -#endif - -// ----------------------------------------------------------------------------- -// Standard Library Check -// ----------------------------------------------------------------------------- - -#if defined(_STLPORT_VERSION) -#error "STLPort is not supported." -#endif - -// ----------------------------------------------------------------------------- -// `char` Size Check -// ----------------------------------------------------------------------------- - -// Abseil currently assumes CHAR_BIT == 8. If you would like to use Abseil on a -// platform where this is not the case, please provide us with the details about -// your platform so we can consider relaxing this requirement. -#if CHAR_BIT != 8 -#error "Abseil assumes CHAR_BIT == 8." -#endif - -// ----------------------------------------------------------------------------- -// `int` Size Check -// ----------------------------------------------------------------------------- - -// Abseil currently assumes that an int is 4 bytes. If you would like to use -// Abseil on a platform where this is not the case, please provide us with the -// details about your platform so we can consider relaxing this requirement. -#if INT_MAX < 2147483647 -#error "Abseil assumes that int is at least 4 bytes. " -#endif - -#endif // OTABSL_BASE_POLICY_CHECKS_H_ diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/port.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/port.h deleted file mode 100644 index aaba551b5..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/base/port.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// This files is a forwarding header for other headers containing various -// portability macros and functions. -// This file is used for both C and C++! - -#ifndef OTABSL_BASE_PORT_H_ -#define OTABSL_BASE_PORT_H_ - -#include "attributes.h" -#include "config.h" -#include "optimization.h" - -#endif // OTABSL_BASE_PORT_H_ diff --git a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/meta/type_traits.h b/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/meta/type_traits.h deleted file mode 100644 index dbd034887..000000000 --- a/ext/opentelemetry-cpp-1.21.0/api/include/opentelemetry/nostd/internal/absl/meta/type_traits.h +++ /dev/null @@ -1,779 +0,0 @@ -// -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ----------------------------------------------------------------------------- -// type_traits.h -// ----------------------------------------------------------------------------- -// -// This file contains C++11-compatible versions of standard API -// functions for determining the characteristics of types. Such traits can -// support type inference, classification, and transformation, as well as -// make it easier to write templates based on generic type behavior. -// -// See https://en.cppreference.com/w/cpp/header/type_traits -// -// WARNING: use of many of the constructs in this header will count as "complex -// template metaprogramming", so before proceeding, please carefully consider -// https://google.github.io/styleguide/cppguide.html#Template_metaprogramming -// -// WARNING: using template metaprogramming to detect or depend on API -// features is brittle and not guaranteed. Neither the standard library nor -// Abseil provides any guarantee that APIs are stable in the face of template -// metaprogramming. Use with caution. -#ifndef OTABSL_META_TYPE_TRAITS_H_ -#define OTABSL_META_TYPE_TRAITS_H_ - -#include -#include -#include - -#include "../base/config.h" - -// MSVC constructibility traits do not detect destructor properties and so our -// implementations should not use them as a source-of-truth. -#if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__) -#define OTABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION 1 -#endif - -namespace absl { -OTABSL_NAMESPACE_BEGIN - -// Defined and documented later on in this file. -template -struct is_trivially_destructible; - -// Defined and documented later on in this file. -template -struct is_trivially_move_assignable; - -namespace type_traits_internal { - -// Silence MSVC warnings about the destructor being defined as deleted. -#if defined(_MSC_VER) && !defined(__GNUC__) -#pragma warning(push) -#pragma warning(disable : 4624) -#endif // defined(_MSC_VER) && !defined(__GNUC__) - -template -union SingleMemberUnion { - T t; -}; - -// Restore the state of the destructor warning that was silenced above. -#if defined(_MSC_VER) && !defined(__GNUC__) -#pragma warning(pop) -#endif // defined(_MSC_VER) && !defined(__GNUC__) - -template -struct IsTriviallyMoveConstructibleObject - : std::integral_constant< - bool, std::is_move_constructible< - type_traits_internal::SingleMemberUnion>::value && - absl::OTABSL_OPTION_NAMESPACE_NAME::is_trivially_destructible::value> {}; - -template -struct IsTriviallyCopyConstructibleObject - : std::integral_constant< - bool, std::is_copy_constructible< - type_traits_internal::SingleMemberUnion>::value && - absl::OTABSL_OPTION_NAMESPACE_NAME::is_trivially_destructible::value> {}; - -template -struct IsTriviallyMoveAssignableReference : std::false_type {}; - -template -struct IsTriviallyMoveAssignableReference - : absl::OTABSL_OPTION_NAMESPACE_NAME::is_trivially_move_assignable::type {}; - -template -struct IsTriviallyMoveAssignableReference - : absl::OTABSL_OPTION_NAMESPACE_NAME::is_trivially_move_assignable::type {}; - -template -struct VoidTImpl { - using type = void; -}; - -//////////////////////////////// -// Library Fundamentals V2 TS // -//////////////////////////////// - -// NOTE: The `is_detected` family of templates here differ from the library -// fundamentals specification in that for library fundamentals, `Op` is -// evaluated as soon as the type `is_detected` undergoes -// substitution, regardless of whether or not the `::value` is accessed. That -// is inconsistent with all other standard traits and prevents lazy evaluation -// in larger contexts (such as if the `is_detected` check is a trailing argument -// of a `conjunction`. This implementation opts to instead be lazy in the same -// way that the standard traits are (this "defect" of the detection idiom -// specifications has been reported). - -template class Op, class... Args> -struct is_detected_impl { - using type = std::false_type; -}; - -template