From be7ce4110eee278963e99b756ebaa874fb8de130 Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Fri, 24 Jun 2022 10:12:36 -0700 Subject: [PATCH] Revert "Delete and re-add libpqxx-7.7.3 due to weird corruption." This reverts commit e96515433d71684a5a9a876c7af93530e11e160b. --- ext/libpqxx-7.7.3/.circleci/config.yml | 60 + ext/libpqxx-7.7.3/.clang-format | 71 + ext/libpqxx-7.7.3/.cmake-format | 184 + ext/libpqxx-7.7.3/.github/workflows/stale.yml | 19 + ext/libpqxx-7.7.3/.gitignore | 49 + ext/libpqxx-7.7.3/.lgtm.yml | 9 + ext/libpqxx-7.7.3/.lift/ignoreFiles | 3 + ext/libpqxx-7.7.3/AUTHORS | 4 + ext/libpqxx-7.7.3/BUILDING-cmake.md | 272 + ext/libpqxx-7.7.3/BUILDING-configure.md | 275 + ext/libpqxx-7.7.3/CMakeLists.txt | 66 + ext/libpqxx-7.7.3/COPYING | 27 + ext/libpqxx-7.7.3/INSTALL | 2 + ext/libpqxx-7.7.3/Makefile.am | 23 + ext/libpqxx-7.7.3/Makefile.in | 1253 + ext/libpqxx-7.7.3/NEWS | 1040 + ext/libpqxx-7.7.3/README.md | 199 + ext/libpqxx-7.7.3/VERSION | 1 + ext/libpqxx-7.7.3/aclocal.m4 | 1187 + ext/libpqxx-7.7.3/appveyor.yml | 30 + ext/libpqxx-7.7.3/autogen.sh | 44 + ext/libpqxx-7.7.3/cmake/config.cmake | 157 + ext/libpqxx-7.7.3/cmake/libpqxx-config.cmake | 4 + ext/libpqxx-7.7.3/compile_flags.in | 1 + ext/libpqxx-7.7.3/config-tests/README.md | 22 + .../config-tests/charconv_float.cxx | 16 + .../config-tests/charconv_int.cxx | 16 + ext/libpqxx-7.7.3/config-tests/cmp.cxx | 8 + ext/libpqxx-7.7.3/config-tests/concepts.cxx | 21 + .../config-tests/cxa_demangle.cxx | 19 + ext/libpqxx-7.7.3/config-tests/fs.cxx | 9 + ext/libpqxx-7.7.3/config-tests/gcc_pure.cxx | 10 + .../config-tests/gcc_visibility.cxx | 12 + ext/libpqxx-7.7.3/config-tests/likely.cxx | 15 + .../config-tests/multidim-subscript.cxx | 14 + ext/libpqxx-7.7.3/config-tests/need_fslib.cxx | 21 + ext/libpqxx-7.7.3/config-tests/poll.cxx | 7 + ext/libpqxx-7.7.3/config-tests/sleep_for.cxx | 28 + ext/libpqxx-7.7.3/config-tests/span.cxx | 8 + ext/libpqxx-7.7.3/config-tests/strerror_r.cxx | 14 + ext/libpqxx-7.7.3/config-tests/strerror_s.cxx | 11 + .../config-tests/thread_local.cxx | 15 + .../config-tests/year_month_day.cxx | 7 + ext/libpqxx-7.7.3/config/Makefile.am | 8 + ext/libpqxx-7.7.3/config/Makefile.in | 470 + ext/libpqxx-7.7.3/config/compile | 348 + ext/libpqxx-7.7.3/config/config.guess | 1502 ++ ext/libpqxx-7.7.3/config/config.sub | 1714 ++ ext/libpqxx-7.7.3/config/depcomp | 791 + ext/libpqxx-7.7.3/config/install-sh | 520 + ext/libpqxx-7.7.3/config/ltmain.sh | 11251 +++++++++ ext/libpqxx-7.7.3/config/m4/Makefile.am | 3 + ext/libpqxx-7.7.3/config/m4/libtool.m4 | 8394 +++++++ ext/libpqxx-7.7.3/config/m4/ltoptions.m4 | 437 + ext/libpqxx-7.7.3/config/m4/ltsugar.m4 | 124 + ext/libpqxx-7.7.3/config/m4/ltversion.m4 | 23 + ext/libpqxx-7.7.3/config/m4/lt~obsolete.m4 | 99 + ext/libpqxx-7.7.3/config/missing | 215 + ext/libpqxx-7.7.3/config/mkinstalldirs | 40 + ext/libpqxx-7.7.3/config/test-driver | 148 + ext/libpqxx-7.7.3/configitems | 26 + ext/libpqxx-7.7.3/configure | 20443 ++++++++++++++++ ext/libpqxx-7.7.3/configure.ac | 738 + ext/libpqxx-7.7.3/doc/CMakeLists.txt | 50 + ext/libpqxx-7.7.3/doc/Doxyfile.in | 1280 + ext/libpqxx-7.7.3/doc/Makefile.am | 51 + ext/libpqxx-7.7.3/doc/Makefile.in | 507 + ext/libpqxx-7.7.3/doc/conf.py | 199 + ext/libpqxx-7.7.3/doc/index.rst | 20 + ext/libpqxx-7.7.3/include/CMakeLists.txt | 68 + .../include/CMakeLists.txt.template | 23 + ext/libpqxx-7.7.3/include/Makefile.am | 79 + ext/libpqxx-7.7.3/include/Makefile.in | 802 + ext/libpqxx-7.7.3/include/pqxx/Makefile.am | 13 + ext/libpqxx-7.7.3/include/pqxx/Makefile.in | 556 + ext/libpqxx-7.7.3/include/pqxx/array | 6 + ext/libpqxx-7.7.3/include/pqxx/array.hxx | 103 + ext/libpqxx-7.7.3/include/pqxx/binarystring | 6 + .../include/pqxx/binarystring.hxx | 236 + ext/libpqxx-7.7.3/include/pqxx/blob | 6 + ext/libpqxx-7.7.3/include/pqxx/blob.hxx | 351 + ext/libpqxx-7.7.3/include/pqxx/composite | 6 + ext/libpqxx-7.7.3/include/pqxx/composite.hxx | 149 + ext/libpqxx-7.7.3/include/pqxx/config.h.in | 121 + ext/libpqxx-7.7.3/include/pqxx/connection | 8 + ext/libpqxx-7.7.3/include/pqxx/connection.hxx | 1261 + ext/libpqxx-7.7.3/include/pqxx/cursor | 8 + ext/libpqxx-7.7.3/include/pqxx/cursor.hxx | 483 + ext/libpqxx-7.7.3/include/pqxx/dbtransaction | 8 + .../include/pqxx/dbtransaction.hxx | 70 + .../include/pqxx/doc/accessing-results.md | 157 + .../include/pqxx/doc/binary-data.md | 56 + .../include/pqxx/doc/datatypes.md | 373 + .../include/pqxx/doc/escaping.md | 74 + .../include/pqxx/doc/getting-started.md | 142 + .../include/pqxx/doc/mainpage.md | 28 + .../include/pqxx/doc/mainpage.md.template | 28 + .../include/pqxx/doc/parameters.md | 90 + .../include/pqxx/doc/performance.md | 24 + .../include/pqxx/doc/prepared-statement.md | 125 + ext/libpqxx-7.7.3/include/pqxx/doc/streams.md | 107 + .../include/pqxx/doc/thread-safety.md | 29 + ext/libpqxx-7.7.3/include/pqxx/errorhandler | 8 + .../include/pqxx/errorhandler.hxx | 92 + ext/libpqxx-7.7.3/include/pqxx/except | 8 + ext/libpqxx-7.7.3/include/pqxx/except.hxx | 447 + ext/libpqxx-7.7.3/include/pqxx/field | 8 + ext/libpqxx-7.7.3/include/pqxx/field.hxx | 542 + .../include/pqxx/internal/array-composite.hxx | 305 + .../include/pqxx/internal/callgate.hxx | 70 + .../include/pqxx/internal/concat.hxx | 45 + .../include/pqxx/internal/conversions.hxx | 1188 + .../include/pqxx/internal/encoding_group.hxx | 60 + .../include/pqxx/internal/encodings.hxx | 90 + .../gates/connection-errorhandler.hxx | 26 + .../internal/gates/connection-largeobject.hxx | 35 + .../connection-notification_receiver.hxx | 29 + .../internal/gates/connection-pipeline.hxx | 23 + .../internal/gates/connection-sql_cursor.hxx | 19 + .../internal/gates/connection-stream_from.hxx | 15 + .../internal/gates/connection-stream_to.hxx | 17 + .../internal/gates/connection-transaction.hxx | 44 + .../gates/errorhandler-connection.hxx | 13 + .../gates/icursor_iterator-icursorstream.hxx | 24 + .../gates/icursorstream-icursor_iterator.hxx | 32 + .../pqxx/internal/gates/result-connection.hxx | 14 + .../pqxx/internal/gates/result-creation.hxx | 24 + .../pqxx/internal/gates/result-pipeline.hxx | 16 + .../pqxx/internal/gates/result-sql_cursor.hxx | 13 + .../internal/gates/transaction-sql_cursor.hxx | 10 + .../gates/transaction-transaction_focus.hxx | 30 + .../include/pqxx/internal/header-post.hxx | 22 + .../include/pqxx/internal/header-pre.hxx | 169 + .../pqxx/internal/ignore-deprecated-post.hxx | 15 + .../pqxx/internal/ignore-deprecated-pre.hxx | 28 + .../include/pqxx/internal/libpq-forward.hxx | 31 + .../include/pqxx/internal/result_iter.hxx | 124 + .../include/pqxx/internal/result_iterator.hxx | 389 + .../include/pqxx/internal/sql_cursor.hxx | 118 + .../pqxx/internal/statement_parameters.hxx | 131 + .../include/pqxx/internal/stream_iterator.hxx | 105 + .../include/pqxx/internal/wait.hxx | 18 + ext/libpqxx-7.7.3/include/pqxx/isolation | 8 + ext/libpqxx-7.7.3/include/pqxx/isolation.hxx | 75 + ext/libpqxx-7.7.3/include/pqxx/largeobject | 8 + .../include/pqxx/largeobject.hxx | 735 + ext/libpqxx-7.7.3/include/pqxx/nontransaction | 8 + .../include/pqxx/nontransaction.hxx | 76 + ext/libpqxx-7.7.3/include/pqxx/notification | 8 + .../include/pqxx/notification.hxx | 94 + ext/libpqxx-7.7.3/include/pqxx/params | 8 + ext/libpqxx-7.7.3/include/pqxx/params.hxx | 383 + ext/libpqxx-7.7.3/include/pqxx/pipeline | 8 + ext/libpqxx-7.7.3/include/pqxx/pipeline.hxx | 237 + ext/libpqxx-7.7.3/include/pqxx/pqxx | 28 + .../include/pqxx/prepared_statement | 3 + .../include/pqxx/prepared_statement.hxx | 3 + ext/libpqxx-7.7.3/include/pqxx/range | 6 + ext/libpqxx-7.7.3/include/pqxx/range.hxx | 515 + ext/libpqxx-7.7.3/include/pqxx/result | 16 + ext/libpqxx-7.7.3/include/pqxx/result.hxx | 335 + .../include/pqxx/robusttransaction | 8 + .../include/pqxx/robusttransaction.hxx | 120 + ext/libpqxx-7.7.3/include/pqxx/row | 11 + ext/libpqxx-7.7.3/include/pqxx/row.hxx | 561 + ext/libpqxx-7.7.3/include/pqxx/separated_list | 6 + .../include/pqxx/separated_list.hxx | 142 + ext/libpqxx-7.7.3/include/pqxx/strconv | 6 + ext/libpqxx-7.7.3/include/pqxx/strconv.hxx | 468 + ext/libpqxx-7.7.3/include/pqxx/stream_from | 8 + .../include/pqxx/stream_from.hxx | 361 + ext/libpqxx-7.7.3/include/pqxx/stream_to | 8 + ext/libpqxx-7.7.3/include/pqxx/stream_to.hxx | 455 + ext/libpqxx-7.7.3/include/pqxx/subtransaction | 8 + .../include/pqxx/subtransaction.hxx | 96 + ext/libpqxx-7.7.3/include/pqxx/time | 6 + ext/libpqxx-7.7.3/include/pqxx/time.hxx | 88 + ext/libpqxx-7.7.3/include/pqxx/transaction | 8 + .../include/pqxx/transaction.hxx | 108 + .../include/pqxx/transaction_base | 9 + .../include/pqxx/transaction_base.hxx | 810 + .../include/pqxx/transaction_focus | 7 + .../include/pqxx/transaction_focus.hxx | 89 + ext/libpqxx-7.7.3/include/pqxx/transactor | 8 + ext/libpqxx-7.7.3/include/pqxx/transactor.hxx | 147 + ext/libpqxx-7.7.3/include/pqxx/types | 7 + ext/libpqxx-7.7.3/include/pqxx/types.hxx | 173 + ext/libpqxx-7.7.3/include/pqxx/util | 6 + ext/libpqxx-7.7.3/include/pqxx/util.hxx | 521 + ext/libpqxx-7.7.3/include/pqxx/version | 7 + ext/libpqxx-7.7.3/include/pqxx/version.hxx | 55 + .../include/pqxx/version.hxx.template | 55 + ext/libpqxx-7.7.3/include/pqxx/zview | 6 + ext/libpqxx-7.7.3/include/pqxx/zview.hxx | 163 + .../install/ubuntu22.04/include/pqxx/array | 6 + .../ubuntu22.04/include/pqxx/array.hxx | 103 + .../ubuntu22.04/include/pqxx/binarystring | 6 + .../ubuntu22.04/include/pqxx/binarystring.hxx | 236 + .../install/ubuntu22.04/include/pqxx/blob | 6 + .../install/ubuntu22.04/include/pqxx/blob.hxx | 351 + .../ubuntu22.04/include/pqxx/composite | 6 + .../ubuntu22.04/include/pqxx/composite.hxx | 149 + .../include/pqxx/config-public-compiler.h | 81 + .../ubuntu22.04/include/pqxx/connection | 8 + .../ubuntu22.04/include/pqxx/connection.hxx | 1261 + .../install/ubuntu22.04/include/pqxx/cursor | 8 + .../ubuntu22.04/include/pqxx/cursor.hxx | 483 + .../ubuntu22.04/include/pqxx/dbtransaction | 8 + .../include/pqxx/dbtransaction.hxx | 70 + .../ubuntu22.04/include/pqxx/errorhandler | 8 + .../ubuntu22.04/include/pqxx/errorhandler.hxx | 92 + .../install/ubuntu22.04/include/pqxx/except | 8 + .../ubuntu22.04/include/pqxx/except.hxx | 447 + .../install/ubuntu22.04/include/pqxx/field | 8 + .../ubuntu22.04/include/pqxx/field.hxx | 542 + .../include/pqxx/internal/array-composite.hxx | 305 + .../include/pqxx/internal/callgate.hxx | 70 + .../include/pqxx/internal/concat.hxx | 45 + .../include/pqxx/internal/conversions.hxx | 1188 + .../include/pqxx/internal/encoding_group.hxx | 60 + .../include/pqxx/internal/encodings.hxx | 90 + .../gates/connection-errorhandler.hxx | 26 + .../internal/gates/connection-largeobject.hxx | 35 + .../connection-notification_receiver.hxx | 29 + .../internal/gates/connection-pipeline.hxx | 23 + .../internal/gates/connection-sql_cursor.hxx | 19 + .../internal/gates/connection-stream_from.hxx | 15 + .../internal/gates/connection-stream_to.hxx | 17 + .../internal/gates/connection-transaction.hxx | 44 + .../gates/errorhandler-connection.hxx | 13 + .../gates/icursor_iterator-icursorstream.hxx | 24 + .../gates/icursorstream-icursor_iterator.hxx | 32 + .../pqxx/internal/gates/result-connection.hxx | 14 + .../pqxx/internal/gates/result-creation.hxx | 24 + .../pqxx/internal/gates/result-pipeline.hxx | 16 + .../pqxx/internal/gates/result-sql_cursor.hxx | 13 + .../internal/gates/transaction-sql_cursor.hxx | 10 + .../gates/transaction-transaction_focus.hxx | 30 + .../include/pqxx/internal/header-post.hxx | 22 + .../include/pqxx/internal/header-pre.hxx | 169 + .../pqxx/internal/ignore-deprecated-post.hxx | 15 + .../pqxx/internal/ignore-deprecated-pre.hxx | 28 + .../include/pqxx/internal/libpq-forward.hxx | 31 + .../include/pqxx/internal/result_iter.hxx | 124 + .../include/pqxx/internal/result_iterator.hxx | 389 + .../include/pqxx/internal/sql_cursor.hxx | 118 + .../pqxx/internal/statement_parameters.hxx | 131 + .../include/pqxx/internal/stream_iterator.hxx | 105 + .../include/pqxx/internal/wait.hxx | 18 + .../ubuntu22.04/include/pqxx/isolation | 8 + .../ubuntu22.04/include/pqxx/isolation.hxx | 75 + .../ubuntu22.04/include/pqxx/largeobject | 8 + .../ubuntu22.04/include/pqxx/largeobject.hxx | 735 + .../ubuntu22.04/include/pqxx/nontransaction | 8 + .../include/pqxx/nontransaction.hxx | 76 + .../ubuntu22.04/include/pqxx/notification | 8 + .../ubuntu22.04/include/pqxx/notification.hxx | 94 + .../install/ubuntu22.04/include/pqxx/params | 8 + .../ubuntu22.04/include/pqxx/params.hxx | 383 + .../install/ubuntu22.04/include/pqxx/pipeline | 8 + .../ubuntu22.04/include/pqxx/pipeline.hxx | 237 + .../install/ubuntu22.04/include/pqxx/pqxx | 28 + .../include/pqxx/prepared_statement | 3 + .../include/pqxx/prepared_statement.hxx | 3 + .../install/ubuntu22.04/include/pqxx/range | 6 + .../ubuntu22.04/include/pqxx/range.hxx | 515 + .../install/ubuntu22.04/include/pqxx/result | 16 + .../ubuntu22.04/include/pqxx/result.hxx | 335 + .../include/pqxx/robusttransaction | 8 + .../include/pqxx/robusttransaction.hxx | 120 + .../install/ubuntu22.04/include/pqxx/row | 11 + .../install/ubuntu22.04/include/pqxx/row.hxx | 561 + .../ubuntu22.04/include/pqxx/separated_list | 6 + .../include/pqxx/separated_list.hxx | 142 + .../install/ubuntu22.04/include/pqxx/strconv | 6 + .../ubuntu22.04/include/pqxx/strconv.hxx | 468 + .../ubuntu22.04/include/pqxx/stream_from | 8 + .../ubuntu22.04/include/pqxx/stream_from.hxx | 361 + .../ubuntu22.04/include/pqxx/stream_to | 8 + .../ubuntu22.04/include/pqxx/stream_to.hxx | 455 + .../ubuntu22.04/include/pqxx/subtransaction | 8 + .../include/pqxx/subtransaction.hxx | 96 + .../install/ubuntu22.04/include/pqxx/time | 6 + .../install/ubuntu22.04/include/pqxx/time.hxx | 88 + .../ubuntu22.04/include/pqxx/transaction | 8 + .../ubuntu22.04/include/pqxx/transaction.hxx | 108 + .../ubuntu22.04/include/pqxx/transaction_base | 9 + .../include/pqxx/transaction_base.hxx | 810 + .../include/pqxx/transaction_focus | 7 + .../include/pqxx/transaction_focus.hxx | 89 + .../ubuntu22.04/include/pqxx/transactor | 8 + .../ubuntu22.04/include/pqxx/transactor.hxx | 147 + .../install/ubuntu22.04/include/pqxx/types | 7 + .../ubuntu22.04/include/pqxx/types.hxx | 173 + .../install/ubuntu22.04/include/pqxx/util | 6 + .../install/ubuntu22.04/include/pqxx/util.hxx | 521 + .../install/ubuntu22.04/include/pqxx/version | 7 + .../ubuntu22.04/include/pqxx/version.hxx | 55 + .../install/ubuntu22.04/include/pqxx/zview | 6 + .../ubuntu22.04/include/pqxx/zview.hxx | 163 + .../libpqxx/libpqxx-config-version.cmake | 70 + .../lib/cmake/libpqxx/libpqxx-config.cmake | 4 + .../libpqxx/libpqxx-targets-noconfig.cmake | 19 + .../lib/cmake/libpqxx/libpqxx-targets.cmake | 99 + .../install/ubuntu22.04/lib/libpqxx-7.7.a | Bin 0 -> 4600578 bytes .../install/ubuntu22.04/lib/libpqxx.a | 1 + .../ubuntu22.04/lib/pkgconfig/libpqxx.pc | 10 + .../share/doc/libpqxx/accessing-results.md | 157 + .../share/doc/libpqxx/binary-data.md | 56 + .../share/doc/libpqxx/datatypes.md | 373 + .../ubuntu22.04/share/doc/libpqxx/escaping.md | 74 + .../share/doc/libpqxx/getting-started.md | 142 + .../ubuntu22.04/share/doc/libpqxx/mainpage.md | 28 + .../share/doc/libpqxx/parameters.md | 90 + .../share/doc/libpqxx/performance.md | 24 + .../share/doc/libpqxx/prepared-statement.md | 125 + .../ubuntu22.04/share/doc/libpqxx/streams.md | 107 + .../share/doc/libpqxx/thread-safety.md | 29 + ext/libpqxx-7.7.3/libpqxx.pc.in | 10 + ext/libpqxx-7.7.3/requirements.json | 9 + ext/libpqxx-7.7.3/src/CMakeLists.txt | 91 + ext/libpqxx-7.7.3/src/Makefile.am | 44 + ext/libpqxx-7.7.3/src/Makefile.in | 809 + ext/libpqxx-7.7.3/src/array.cxx | 240 + ext/libpqxx-7.7.3/src/binarystring.cxx | 108 + ext/libpqxx-7.7.3/src/blob.cxx | 337 + ext/libpqxx-7.7.3/src/connection.cxx | 1274 + ext/libpqxx-7.7.3/src/cursor.cxx | 339 + ext/libpqxx-7.7.3/src/encodings.cxx | 839 + ext/libpqxx-7.7.3/src/errorhandler.cxx | 43 + ext/libpqxx-7.7.3/src/except.cxx | 126 + ext/libpqxx-7.7.3/src/field.cxx | 80 + ext/libpqxx-7.7.3/src/largeobject.cxx | 322 + ext/libpqxx-7.7.3/src/notification.cxx | 35 + ext/libpqxx-7.7.3/src/params.cxx | 122 + ext/libpqxx-7.7.3/src/pipeline.cxx | 448 + ext/libpqxx-7.7.3/src/pqxx-source.hxx | 30 + ext/libpqxx-7.7.3/src/result.cxx | 536 + ext/libpqxx-7.7.3/src/robusttransaction.cxx | 221 + ext/libpqxx-7.7.3/src/row.cxx | 250 + ext/libpqxx-7.7.3/src/sql_cursor.cxx | 276 + ext/libpqxx-7.7.3/src/strconv.cxx | 785 + ext/libpqxx-7.7.3/src/stream_from.cxx | 327 + ext/libpqxx-7.7.3/src/stream_to.cxx | 170 + ext/libpqxx-7.7.3/src/subtransaction.cxx | 68 + ext/libpqxx-7.7.3/src/time.cxx | 226 + ext/libpqxx-7.7.3/src/transaction.cxx | 107 + ext/libpqxx-7.7.3/src/transaction_base.cxx | 539 + ext/libpqxx-7.7.3/src/util.cxx | 194 + ext/libpqxx-7.7.3/src/version.cxx | 27 + ext/libpqxx-7.7.3/src/wait.cxx | 136 + ext/libpqxx-7.7.3/test/CMakeLists.txt | 24 + ext/libpqxx-7.7.3/test/Makefile.am | 129 + ext/libpqxx-7.7.3/test/Makefile.am.template | 38 + ext/libpqxx-7.7.3/test/Makefile.in | 1302 + ext/libpqxx-7.7.3/test/runner.cxx | 203 + ext/libpqxx-7.7.3/test/test00.cxx | 114 + ext/libpqxx-7.7.3/test/test01.cxx | 33 + ext/libpqxx-7.7.3/test/test02.cxx | 76 + ext/libpqxx-7.7.3/test/test04.cxx | 77 + ext/libpqxx-7.7.3/test/test07.cxx | 133 + ext/libpqxx-7.7.3/test/test10.cxx | 106 + ext/libpqxx-7.7.3/test/test11.cxx | 76 + ext/libpqxx-7.7.3/test/test13.cxx | 86 + ext/libpqxx-7.7.3/test/test14.cxx | 36 + ext/libpqxx-7.7.3/test/test16.cxx | 46 + ext/libpqxx-7.7.3/test/test17.cxx | 29 + ext/libpqxx-7.7.3/test/test18.cxx | 80 + ext/libpqxx-7.7.3/test/test20.cxx | 95 + ext/libpqxx-7.7.3/test/test21.cxx | 70 + ext/libpqxx-7.7.3/test/test26.cxx | 86 + ext/libpqxx-7.7.3/test/test29.cxx | 108 + ext/libpqxx-7.7.3/test/test30.cxx | 73 + ext/libpqxx-7.7.3/test/test32.cxx | 78 + ext/libpqxx-7.7.3/test/test37.cxx | 78 + ext/libpqxx-7.7.3/test/test39.cxx | 89 + ext/libpqxx-7.7.3/test/test46.cxx | 74 + ext/libpqxx-7.7.3/test/test56.cxx | 24 + ext/libpqxx-7.7.3/test/test60.cxx | 85 + ext/libpqxx-7.7.3/test/test61.cxx | 61 + ext/libpqxx-7.7.3/test/test62.cxx | 61 + ext/libpqxx-7.7.3/test/test69.cxx | 55 + ext/libpqxx-7.7.3/test/test70.cxx | 101 + ext/libpqxx-7.7.3/test/test71.cxx | 74 + ext/libpqxx-7.7.3/test/test72.cxx | 53 + ext/libpqxx-7.7.3/test/test74.cxx | 72 + ext/libpqxx-7.7.3/test/test75.cxx | 108 + ext/libpqxx-7.7.3/test/test76.cxx | 52 + ext/libpqxx-7.7.3/test/test77.cxx | 28 + ext/libpqxx-7.7.3/test/test78.cxx | 69 + ext/libpqxx-7.7.3/test/test79.cxx | 70 + ext/libpqxx-7.7.3/test/test82.cxx | 154 + ext/libpqxx-7.7.3/test/test84.cxx | 109 + ext/libpqxx-7.7.3/test/test87.cxx | 83 + ext/libpqxx-7.7.3/test/test88.cxx | 91 + ext/libpqxx-7.7.3/test/test89.cxx | 44 + ext/libpqxx-7.7.3/test/test90.cxx | 23 + ext/libpqxx-7.7.3/test/test_helpers.hxx | 305 + ext/libpqxx-7.7.3/test/test_types.hxx | 242 + ext/libpqxx-7.7.3/test/unit/CMakeLists.txt | 25 + ext/libpqxx-7.7.3/test/unit/test_array.cxx | 548 + .../test/unit/test_binarystring.cxx | 211 + ext/libpqxx-7.7.3/test/unit/test_blob.cxx | 644 + .../test/unit/test_cancel_query.cxx | 25 + ext/libpqxx-7.7.3/test/unit/test_column.cxx | 61 + .../test/unit/test_composite.cxx | 98 + .../test/unit/test_connection.cxx | 212 + ext/libpqxx-7.7.3/test/unit/test_cursor.cxx | 50 + .../test/unit/test_encodings.cxx | 114 + .../test/unit/test_error_verbosity.cxx | 37 + .../test/unit/test_errorhandler.cxx | 223 + ext/libpqxx-7.7.3/test/unit/test_escape.cxx | 228 + .../test/unit/test_exceptions.cxx | 45 + ext/libpqxx-7.7.3/test/unit/test_field.cxx | 57 + ext/libpqxx-7.7.3/test/unit/test_float.cxx | 175 + .../test/unit/test_largeobject.cxx | 58 + .../test/unit/test_nonblocking_connect.cxx | 27 + .../test/unit/test_notification.cxx | 86 + ext/libpqxx-7.7.3/test/unit/test_pipeline.cxx | 64 + .../test/unit/test_prepared_statement.cxx | 334 + ext/libpqxx-7.7.3/test/unit/test_range.cxx | 555 + .../test/unit/test_read_transaction.cxx | 22 + .../test/unit/test_result_iteration.cxx | 137 + .../test/unit/test_result_slicing.cxx | 157 + ext/libpqxx-7.7.3/test/unit/test_row.cxx | 84 + .../test/unit/test_separated_list.cxx | 33 + .../unit/test_simultaneous_transactions.cxx | 20 + .../test/unit/test_sql_cursor.cxx | 270 + .../test/unit/test_stateless_cursor.cxx | 85 + ext/libpqxx-7.7.3/test/unit/test_strconv.cxx | 143 + .../test/unit/test_stream_from.cxx | 344 + .../test/unit/test_stream_to.cxx | 445 + .../test/unit/test_string_conversion.cxx | 178 + .../test/unit/test_subtransaction.cxx | 78 + .../test/unit/test_test_helpers.cxx | 214 + .../test/unit/test_thread_safety_model.cxx | 23 + ext/libpqxx-7.7.3/test/unit/test_time.cxx | 86 + .../test/unit/test_transaction.cxx | 113 + .../test/unit/test_transaction_base.cxx | 106 + .../test/unit/test_transaction_focus.cxx | 53 + .../test/unit/test_transactor.cxx | 130 + .../test/unit/test_type_name.cxx | 19 + ext/libpqxx-7.7.3/test/unit/test_zview.cxx | 16 + ext/libpqxx-7.7.3/tools/Makefile.am | 20 + ext/libpqxx-7.7.3/tools/Makefile.in | 638 + ext/libpqxx-7.7.3/tools/deprecations | 6 + ext/libpqxx-7.7.3/tools/extract_version | 73 + ext/libpqxx-7.7.3/tools/format | 20 + ext/libpqxx-7.7.3/tools/lint | 197 + ext/libpqxx-7.7.3/tools/m4esc.py | 70 + ext/libpqxx-7.7.3/tools/pqxxthreadsafety.cxx | 10 + ext/libpqxx-7.7.3/tools/rmlo.cxx | 39 + ext/libpqxx-7.7.3/tools/splitconfig | 244 + ext/libpqxx-7.7.3/tools/template2mak.py | 194 + ext/libpqxx-7.7.3/tools/test_all.py | 630 + ext/libpqxx-7.7.3/tools/todo | 31 + ext/libpqxx-7.7.3/tools/update-copyright | 29 + 457 files changed, 110654 insertions(+) create mode 100644 ext/libpqxx-7.7.3/.circleci/config.yml create mode 100644 ext/libpqxx-7.7.3/.clang-format create mode 100644 ext/libpqxx-7.7.3/.cmake-format create mode 100644 ext/libpqxx-7.7.3/.github/workflows/stale.yml create mode 100644 ext/libpqxx-7.7.3/.gitignore create mode 100644 ext/libpqxx-7.7.3/.lgtm.yml create mode 100644 ext/libpqxx-7.7.3/.lift/ignoreFiles create mode 100644 ext/libpqxx-7.7.3/AUTHORS create mode 100644 ext/libpqxx-7.7.3/BUILDING-cmake.md create mode 100644 ext/libpqxx-7.7.3/BUILDING-configure.md create mode 100644 ext/libpqxx-7.7.3/CMakeLists.txt create mode 100644 ext/libpqxx-7.7.3/COPYING create mode 100644 ext/libpqxx-7.7.3/INSTALL create mode 100644 ext/libpqxx-7.7.3/Makefile.am create mode 100644 ext/libpqxx-7.7.3/Makefile.in create mode 100644 ext/libpqxx-7.7.3/NEWS create mode 100644 ext/libpqxx-7.7.3/README.md create mode 100644 ext/libpqxx-7.7.3/VERSION create mode 100644 ext/libpqxx-7.7.3/aclocal.m4 create mode 100644 ext/libpqxx-7.7.3/appveyor.yml create mode 100755 ext/libpqxx-7.7.3/autogen.sh create mode 100644 ext/libpqxx-7.7.3/cmake/config.cmake create mode 100644 ext/libpqxx-7.7.3/cmake/libpqxx-config.cmake create mode 100644 ext/libpqxx-7.7.3/compile_flags.in create mode 100644 ext/libpqxx-7.7.3/config-tests/README.md create mode 100644 ext/libpqxx-7.7.3/config-tests/charconv_float.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/charconv_int.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/cmp.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/concepts.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/cxa_demangle.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/fs.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/gcc_pure.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/gcc_visibility.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/likely.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/multidim-subscript.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/need_fslib.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/poll.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/sleep_for.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/span.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/strerror_r.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/strerror_s.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/thread_local.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/year_month_day.cxx create mode 100644 ext/libpqxx-7.7.3/config/Makefile.am create mode 100644 ext/libpqxx-7.7.3/config/Makefile.in create mode 100755 ext/libpqxx-7.7.3/config/compile create mode 100755 ext/libpqxx-7.7.3/config/config.guess create mode 100755 ext/libpqxx-7.7.3/config/config.sub create mode 100755 ext/libpqxx-7.7.3/config/depcomp create mode 100755 ext/libpqxx-7.7.3/config/install-sh create mode 100755 ext/libpqxx-7.7.3/config/ltmain.sh create mode 100644 ext/libpqxx-7.7.3/config/m4/Makefile.am create mode 100644 ext/libpqxx-7.7.3/config/m4/libtool.m4 create mode 100644 ext/libpqxx-7.7.3/config/m4/ltoptions.m4 create mode 100644 ext/libpqxx-7.7.3/config/m4/ltsugar.m4 create mode 100644 ext/libpqxx-7.7.3/config/m4/ltversion.m4 create mode 100644 ext/libpqxx-7.7.3/config/m4/lt~obsolete.m4 create mode 100755 ext/libpqxx-7.7.3/config/missing create mode 100755 ext/libpqxx-7.7.3/config/mkinstalldirs create mode 100755 ext/libpqxx-7.7.3/config/test-driver create mode 100644 ext/libpqxx-7.7.3/configitems create mode 100755 ext/libpqxx-7.7.3/configure create mode 100644 ext/libpqxx-7.7.3/configure.ac create mode 100644 ext/libpqxx-7.7.3/doc/CMakeLists.txt create mode 100644 ext/libpqxx-7.7.3/doc/Doxyfile.in create mode 100644 ext/libpqxx-7.7.3/doc/Makefile.am create mode 100644 ext/libpqxx-7.7.3/doc/Makefile.in create mode 100644 ext/libpqxx-7.7.3/doc/conf.py create mode 100644 ext/libpqxx-7.7.3/doc/index.rst create mode 100644 ext/libpqxx-7.7.3/include/CMakeLists.txt create mode 100644 ext/libpqxx-7.7.3/include/CMakeLists.txt.template create mode 100644 ext/libpqxx-7.7.3/include/Makefile.am create mode 100644 ext/libpqxx-7.7.3/include/Makefile.in create mode 100644 ext/libpqxx-7.7.3/include/pqxx/Makefile.am create mode 100644 ext/libpqxx-7.7.3/include/pqxx/Makefile.in create mode 100644 ext/libpqxx-7.7.3/include/pqxx/array create mode 100644 ext/libpqxx-7.7.3/include/pqxx/array.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/binarystring create mode 100644 ext/libpqxx-7.7.3/include/pqxx/binarystring.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/blob create mode 100644 ext/libpqxx-7.7.3/include/pqxx/blob.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/composite create mode 100644 ext/libpqxx-7.7.3/include/pqxx/composite.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/config.h.in create mode 100644 ext/libpqxx-7.7.3/include/pqxx/connection create mode 100644 ext/libpqxx-7.7.3/include/pqxx/connection.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/cursor create mode 100644 ext/libpqxx-7.7.3/include/pqxx/cursor.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/dbtransaction create mode 100644 ext/libpqxx-7.7.3/include/pqxx/dbtransaction.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/accessing-results.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/binary-data.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/datatypes.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/escaping.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/getting-started.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md.template create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/parameters.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/performance.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/prepared-statement.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/streams.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/thread-safety.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/errorhandler create mode 100644 ext/libpqxx-7.7.3/include/pqxx/errorhandler.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/except create mode 100644 ext/libpqxx-7.7.3/include/pqxx/except.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/field create mode 100644 ext/libpqxx-7.7.3/include/pqxx/field.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/array-composite.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/callgate.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/concat.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/conversions.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/encoding_group.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/encodings.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-errorhandler.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-largeobject.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-notification_receiver.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_from.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_to.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-transaction.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/errorhandler-connection.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-connection.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-creation.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-transaction_focus.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/header-post.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/header-pre.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-post.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-pre.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/libpq-forward.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/result_iter.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/result_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/statement_parameters.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/stream_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/wait.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/isolation create mode 100644 ext/libpqxx-7.7.3/include/pqxx/isolation.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/largeobject create mode 100644 ext/libpqxx-7.7.3/include/pqxx/largeobject.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/nontransaction create mode 100644 ext/libpqxx-7.7.3/include/pqxx/nontransaction.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/notification create mode 100644 ext/libpqxx-7.7.3/include/pqxx/notification.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/params create mode 100644 ext/libpqxx-7.7.3/include/pqxx/params.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/pipeline create mode 100644 ext/libpqxx-7.7.3/include/pqxx/pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/pqxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/prepared_statement create mode 100644 ext/libpqxx-7.7.3/include/pqxx/prepared_statement.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/range create mode 100644 ext/libpqxx-7.7.3/include/pqxx/range.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/result create mode 100644 ext/libpqxx-7.7.3/include/pqxx/result.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/robusttransaction create mode 100644 ext/libpqxx-7.7.3/include/pqxx/robusttransaction.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/row create mode 100644 ext/libpqxx-7.7.3/include/pqxx/row.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/separated_list create mode 100644 ext/libpqxx-7.7.3/include/pqxx/separated_list.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/strconv create mode 100644 ext/libpqxx-7.7.3/include/pqxx/strconv.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/stream_from create mode 100644 ext/libpqxx-7.7.3/include/pqxx/stream_from.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/stream_to create mode 100644 ext/libpqxx-7.7.3/include/pqxx/stream_to.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/subtransaction create mode 100644 ext/libpqxx-7.7.3/include/pqxx/subtransaction.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/time create mode 100644 ext/libpqxx-7.7.3/include/pqxx/time.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transaction create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transaction.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transaction_base create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transaction_base.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transaction_focus create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transaction_focus.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transactor create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transactor.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/types create mode 100644 ext/libpqxx-7.7.3/include/pqxx/types.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/util create mode 100644 ext/libpqxx-7.7.3/include/pqxx/util.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/version create mode 100644 ext/libpqxx-7.7.3/include/pqxx/version.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/version.hxx.template create mode 100644 ext/libpqxx-7.7.3/include/pqxx/zview create mode 100644 ext/libpqxx-7.7.3/include/pqxx/zview.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/array create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/array.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/binarystring create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/binarystring.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/blob create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/blob.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/composite create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/composite.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/config-public-compiler.h create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/connection create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/connection.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/cursor create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/dbtransaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/dbtransaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/errorhandler create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/errorhandler.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/except create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/except.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/field create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/field.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/array-composite.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/callgate.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/concat.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/conversions.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/encoding_group.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/encodings.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-errorhandler.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-largeobject.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-notification_receiver.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-stream_from.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-stream_to.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-transaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/errorhandler-connection.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-connection.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-creation.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/transaction-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/transaction-transaction_focus.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/header-post.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/header-pre.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/ignore-deprecated-post.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/ignore-deprecated-pre.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/libpq-forward.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/result_iter.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/result_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/statement_parameters.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/stream_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/wait.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/isolation create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/isolation.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/largeobject create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/largeobject.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/nontransaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/nontransaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/notification create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/notification.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/params create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/params.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/pipeline create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/pqxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/prepared_statement create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/prepared_statement.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/range create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/range.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/result create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/result.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/robusttransaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/robusttransaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/row create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/row.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/separated_list create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/separated_list.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/strconv create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/strconv.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_from create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_from.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_to create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_to.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/subtransaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/subtransaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/time create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/time.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_base create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_base.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_focus create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_focus.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transactor create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transactor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/types create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/types.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/util create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/util.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/version create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/version.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/zview create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/zview.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-config-version.cmake create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-config.cmake create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-targets.cmake create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/lib/libpqxx-7.7.a create mode 120000 ext/libpqxx-7.7.3/install/ubuntu22.04/lib/libpqxx.a create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/lib/pkgconfig/libpqxx.pc create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/accessing-results.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/binary-data.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/datatypes.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/escaping.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/getting-started.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/mainpage.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/parameters.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/performance.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/prepared-statement.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/streams.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/thread-safety.md create mode 100644 ext/libpqxx-7.7.3/libpqxx.pc.in create mode 100644 ext/libpqxx-7.7.3/requirements.json create mode 100644 ext/libpqxx-7.7.3/src/CMakeLists.txt create mode 100644 ext/libpqxx-7.7.3/src/Makefile.am create mode 100644 ext/libpqxx-7.7.3/src/Makefile.in create mode 100644 ext/libpqxx-7.7.3/src/array.cxx create mode 100644 ext/libpqxx-7.7.3/src/binarystring.cxx create mode 100644 ext/libpqxx-7.7.3/src/blob.cxx create mode 100644 ext/libpqxx-7.7.3/src/connection.cxx create mode 100644 ext/libpqxx-7.7.3/src/cursor.cxx create mode 100644 ext/libpqxx-7.7.3/src/encodings.cxx create mode 100644 ext/libpqxx-7.7.3/src/errorhandler.cxx create mode 100644 ext/libpqxx-7.7.3/src/except.cxx create mode 100644 ext/libpqxx-7.7.3/src/field.cxx create mode 100644 ext/libpqxx-7.7.3/src/largeobject.cxx create mode 100644 ext/libpqxx-7.7.3/src/notification.cxx create mode 100644 ext/libpqxx-7.7.3/src/params.cxx create mode 100644 ext/libpqxx-7.7.3/src/pipeline.cxx create mode 100644 ext/libpqxx-7.7.3/src/pqxx-source.hxx create mode 100644 ext/libpqxx-7.7.3/src/result.cxx create mode 100644 ext/libpqxx-7.7.3/src/robusttransaction.cxx create mode 100644 ext/libpqxx-7.7.3/src/row.cxx create mode 100644 ext/libpqxx-7.7.3/src/sql_cursor.cxx create mode 100644 ext/libpqxx-7.7.3/src/strconv.cxx create mode 100644 ext/libpqxx-7.7.3/src/stream_from.cxx create mode 100644 ext/libpqxx-7.7.3/src/stream_to.cxx create mode 100644 ext/libpqxx-7.7.3/src/subtransaction.cxx create mode 100644 ext/libpqxx-7.7.3/src/time.cxx create mode 100644 ext/libpqxx-7.7.3/src/transaction.cxx create mode 100644 ext/libpqxx-7.7.3/src/transaction_base.cxx create mode 100644 ext/libpqxx-7.7.3/src/util.cxx create mode 100644 ext/libpqxx-7.7.3/src/version.cxx create mode 100644 ext/libpqxx-7.7.3/src/wait.cxx create mode 100644 ext/libpqxx-7.7.3/test/CMakeLists.txt create mode 100644 ext/libpqxx-7.7.3/test/Makefile.am create mode 100644 ext/libpqxx-7.7.3/test/Makefile.am.template create mode 100644 ext/libpqxx-7.7.3/test/Makefile.in create mode 100644 ext/libpqxx-7.7.3/test/runner.cxx create mode 100644 ext/libpqxx-7.7.3/test/test00.cxx create mode 100644 ext/libpqxx-7.7.3/test/test01.cxx create mode 100644 ext/libpqxx-7.7.3/test/test02.cxx create mode 100644 ext/libpqxx-7.7.3/test/test04.cxx create mode 100644 ext/libpqxx-7.7.3/test/test07.cxx create mode 100644 ext/libpqxx-7.7.3/test/test10.cxx create mode 100644 ext/libpqxx-7.7.3/test/test11.cxx create mode 100644 ext/libpqxx-7.7.3/test/test13.cxx create mode 100644 ext/libpqxx-7.7.3/test/test14.cxx create mode 100644 ext/libpqxx-7.7.3/test/test16.cxx create mode 100644 ext/libpqxx-7.7.3/test/test17.cxx create mode 100644 ext/libpqxx-7.7.3/test/test18.cxx create mode 100644 ext/libpqxx-7.7.3/test/test20.cxx create mode 100644 ext/libpqxx-7.7.3/test/test21.cxx create mode 100644 ext/libpqxx-7.7.3/test/test26.cxx create mode 100644 ext/libpqxx-7.7.3/test/test29.cxx create mode 100644 ext/libpqxx-7.7.3/test/test30.cxx create mode 100644 ext/libpqxx-7.7.3/test/test32.cxx create mode 100644 ext/libpqxx-7.7.3/test/test37.cxx create mode 100644 ext/libpqxx-7.7.3/test/test39.cxx create mode 100644 ext/libpqxx-7.7.3/test/test46.cxx create mode 100644 ext/libpqxx-7.7.3/test/test56.cxx create mode 100644 ext/libpqxx-7.7.3/test/test60.cxx create mode 100644 ext/libpqxx-7.7.3/test/test61.cxx create mode 100644 ext/libpqxx-7.7.3/test/test62.cxx create mode 100644 ext/libpqxx-7.7.3/test/test69.cxx create mode 100644 ext/libpqxx-7.7.3/test/test70.cxx create mode 100644 ext/libpqxx-7.7.3/test/test71.cxx create mode 100644 ext/libpqxx-7.7.3/test/test72.cxx create mode 100644 ext/libpqxx-7.7.3/test/test74.cxx create mode 100644 ext/libpqxx-7.7.3/test/test75.cxx create mode 100644 ext/libpqxx-7.7.3/test/test76.cxx create mode 100644 ext/libpqxx-7.7.3/test/test77.cxx create mode 100644 ext/libpqxx-7.7.3/test/test78.cxx create mode 100644 ext/libpqxx-7.7.3/test/test79.cxx create mode 100644 ext/libpqxx-7.7.3/test/test82.cxx create mode 100644 ext/libpqxx-7.7.3/test/test84.cxx create mode 100644 ext/libpqxx-7.7.3/test/test87.cxx create mode 100644 ext/libpqxx-7.7.3/test/test88.cxx create mode 100644 ext/libpqxx-7.7.3/test/test89.cxx create mode 100644 ext/libpqxx-7.7.3/test/test90.cxx create mode 100644 ext/libpqxx-7.7.3/test/test_helpers.hxx create mode 100644 ext/libpqxx-7.7.3/test/test_types.hxx create mode 100644 ext/libpqxx-7.7.3/test/unit/CMakeLists.txt create mode 100644 ext/libpqxx-7.7.3/test/unit/test_array.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_binarystring.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_blob.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_cancel_query.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_column.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_composite.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_connection.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_cursor.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_encodings.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_error_verbosity.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_errorhandler.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_escape.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_exceptions.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_field.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_float.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_largeobject.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_nonblocking_connect.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_notification.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_pipeline.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_prepared_statement.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_range.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_read_transaction.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_result_iteration.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_result_slicing.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_row.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_separated_list.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_simultaneous_transactions.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_sql_cursor.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_stateless_cursor.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_strconv.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_stream_from.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_stream_to.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_string_conversion.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_subtransaction.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_test_helpers.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_thread_safety_model.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_time.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_transaction.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_transaction_base.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_transaction_focus.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_transactor.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_type_name.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_zview.cxx create mode 100644 ext/libpqxx-7.7.3/tools/Makefile.am create mode 100644 ext/libpqxx-7.7.3/tools/Makefile.in create mode 100755 ext/libpqxx-7.7.3/tools/deprecations create mode 100755 ext/libpqxx-7.7.3/tools/extract_version create mode 100755 ext/libpqxx-7.7.3/tools/format create mode 100755 ext/libpqxx-7.7.3/tools/lint create mode 100755 ext/libpqxx-7.7.3/tools/m4esc.py create mode 100644 ext/libpqxx-7.7.3/tools/pqxxthreadsafety.cxx create mode 100644 ext/libpqxx-7.7.3/tools/rmlo.cxx create mode 100755 ext/libpqxx-7.7.3/tools/splitconfig create mode 100755 ext/libpqxx-7.7.3/tools/template2mak.py create mode 100755 ext/libpqxx-7.7.3/tools/test_all.py create mode 100755 ext/libpqxx-7.7.3/tools/todo create mode 100755 ext/libpqxx-7.7.3/tools/update-copyright diff --git a/ext/libpqxx-7.7.3/.circleci/config.yml b/ext/libpqxx-7.7.3/.circleci/config.yml new file mode 100644 index 000000000..038d7adb0 --- /dev/null +++ b/ext/libpqxx-7.7.3/.circleci/config.yml @@ -0,0 +1,60 @@ +# CircleCI config for automated test builds triggered from Github. +version: 2 +jobs: + build: + docker: + - image: debian:testing +# - image: postgres:latest + environment: + - PGHOST: "/tmp" + steps: + - checkout + - run: + name: Configure apt archives + command: apt update + - run: + name: Install + command: apt install -y lsb-release python3 cmake postgresql libpq-dev postgresql-server-dev-all build-essential autoconf dh-autoreconf autoconf-archive automake cppcheck + - run: + name: Identify + command: lsb_release -a && c++ --version + - run: + name: Prepare postgres + command: | + mkdir /tmp/db && + chown postgres /tmp/db && + su postgres -c '/usr/lib/postgresql/*/bin/initdb --pgdata /tmp/db --auth trust --nosync' + - run: + name: Run postgres + command: (su postgres -c '/usr/lib/postgresql/*/bin/postgres -D /tmp/db -k /tmp' &) && sleep 5 + - run: + name: Create postgres user + command: su postgres -c "createuser -w -d root" + - run: + name: Set up database + command: createdb root + - run: + name: Autogen + command: NOCONFIGURE=1 ./autogen.sh + - run: + name: Configure + command: | + ./configure \ + --disable-documentation \ + --enable-maintainer-mode \ + --enable-audit \ + --enable-shared --disable-static \ + CXXFLAGS=-O3 + - store_artifacts: + path: config.log + - run: + name: Make + command: make -j$(nproc) + - run: + name: Test + command: PGDATA=db/data make check + - run: + name: Analyse + command: ./tools/lint --full >lint.log + - store_artifacts: + path: lint.log diff --git a/ext/libpqxx-7.7.3/.clang-format b/ext/libpqxx-7.7.3/.clang-format new file mode 100644 index 000000000..97823d8ff --- /dev/null +++ b/ext/libpqxx-7.7.3/.clang-format @@ -0,0 +1,71 @@ +Language: Cpp + +AlignAfterOpenBracket: AlwaysBreak +# AllowAllArgumentsOnNextLine: true +# AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: Inline +# AllowShortIfStatementsOnASingleLine: WithoutElse +# AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +# AlwaysBreakTemplateDeclarations: No +BinPackArguments: true +BinPackParameters: true +BreakBeforeBraces: Custom +BraceWrapping: + # AfterCaseLabel: true + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterExternBlock: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyNamespace: false + SplitEmptyRecord: false +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: false +BreakConstructorInitializers: AfterColon +# BreakInheritanceList: AfterColon +BreakStringLiterals: true +ColumnLimit: 79 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 2 +Cpp11BracedListStyle: true +FixNamespaceComments: true +IncludeBlocks: Preserve +IndentCaseLabels: false +IndentPPDirectives: AfterHash +IndentWidth: 2 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 2 +# NamespaceIndentation: All +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +# SpaceBeforeCpp11BracedList: false +# SpaceBeforeCtorInitializerColon: true +# SpaceBeforeInheritanceColon: true +# SpaceBeforeParents: ControlStatements +# SpaceBeforeRangedBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +UseTab: Never +--- diff --git a/ext/libpqxx-7.7.3/.cmake-format b/ext/libpqxx-7.7.3/.cmake-format new file mode 100644 index 000000000..af00ef936 --- /dev/null +++ b/ext/libpqxx-7.7.3/.cmake-format @@ -0,0 +1,184 @@ +format: + _help_max_prefix_chars: + - !!python/unicode 'If the statement spelling length (including space and' + - !!python/unicode 'parenthesis) is larger than the tab width by more than this' + - !!python/unicode 'amount, then force reject un-nested layouts.' + max_prefix_chars: 10 + _help_dangle_align: + - !!python/unicode 'If the trailing parenthesis must be ''dangled'' on its own' + - !!python/unicode 'line, then align it to this reference: `prefix`: the start' + - !!python/unicode 'of the statement, `prefix-indent`: the start of the' + - !!python/unicode 'statement, plus one indentation level, `child`: align to' + - !!python/unicode 'the column of the arguments' + dangle_align: !!python/unicode 'prefix' + _help_max_subgroups_hwrap: + - !!python/unicode 'If an argument group contains more than this many sub-groups' + - !!python/unicode '(parg or kwarg groups) then force it to a vertical layout.' + max_subgroups_hwrap: 2 + _help_min_prefix_chars: + - !!python/unicode 'If the statement spelling length (including space and' + - !!python/unicode 'parenthesis) is smaller than this amount, then force reject' + - !!python/unicode 'nested layouts.' + min_prefix_chars: 4 + _help_max_pargs_hwrap: + - !!python/unicode 'If a positional argument group contains more than this many' + - !!python/unicode 'arguments, then force it to a vertical layout.' + max_pargs_hwrap: 6 + _help_max_lines_hwrap: + - !!python/unicode 'If a candidate layout is wrapped horizontally but it exceeds' + - !!python/unicode 'this many lines, then reject the layout.' + max_lines_hwrap: 2 + _help_autosort: + - !!python/unicode 'If true, the parsers may infer whether or not an argument' + - !!python/unicode 'list is sortable (without annotation).' + autosort: false + _help_line_ending: + - !!python/unicode 'What style line endings to use in the output.' + line_ending: !!python/unicode 'unix' + _help_line_width: + - !!python/unicode 'How wide to allow formatted cmake files' + line_width: 80 + _help_dangle_parens: + - !!python/unicode 'If a statement is wrapped to more than one line, then dangle' + - !!python/unicode 'the closing parenthesis on its own line.' + dangle_parens: true + _help_tab_size: + - !!python/unicode 'How many spaces to tab for indent' + tab_size: 4 + _help_always_wrap: + - !!python/unicode 'A list of command names which should always be wrapped' + always_wrap: [] + _help_require_valid_layout: + - !!python/unicode 'By default, if cmake-format cannot successfully fit' + - !!python/unicode 'everything into the desired linewidth it will apply the' + - !!python/unicode 'last, most agressive attempt that it made. If this flag is' + - !!python/unicode 'True, however, cmake-format will print error, exit with non-' + - !!python/unicode 'zero status code, and write-out nothing' + require_valid_layout: true + _help_keyword_case: + - !!python/unicode 'Format keywords consistently as ''lower'' or ''upper'' case' + keyword_case: !!python/unicode 'unchanged' + _help_layout_passes: + - !!python/unicode 'A dictionary mapping layout nodes to a list of wrap' + - !!python/unicode 'decisions. See the documentation for more information.' + layout_passes: {} + _help_enable_sort: + - !!python/unicode 'If true, the argument lists which are known to be sortable' + - !!python/unicode 'will be sorted lexicographically' + enable_sort: true +_help_markup: !!python/unicode 'Options affecting comment reflow and formatting.' +markup: + _help_literal_comment_pattern: + - !!python/unicode 'If comment markup is enabled, don''t reflow any comment block' + - !!python/unicode 'which matches this (regex) pattern. Default is `None`' + - !!python/unicode '(disabled).' + literal_comment_pattern: null + _help_hashruler_min_length: + - !!python/unicode 'If a comment line starts with at least this many consecutive' + - !!python/unicode 'hash characters, then don''t lstrip() them off. This allows' + - !!python/unicode 'for lazy hash rulers where the first hash char is not' + - !!python/unicode 'separated by space' + hashruler_min_length: 10 + _help_fence_pattern: + - !!python/unicode 'Regular expression to match preformat fences in comments' + - !!python/unicode 'default=r''^\s*([`~]{3}[`~]*)(.*)$''' + fence_pattern: !!python/unicode '^\s*([`~]{3}[`~]*)(.*)$' + _help_canonicalize_hashrulers: + - !!python/unicode 'If true, then insert a space between the first hash char and' + - !!python/unicode 'remaining hash chars in a hash ruler, and normalize its' + - !!python/unicode 'length to fill the column' + canonicalize_hashrulers: true + _help_explicit_trailing_pattern: + - !!python/unicode 'If a comment line matches starts with this pattern then it' + - !!python/unicode 'is explicitly a trailing comment for the preceeding' + - !!python/unicode 'argument. Default is ''#<''' + explicit_trailing_pattern: !!python/unicode '#<' + _help_first_comment_is_literal: + - !!python/unicode 'If comment markup is enabled, don''t reflow the first comment' + - !!python/unicode 'block in each listfile. Use this to preserve formatting of' + - !!python/unicode 'your copyright/license statements.' + first_comment_is_literal: false + _help_enable_markup: + - !!python/unicode 'enable comment markup parsing and reflow' + enable_markup: true + _help_ruler_pattern: + - !!python/unicode 'Regular expression to match rulers in comments' + - !!python/unicode 'default=r''^\s*[^\w\s]{3}.*[^\w\s]{3}$''' + ruler_pattern: !!python/unicode '^\s*[^\w\s]{3}.*[^\w\s]{3}$' + _help_enum_char: + - !!python/unicode 'What character to use as punctuation after numerals in an' + - !!python/unicode 'enumerated list' + enum_char: . + _help_bullet_char: + - !!python/unicode 'What character to use for bulleted lists' + bullet_char: '*' +_help_lint: !!python/unicode 'Options affecting the linter' +lint: + _help_function_pattern: + - !!python/unicode 'regular expression pattern describing valid function names' + function_pattern: !!python/unicode '[0-9a-z_]+' + _help_disabled_codes: + - !!python/unicode 'a list of lint codes to disable' + disabled_codes: [] + _help_min_statement_spacing: + - !!python/unicode 'Require at least this many newlines between statements' + min_statement_spacing: 1 + _help_macro_pattern: + - !!python/unicode 'regular expression pattern describing valid macro names' + macro_pattern: !!python/unicode '[0-9A-Z_]+' + _help_public_var_pattern: + - !!python/unicode 'regular expression pattern describing valid names for' + - !!python/unicode 'publicdirectory variables' + public_var_pattern: !!python/unicode '[0-9A-Z][0-9A-Z_]+' + max_statements: 50 + _help_max_conditionals_custom_parser: + - !!python/unicode 'In the heuristic for C0201, how many conditionals to match' + - !!python/unicode 'within a loop in before considering the loop a parser.' + max_conditionals_custom_parser: 2 + _help_global_var_pattern: + - !!python/unicode 'regular expression pattern describing valid names for' + - !!python/unicode 'variables with global scope' + global_var_pattern: !!python/unicode '[0-9A-Z][0-9A-Z_]+' + _help_keyword_pattern: + - !!python/unicode 'regular expression pattern describing valid names for' + - !!python/unicode 'keywords used in functions or macros' + keyword_pattern: !!python/unicode '[0-9A-Z_]+' + max_arguments: 5 + _help_private_var_pattern: + - !!python/unicode 'regular expression pattern describing valid names for' + - !!python/unicode 'privatedirectory variables' + private_var_pattern: !!python/unicode '_[0-9a-z_]+' + max_localvars: 15 + max_branches: 12 + _help_local_var_pattern: + - !!python/unicode 'regular expression pattern describing valid names for' + - !!python/unicode 'variables with local scope' + local_var_pattern: !!python/unicode '[0-9a-z_]+' + _help_max_statement_spacing: + - !!python/unicode 'Require no more than this many newlines between statements' + max_statement_spacing: 1 + _help_internal_var_pattern: + - !!python/unicode 'regular expression pattern describing valid names for' + - !!python/unicode 'variables with global scope (but internal semantic)' + internal_var_pattern: !!python/unicode '_[0-9A-Z][0-9A-Z_]+' + max_returns: 6 +_help_misc: !!python/unicode 'Miscellaneous configurations options.' +misc: + _help_per_command: + - !!python/unicode 'A dictionary containing any per-command configuration' + - !!python/unicode 'overrides. Currently only `command_case` is supported.' + per_command: {} +_help_parse: !!python/unicode 'Options affecting listfile parsing' +parse: + _help_additional_commands: + - !!python/unicode 'Specify structure for custom cmake functions' + additional_commands: + !!python/unicode 'foo': + !!python/unicode 'flags': + - !!python/unicode 'BAR' + - !!python/unicode 'BAZ' + !!python/unicode 'kwargs': + !!python/unicode 'HEADERS': !!python/unicode '*' + !!python/unicode 'DEPENDS': !!python/unicode '*' + !!python/unicode 'SOURCES': !!python/unicode '*' +_help_encode: !!python/unicode 'Options effecting file encoding' diff --git a/ext/libpqxx-7.7.3/.github/workflows/stale.yml b/ext/libpqxx-7.7.3/.github/workflows/stale.yml new file mode 100644 index 000000000..0983a3e54 --- /dev/null +++ b/ext/libpqxx-7.7.3/.github/workflows/stale.yml @@ -0,0 +1,19 @@ +name: Mark stale issues and pull requests + +on: + schedule: + - cron: "30 1 * * *" + +jobs: + stale: + + runs-on: ubuntu-latest + + steps: + - uses: actions/stale@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'There has been no activity on this ticket. Consider closing it.' + stale-pr-message: 'There has been no activity on this pull request. Complete it or drop it.' + stale-issue-label: 'no-issue-activity' + stale-pr-label: 'no-pr-activity' diff --git a/ext/libpqxx-7.7.3/.gitignore b/ext/libpqxx-7.7.3/.gitignore new file mode 100644 index 000000000..d798c9dca --- /dev/null +++ b/ext/libpqxx-7.7.3/.gitignore @@ -0,0 +1,49 @@ +autom4te.cache +build-*.out +ChangeLog +CMakeFiles/CMakeTmp +confdefs.h +config.log +config.status +conftest +conftest.cpp +conftest.err +doc/_build +doc/Doxyfile +doc/html/Reference/*.css +doc/html/Reference/*.html +doc/html/Reference/*.js +doc/html/Reference/*.png +doc/html/Reference/*.map +doc/html/Reference/*.md5 +doc/reference-stamp +include/pqxx/config-*-*.h +include/pqxx/config.h +include/pqxx/stamp-h1 +libpqxx.pc +libpqxx-*.tar.gz +libtool +pqxx-config +pqxxlo.txt +test/pqxxlo.txt +tools/pqxxthreadsafety +tools/rmlo +README +win32/common +**/Makefile +**/*.la +**/*.lo +**/*.o +**/*.out +**/.*.swp +**/.swp +**/*.tmp +**/.deps +**/.libs +**/*~ +**/lint.log +**/lint.trs +**/runner +**/runner.log +**/runner.trs +**/test-suite.log diff --git a/ext/libpqxx-7.7.3/.lgtm.yml b/ext/libpqxx-7.7.3/.lgtm.yml new file mode 100644 index 000000000..d53664eb4 --- /dev/null +++ b/ext/libpqxx-7.7.3/.lgtm.yml @@ -0,0 +1,9 @@ +# Config file for lgtm.com static analysis. + +path_classifiers: + test: + - test + generated: + - aclocal.m4 + - configure + - ltmain.sh diff --git a/ext/libpqxx-7.7.3/.lift/ignoreFiles b/ext/libpqxx-7.7.3/.lift/ignoreFiles new file mode 100644 index 000000000..8c6c7a103 --- /dev/null +++ b/ext/libpqxx-7.7.3/.lift/ignoreFiles @@ -0,0 +1,3 @@ +# Make Sonatype Lift ignore these generated files. +configure +config/* diff --git a/ext/libpqxx-7.7.3/AUTHORS b/ext/libpqxx-7.7.3/AUTHORS new file mode 100644 index 000000000..6a922e950 --- /dev/null +++ b/ext/libpqxx-7.7.3/AUTHORS @@ -0,0 +1,4 @@ +Jeroen T. Vermeulen. Wrote the code. +Ray Dassen. Did most of the autoconf etc. stuff. + +Lots of others helped with various other contributions. diff --git a/ext/libpqxx-7.7.3/BUILDING-cmake.md b/ext/libpqxx-7.7.3/BUILDING-cmake.md new file mode 100644 index 000000000..48b1e7930 --- /dev/null +++ b/ext/libpqxx-7.7.3/BUILDING-cmake.md @@ -0,0 +1,272 @@ +Building using CMake +==================== + +The build requires the full PostgreSQL development package. That package must +be installed before you can build libpqxx. + +The instructions will assume that you're working from a command-line shell. +If you prefer to work from an IDE, you'll have to know how your IDE likes to +do things, and you'll want to follow the shell instructions as a guide. + +I'm not too familiar with CMake, and this build relies heavily on contributions +from users. If you see something wrong here, please file a bug and explain, in +simple words, what needs changing and why. + + +Quick start +----------- + +If you just want to get it built and installed quickly, run `cmake` from the +root of the libpqxx source tree. This configures your build. + +Then compile libpqxx by running: + +```shell + cmake --build . +``` + +To install in the default location: + +```shell + cmake --install . +``` + + +Stages +------ + +I'll explain the main build steps in more detail below, but here's a quick +rundown: +1. Configure +2. Compile +3. Test +4. Install +5. Use + +The Test step is optional. + + +Configure +--------- + +Run `cmake` to configure your build. It figures out various parameters, such +as where libpq and its headers are, which C++ features your compiler supports, +and which options your compiler needs. CMake generates configuration for your +build tool: `Makefile`s for `make`, or a Solution (".sln") file for MSVC's +`msbuild`, and so on. + +At this stage you can also override those options yourself. e.g. to instruct +the compiler to look for libpq in a non-standard place, or to use a different +compiler, or pass different compiler flags. Don't try to specify those while +doing the actual compile; set them once when running `cmake`. + +Let's say `$BUILD` is the directory where you want to build libpqxx, and +`$SRC` is where its source code is. So for example, the readme file will be at +`$SRC/README.md`. + +In the simplest case, you just do: + +```shell + cd $BUILD + cmake $SRC +``` + +Add CMake options as needed. There's more about the options below. I'll also +explain the two directories. + + +### Cheat sheet + +Here are some popular `cmake` options for libpqxx: +* `-DSKIP_BUILD_TEST=on` skips compiling libpqxx's tests. +* `-DBUILD_SHARED_LIBS=on` to build a shared library. +* `-DBUILD_SHARED_LIBS=off` to build a static library. +* `-DBUILD_DOC=on` to build documentation. +* `-DINSTALL_TEST=on` to install test executor binary. + +On Windows, I recommend building libpqxx as a shared library and bundling it +with your application. On other platforms I would prefer a static library. + +Building the documentation requires some tools to be installed. It takes at +least Doxygen, but there's no list of requirements. The way to get this set up +is to just try it and see what it's missing. + + +### Generators + +You can also choose your own build tool by telling CMake to use a particular +"generator." For example, here's how to force use of `make`: + +```shell + cmake -G 'Unix Makefiles' +``` + +Or if you prefer to build using `ninja` instead: + +```shell + cmake -G Ninja +``` + +There are many more options. You may prefer yet a different build tool. + + +### Finding libpq + +The CMake step tries to figure out where libpq is, using Cmake's `find_package` +function. If that doesn't work, or if you want a libpq in a different location +from the one it finds, there are two ways to override it. + +The first is to set the individual include and link paths. + +To make the build look for the libpq headers in some directory `$DIR`, add +these options: +* `-DPostgreSQL_TYPE_INCLUDE_DIR=$DIR` +* `-DPostgreSQL_INCLUDE_DIR=$DIR` + +To make the build look for the libpq library binary in a directory `$DIR`, add +this option: +* `-DPostgreSQL_LIBRARY_DIR=$DIR` + +The second, easier way requires CMake 3.12 or better. Here, you specify a path +to a full PostgreSQL build tree. You do this (again for some directory `$DIR`) +by simply passing this cmake option: `-DPostgreSQL_ROOT=$DIR` + + +### Source and Build trees + +Where should you run `cmake`? + +Two directories matter when building libpqxx: the _source tree_ (where the +libpqxx source code is) and the _build tree_ (where you want your build +artefacts). Here I will call them `$SRC` and `$BUILD`, but you can call them +anything you like. + +They can be one and the same, if you like. It's convenient, but less clean, as +source code and build artefacts will exist in the same directory tree. If +you're going to delete the source tree after installing, of course it's fine to +make a mess in there. + + +Compile +------- + +To compile, run: + +```shell + cmake --build $BUILD +``` + +(Where `$BUILD` is again the directory where you wish to do the build.) + +This command will invoke your build tool. Other ways to do the same thing +would be... +* With Unix Makefiles: `make` +* With Ninja: `ninja` +* With Visual Studio: `msbuild libpqxx.sln` +* etc. + +Depending on your build tool, you may want to speed this up by adding an option +like `-j 16`, where `16` is an example of how many processes you might want to +run in parallel. The optimal number depends on your available CPUs and memory. +If you have enough memory, usually the number of CPUs will be a good starting +point for the right number. Don't use this option with Ninja though. It +figures things out for itself. + + +Test +---- + +Of course libpqxx comes with a test suite, to check that the library is +functioning correctly. + +You can run it, but there's one caveat: you need to give it a database where it +can log in, without a password or any other parameters, and try out various +things. + +And when I say you need to "give" it a database, I really mean "give." The +test suite will create and drop tables. Those will all have names prefixed +with "pqxx", so it's probably safe to use a database you already had, but if +any of the items in your database happen to have names starting with `pqxx`, +tough luck. They're fair game. + +Enter this in your shell to build and run the tests: + +```shell + test/runner +``` + + +### Configuring the test database + +But what if you do need a password to log into your test database? Or, what if +it's running on a different system so you need to pass that machine's address? +What if it's not running on the default port? + +You can set these parameters for the test suite, or for any other libpq-based +application, using the following environment variables. (They only set default +values, so they won't override parameters that the application sets in some +other way.) +* `PGHOST` — the IP address where we can contact the database's socket. Or + for a Unix domain socket, its absolute path on the filesystem. +* `PGPORT` — TCP port number on which we can connect to the database. +* `PGDATABASE` — the name of the database to which you wish to connect. +* `PGUSER` — user name under which you wish to log in on the database. +* `PGPASSWORD` — user name's password for accessing the database. + +See the full list at https://www.postgresql.org/docs/current/libpq-envars.html + +**Be careful with passwords,** by the way. Depending on your operating system +and configuration, an attacker with access to your machine could try to read +your password if you set it on the command line: +* Your shell may keep a log of the commands you have entered. +* Environment variables may be visible to other users on the system. + +If at all possible, rely on postgres "peer authentication." Once set up, it is +both more secure and more convenient than passwords. + + +Install +------- + +Once you've built libpqxx, CMake can also help you install the library and +headers on your system. The default installation location will vary from one +operating system to another, but you can set it explicitly. + +Let's say you've got your finished build in `$BUILD`, and you want to install +it to your system's default install location. The command for this is: + +```shell + cmake --install $BUILD +``` + +But you may want to install to some other location. Let's call it `$DEST`. +`$DEST` might be something like `/usr/local` on a Unix-like system, or +something like `D:\Software` on a Windows system. + +To install to `$DEST`, run: + +```shell + cmake --install $BUILD --prefix $DEST +``` + + +Use +--- + +Other projects can include libpqxx in their CMake builds. + +`@abrownsword` uses this configuration: + +```cmake + set(libpqxxdir "libpqxx-${LIBVERSION}") # LIBVERSION set above + set(SKIP_BUILD_TEST on) + set(BUILD_SHARED_LIBS OFF) + + # Used this instead of FindLibrary. + # Setting PostgresSQL_INCLUDE_DIRS externally. + set(PostgreSQL_FOUND true) + set(PostgresSQL_INCLUDE_DIR ${PostgresSQL_INCLUDE_DIRS}) + set(PostgresSQL_TYPE_INCLUDE_DIR ${PostgresSQL_INCLUDE_DIRS}) + + add_subdirectory(${libpqxxdir}) +``` diff --git a/ext/libpqxx-7.7.3/BUILDING-configure.md b/ext/libpqxx-7.7.3/BUILDING-configure.md new file mode 100644 index 000000000..7c63f5b4c --- /dev/null +++ b/ext/libpqxx-7.7.3/BUILDING-configure.md @@ -0,0 +1,275 @@ +Building using `configure` +========================== + +The build requires `libpq`, the C client library for PostgreSQL. This library +must be installed before you can build libpqxx. You'll need the headers as +well as the library binary. + +The instructions will assume that you're working from a command-line shell. +If you prefer to work from an IDE, you'll have to know how your IDE likes to +do things, and you'll want to follow the shell instructions as a guide. + + +Quick start +----------- + +If you just want to get it built and installed quickly, try: + +```shell + ./configure + make + sudo make install +``` + +Want more detail? Read on. + + +Stages +------ + +I'll explain the main build steps in more detail below, but here's a quick +overview: +1. Configure +2. Compile +3. Test +4. Install + +The Test step is optional. + + +Configure +--------- + +The `configure` script configures your build. It figures out various +parameters, such as where libpq and its headers are, which C++ features your +compiler supports, and which options your compiler needs. It generates +Makefiles, which in turn tell the `make` utility how to perform tasks such as +compiling libpqxx, running tests, cleaning up after itself, and installing +libpqxx. + +The `configure` step is also where you can set these options, e.g. to instruct +the compiler to look for libpq in a non-standard place, or to use a different +compiler, or pass different compiler flags. Don't try to specify those while +doing the actual compile; set them once when running `configure`. + +Let's say `$BUILD` is the directory where you want to build libpqxx, and +`$SRC` is where its source code is. So for example, the readme file will be at +`$SRC/README.md`. + +In the simplest case, you just do: + +```shell + cd $BUILD + $SRC/configure +``` + +Add `configure` options as needed. There's more about the options below, or in +the output of `configure --help`. I'll also explain the two directories. + + +### Cheat sheet + +Here are some popular `configure` options: +* `--disable-documentation` skips building of the documentation. +* `CXXFLAGS=-O0` disables optimisation. Slower code, but faster build. +* `CXXFLAGS=-O3` asks for _more_ optimisation. Faster code, slower build. +* `CXX=clang++` compiles with `clang++` as the compiler. +* `--enable-maintainer-mode` makes the compiler more pedantic about the code. +* `--enable-audit` enables expensive run-time checks for debugging. +* `--with-postgres-lib=$DIR` looks for libpq in `$DIR`. +* `--with-postgres-include=$DIR` looks for the libpq headers in `$DIR`. +* `--prefix=$PATH` prepares to install libpqxx in `$PATH`. +* `--enable-shared` enables compilation of libpqxx as a shared library. +* `--disable-shared` disbles compilation of libpqxx as a shared library. +* `--enable-static` enables compilation of libpqxx as a static library. +* `--disable-static` disables compilation of libpqxx as a static library. +* `--help` shows you a lot more of the options. + +So for example, to get a very quick build but produce very inefficient code: + +```shell + ./configure --disable-documentation CXXFLAGS=-O0 +``` + + +Or if you want to pull out all the stops to find problems in the code: + +```shell + ./configure --enable-maintainer-mode --enable-audit CXXFLAGS=-O3 +``` + +(Requesting `-O3` optimisation will make some compilers perform extra analysis +which may, as a side effect, cause them to notice and warn about certain kinds +of mistakes in the code, such as occasionally-unused variables.) + + +### Finding libpq + +One of `configure`'s most important jobs in the libpqxx build is to find the +headers and library for libpq. It has three ways of finding those: +1. Asking a popular tool called `pkg-config`, if installed. +2. Asking postgres' deprecated `pg_config` tool, if installed. +3. Through explicit command-line options to `configure`. + +The explicit command-line options are `--with-postgres-lib` (for the libpq +library binary) and `--with-postgres-include` (for the libpq headers). + +If you want to use a version of libpq that's not installed in a standard +location, e.g. if you're cross-compiling to produce a binary for a different +CPU architecture than your native system's, use the explicit options. + + +### Where does the `configure` script come from? + +I didn't write the `configure` script. It was generated by GNU `autoconf` and +related GNU tools. There's a script to re-generate it, called `autogen.sh`. + +The contents of `configure` are based on a higher-level script called +`configure.ac`. This is where I script checks for specific features in libpq +or the compiler. The `configure` script adds a lot of built-in items that I +don't need to worry about, such as figuring out exactly how your build tools +work. + +Don't try to debug `configure` yourself if you can help it. It's very hard to +read, partly because it's automatically generated, but also because it is +engineered to work with an extremely broad range of shells, compilers, tools, +and operating systems. If you're going to do a "deep dive," try looking at +`configure.ac` instead. + + +### Source and Build trees + +Where should you run `configure`? + +Two directories matter when building libpqxx: the _source tree_ (where the +libpqxx source code is) and the _build tree_ (where you want your build +artefacts). Here I will call them `$SRC` and `$BUILD`, but you can call them +anything you like. + +They can be one and the same, if you like. It's convenient, but less clean, as +source code and build artefacts will exist in the same directory tree. If +you're going to delete the source tree after installing, of course it's fine to +make a mess in there. + + +Compile +------- + +To start the compile, run the `make` tool. It will go through all the steps to +produce a libpqxx library binary. + +Beware though, it only runs _one_ compiler process at a time. That could take +a while. Use the `-j` option to make it run concurrent processes, e.g.: + +```shell + make -j8 +``` + +Very roughly speaking, it's probably fastest if you run one process per CPU +core in your system. If you have the `nproc` utility installed: + +```shell + make -j$(nproc) +``` + +If you want a very fast build and don't mind missing out on efficient code or +documentation, tweak the Configure step above by adding `configure` options +like `CXXFLAGS=-O0` and `--disable-documentation`. + + +Test +---- + +Of course libpqxx comes with a test suite, to check that the library is +functioning correctly. + +You can run it, but there's one caveat: you need to give it a database where it +can log in, without a password or any other parameters, and try out various +things. + +And when I say you need to "give" it a database, I really mean "give." The +test suite will create and drop tables. Those will all have names prefixed +with "pqxx", so it's probably safe to use a database you already had, but if +any of the items in your database happen to have names starting with `pqxx`, +tough luck. They're fair game. + +Enter this in your shell to build and run the tests: + +```shell + make check +``` + +As with compiling, use the `-j` option to make better use of your CPUs. For +example: + +```shell + make check -j$(nproc) +``` + + +### Configuring the test database + +But what if you do need a password to log into your test database? Or, what if +it's running on a different system so you need to pass that machine's address? +What if it's not running on the default port? + +You can set these parameters for the test suite, or for any other libpq-based +application, using the following environment variables. (They only set default +values, so they won't override parameters that the application sets in some +other way.) +* `PGHOST` — the IP address where we can contact the database's socket. Or + for a Unix domain socket, its absolute path on the filesystem. +* `PGPORT` — +* `PGDATABASE` — the name of the database to which you wish to connect. +* `PGUSER` — user name under which you wish to log in on the database. +* `PGPASSWORD` — user name's password for accessing the database. + +See the full list at https://www.postgresql.org/docs/current/libpq-envars.html + +**Be careful with passwords,** by the way. Depending on your operating system +and configuration, an attacker with access to your machine could try to read +your password if you set it on the command line: +* Your shell may keep a log of the commands you have entered. +* Environment variables may be visible to other users on the system. + +If at all possible, rely on postgres "peer authentication." Once set up, it is +both more secure and more convenient than passwords. + + +Install +------- + +Installing libpqxx will install the library and headers in a location chosen at +the time you can the `configure` script. On some systems it defaults to the +`/usr/local/` tree, but it may be different in your environment. Or, use the +`configure` script's `--prefix` option to set an install location. + +(If you want to see exactly what happens, you can run any `make` command line +with the `-n` option, which means: don't actually do this, but print all the +commands you would execute if you did. It's a lot of output though.) + +To install, ensure that you have sufficient privileges to write the files to +their install locations, and run: + +```shell + make install +``` + +Save your build tree somewhere, so that you will be able to undo installation +in the future: + +```shell + make uninstall +``` + +When using the library, make sure the libpqxx headers are in your compiler's +include path. (You will no longer need the libpq headers at that time.) + +Also, building an application which uses libpqxx, make sure the libpqxx library +binary is in your compiler's library search path. And if the library binary is +a shared library, you'll also need it in your loader's search path when running +your application. + +This last part goes for libpq as well: when using libpq, make sure you have +the libpq library binary in your compiler's library search path, and if it's a +shared library, also have it in your loader's search path when running. diff --git a/ext/libpqxx-7.7.3/CMakeLists.txt b/ext/libpqxx-7.7.3/CMakeLists.txt new file mode 100644 index 000000000..55b3c4d44 --- /dev/null +++ b/ext/libpqxx-7.7.3/CMakeLists.txt @@ -0,0 +1,66 @@ +cmake_minimum_required(VERSION 3.8) + +file(READ VERSION VER_FILE_CONTENT) +string(STRIP ${VER_FILE_CONTENT} VER_FILE_CONTENT) + +project( + libpqxx + VERSION ${VER_FILE_CONTENT} + LANGUAGES CXX +) + +if(NOT "${CMAKE_CXX_STANDARD}") + set(CMAKE_CXX_STANDARD 17) +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + +option(BUILD_DOC "Build documentation" OFF) + +if(NOT SKIP_BUILD_TEST) + option(BUILD_TEST "Build all test cases" ON) +endif() + +include(GNUInstallDirs) +include(CMakePackageConfigHelpers) +include(config) + +add_subdirectory(src) +add_subdirectory(include) +if(BUILD_DOC) + add_subdirectory(doc) +endif() +if(BUILD_TEST) + add_subdirectory(test) +endif() + +# installation +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/libpqxx-config-version.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion +) +install(FILES cmake/libpqxx-config.cmake + "${CMAKE_CURRENT_BINARY_DIR}/libpqxx-config-version.cmake" + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libpqxx +) +install( + EXPORT libpqxx-targets + NAMESPACE libpqxx:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libpqxx +) +# Build tree export +export( + EXPORT libpqxx-targets + NAMESPACE libpqxx:: + FILE ${CMAKE_CURRENT_BINARY_DIR}/libpqxx-targets.cmake +) +configure_file( + cmake/libpqxx-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/libpqxx-config.cmake + COPYONLY +) +# Package generation +set(CPACK_GENERATOR TGZ) +set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) +include(CPack) diff --git a/ext/libpqxx-7.7.3/COPYING b/ext/libpqxx-7.7.3/COPYING new file mode 100644 index 000000000..8a566aabe --- /dev/null +++ b/ext/libpqxx-7.7.3/COPYING @@ -0,0 +1,27 @@ +Copyright (c) 2000-2022 Jeroen T. Vermeulen. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* Neither the name of the author, nor the names of other contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/ext/libpqxx-7.7.3/INSTALL b/ext/libpqxx-7.7.3/INSTALL new file mode 100644 index 000000000..1c03a1c3b --- /dev/null +++ b/ext/libpqxx-7.7.3/INSTALL @@ -0,0 +1,2 @@ +For installation instructions, see `BUILDING-configure.md` (for the `configure` +build) and `BUILDING-cmake.md` (for the CMake build). diff --git a/ext/libpqxx-7.7.3/Makefile.am b/ext/libpqxx-7.7.3/Makefile.am new file mode 100644 index 000000000..cd93a57ef --- /dev/null +++ b/ext/libpqxx-7.7.3/Makefile.am @@ -0,0 +1,23 @@ +SUBDIRS = include src test tools config doc +EXTRA_DIST = autogen.sh configitems README.md VERSION requirements.json + +MAINTAINERCLEANFILES = \ + Makefile.in aclocal.m4 config.h.in config.log configure stamp-h.in + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libpqxx.pc + +TESTS = tools/lint + + +# Generate ChangeLog from git history. It goes all the way back through +# the project's git, bzr, svn, and cvs days. +dist-hook: ChangeLog + +ChangeLog: configure.ac + git log --stat --name-only --date=short --abbrev-commit >$@ + + +# We use README.md, but automake expects plain README. +README: README.md + ln -s $< $@ diff --git a/ext/libpqxx-7.7.3/Makefile.in b/ext/libpqxx-7.7.3/Makefile.in new file mode 100644 index 000000000..f6798aa75 --- /dev/null +++ b/ext/libpqxx-7.7.3/Makefile.in @@ -0,0 +1,1253 @@ +# Makefile.in generated by automake 1.16.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/pqxx/config.h +CONFIG_CLEAN_FILES = libpqxx.pc compile_flags +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgconfigdir)" +DATA = $(pkgconfig_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope check recheck distdir distdir-am dist dist-all \ + distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' +RECHECK_LOGS = $(TEST_LOGS) +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/compile_flags.in \ + $(srcdir)/libpqxx.pc.in $(top_srcdir)/config/compile \ + $(top_srcdir)/config/config.guess \ + $(top_srcdir)/config/config.sub \ + $(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \ + $(top_srcdir)/config/missing \ + $(top_srcdir)/config/mkinstalldirs \ + $(top_srcdir)/config/test-driver AUTHORS COPYING ChangeLog \ + INSTALL NEWS README README.md +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +# Exists only to be overridden by the user if desired. +AM_DISTCHECK_DVI_TARGET = dvi +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_DOT = @HAVE_DOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PG_CONFIG = @PG_CONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +POSTGRES_INCLUDE = @POSTGRES_INCLUDE@ +PQXXVERSION = @PQXXVERSION@ +PQXX_ABI = @PQXX_ABI@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_postgres_lib = @with_postgres_lib@ +SUBDIRS = include src test tools config doc +EXTRA_DIST = autogen.sh configitems README.md VERSION requirements.json +MAINTAINERCLEANFILES = \ + Makefile.in aclocal.m4 config.h.in config.log configure stamp-h.in + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libpqxx.pc +TESTS = tools/lint +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .log .test .test$(EXEEXT) .trs +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): +libpqxx.pc: $(top_builddir)/config.status $(srcdir)/libpqxx.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +compile_flags: $(top_builddir)/config.status $(srcdir)/compile_flags.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +tools/lint.log: tools/lint + @p='tools/lint'; \ + b='tools/lint'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-recursive +all-am: Makefile $(DATA) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pkgconfigDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkgconfigDATA + +.MAKE: $(am__recursive_targets) check-am install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-TESTS check-am clean clean-cscope \ + clean-generic clean-libtool cscope cscopelist-am ctags \ + ctags-am dist dist-all dist-bzip2 dist-gzip dist-hook \ + dist-lzip dist-shar dist-tarZ dist-xz dist-zip dist-zstd \ + distcheck distclean distclean-generic distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am recheck tags tags-am uninstall uninstall-am \ + uninstall-pkgconfigDATA + +.PRECIOUS: Makefile + + +# Generate ChangeLog from git history. It goes all the way back through +# the project's git, bzr, svn, and cvs days. +dist-hook: ChangeLog + +ChangeLog: configure.ac + git log --stat --name-only --date=short --abbrev-commit >$@ + +# We use README.md, but automake expects plain README. +README: README.md + ln -s $< $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ext/libpqxx-7.7.3/NEWS b/ext/libpqxx-7.7.3/NEWS new file mode 100644 index 000000000..102716c2e --- /dev/null +++ b/ext/libpqxx-7.7.3/NEWS @@ -0,0 +1,1040 @@ +7.7.3 + - Fix up more damage done by auto-formatting. + - New `result::for_each()`: simple iteration and conversion of rows. (#528) + - Add some missing headers in ``. (#551) + - More strictness in `header-pre.hxx`/`header-post.hxx` checking. + - Disallow nesting of `ignore-deprecated` blocks. + - Deprecate `exec` functions' `desc` parameter. + - Fix `placeholders` documentation. (#557) + - Strip `const` and references from `value_type`. (#558) + - Get tests running on appveyor. (#560) + - Fix broken nonblocking connection on Windows. (#560) +7.7.2 + - Fix up damage done by auto-formatting. +7.7.1 + - When you build libpqxx, configure the compiler's C++ version yourself! + - Finally fix a long-standing silly warning in autogen. + - Fix `digit_to_number` not being found on some comilers. (#518, #519) + - In audit mode, define `_FORTIFY_SOURCE` to enable some extra checks. + - Make more functions `constexpr`. Nothing particularly useful though. + - Make more functions `noexcept`. + - Move constructor & assignment for `result`. + - Support LGTM.com and Facebook "infer" static analysis. + - Deprecated `set_variable`/`get_variable` on `transaction_base`. + - (Design unearthed warts in SQL variables, which were then fixed.) + - Set/get session variables on `connection`: `set_session_var`/`get_var`. + - Set/get local variables: execute SQL statements. + - When using `select()`, include `` if available. +7.7.0 + - Fix `stream_to` for differing table/client encodings. (#473) + - Use `[[likely]]` & `[[unlikely]]` only in C++20, to silence warnings. + - Fix clang "not a const expression" error in Windows. (#472) + - Fix warnings about `[[likely]]` in `if constexpr`. (#475) + - Clearer error for ambiguous string conversion of `char` type. (#481) + - Pseudo-statement in `prepare()` error was for the wrong statement. (#488) + - New class, `connecting` for nonblocking connection to the database. (#487) + - New class, `range` for SQL range types. (#490) + - Replace `std::isdigit` with a safer alternative. + - Support string conversions for `std::chrono::year_month_day`. (#492) + - Helper for implementing string traits: `generic_to_buf`. + - Support `result::at(row_num, col_num)`. + - Support `result[row_num, col_num]` if the compiler allows it. + - Work around broken `std::filesystem::path` in MinGW. (#498) + - Fix leak when getting client encoding fails. (#500) + - Use `std::cmp_greater` etc. when available. Saves some ugly casts. + - Move `result_iterator.hxx` into `pqxx/include/internal/`. + - Move `compiler-public.hxx` into `pqxx/include/internal/`. + - Add script for updating copyright strings. + - Make `tools/lint` figure out source directory by itself. + - Pass the actual C++ version to `tools/lint`, not the baseline one. + - Re-enable pyflakes testing in `tools/lint`. + - Make more functions `[[nodiscard]]`. + - Qualified some member functions as lvalue or rvalue. + - Don't run clang-tidy by default. Compatibility issues with gcc options. + - Describe version requirements in a JSON file, `requirements.json`. + - Doxygen documentation now uses the (Doxygen-extended) Markdown format. + - Build docs in `doc/html/`, no longer in `doc/html/Reference/`. + - Disable some `std::filesystem` features on Windows. + - Shut up stupid Visual Studio warnings. + - On gcc, mark rarely-used functions as "cold," to be optimised for size. + - Glyph scanning for GB18030 encoding was utterly broken. (#517) +7.6.0 + - Removed bad string conversion to `std::basic_string_view`. (#463) + - Add C++20 concepts: `binary`, `char_string`, `char_strings`. + - Generalise binary strings to any contiguous range of `std::byte`. + - Mark `zview` as a view and as a borrowed range. + - Save a copy step on string fields in `stream_to`. + - New helper: `pqxx::value_type`. + - New helper: `pqxx::binary_cast`. (#450) + - Some escaping functions now have "into my buffer" variants. + - More generic escaping functions, supporting more types of binary. + - In C++20, accept generic columns list for `stream_to`. (#447) + - Renamed `` to ``. + - Deprecated `dynamic_params` in favour of `params`. + - `pqxx::params::append_multi()` now calls `reserve()` if possible. + - `pqxx::params::size()` is now `noexcept` (but sadly, `ssize()` is not). + - Helper for generating parameter placeholders `$1`, `$2`, etc. (#443) + - Now requires support for C++14 `[[deprecated]]` attribute. + - Deprecated `unesc_raw()` with `unesc_bin()` variants. + - Once `unesc_raw()` is gone, we'll support only the hex escape format. + - Work around broken `thread_local` in MinGW gcc < 11.1. + - `pqxx::blob` now supports `std::filesystem::path`. + - Fixed check against header/lib version mismatch: `check_pqxx_version_7_6` + - Deprecated result slicing. Expect `row::slice()` to disappear. + - More complete documentation, of cursors in particular. +7.5.2 + - **Actual serious bug.** `blob::read(std::vector<...>)` was broken. +7.5.1 + - Fixed some Visual Studio warnings. + - Missed a bit in working around MinGW's broken ``. + - Deprecated more obsolete representations of binary data. Use `std::byte`. + - New script `tools/deprecations` lists files that use deprecated code. + - Added automake-generated `config/compile` to revision control. +7.5.0 + - Now requires `std::variant` support! No longer works with gcc7. + - When implementing a string conversion, consider specialising `param_format`. + - Stop "aborting" nontransaction on closing. (#419) + - Silence an overzealous Visual C++ warning. (#418) + - Starting support for C++20 `std::span`. + - New `blob::read()` using `std::span`. (#429) + - New `params` class lets you build parameter lists incrementally. (#387) + - Pass `std::vector` params in binary format. + - Dropped legacy tests 31 and 49 to work around clang C++20 bug. + - Fixed `stream_to` test failure in non-English locales. (#440) + - Clarify `transaction_base::stream` documentation. (#423) + - Avoid `` on MinGW; it's broken there. (#336, #398, #424, #441) +7.4.1 + - Missing includes; broke macOS clang build. (#416) +7.4.0 + - Work around Visual Studio 2017 bug with `[[deprecated]]`. (#405, #406) + - Work around eternal Windows bug with `max` macro yet again. (#101) + - Prepare for C++20 `std::ssize()`. + - Dropped test12, which didn't add much and tried to read null strings. + - Support string conversion for `std::monostate`. (#409) + - Consistent "named constructors" for `stream_to` and `stream_from`. + - New `table_path` type. + - New `connection` methods `quote_table` and `quote_columns`. + - Lots of deprecated stream constructors. + - `pqxx::row::swap()` now finally has the `deprecated` attribute. + - Finally deprecated a bunch of `field`, `row`, and `result` constructors. + - Exposed `transaction_focus` marker class. +7.3.1 + - New, simpler API for large objects: `blob` ("binary large object"). + - `largeobject` and friends are now deprecated. + - Fix visibility issue on gcc/clang, especially on macOS. (#395) + - Use "pure" & "visibility" attributes if they work, regardless of compiler. + - More deprecated items now have the `[[deprecated]]` attribute. + - Document the concept of transaction focus. + - Error messages more often report query description, if given. + - Suppress spurious deprecation messages on Visual Studio. (#402) + - Correct error when prepared/param statement clashes with tx focus. (#401) + - `from_stream` with `from_query` now has a convenient factory function. + - Removed some obsolete scripts from the `tools/` directory. +7.3.0 + - `stream_to` now quotes and escapes its table name. + - Removed `transaction_base::classname()`. Did anyone ever use it? + - Internal reorg of the `transaction` and `transactionfocus` hierarchies. + - Removed the only case of virtual inheritance, related to `namedclass`. + - Internal `concat()` for faster, simpler string concatentation. + - Fix compile omission in string conversions for `nullptr_t`. + - `pqxx::size_buffer()` can now size multiple values at once. + - `multi_to_string()` to convert multiple values into one `std::string`. + - Implicit `zview` constructor from `char const *`. (#389) + - Many `std::string&` parameters are now `zview` or `std::string_view`. + - Now checking statement parameter lengths for overflow. + - `#include ` in connection.cxx. (#394) +7.2.1 + - Fix infinite loop in converting `char *` to string. (#377) + - Deprecated `namedclass`. + - Convert an entire row using `row::as()`. + - Internal rework of `field::to()` and `field::as()` functions. + - Some more warning options in maintainer mode. + - Removed the old, DocBook-based tutorial. + - Fixed wrong `query` and SQLSTATE params to some exceptions. (#378) +7.2.0 + - You can now implicitly convert a `const std::string &` to `zview`. + - Replaced some overloads for C strings and C++ strings with `zview`. + - Deprecating `binarystring`. Use `std::basic_string` instead! + - Array parser did not recognise escaping in unquoted values. + - gcc10 test build fix: a result iterator is not the same thing as a `row`. + - Doc fix: field size does _not_ include terminating zero. (#356) + - Fix error message in `demangle_type_name`: printed result, not raw name. + - Fix compile warning in `demangle_type_name` on GNU systems. + - Document that string conversions assume non-null values. + - Start playing with C++20 _concepts._ + - Sketch out concepts-based `PQconnectdbParams` support. (#343) + - Add missing link to "datatypes" documentation. (#346) + - Supports `to_string`, `stream_to`, etc. for `binarystring`. (#312) + - Fixed infinite recursion when using `std::optional` in `stream_to`. (#364) + - Home-rolled hex-escaping. Saves an allocation. + - Catch floating-point negative overflow in `check_cast`, not underflow. + - Bit more work on CMake build doc. (#318) + - Typo in `datatypes.md`: `nullness`, not `nullness_traits`. (#353) + - Fixed test names map in `tests/runner.cxx`. (#354) + - Integral `from_string` now accept leading whitespace, as in composite types. + - Experimental support basics for composite types. (#355) + - Use `stream_from` without knowing the number of fields. (#357) + - Global `size_buffer` function. + - `quote()` now works for always-null types without conversions defined. + - `std::nullopt` now converts to an SQL null. + - Skip quoting and escaping array/composite fields of "safe" types. + - New type trait: `is_unquoted_safe`. + - Forbid invalid specialisations of `query_value`. + - Fixed `mktemp` invocation that broke on FreeBSD. + - Avoid unneeded encode/decode step on more binary data. + - If `__cxa_demangle` fails, fall back on raw type name. (#361) +7.1.2 + - Document build in `BUILDING-configure.md` / `BUILDING-cmake.md`. + - Work around silly clang warning in `test_errorhandler.cxx`. + - Fix install error with some internal headers. (#322) + - Fix "No object selected" error message in large objects. (#324) + - If error has no SQLSTATE, throw `broken_connection`. (#280) + - Fix argument order in `encrypt_password`. (#333, #334) + - Fix underestimate of buffer size for `to_string` for floats. (#328) +7.1.1 + - Compile fix for Visual Studio. + - Warning fix for clang. + - Also install `transaction_focus.hxx`. (#320) +7.1.0 + - Query tuples straight into `std::tuple` using `transaction::stream()`! + - And, `stream_from` now supports more or less arbitrary queries. + - Instead of a tuple of fields, you can pass `stream_to` a container as well. + - `string_traits::size_buffer()` must now be `noexcept`. + - New `nullness` member: `always_null`. + - There is now `to_buf` support for string literals. + - Streaming data is now more efficient. + - The table name in `stream_from` is now escaped. + - You can now "convert" strings to `std::string_view`. Mind your lifetimes! + - A `std::variant` will now convert to string, if its member types do. + - If a `stream_from` row fails to convert, you can no longer retry it. + - `from_string(field const &)` now handles null values properly. + - Obsolete Windows build docs are gone. + - Added `row::to(std::tuple<...>)`. + - Unified the test suites. We no longer need `test/unit/unit_runner`. + - New helper: `strip_t<...>` to remove a type's constness and reference. + - Replace custom templating with CMake glob in `src/CMakeLists.txt`. + - Replace custom templating with CMake glob in `doc/CMakeLists.txt`. + - Replace custom templating with CMake glob in `test/unit/CMakeLists.txt`. +7.0.8 + - Inline `type_name` in `PQXX_DECLARE_ENUM_CONVERSION`. +7.0.7 + - Fix broken `--with-postgres-lib` option in `configure` script (#311) + - Should now build even if neither `pkg-config` nor `pg_config` is available. + - CMake accepts `PostgreSQL_ROOT`, if it's a sufficiently recent version. +7.0.6 + - Prefer `pg_config` over `pkg-config` for include path (#291). + - Try to plod on if we don't know the PostgreSQL include path. + - Fix error message when starting overlapping transactions and such (#303). + - Fix potential crashes when converting invalid strings to floats (#307, #308). +7.0.5 + - Compile fix for g++ 10: include `` (#292). + - Cleaned up error-checking of PG results. (#280). + - The `esc()` methods now also take `std::string_view` (#295). +7.0.4 + - Fix possible crash in `connection::connection_string` (#290). + - Fix filtering of default values in `connection::connection_string` (#288). + - Deprecate `row::swap` and public inheritance of iterators from `row`. + - More copy/move/default constructors/assignments on result iterators. + - More copy/move/default constructors/assignments on row iterators. +7.0.3 + - Fixed misreporting of broken connection as `sql_error` (#280). + - Replaced non-ASCII test texts with escape codes (#282, #283). + - `ilostream` could truncate at `0xff` byte at buffer boundary (#284, #286). +7.0.2 + - New query function: `query_value`, queries and converts a single value. + - A `stream_from` stream can now be iterated. + - More callable types qualify as transactors, thanks to `std::invoke`. +7.0.1 + - Windows build fixes. + - Documentation for writing your own string conversions. + - `transaction_rollback` and children are now `sql_error`, not just `failure`. +7.0.0 + - Bumped minimum required C++ version to C++17. + - Everything has changed. If you're porting from older versions, be careful! + - There is now only one connection class: `connection`. + - Removed tablereader/tablewriter, replaced by stream_from/stream_to. + - Removed obsolete transactor framework, replaced by post-C++11 one. + - Removed old ways of invoking parameterised and prepared statements. + - Session variables are no longer cached. + - If you do weird stuff with setting/getting variables, it may break. + - Reading a variable written from raw SQL, procedures, etc, will now work. + - Prepared statements are now registered immediately. + - If you do weird stuff with preparing/unpreparing statements, it may break. + - Changed exceptions and errors for many error situations. + - Mishandling prepared statements will now break the connection. + - Many string references and const char pointers are now `std::string_view`. + - New `zview` class wraps `string_view` for string with terminating zero. + - The `stream_base` abstract base class is gone. + - Transactions no longer have an `isolation_tag` nested type. + - The `isolation_traits` type is gone. + - There's no more `pqxx_exception`. Complicated things too much. + - `pqxx::string_traits<>::name()` has been replaced with `pqxx::type_name`. + - `to_string()` can now handle `std::vector` (to produce an SQL array). + - All `from_string()` that took a C string now take a `std::string_view`. + - There are now separate `string_traits` and `null_traits` templates. + - Enums outside classes are now scoped enums. + - `error_verbosity` is no longer nested in connection. + - `connection::get_verbosity` is gone. + - Some enums have changed names: `accesspolicy` to `access_policy`, and so on. + - `dynamic_params` now accepts an accessor. + - Fixed "const" support in arguments to parameterised/prepared statements. + - Connection objects can now be moved. + - `connections::options()` has been replaced by `connection_string()`. + - Replaced pqxx-fulltest with `test_all.py`. + - Some `size_type` have changed to different types, to match current libpq. + - Internal overflows are more consistently caught and reported. + - Deprecated items have been removed. + - Large objects now require backend version 9.3 or better. + - Seeking inside large objects now supports 64-bit sizes. + - Visual Studio project files and sample headers are gone. Use CMake. + - MinGW Makefiles are gone. Use `configure` or CMake. + - Need PostgreSQL 10 to use robusttransaction. + - `robusttransaction` no longer uses a log table. Feel free to drop it. +6.4.4 + - Use pkg-config if pg-config is not available. + - In CMake build, prefer CMake's config headers over any found in source tree. +6.4.3 + - Updated copyright strings. + - Added missing "stream" headers to autotools-based install. + - Added stream headers to pqxx/pqxx header. +6.4.2 + - Fix mistake for Windows in 6.4.1: use PQfreemem, not std::free. + - Easily enable runtime checks in configure: "--enable-audit". + - Enable optimisation in CircleCI build. +6.4.1 + - Fixed more memory leaks. +6.4.0 + - Half fix, half work around nasty notice processor life time bug. + - Fix selective running of tests: "test/unit/runner test_infinities". + - Added some missing `std::` qualifications. +6.3.3 + - Throw more appropriate error when unable to read client encoding. + - CMake build fixes. +6.3.2 + - Conversion errors no longer throw pqxx::failure; always conversion_error! + - Use C++17's built-in numeric string conversions, if available. + - Query numeric precision in a more sensible, standard way. + - Avoid "dead code" warning. + - Replace obsolete autoconf macros. + - Remove all "using namespace std". + - CMake build fixes. +6.3.1 + - Windows compile fix (CALLBACK is a macro there). + - Work around Visual Studio 2017 not supporting ISO 646. +6.3.0 + - New "table stream" classes by Joseph Durel: stream_from/stream_to. + - Support weird characters in more identifiers: cursors, notifcations, etc. + - Connection policies are deprecated. It'll all be one class in 7.0! + - Connection deactivation/reactivation is deprecated. + - Some items that were documented as deprecated are now also declared as such. + - Fix Windows bug where WSAPoll was never used. Thanks dpolunin. + - Fix Windows CMake build to link to socket libraries. Thanks dpolunin. + - Various other changes to the CMake build. + - Fix failure when doing multiple string conversions with Visual C++. + - Fix nested project builds in CMake. Thanks Andrew Brownsword. + - In Visual Studio, build for host architecture, not "x64". + - Fix string conversion link error in Visual Studio. Thanks Ivan Poiakov. + - Fix string conversion to bool for "1". Thanks Amaracs. + - Fix in escaping of strings in arrays. Thanks smirql. + - Faster copying of results of large queries. Thanks Vsevolod Strukchinsky. + - Starting to handle encodings properly! Thanks to Joseph Durel. + - No longer using std::iterator (deprecated in C++17). +6.2.5 + - Removed deprecated pqxx-config. + - Build fix on Visual C++ when not defining NOMINMAX. + - Reduce setup code for string conversions, hopefully improving speed. + - Allow nul bytes in tablereader. + - Support defining string conversions for enum types. + - Fixed const/pure attributes warning in gcc 8. + - Updated build documentation to mention CMake option. + - Fixed a floating-point string conversion failure with Visual Studio 2017. +6.2.4 + - Fix builds in paths containing non-ASCII characters. + - New macro: PQXX_HIDE_EXP_OPTIONAL (to work around a client build error). +6.2.3 + - Build fixes. +6.2.2 + - Variable number of arguments to prepared or parameterised statement (#75). + - Windows build fix (#76). +6.2.1 + - Compile fixes. +6.2.0 + - At last! A check against version mismatch between library and headers. + - Small compile fixes. +6.1.1 + - Small compile fixes. + - A particular error string would always come out empty. +6.1.0 + - Dependencies among headers have changed. You may need extra includes. + - Library headers now include "*.hxx" directly, not the user-level headers. + - Supports parsing of SQL arrays, when using "ASCII-like" encodings. +6.0.0 + - C++11 is now required. Your compiler must have shared_ptr, noexcept, etc. + - Removed configure.ac.in; we now use configure.ac directly. + - Removed pqxx::items. Use the new C++11 initialiser syntax. + - Removed maketemporary. We weren't using it. + - Can now be built outside the source tree. + - New, simpler, lambda-friendly transactor framework. + - New, simpler, prepared statements and parameterised statements. + - Result rows can be passed around independently. + - New exec0(): perform query, expect zero rows of data. + - New exec1(): perform query, expect (and return) a single row of data. + - New exec_n(): perform query, expect exactly n rows of data. + - No longer defines Visual Studio's NOMINMAX in headers. + - Much faster configure script. + - Most configuration items are gone. + - Retired all existing capability flags. + - Uses WSAPoll() on Windows. + - Documentation on readthedocs.org, thanks Tim Sheerman-Chase. +5.1.0 + - Releases after this will require C++11! + - Internal simplification to pqxx::result. + - A row object now keeps its result object alive. + - New exec() variants: "expect & return 1 row," "expect no rows," "expect n." + - ChangeLog is gone. It was a drag on maintenance. +5.0.1 + - Exposed sqlstate in sql_error exception class. +5.0 + - The PGSTD namespace alias is gone. Use the std namespace directly. + - pqxx::tuple is now pqxx::row, to avoid clashes with std::tuple. + - Deprecated escape_binary functions dropped. + - Deprecated notify_listener class dropped. + - Support for many old compilers dropped. + - Support for "long long" and "long double" types is always enabled. + - No longer uses obsolete std::tr1 namespace; use plain std instead. + - Now requires libpq 9.1 or better. + - Requires server version 9.1 or better. + - Support for REPEATABLE READ isolation level added. + - Makefile fixes for Visual Studio 2013. + - Supports C++11 and C++14. + - No longer has obsolete debian & RPM packaging built in. + - Fixed failure to abort uncommitted subtransactions on destruction. + - Fixed failure to detect some integer overflows during conversion. + - Build tooling uses /usr/bin/env python instead of /usr/bin/python. + - New configure options: --with-postgres-include and --with-postgres-lib. + - In g++ or compatible compilers, non-exported items are no longer accessible. + - Many build fixes for various platforms and compilers. +4.0 + - API change: noticers are gone! Use errorhandlers to capture error output. + - API change: tablereaders and tablewriters are gone; they weren't safe. + - API change: prepared statements are now weakly-typed, and much simpler. + - API change: fields and tuples are now stand-alone classes in ::pqxx. + - API change: thread-safety field have_strerror_r is now have_safe_strerror. + - API change: notify_listener has been replaced with notification_receiver. + - notification_receiver takes a payload parameter. + - Easier Visual C++ setup. + - Absolutely requires a libpq version with PQescapeStringConn. + - Absolutely requires libpq 8.0 or better. + - Changes for C++0x. + - Supports clang++. + - Visual C++ makefiles now support new-style unit tests. + - Sample headers for more recent Visual Studio versions. + - Fixes binary-data escaping problems with postgres 9.0. + - Fixes problems with binary-string handling and escaping. + - Fixes compatibility problems between 9.x libpq and 7.x backend. + - quote_name to escape SQL identifiers for use in queries. + - syntax_error reports error's approximate location in the query. + - On Windows, now uses ws2_32 instead of wsock32. + - Various Windows build fixes. + - Updated for gcc 4.6.0. + - configure script supports --enable-documentation/--disable-documentation. + - Streamlined test/release toolchain. +3.1 + - Shared libraries are now versioned by ABI: 3.1 instead of 3.1.0 etc. + - Threading behaviour is now documented, and can be queried. + - Version information available at compile time. + - Supports parameterized statements. + - Result tuples now support slicing. + - Configure with --with-tr1=boost to use BOOST shared_ptr. + - String conversion now has its own header file. + - Supports read-only transactions. + - Fixed breakage with Solaris "make". + - Uses shared_ptr if available. + - binarystring::str() is no longer cached; no longer returns reference. + - Fixed problems in Visual C++ Makefile for test suite. + - Fixed problems with RPM packaging. + - Fixed build problem on RedHat/CentOS 5. + - Lets you check whether a prepared statement has been defined. + - "Varargs" prepared statements. + - Unnamed prepared statements now supported. + - Results have iterator as well as const_iterator. + - Rewrite of robusttransaction logic; may actually do its job now. + - Connections support async query cancel from signal handler or thread. + - More documentation for performance features. +3.0 + - Website is now at http://pqxx.org/ (no redirects) + - Completely replaced cursor classes + - More helpful error messages on failed connections + - More detailed hierarchy of constraint-violation exception classes + - trigger is now called notify_listener, trigger header is now notify-listen + - New mixin base class pqxx_exception distinguishes libpqxx exception types + - Quoting is back! transaction_base::quote() & connection_base::quote() + - Several build & documentation problems with Visual C++ fixed + - Compile fixes for gcc 4.2, 4.3 + - Compile fixes for Sun Studio Express 5.9 + - Uses strlcpy() where available, instead of strncpy() + - Keeps better track of applicable text encodings + - Fixed bug with prepared statement parameters in separate C++ statements + - robusttransaction now works for multiple users + - Pipeline lets you cancel ongoing queries, e.g. because they run for too long + - Fixed broken escaping of binary values in tablewriter + - Floating-point types now represented with full precision + - Proper unit tests for new functionality + - New traits-based system for adding data types + - Floating-point infinities now supported + - Flushing/completing a pipeline now frees up the transaction for other use + - Completely reworked test suite, builds and runs much faster + - tablewriter supports writing of raw lines +2.6.9 + - Removed old 1.x API (that means all identifiers with capital letters!) + - Tested with all current libpq versions and oldest/newest supported backends + - No longer have old OnCommit()/OnAbort()/OnDoubt() callbacks in transactor! + - Fixes failure when closing cursors with upper-case letters in their names + - Fixes bug when adding triggers to connections that aren't open yet + - Fixes bug when removing triggers + - Fixes small memory leak when preparing statements + - Fixes many problems with older backends + - Fixes bug in result::swap(): protocol versions were not swapped + - Some errors went undetected when using certain libpq versions + - Fixes prepared statements on new libpq versions talking to old backends + - Can estimate server version if libpq does not know how to obtain it + - Greatly reduced memory usage while escaping strings + - With Visual C++, creates lib/ directory if not already present + - Useful error messages when preparing statements + - Allows prepared statements to be registered explicitly + - Support for "long long" types; enable with PQXX_ALLOW_LONG_LONG macro + - Compilation errors for older libpq versions fixed + - Some new small utility classes for disabling notice processing etc. + - Result sets remember the queries that yielded them + - New test script, pqxx-fulltest, tests against all current postgres versions + - Connections can simulate failure + - Adds password encryption function +2.6.8 + - Fixes bug: binary parameters to prepared statements truncated at nul bytes + - New, more specific exception types to distinguish errors from server + - Resolved serious problems with generated reference documentation + - Automatically detect Windows socket library with MinGW + - Windows "make" fixed to run from main directory, not win32 + - Fixes "mktemp" problems on some BSD-based platforms + - pqxx-config is deprecated; use pkg-config instead + - On GNU/Linux, uses poll() instead of select() to avoid file descriptor limit + - Will provide server and protocol version information where available + - New cursor class, absolute_cursor +2.6.7 + - New escape functions for binary data: transaction_base::esc_raw() + - Improved detection of socket libraries, especially for MinGW + - Works around bug in some versions of GNU grep 2.5.1 + - Fixes problem with configuration headers + - Fixes PQprepare() detection + - Fixes incomplete Visual C++ Makefile + - Fixes compile error in workaround for older libpq versions + - Removes "rpath" link option +2.6.6 + - New, encoding-safe string-escaping functions + - Upper-case letters now allowed in prepared-statement names + - Fixes crash in test005 + - More Visual C++ improvements + - Removed collaboration diagrams from reference docs + - New templating system for generating Windows Makefiles etc. +2.6.5 + - Visual C++ users: copy win32/common-sample to win32/common before editing it + - Should fix problems finding socket library on MinGW + - Even more work on Visual C++ problems + - Updated documentation for Visual C++ users + - Fixed bug in prepared statements (mostly visible on Visual C++) + - Nested transactions work harder to detect backend support +2.6.4 + - Massively improved compatibility with Windows and Visual C++ + - Fixed late initialization of "direct" connection state + - Fixed problem with initialization of connection capabilities + - Fixed configuration bug for libpq in nonstandard locations + - Sample configuration header for libpq found in PostgreSQL 8.1 +2.6.3 + - Radical rework of prepared statements; INCOMPATIBLE INTERFACE CHANGE! + - Dropped support for g++ 2.95 + - Emulate prepared statements support on old libpq or old backend + - Bug fix: missing tutorial (release script now tests for this) + - Automatically links in socket library on Windows or Solaris, if needed + - Bug fix: check for std namespace didn't work + - Fixes for Cygwin/MSYS/MinGW +2.6.2 + - Bug fix: connection state was not set up properly in some common cases + - Bug fix: headers were installed in "include" instead of "include/pqxx" + - Bug fix: sqlesc(string) broke with multibyte or multiple encodings + - namedclass is now used as a virtual base; affects all subclass constructors + - Initial implementation of subtransactions + - Detect more connection capabilities + - Standard library namespace can be set from configure script's command line + - Completely reworked connection hierarchy, with separate policy objects + - Clients can now define their own connection policies + - Paved the way for client-defined thread synchronization + - Now lives at http://thaiopensource.org/development/libpqxx/ +2.6.1 + - Hugely improved recognition of different strerror_r() versions + - Resolved link problems with gcc 4.0 and shared library +2.6.0 + - New macro PQXX_SHARED defines whether to use/build libpqxx as shared library + - Robusttransaction compatible with PostgreSQL 8.1 + - Infrastructure for querying connection/backend capabilities at runtime + - Greatly improved cursor support + - Connection reactivation can be inhibited explicitly + - Tries even harder to make sense of conflicting strerror_r() definitions + - Detects connection failures that libpq glosses over + - Reference documentation grouped into more coherent sections + - Assumes strerror() is threadsafe on systems that have no strerror_r() + - Now allows connection's socket number to be queried + - New internal_error class for libpqxx-internal errors + - With Visual C++, doesn't redefine NOMINMAX if it is defined already + - Several compatibility improvements for Visual C++ + - Fixes and workarounds for HP-UX and HP aCC compiler + - Phased old cursor interface out of test suite; tests ported to new interface + - Added documentation on thread safety + - New thread safety model + - Large objects have functions to tell current position + - Minor updates to tutorial (somebody pay me and I'll do more :) + - No longer needs libpq-fs.h header + - Meaningful error messages for ambiguous string conversions fixed +2.5.6 + - Support null parameters to prepared statements (use C-style char pointers) +2.5.5 + - Diagnoses connection failure during result transfer + - Fixes invalid -R link option in pqxx-config +2.5.4 + - Fix workaround code for older libpq versions without PQunescapeBytea() + - Work around grep bug in Fedora Core 4 that broke configure in UTF-8 locales + - In Visual C++, assume libpqxx is a DLL when linking to std library as DLL + - Missing documentation in distribution archive is back again + - Export fewer symbols from library binary with gcc 4.0 + - Releases now automatically tested against gcc 4.0 + - Meaningful link errors for additional ambiguous string conversions + - DLL symbol exports now automatically tested before each release +2.5.3 + - Greatly improved builds on MinGW with MSYS + - All known problems with MinGW fixed + - Fix bugs in stream classes that caused failures and crashes with STLport + - Detects and uses STLport automatically +2.5.2 + - Fix memory leaks + - Fix problems with NaN (not-a-number values) on some compilers +2.5.1 + - Fix configure script; broke when very recent libpqxx was already installed + - Fix cursor breakage when "long" is more than 32 bits + - Fix cases where new-style abort/doubt handlers are used + - Fix for division-by-zero error in Visual C++ (changed sample headers) + - Improved checking for strerror_r in configure script + - Fix for problem MinGW has with configure script + - Fix spurious failure of Oid check in configure script +2.5.0 + - Fix race condition in removing triggers + - Fix binary string conversion with older libpq + - Fix some error strings that may previously have come out wrong + - No longer includes any libpq headers while compiling client code + - Improved thread safety: avoid strerror() where possible + - Prepared statements + - Translate more error conditions to std::bad_alloc exception + - Clearer and more specific explanations for configuration failures + - Improved documentation + - Looks for standard library in global namespace as well as std + - Accepts standard C library in std namespace + - Release script automatically tests with a range of compilers, not just one + - Compatible with g++ 2.95 again; this time it's tested automatically +2.4.4 + - Fix problems building shared library in Visual C++ + - Fix autobuild in Debian, which was broken by mistake in BSD grep workaround + - Fix conversion of string to floating-point type NaN + - Remove stray CVS directories from distribution archive + - Workaround for Visual C++ problem when issuing messages from destructors + - Yet more workarounds for Visual C++ bugs + - Fix situation where connection state might not be restored after failure + - Fix configuration problem on SunOS + - Network speedup in connection setup with pending variables and/or triggers +2.4.3 + - Yet more workarounds for bugs in Visual C++ .NET 2003 + - Fixes for SunC++ 5.5 + - On Visual C++, now defines NOMINMAX, fixing large object support + - Workaround for BSD grep + - Improvements for builds from CVS + - Sample config headers for Sun ONE Studio 8 +2.4.2 + - Fix minor problems with Apple's version of g++ 3.3 + - Fix problem with MingW on Windows + - Workarounds and fixes for Visual C++.NET 2003 + - Renewed compatibility with g++ 2.95 + - More sample configuration headers + - Updated reference documentation + - Removed assert code +2.4.1 + - Several bugs in icursor_iterator fixed; incompatible interface changes + - Tightens throw specifications on begin(), end(), size(), capacity() + - Containers define reference and pointer types + - Implements swap() in all container types + - Implements == and != in all container types + - Stabilizes new (but still limited) cursor interface + - icursor_iterator thinks purely in stride granularity + - Introduces />= comparisons for icursor_iterators + - Allows "adopted SQL cursors" in new cursor interface + - Reference-counting in binarystrings, so they can be copied (and efficiently) + - Fixes reference-to-temporary problem with std::reverse_iterator in results + - Result/tuple reverse_iterators no longer require std::reverse_iterator + - Includes some sample config headers (in config/sample-headers) + - Replaces iffy autoconf checks (avoid failures with maintainer mode's -Werror) + - Fixes incompatibility with some implementations of Unix "cut" program (again) +2.4.0 + - Fixes incompatibility with some implementations of Unix "cut" program + - Fixes "ptrdiff_t redefinition" problem in some environments + - More container-like tuples, so fields can be iterated + - All size_type types are now unsigned + - More conservative robusttransaction--thanks Tom Lane + - Stream-like extraction operator for result field conversion + - Warnings about deprecated headers now suppressed while compiling library + - Iterator constructors and copy assignments now have empty throw specs +2.3.0 + - Generates MinGW Makefile automatically + - Documents MinGW build + - Workaround for missing prepared-statement support + - Potential bug fixed in closing of connections + - Fixed incompatibility between new cursor streams and older backends + - Removed pqxxbench +2.2.9 + - Bugfix in removing trigger + - Added "failed connection" to regression test + - Some changes to throw specifications + - Putting libpq in its own namespace is optional +2.2.8 + - Moved libpq into pqxx::internal::pq namespace + - New config system separates compiler-related items from libpq-related ones + - Auto-generates Visual C++ Makefile, should always remain up-to-date now +2.2.7 + - Bugfix: from_string() didn't handle LONG_MIN--thanks Yannick Boivin +2.2.6 + - Complete "pipeline" rewrite, for better exception safety + - New garbage collection scheme for "result;" constructors now exception-free +2.2.5 + - First new cursor classes! + - Fixed strange failure in tablewriter during large insertions + - Updated tutorial +2.2.4 + - New utility class template, items<> for easy container initialization + - New utility function template, separated_list() + - Error handling bugfix in tablewriter + - Fixed tablereader handling of lines ending in empty fields + - tablereader lines no longer end in newline with old libpq versions +2.2.3 + - Trigger names no longer need to be proper identifiers + - Compile fixes for g++ 3.4.0 and other modern compilers + - Tablestreams may specify column lists + - Deprecated Quote() in favour of sqlesc(); improved quoting + - Fixed generation of libpqxx.spec +2.2.2 + - Bugfix in fieldstream w.r.t. reading strings on some systems + - Renamed config.h to internalconfig.h to avoid confusion + - New connection functions allow client to sleep until notification arrives + - Notification functions return number of notifications received + - Even fewer client-visible macros exported by libconfig.h +2.2.1 + - New, 2.x-style string conversions without locale problem + - Documentation improvements + - Implemented result::swap() +2.2.0 + - Installs to /usr/local by default, NOT to /usr/local/pqxx like before! + - Uses Postgres-provided script to find Postgres (thanks Peter Eisentraut) + - Which means no more configure arguments required on Irix (thanks Arjen Baart) + - Fixes long-standing bug in result class! + - New pipeline class for throughput optimization + - New field stream class: read result field as C++ stream + - Separate namespace pqxx::internal for definitions not relevant to the user + - More Windows compilation fixes + - SUN Workshop 6 compile fixes and workarounds (thanks Jon Meinecke) + - Implemented reverse_iterator for result class + - Checks for functional std::reverse_iterator template + - Preliminary Makefile for MinGW compiler (thanks Pasquale Fersini) + - Changed the way unique<> works + - Checks for functional std::count_if() + - Bugs fixed & test programs added +2.1.3 + - Makefile fixes for Visual C++, thanks Paresh Patel + - Library ABI versioning implemented, thanks Roger Leigh + - Uses old SQL isolation level syntax for compatibility, thanks koun@sina.com + - tablestreams can explicitly complete() before destructor + - Bugfix in robusttransaction: forgot to set isolation level + - Fixed off-by-ones in tablewriter escape code + - tablestreams now use \n-style escape sequences + - tablestreams support octal numbers + - Freely definable "null" strings in tablestreams, as originally intended + - Improved Debian packaging, thanks Roger Leigh + - tablestreams use libpq's new-style COPY functions, if available + - Extended automation of build/release procedure + - tablewriter writes in nonblocking mode to help hide communication latency + - Can get backend variables as well as set them + - More configuration macro cleanups + - Workaround for missing clear() in standard string + - Merry Christmas! +2.1.2 + - Compile fix for gcc libstdc++ 2.9, thanks Jaroslaw Staniek + - Moved deprecated functions below current ones + - Cleanups for Debian packaging (thanks Roger Leigh, new Debian maintainer!) + - Updated authors listings + - Bumped ABI version number for the first time (now 2:0:1) +2.1.1 + - More workarounds for gcc 2.95 + - Automated tools keep test makefiles up to date +2.1.0 + - Asynchronous connections + - Fixed configure --includedir option (thanks Ray Dassen!) + - Compile fixes for SUN Workshop 6, and one for gcc on FreeBSD 4.8 +2.0.0 + - New stable release! + - Includes all changes since 1.5 release. + - Workarounds for Microsoft Visual C++ 7 problems. Thanks Costin Musteata! + - No longer need to define PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION + - Integrated Windows configuration into regular configuration + - Only uses #warning if preprocessor supports it + - Works on libpq versions without PQ[un]escapeBytea() +1.9.9 + - Minor documentation changes +1.9.8 + - Workaround for compile problem with postgres 7.3 + - Convenience typedef for transaction<>: "work" +1.9.7 + - binarystring rewritten and moved to its own file + - binarystring::size() does not include terminating null byte! + - Implemented escaping of binary strings + - Fix in workaround for missing numeric_limits on some compilers + - String conversion supported for unsigned char * + - More helpful link errors for unsupported string conversions + - Complete test coverage +1.9.6 + - Fixes in "field table" support + - Improved coexistence with client program's config.h, if any + - Prefixed autoconf macros used in headers with "PQXX_" +1.9.5 + - Header file contents moved to .hxx files for editor filetype recognition + - Fixes wrong timestamp for include/pqxx/result in 1.9.4 distribution +1.9.4 + - Fixes Visual C++ build problem when compiling as library +1.9.3 + - Quick release for various minor changes +1.9.2 + - Renamed most public member functions to all-lower-case names + - (previously is now called +1.9.1 + - tablestream destructor crashed if table didn't exist (thanks Sean [Rogers?]) + - Renamed all header files to remove ".h" suffix + - Tables created by regression test now prefixed with "pqxx" for safety + - Large objects now considered stable + - Migrated tutorial from SGML to DocBook XML (thanks Wichert Akkerman) + - Added tests 57-59 + - Fixed compile error in largeobject + - Updated Windows makefiles +1.9.0 + - EVERYTHING HAS CHANGED. Read the list or run into trouble! + - CURSOR HAS INCOMPATIBLE CHANGES AND MAY BE REPLACED COMPLETELY + - CACHEDRESULT HAS INCOMPATIBLE CHANGES (won't compile without changes) + - REVISE YOUR TRANSACTORS; now templatized on transaction type + - Finally got license file in order + - Incompatible change in setting transactor quality of service + - Cursors require serializable isolation level (checked at link time) + - Renamed Connection_base to connection_base, Connection to connection, + LazyConnection to lazyconnection + - Renamed LargeObject to largeobject, LargeObjectAccess to largeobjectaccess + - Renamed Noticer to noticer + - Renamed Trigger to trigger + - Renamed Result to result, Tuple to tuple, Field to field + - Renamed Unique<> to unique<> + - Renamed CachedResult to cachedresult + - Transformed Transaction Taxonomy (TTT): + - Renamed Transaction_base to transaction_base + - Renamed Transaction to transaction + - Renamed Transactor to transactor<> (now a template) + - Implemented transaction isolation levels as compile-time static properties + - transaction and robusttransaction now templatized on their isolation levels + - cachedresult requires serializable isolation level (checked at link time) + - Now need to include pqxx/transactor.h yourself if you need transactors + - Large objects require real backend transaction at compile time + - New type oid and constant oid_none for row identifiers resp. null oid + - Added some forgotten PQXX_LIBEXPORTs + - Tweaked documentation in many places +1.8.1 + - By popular request: more convenient way to read field values + - Documented locale sensitivity of ToString(), FromString(), Field::to() +1.8.0 + - Compiles on gcc 2.95 again (heavy streambuf workarounds in largeobject.h) + - ConnectionItf renamed to Connection_base, TransactionItf to Transaction_base + - connectionitf.h is now connection_base.h, transactionitf.h connection_base.h +1.7.8 + - BinaryString class for unescaping bytea strings + - PQAlloc template keeps track of libpq-allocated objects + - Removed some consts in Unique<>, ConnectionItf, sorry! + - Can now set session variables on connections, transactions +1.7.7 + - ./configure also looks for postgres in /usr/local/pgsql + - test007 now uses SQL_ASCII as its test encoding + - integrated Greg Hookey's Debian packaging +1.7.6 + - added postgres library (libpq) to dynamic link path +1.7.5 + - added test052 - test055 + - added Result::Tuple::ColumnNumber() + - also test setting of client encodings + - removed superfluous versions of to_file() from large object classes +1.7.4 + - new exception class, sql_error, remembers query text + - moved exception classes to new file include/pqxx/except.h + - test cases report texts of any failed queries + - added tools/rmlo.cxx +1.7.3 + - default constructors for connection classes + - revamped seeking operations on large objects + - better error messages in large objects + - added test050, test051 +1.7.2 + - more workarounds for Sun CC 5.1, thanks Jeroen van Erp! + - preliminary support for "named" queries + - can now Quote() string constants + - included Doxyfile in distribution archive + - helps avoid Windows memory allocation problem in DLLs + - allows setting of client character set encoding +1.7.1 + - regenerated documentation +1.7.0 + - removed all deprecated features + - connection string documentation in README + - separate Connection, LazyConnection classes + - made test001 more concise + - added test049 +1.6.4 + - configure script now respects different std namespace +1.6.3 + - olostream, lostream now flush themselves before closing + - fixed compilation problems when using ToString<>() on a plain char * + - compilation fixes for Sun compiler (thanks Jeroen van Erp!) + - added .pc file for pkgconfig (thanks Ray Dassen!) +1.6.2 + - Debian packaging added to distribution archive + - new ilostream, olostream, lostream classes +1.6.1 + - large object's cunlink() replaced by remove() + - default constructor for LargeObject +1.6.0 + - new large objects interface + - added test048 +1.5.0 + - allow result fields to be written to streams + - removed confusing CachedResult::clear() + - minor documentation updates + - added test046, test047 + - added convenience header +1.4.5 + - fixed crash CachedResult that was less shallow than I thought + - fixed quoting problem with adopted SQL cursors +1.4.4 + - (forgot to save cursor.cxx with new constructor in 1.4.4, sorry) +1.4.3 + - all tests now have three-digit numbers + - Cursor can adopt SQL cursor returned by a function +1.4.2 + - bugfix in CachedResult when accessing empty Results + - minor documentation improvements +1.4.1 + - documents new homepage: http://pqxx.tk/ + - Connection constructor accepts null connect string + - Exec() now also takes queries as C++ strings +1.4.0 + - Connection::IsOpen() renamed to is_open() + - NoticeProcessor replaced by Noticer (with C++ linkage) +1.3.7: + - detects nasty rare problem case with Cursors in unknown positions +1.3.6: + - fixed detection of missing PQescapeString(). Thanks David Wright! +v1.3.5: + - documented Windows build procedure + - fixed problem with upper-case letters in cursor names. Thanks key88! +2003-01-19 16:00, v1.3.4: + - support long double type + - clarified some error messages +2003-01-08 18:45, v1.3.3: + - fix missing include in test13 +2003-01-07 02:30, v1.3.2: + - configure looks for postgres includes/library in more places, thanks Ray! +2003-01-02 23:00, v1.3.1: + - bugfix in Cursor positioning +2003-01-02 20:30, v1.3.0: + - absolute positioning for Cursor + - better documentation on cursors + - reduced, but improved test suite output +2002-12-23 17:30, v1.2.8: + - Cursor::Move() returns number of rows skipped + - new typedef Cursor::size_type +2002-12-14 23:30, v1.2.7: + - test suite now distinguishes expected errors from unexpected ones +2002-12-09 20:00, v1.2.6: + - fixed some Cursor test cases for change in postgres 7.3 + - added important warning to Cursor +2002-12-09 02:00, v1.2.5: + - added important warning to CachedResult +2002-12-08 14:14, v1.2.4: + - fixed compile error on some systems in include/pqxx/util.h +2002-12-04 12:00, v1.2.3: + - workaround for broken on some systems + - fixed Quote() bug +2002-12-03 01:30, v1.2.2: + - fixed serious CachedResult bug + - added test41 +2002-12-02 17:00, v1.2.1: + - hopefully fixed cursor bug with PostgreSQL 7.3 +2002-12-01 22:00, v1.2.0: + - new CachedResult class +2002-11-07 13:15, v1.1.4: + - workaround for missing InvalidOid definition +2002-10-23 16:00, v1.1.3: + - Cursor & TableStream hierarchy now work on any transaction type + - get no. of affected rows & oid of inserted row from Result + - increased test coverage +2002-10-21 01:30, v1.1.2: + - updated build procedure + - Debian packaging improvements +2002-09-25 03:00, v1.1.1: + - supports activating/deactivating of connections + - various Connection getters now activate deferred connection first +2002-09-23 01:00, v1.1.0: + - supports lazy connections (added 19 test cases just for these) + - greatly reduced performance overhead for RobustTransaction + - removed id field from RobustTransaction's transaction log tables +2002-09-14 20:00, v1.0.1: + - now lives on GBorg + - various packaging updates +2002-06-12 17:30, v0.5.1: + - no longer have to destroy one transaction before creating the next +2002-06-07 17:15, v0.5.0: + - "make install" now finally installs headers! + - distribution now includes SGML (DocBook) version of tutorial +2002-06-04 15:00, v0.4.4: + - may now have multiple triggers with same name on single connection +2002-06-02 23:00, v0.4.3: + - fixed TableReader problem with \t and \n +2002-06-01 21:00, v0.4.2: + - hopefully fixes compile problem with broken std::iterator + - configure no longer requires --with-postgres-include=/usr/include/postgresql +2002-05-29 22:00, v0.4.1: + - can now also handle bool, unsigned char, short field types +2002-05-27 22:30, v0.4.0: + - RENAMED Transactor::TRANSACTIONTYPE to argument_type for STL conformance + - RENAMED Result::Field::name() to Name() + - documentation improvements + - minor optimizations +2002-05-18 00:00, v0.3.1: + - removed broken postgres_fe.h dependency (hopefully permanent fix) +2002-05-12 22:45, v0.3.0: + - also looks for postgres_fe.h in postgres' internal/ directory (tmp fix) +2002-05-05 01:30, v0.2.3: + - extensive build instructions in README + - make check now controlled through PG environment variables +2002-05-04 19:30, v0.2.2: + - more STL conformance + - fixed regression test + - test6 now copies "orgevents" to "events" by default +2002-04-28 23:45 Version bumped to 0.2 +2002-04-28 23:45 Self-generated distribution archive +2002-04-27 14:20 Replaced automake symlinks with actual files +2002-04-07 02:30 Released with configure script +2002-03-29 01:15 Not yet released. Still integrating autogen stuff... diff --git a/ext/libpqxx-7.7.3/README.md b/ext/libpqxx-7.7.3/README.md new file mode 100644 index 000000000..3a1c17ded --- /dev/null +++ b/ext/libpqxx-7.7.3/README.md @@ -0,0 +1,199 @@ +libpqxx +======= + +Welcome to libpqxx, the C++ API to the PostgreSQL database management system. + +Home page: http://pqxx.org/development/libpqxx/ + +Find libpqxx on Github: https://github.com/jtv/libpqxx + +Documentation on Read The Docs: https://libpqxx.readthedocs.io + +Compiling this package requires PostgreSQL to be installed -- or at least the C +headers and library for client development. The library builds on top of +PostgreSQL's standard C API, libpq, though your code won't notice. + +If you're getting the code straight from the Git repo, the head of the `master` +branch represents the current _development version._ Releases are tags on +commits in `master`. For example, to get version 7.1.1: + + git checkout 7.1.1 + + +Upgrade notes +------------- + +**The 7.x versions require at least C++17.** Make sure your compiler is up to +date. For libpqxx 8.x you will need at least C++20. + +Also, **7.0 makes some breaking changes in rarely used APIs:** +* There is just a single `connection` class. It connects immediately. +* Custom `connection` classes are no longer supported. +* It's no longer possible to reactivate a connection once it's been closed. +* The API for defining string conversions has changed. + +If you're defining your own type conversions, **7.1 requires one additional +field in your `nullness` traits.** + + +Building libpqxx +---------------- + +There are two different ways of building libpqxx from the command line: +1. Using CMake, on any system which supports it. +2. On Unix-like systems, using a `configure` script. + +"Unix-like" systems include GNU/Linux, Apple macOS and the BSD family, AIX, +HP-UX, Irix, Solaris, etc. Even on Microsoft Windows, a Unix-like environment +such as WSL, Cygwin, or MinGW should work. + +You'll find detailed build and install instructions in `BUILDING-configure.md` +and `BUILDING-cmake.md`, respectively. + +And if you're working with Microsoft Visual Studio, have a look at Gordon +Elliott's +[ + Easy-PQXX Build for Windows Visual Studio +](https://github.com/GordonLElliott/Easy-PQXX-Build-for-Windows-Visual-Studio) +project. + + +Documentation +------------- + +Building the library, if you have the right tools installed, generates HTML +documentation in the `doc/` directory. It is based on the headers in +`include/pqxx/` and text in `include/pqxx/doc/`. This documentation is also +available online at [readthedocs](https://libpqxx.readthedocs.io). + + +Programming with libpqxx +------------------------ + +Your first program will involve the libpqxx classes `connection` (see the +`pqxx/connection.hxx` header), and `work` (a convenience alias for +`transaction<>` which conforms to the interface defined in +`pqxx/transaction_base.hxx`). + +These `*.hxx` headers are not the ones you include in your program. Instead, +include the versions without filename suffix (e.g. `pqxx/connection`). Those +will include the actual .hxx files for you. This was done so that includes are +in standard C++ style (as in `` etc.), but an editor will still +recognize them as files containing C++ code. + +Continuing the list of classes, you will most likely also need the result class +(`pqxx/result.hxx`). In a nutshell, you create a `connection` based on a +Postgres connection string (see below), create a `work` in the context of that +connection, and run one or more queries on the work which return `result` +objects. The results are containers of rows of data, each of which you can +treat as an array of strings: one for each field in the row. It's that simple. + +Here is a simple example program to get you going, with full error handling: + +```c++ + #include + #include + + int main() + { + try + { + // Connect to the database. + pqxx::connection C; + std::cout << "Connected to " << C.dbname() << '\n'; + + // Start a transaction. + pqxx::work W{C}; + + // Perform a query and retrieve all results. + pqxx::result R{W.exec("SELECT name FROM employee")}; + + // Iterate over results. + std::cout << "Found " << R.size() << "employees:\n"; + for (auto row: R) + std::cout << row[0].c_str() << '\n'; + + // Perform a query and check that it returns no result. + std::cout << "Doubling all employees' salaries...\n"; + W.exec0("UPDATE employee SET salary = salary*2"); + + // Commit the transaction. + std::cout << "Making changes definite: "; + W.commit(); + std::cout << "OK.\n"; + } + catch (std::exception const &e) + { + std::cerr << e.what() << '\n'; + return 1; + } + return 0; + } +``` + + +Connection strings +------------------ + +Postgres connection strings state which database server you wish to connect to, +under which username, using which password, and so on. Their format is defined +in the documentation for libpq, the C client interface for PostgreSQL. +Alternatively, these values may be defined by setting certain environment +variables as documented in e.g. the manual for psql, the command line interface +to PostgreSQL. Again the definitions are the same for libpqxx-based programs. + +The connection strings and variables are not fully and definitively documented +here; this document will tell you just enough to get going. Check the +PostgreSQL documentation for authoritative information. + +The connection string consists of attribute=value pairs separated by spaces, +e.g. "user=john password=1x2y3z4". The valid attributes include: +* `host` — + Name of server to connect to, or the full file path (beginning with a + slash) to a Unix-domain socket on the local machine. Defaults to + "/tmp". Equivalent to (but overrides) environment variable PGHOST. +* `hostaddr` — + IP address of a server to connect to; mutually exclusive with "host". +* `port` — + Port number at the server host to connect to, or socket file name + extension for Unix-domain connections. Equivalent to (but overrides) + environment variable PGPORT. +* `dbname` — + Name of the database to connect to. A single server may host multiple + databases. Defaults to the same name as the current user's name. + Equivalent to (but overrides) environment variable PGDATABASE. +* `user` — + User name to connect under. This defaults to the name of the current + user, although PostgreSQL users are not necessarily the same thing as + system users. +* `requiressl` — + If set to 1, demands an encrypted SSL connection (and fails if no SSL + connection can be created). + +Settings in the connection strings override the environment variables, which in +turn override the default, on a variable-by-variable basis. You only need to +define those variables that require non-default values. + + +Linking with libpqxx +-------------------- + +To link your final program, make sure you link to both the C-level libpq library +and the actual C++ library, libpqxx. With most Unix-style compilers, you'd do +this using the options + + -lpqxx -lpq + +while linking. Both libraries must be in your link path, so the linker knows +where to find them. Any dynamic libraries you use must also be in a place +where the loader can find them when loading your program at runtime. + +Some users have reported problems using the above syntax, however, particularly +when multiple versions of libpqxx are partially or incorrectly installed on the +system. If you get massive link errors, try removing the "-lpqxx" argument from +the command line and replacing it with the name of the libpqxx library binary +instead. That's typically libpqxx.a, but you'll have to add the path to its +location as well, e.g. /usr/local/pqxx/lib/libpqxx.a. This will ensure that the +linker will use that exact version of the library rather than one found +elsewhere on the system, and eliminate worries about the exact right version of +the library being installed with your program.. diff --git a/ext/libpqxx-7.7.3/VERSION b/ext/libpqxx-7.7.3/VERSION new file mode 100644 index 000000000..d92ba80de --- /dev/null +++ b/ext/libpqxx-7.7.3/VERSION @@ -0,0 +1 @@ +7.7.3 diff --git a/ext/libpqxx-7.7.3/aclocal.m4 b/ext/libpqxx-7.7.3/aclocal.m4 new file mode 100644 index 000000000..2c938cff6 --- /dev/null +++ b/ext/libpqxx-7.7.3/aclocal.m4 @@ -0,0 +1,1187 @@ +# generated automatically by aclocal 1.16.4 -*- Autoconf -*- + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Copyright (C) 2002-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.16' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.16.4], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.16.4])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? + done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE="gmake" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +# Variables for tags utilities; see am/tags.am +if test -z "$CTAGS"; then + CTAGS=ctags +fi +AC_SUBST([CTAGS]) +if test -z "$ETAGS"; then + ETAGS=etags +fi +AC_SUBST([ETAGS]) +if test -z "$CSCOPE"; then + CSCOPE=cscope +fi +AC_SUBST([CSCOPE]) + +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless 'enable' is passed literally. +# For symmetry, 'disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], + [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], + am_maintainer_other[ make rules and dependencies not useful + (and sometimes confusing) to the casual installer])], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. +AC_DEFUN([AM_MAKE_INCLUDE], +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + MISSING="\${SHELL} '$am_aux_dir/missing'" +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([config/m4/libtool.m4]) +m4_include([config/m4/ltoptions.m4]) +m4_include([config/m4/ltsugar.m4]) +m4_include([config/m4/ltversion.m4]) +m4_include([config/m4/lt~obsolete.m4]) diff --git a/ext/libpqxx-7.7.3/appveyor.yml b/ext/libpqxx-7.7.3/appveyor.yml new file mode 100644 index 000000000..110bd75ad --- /dev/null +++ b/ext/libpqxx-7.7.3/appveyor.yml @@ -0,0 +1,30 @@ +# Configuration for test runs in Appveyor. +version: 1.0.{build} +image: Visual Studio 2022 +services: postgresql13 +# Run CMake to build libpqxx.sln. +before_build: +- cmd: >- + call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" + + cmake -DBUILD_SHARED_LIBS=1 -DCMAKE_CXX_STANDARD=23 +configuration: Release +build: + parallel: true + project: libpqxx.sln +test_script: +- ps: >- + $env:Path += ";.\src\Release;C:\Program Files\PostgreSQL\13\bin" + + $env:PGUSER = "postgres" + + $env:PGPASSWORD = "Password12!" + + .\test\Release\runner.exe +notifications: +- provider: Email + subject: 'libpqxx: AppVeyor build failure' + message: The libpqxx AppVeyor build has failed. + on_build_success: false + on_build_failure: true + on_build_status_changed: false diff --git a/ext/libpqxx-7.7.3/autogen.sh b/ext/libpqxx-7.7.3/autogen.sh new file mode 100755 index 000000000..a09cb5ae7 --- /dev/null +++ b/ext/libpqxx-7.7.3/autogen.sh @@ -0,0 +1,44 @@ +#! /bin/sh +# Run this to generate the configure script etc. + +set -eu + +PQXXVERSION=$(./tools/extract_version) +PQXX_ABI=$(./tools/extract_version --abi) +PQXX_MAJOR=$(./tools/extract_version --major) +PQXX_MINOR=$(./tools/extract_version --minor) +echo "libpqxx version $PQXXVERSION" +echo "libpqxx ABI version $PQXX_ABI" + +substitute() { + sed -e "s/@PQXXVERSION@/$PQXXVERSION/g" \ + -e "s/@PQXX_MAJOR@/$PQXX_MAJOR/g" \ + -e "s/@PQXX_MINOR@/$PQXX_MINOR/g" \ + -e "s/@PQXX_ABI@/$PQXX_ABI/g" \ + "$1" +} + + +# Use templating system to generate various Makefiles. +expand_templates() { + for template in "$@" + do + ./tools/template2mak.py "$template" "${template%.template}" + done +} + + +# We have two kinds of templates. One uses our custom templating tool. And +# a few others simply have some substitutions done. +expand_templates $(find -name \*.template) +substitute include/pqxx/version.hxx.template >include/pqxx/version.hxx +substitute include/pqxx/doc/mainpage.md.template >include/pqxx/doc/mainpage.md + + +autoheader +libtoolize --force --automake --copy +aclocal -I . -I config/m4 +automake --add-missing --copy +autoconf + +echo "Done." diff --git a/ext/libpqxx-7.7.3/cmake/config.cmake b/ext/libpqxx-7.7.3/cmake/config.cmake new file mode 100644 index 000000000..816ee4474 --- /dev/null +++ b/ext/libpqxx-7.7.3/cmake/config.cmake @@ -0,0 +1,157 @@ +function(detect_code_compiled code macro msg) + message(STATUS "Detecting ${msg}") + check_cxx_source_compiles("${code}" "${macro}" FAIL_REGEX "warning") + if(${macro}) + message(STATUS "Detecting ${msg} - supported") + else() + message(STATUS "Detecting ${msg} - not supported") + endif() +endfunction(detect_code_compiled) + +include(CheckIncludeFileCXX) +include(CheckFunctionExists) +include(CheckSymbolExists) +include(CMakeDetermineCompileFeatures) +include(CheckCXXSourceCompiles) +include(CMakeFindDependencyMacro) + +if(NOT PostgreSQL_FOUND) + if(POLICY CMP0074) + cmake_policy(PUSH) + # CMP0074 is `OLD` by `cmake_minimum_required(VERSION 3.7)`, + # sets `NEW` to enable support CMake variable `PostgreSQL_ROOT`. + cmake_policy(SET CMP0074 NEW) + endif() + + find_package(PostgreSQL REQUIRED) + + if(POLICY CMP0074) + cmake_policy(POP) + endif() +endif() + +check_function_exists("poll" PQXX_HAVE_POLL) + +set(CMAKE_REQUIRED_LIBRARIES pq) +check_symbol_exists( + PQencryptPasswordConn + "${PostgreSQL_INCLUDE_DIR}/libpq-fe.h" + PQXX_HAVE_PQENCRYPTPASSWORDCONN) +check_symbol_exists( + PQenterPipelineMode + "${PostgreSQL_INCLUDE_DIR}/libpq-fe.h" + PQXX_HAVE_PQ_PIPELINE) + +cmake_determine_compile_features(CXX) +cmake_policy(SET CMP0057 NEW) + +# check_cxx_source_compiles requires CMAKE_REQUIRED_DEFINITIONS to specify +# compiling arguments. +# Wordaround: Push CMAKE_REQUIRED_DEFINITIONS +if(CMAKE_REQUIRED_DEFINITIONS) + set(def "${CMAKE_REQUIRED_DEFINITIONS}") +endif() +set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION}) +set(CMAKE_REQUIRED_QUIET ON) + +try_compile( + PQXX_HAVE_GCC_PURE + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/gcc_pure.cxx) +try_compile( + PQXX_HAVE_GCC_VISIBILITY + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/gcc_visibility.cxx) +try_compile( + PQXX_HAVE_LIKELY + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/likely.cxx) +try_compile( + PQXX_HAVE_CXA_DEMANGLE + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/cxa_demangle.cxx) +try_compile( + PQXX_HAVE_CONCEPTS + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/concepts.cxx) +try_compile( + PQXX_HAVE_SPAN + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/span.cxx) +try_compile( + PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/multidim-subscript.cxx) +try_compile( + PQXX_HAVE_CHARCONV_FLOAT + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/charconv_float.cxx) +try_compile( + PQXX_HAVE_CHARCONV_INT + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/charconv_int.cxx) +try_compile( + PQXX_HAVE_PATH + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/fs.cxx) +try_compile( + PQXX_HAVE_THREAD_LOCAL + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/thread_local.cxx) +try_compile( + PQXX_HAVE_SLEEP_FOR + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/sleep_for.cxx) +try_compile( + PQXX_HAVE_STRERROR_R + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/strerror_r.cxx) +try_compile( + PQXX_HAVE_STRERROR_S + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/strerror_s.cxx) +try_compile( + PQXX_HAVE_YEAR_MONTH_DAY + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/year_month_day.cxx) +try_compile( + PQXX_HAVE_CMP + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/cmp.cxx) + +try_compile( + need_fslib + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/need_fslib.cxx) +if(!need_fslib) + # TODO: This may work for gcc 8, but some clang versions may need -lc++fs. + link_libraries(stdc++fs) +endif() + +# check_cxx_source_compiles requires CMAKE_REQUIRED_DEFINITIONS to specify +# compiling arguments. +# Workaround: Pop CMAKE_REQUIRED_DEFINITIONS +if(def) + set(CMAKE_REQUIRED_DEFINITIONS ${def}) + unset(def CACHE) +else() + unset(CMAKE_REQUIRED_DEFINITIONS CACHE) +endif() +set(CMAKE_REQUIRED_QUIET OFF) + +set(AC_CONFIG_H_IN "${PROJECT_SOURCE_DIR}/include/pqxx/config.h.in") +set(CM_CONFIG_H_IN "${PROJECT_BINARY_DIR}/include/pqxx/config_cmake.h.in") +set(CM_CONFIG_PUB "${PROJECT_BINARY_DIR}/include/pqxx/config-public-compiler.h") +set(CM_CONFIG_INT "${PROJECT_BINARY_DIR}/include/pqxx/config-internal-compiler.h") +set(CM_CONFIG_PQ "${PROJECT_BINARY_DIR}/include/pqxx/config-internal-libpq.h") +message(STATUS "Generating config.h") +file(WRITE "${CM_CONFIG_H_IN}" "") +file(STRINGS "${AC_CONFIG_H_IN}" lines) +foreach(line ${lines}) + string(REGEX REPLACE "^#undef" "#cmakedefine" l "${line}") + file(APPEND "${CM_CONFIG_H_IN}" "${l}\n") +endforeach() +configure_file("${CM_CONFIG_H_IN}" "${CM_CONFIG_INT}" @ONLY) +configure_file("${CM_CONFIG_H_IN}" "${CM_CONFIG_PUB}" @ONLY) +configure_file("${CM_CONFIG_H_IN}" "${CM_CONFIG_PQ}" @ONLY) +message(STATUS "Generating config.h - done") diff --git a/ext/libpqxx-7.7.3/cmake/libpqxx-config.cmake b/ext/libpqxx-7.7.3/cmake/libpqxx-config.cmake new file mode 100644 index 000000000..cb25a05f2 --- /dev/null +++ b/ext/libpqxx-7.7.3/cmake/libpqxx-config.cmake @@ -0,0 +1,4 @@ +include(CMakeFindDependencyMacro) +find_dependency(PostgreSQL) + +include("${CMAKE_CURRENT_LIST_DIR}/libpqxx-targets.cmake") diff --git a/ext/libpqxx-7.7.3/compile_flags.in b/ext/libpqxx-7.7.3/compile_flags.in new file mode 100644 index 000000000..1304e8aa8 --- /dev/null +++ b/ext/libpqxx-7.7.3/compile_flags.in @@ -0,0 +1 @@ +@CPPFLAGS@ @CXXFLAGS@ diff --git a/ext/libpqxx-7.7.3/config-tests/README.md b/ext/libpqxx-7.7.3/config-tests/README.md new file mode 100644 index 000000000..b3865d0f0 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/README.md @@ -0,0 +1,22 @@ +Configuration tests +=================== + +Libpqxx comes with support for different build systems: the GNU autotools, +CMake, Visual Studio's "nmake", and raw GNU "make" on Windows. + +For several of these build systems, we need to test things like "does this +compiler environment support `std::to_chars` for floating-point types?" + +We test these things by trying to compile a particular snippet of code, and +seeing whether that succeeds. + +To avoid duplicating those snippets for multiple build systems, we put them +here. Both the autotools configuration and the CMake configuration can refer to +them that way. + +It took a bit of nasty magic to read a C++ source file into m4 and treat it as +a string literal, without macro expansion. There is every chance that I missed +something, so be prepared for tests failing for unexpected reasons! Some C++ +syntax may end up having an unforeseen meaning in m4, and screw up the handling +of the code snippet. Re-configure, and read your logs carefully after editing +these snippets. diff --git a/ext/libpqxx-7.7.3/config-tests/charconv_float.cxx b/ext/libpqxx-7.7.3/config-tests/charconv_float.cxx new file mode 100644 index 000000000..bc5d973e3 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/charconv_float.cxx @@ -0,0 +1,16 @@ +// Test for std::to_string/std::from_string for floating-point types. +#include +#include + +int main() +{ + char z[100]; + auto rt = std::to_chars(std::begin(z), std::end(z), 3.14159L); + if (rt.ec != std::errc{}) + return 1; + long double n; + auto rf = std::from_chars(std::cbegin(z), std::cend(z), n); + if (rf.ec != std::errc{}) + return 2; + return (n > 3 and n < 4) ? 0 : 1; +} diff --git a/ext/libpqxx-7.7.3/config-tests/charconv_int.cxx b/ext/libpqxx-7.7.3/config-tests/charconv_int.cxx new file mode 100644 index 000000000..076ee0de3 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/charconv_int.cxx @@ -0,0 +1,16 @@ +// Test for std::to_string/std::from_string for integral types. +#include +#include + +int main() +{ + char z[100]; + auto rt = std::to_chars(std::begin(z), std::end(z), 9ULL); + if (rt.ec != std::errc{}) + return 1; + unsigned long long n; + auto rf = std::from_chars(std::cbegin(z), std::cend(z), n); + if (rf.ec != std::errc{}) + return 2; + return (n == 9ULL) ? 0 : 1; +} diff --git a/ext/libpqxx-7.7.3/config-tests/cmp.cxx b/ext/libpqxx-7.7.3/config-tests/cmp.cxx new file mode 100644 index 000000000..7f5abaa5d --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/cmp.cxx @@ -0,0 +1,8 @@ +// Test for C++20 std::cmp_greater etc. support. +#include + + +int main() +{ + return std::cmp_greater(-1, 2u) && std::cmp_less_equal(3, 0); +} diff --git a/ext/libpqxx-7.7.3/config-tests/concepts.cxx b/ext/libpqxx-7.7.3/config-tests/concepts.cxx new file mode 100644 index 000000000..5589b4e58 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/concepts.cxx @@ -0,0 +1,21 @@ +// Test for concepts support. Not just the language feature; also headers. +#include +#include +#include + + +template +concept Foo = std::ranges::input_range; + + +template auto foo(F const &r) +{ + return std::distance(std::begin(r), std::end(r)); +} + + +int main() +{ + std::vector const v{1, 2, 3}; + std::cout << foo(v) << '\n'; +} diff --git a/ext/libpqxx-7.7.3/config-tests/cxa_demangle.cxx b/ext/libpqxx-7.7.3/config-tests/cxa_demangle.cxx new file mode 100644 index 000000000..4d4ee7e6b --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/cxa_demangle.cxx @@ -0,0 +1,19 @@ +// Test for cross-vendor C++ ABI's __cxa_demangle function. +#include +#include +#include +#include + +#include + +int main() +{ + int status = 0; + char *name = + abi::__cxa_demangle(typeid(10).name(), nullptr, nullptr, &status); + if (status != 0) + throw std::runtime_error("Demangle failed!"); + int result = std::strcmp(name, "int"); + std::free(name); + return result; +} diff --git a/ext/libpqxx-7.7.3/config-tests/fs.cxx b/ext/libpqxx-7.7.3/config-tests/fs.cxx new file mode 100644 index 000000000..d93d37f5d --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/fs.cxx @@ -0,0 +1,9 @@ +// Check for working std::filesystem support. +#include + + +int main() +{ + // Apparently some versions of MinGW lack this comparison operator. + return std::filesystem::path{} != std::filesystem::path{}; +} diff --git a/ext/libpqxx-7.7.3/config-tests/gcc_pure.cxx b/ext/libpqxx-7.7.3/config-tests/gcc_pure.cxx new file mode 100644 index 000000000..4edd267c6 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/gcc_pure.cxx @@ -0,0 +1,10 @@ +// Test for gcc-style "pure" attribute. +int __attribute__((pure)) f() +{ + return 0; +} + +int main() +{ + return f(); +} diff --git a/ext/libpqxx-7.7.3/config-tests/gcc_visibility.cxx b/ext/libpqxx-7.7.3/config-tests/gcc_visibility.cxx new file mode 100644 index 000000000..23d0111d7 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/gcc_visibility.cxx @@ -0,0 +1,12 @@ +// Test for gcc-style "visibility" attribute. +struct __attribute__((visibility("hidden"))) D +{ + D() {} + int f() { return 0; } +}; + +int main() +{ + D d; + return d.f(); +} diff --git a/ext/libpqxx-7.7.3/config-tests/likely.cxx b/ext/libpqxx-7.7.3/config-tests/likely.cxx new file mode 100644 index 000000000..9d0eca8d3 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/likely.cxx @@ -0,0 +1,15 @@ +// Test for C++20 [[likely]] and [[unlikely]] attributes. + +int main(int argc, char **) +{ +#if __cplusplus < 202002L + deliberately_fail(because, older, C++, standard); +#endif + + int x = 0; + if (argc == 1) [[likely]] + x = 0; + else + x = 1; + return x; +} diff --git a/ext/libpqxx-7.7.3/config-tests/multidim-subscript.cxx b/ext/libpqxx-7.7.3/config-tests/multidim-subscript.cxx new file mode 100644 index 000000000..f75d1aa7a --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/multidim-subscript.cxx @@ -0,0 +1,14 @@ +// Test for multidimensional subscript operator support. +// Proposed for C++23: P2128R6. +struct table +{ + int width = 100; + + int operator[](int x, int y) const { return x + width * y; } +}; + + +int main() +{ + return table{}[0, 0]; +} diff --git a/ext/libpqxx-7.7.3/config-tests/need_fslib.cxx b/ext/libpqxx-7.7.3/config-tests/need_fslib.cxx new file mode 100644 index 000000000..041c46b43 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/need_fslib.cxx @@ -0,0 +1,21 @@ +// Check whether we need to link to the stdc++fs library. +// +// We assume that the presence of the header means that we have +// support for the basics of std::filesystem. This check will succeed if +// either there is no header, or there is one and it works without +// any special options. If the link fails, we assume that -lstdc++fs will fix +// it for us. + +#include + +#if __has_include() +# include +#endif + + +int main() +{ +#if __has_include() + std::cout << std::filesystem::path{"foo.bar"}.c_str() << '\n'; +#endif +} diff --git a/ext/libpqxx-7.7.3/config-tests/poll.cxx b/ext/libpqxx-7.7.3/config-tests/poll.cxx new file mode 100644 index 000000000..d67cef55d --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/poll.cxx @@ -0,0 +1,7 @@ +// Test for poll(). +#include + +int main() +{ + return poll(nullptr, 0, 0); +} diff --git a/ext/libpqxx-7.7.3/config-tests/sleep_for.cxx b/ext/libpqxx-7.7.3/config-tests/sleep_for.cxx new file mode 100644 index 000000000..f081fe0e5 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/sleep_for.cxx @@ -0,0 +1,28 @@ +// Test for std::this_thread::sleep_for(). +/* For some reason MinGW's header seems to be broken. + * + * But it gets worse. It looks as if we can include without problems + * in this configuration test. Why does it break when MinGW users try to build + * the library, but succeed when we try it here? + * + * To try and get close to the situation in the library code itself, we try + * including some standard headers that we don't strictly need here. + */ + +#if __has_include() +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +int main() +{ + std::this_thread::sleep_for(std::chrono::microseconds{10u}); +} diff --git a/ext/libpqxx-7.7.3/config-tests/span.cxx b/ext/libpqxx-7.7.3/config-tests/span.cxx new file mode 100644 index 000000000..8c13b97c9 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/span.cxx @@ -0,0 +1,8 @@ +// Test for std::span. +#include + +int main(int argc, char **argv) +{ + std::span args{argv, static_cast(argc)}; + return static_cast(std::size(args) - 1u); +} diff --git a/ext/libpqxx-7.7.3/config-tests/strerror_r.cxx b/ext/libpqxx-7.7.3/config-tests/strerror_r.cxx new file mode 100644 index 000000000..604d3b899 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/strerror_r.cxx @@ -0,0 +1,14 @@ +// Check for strerror_r. +// It can be either the POSIX version (which returns int) or the GNU version +// (which returns char *). + +#include +#include + +int main() +{ + char buffer[200]; + auto res{strerror_r(1, buffer, 200)}; + // Sidestep type differences. We don't really care what the value is. + return not not res; +} diff --git a/ext/libpqxx-7.7.3/config-tests/strerror_s.cxx b/ext/libpqxx-7.7.3/config-tests/strerror_s.cxx new file mode 100644 index 000000000..f6f99a7a5 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/strerror_s.cxx @@ -0,0 +1,11 @@ +// Test for strerror_s, as defined in Windows and C11. +// Presumably this'll be part of the C++ standard some day. + +#include + +int main() +{ + using namespace std; + char buf[200]; + return strerror_s(buf, 200, 1); +} diff --git a/ext/libpqxx-7.7.3/config-tests/thread_local.cxx b/ext/libpqxx-7.7.3/config-tests/thread_local.cxx new file mode 100644 index 000000000..b5a98b7b8 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/thread_local.cxx @@ -0,0 +1,15 @@ +// Test for std::to_string/std::from_string for floating-point types. +#include +#include + +int main(int argc, char **) +{ +#if defined(__MINGW32__) && defined(__GNUC__) +# if __GNUC__ < 11 || ((__GNUC__ == 11) && (__GNU_MINOR__ == 0)) +# error "On MinGW before gcc 11.1, thread_local breaks at run time." +# endif +#endif + thread_local std::stringstream s; + s << argc; + std::cout << s.str(); +} diff --git a/ext/libpqxx-7.7.3/config-tests/year_month_day.cxx b/ext/libpqxx-7.7.3/config-tests/year_month_day.cxx new file mode 100644 index 000000000..dbe543b55 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/year_month_day.cxx @@ -0,0 +1,7 @@ +// Test for std::chrono::year_month_day etc. +#include + +int main() +{ + return int(std::chrono::year{1}); +} diff --git a/ext/libpqxx-7.7.3/config/Makefile.am b/ext/libpqxx-7.7.3/config/Makefile.am new file mode 100644 index 000000000..f34b3107d --- /dev/null +++ b/ext/libpqxx-7.7.3/config/Makefile.am @@ -0,0 +1,8 @@ +EXTRA_DIST=m4/Makefile.am sample-headers +MAINTAINERCLEANFILES=Makefile.in config.guess config.sub install-sh \ + ltmain.sh missing mkinstalldirs + +dist-hook: + find "${distdir}" -type d -name CVS -print0 | xargs -0 rm -rf + find "${distdir}" -type d -name .svn -print0 | xargs -0 rm -rf + diff --git a/ext/libpqxx-7.7.3/config/Makefile.in b/ext/libpqxx-7.7.3/config/Makefile.in new file mode 100644 index 000000000..bf7aa004a --- /dev/null +++ b/ext/libpqxx-7.7.3/config/Makefile.in @@ -0,0 +1,470 @@ +# Makefile.in generated by automake 1.16.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = config +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/pqxx/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in compile config.guess \ + config.sub install-sh ltmain.sh missing mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_DOT = @HAVE_DOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PG_CONFIG = @PG_CONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +POSTGRES_INCLUDE = @POSTGRES_INCLUDE@ +PQXXVERSION = @PQXXVERSION@ +PQXX_ABI = @PQXX_ABI@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_postgres_lib = @with_postgres_lib@ +EXTRA_DIST = m4/Makefile.am sample-headers +MAINTAINERCLEANFILES = Makefile.in config.guess config.sub install-sh \ + ltmain.sh missing mkinstalldirs + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu config/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu config/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am dist-hook distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +dist-hook: + find "${distdir}" -type d -name CVS -print0 | xargs -0 rm -rf + find "${distdir}" -type d -name .svn -print0 | xargs -0 rm -rf + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ext/libpqxx-7.7.3/config/compile b/ext/libpqxx-7.7.3/config/compile new file mode 100755 index 000000000..df363c8fb --- /dev/null +++ b/ext/libpqxx-7.7.3/config/compile @@ -0,0 +1,348 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN* | MSYS*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/* | msys/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/ext/libpqxx-7.7.3/config/config.guess b/ext/libpqxx-7.7.3/config/config.guess new file mode 100755 index 000000000..c2246a4f7 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/config.guess @@ -0,0 +1,1502 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +# Free Software Foundation, Inc. + +timestamp='2009-12-30' + +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# 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 Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# 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;hb=HEAD + +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 (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 + +# 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 tupples: *-*-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=`(/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 ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + 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 + # 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/[-_].*/\./'` + ;; + 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}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${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 ;; + 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'` + exit ;; + 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:*:[456]) + 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/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + 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:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + 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-gnu`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 '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + 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="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${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-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + 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-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + 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-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + 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 configury 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 ;; + 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 ;; + 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 + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + 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 + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + 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 ;; + 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 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +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` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/ext/libpqxx-7.7.3/config/config.sub b/ext/libpqxx-7.7.3/config/config.sub new file mode 100755 index 000000000..c2d125724 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/config.sub @@ -0,0 +1,1714 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +# Free Software Foundation, Inc. + +timestamp='2010-01-22' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# 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. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# 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;hb=HEAD + +# 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 + $0 [OPTION] 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 (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + 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*) + 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 \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | 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 \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | rx \ + | score \ + | 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 \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-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-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | 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-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | 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-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile-* | tilegx-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | 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 + ;; + 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 + ;; + 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) + 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 + ;; + 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'm not sure what "Sysv32" means. Should this be sysv3.2? + 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 + ;; + 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 + ;; + mingw32) + basic_machine=i386-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 + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + 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 + ;; + 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) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + 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 | ppc64-le | powerpc64-little) + 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) + 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 + ;; + 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 + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + # This must be matched before tile*. + tilegx*) + basic_machine=tilegx-unknown + os=-linux-gnu + ;; + tile*) + basic_machine=tile-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 + ;; + 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* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -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* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -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*) + # 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 + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -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 + ;; + # 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 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/ext/libpqxx-7.7.3/config/depcomp b/ext/libpqxx-7.7.3/config/depcomp new file mode 100755 index 000000000..715e34311 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/ext/libpqxx-7.7.3/config/install-sh b/ext/libpqxx-7.7.3/config/install-sh new file mode 100755 index 000000000..6781b987b --- /dev/null +++ b/ext/libpqxx-7.7.3/config/install-sh @@ -0,0 +1,520 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2009-04-28.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/ext/libpqxx-7.7.3/config/ltmain.sh b/ext/libpqxx-7.7.3/config/ltmain.sh new file mode 100755 index 000000000..21e5e0784 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/ltmain.sh @@ -0,0 +1,11251 @@ +#! /bin/sh +## DO NOT EDIT - This file generated from ./build-aux/ltmain.in +## by inline-source v2014-01-03.01 + +# libtool (GNU libtool) 2.4.6 +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +PROGRAM=libtool +PACKAGE=libtool +VERSION="2.4.6 Debian-2.4.6-15" +package_revision=2.4.6 + + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2015-01-20.17; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac +fi + +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" + fi" +done + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are apparently some retarded systems that use ';' as a PATH separator! +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + + +## ------------------------- ## +## Locate command utilities. ## +## ------------------------- ## + + +# func_executable_p FILE +# ---------------------- +# Check that FILE is an executable regular file. +func_executable_p () +{ + test -f "$1" && test -x "$1" +} + + +# func_path_progs PROGS_LIST CHECK_FUNC [PATH] +# -------------------------------------------- +# Search for either a program that responds to --version with output +# containing "GNU", or else returned by CHECK_FUNC otherwise, by +# trying all the directories in PATH with each of the elements of +# PROGS_LIST. +# +# CHECK_FUNC should accept the path to a candidate program, and +# set $func_check_prog_result if it truncates its output less than +# $_G_path_prog_max characters. +func_path_progs () +{ + _G_progs_list=$1 + _G_check_func=$2 + _G_PATH=${3-"$PATH"} + + _G_path_prog_max=0 + _G_path_prog_found=false + _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} + for _G_dir in $_G_PATH; do + IFS=$_G_save_IFS + test -z "$_G_dir" && _G_dir=. + for _G_prog_name in $_G_progs_list; do + for _exeext in '' .EXE; do + _G_path_prog=$_G_dir/$_G_prog_name$_exeext + func_executable_p "$_G_path_prog" || continue + case `"$_G_path_prog" --version 2>&1` in + *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; + *) $_G_check_func $_G_path_prog + func_path_progs_result=$func_check_prog_result + ;; + esac + $_G_path_prog_found && break 3 + done + done + done + IFS=$_G_save_IFS + test -z "$func_path_progs_result" && { + echo "no acceptable sed could be found in \$PATH" >&2 + exit 1 + } +} + + +# We want to be able to use the functions in this file before configure +# has figured out where the best binaries are kept, which means we have +# to search for them ourselves - except when the results are already set +# where we skip the searches. + +# Unless the user overrides by setting SED, search the path for either GNU +# sed, or the sed that truncates its output the least. +test -z "$SED" && { + _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for _G_i in 1 2 3 4 5 6 7; do + _G_sed_script=$_G_sed_script$nl$_G_sed_script + done + echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed + _G_sed_script= + + func_check_prog_sed () + { + _G_path_prog=$1 + + _G_count=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo '' >> conftest.nl + "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + rm -f conftest.sed + SED=$func_path_progs_result +} + + +# Unless the user overrides by setting GREP, search the path for either GNU +# grep, or the grep that truncates its output the least. +test -z "$GREP" && { + func_check_prog_grep () + { + _G_path_prog=$1 + + _G_count=0 + _G_path_prog_max=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo 'GREP' >> conftest.nl + "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + GREP=$func_path_progs_result +} + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. + +: ${CP="cp -f"} +: ${ECHO="printf %s\n"} +: ${EGREP="$GREP -E"} +: ${FGREP="$GREP -F"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} + + +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## + +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' + +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: + +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 + +# The name of this program. +progname=`$ECHO "$progpath" |$SED "$sed_basename"` + +# Make sure we have an absolute progpath for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` + progdir=`cd "$progdir" && pwd` + progpath=$progdir/$progname + ;; + *) + _G_IFS=$IFS + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS=$_G_IFS + test -x "$progdir/$progname" && break + done + IFS=$_G_IFS + test -n "$progdir" || progdir=`pwd` + progpath=$progdir/$progname + ;; +esac + + +## ----------------- ## +## Standard options. ## +## ----------------- ## + +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. + +opt_dry_run=false +opt_quiet=false +opt_verbose=false + +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () +{ + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: +} + + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () +{ + $debug_cmd + + eval _G_current_value='`$ECHO $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () +{ + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` + _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + printf '%s\n%s\n' "$1" "$2" \ + | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n +} + +# func_lt_ver PREV CURR +# --------------------- +# Return true if PREV and CURR are in the correct order according to +# func_sort_ver, otherwise false. Use it like this: +# +# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." +func_lt_ver () +{ + $debug_cmd + + test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2015-10-07.11; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + _G_rc_run_hooks=false + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + if eval $_G_hook '"$@"'; then + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + _G_rc_run_hooks=: + fi + done + + $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, you may remove/edit +# any options that you action, and then pass back the remaining unprocessed +# options in '_result', escaped suitably for +# 'eval'. In this case you also must return $EXIT_SUCCESS to let the +# hook's caller know that it should pay attention to +# '_result'. Returning $EXIT_FAILURE signalizes that +# arguments are left untouched by the hook and therefore caller will ignore the +# result variable. +# +# Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# # No change in '$@' (ignored completely by this hook). There is +# # no need to do the equivalent (but slower) action: +# # func_quote_for_eval ${1+"$@"} +# # my_options_prep_result=$func_quote_for_eval_result +# false +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# args_changed=false +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: +# args_changed=: +# ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# args_changed=: +# ;; +# *) # Make sure the first unrecognised option "$_G_opt" +# # is added back to "$@", we could need that later +# # if $args_changed is true. +# set dummy "$_G_opt" ${1+"$@"}; shift; break ;; +# esac +# done +# +# if $args_changed; then +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# fi +# +# $args_changed +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# false +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll also need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. + + +# func_options_finish [ARG]... +# ---------------------------- +# Finishing the option parse loop (call 'func_options' hooks ATM). +func_options_finish () +{ + $debug_cmd + + _G_func_options_finish_exit=false + if func_run_hooks func_options ${1+"$@"}; then + func_options_finish_result=$func_run_hooks_result + _G_func_options_finish_exit=: + fi + + $_G_func_options_finish_exit +} + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + _G_rc_options=false + + for my_func in options_prep parse_options validate_options options_finish + do + if eval func_$my_func '${1+"$@"}'; then + eval _G_res_var='$'"func_${my_func}_result" + eval set dummy "$_G_res_var" ; shift + _G_rc_options=: + fi + done + + # Save modified positional parameters for caller. As a top-level + # options-parser function we always need to set the 'func_options_result' + # variable (regardless the $_G_rc_options value). + if $_G_rc_options; then + func_options_result=$_G_res_var + else + func_quote_for_eval ${1+"$@"} + func_options_result=$func_quote_for_eval_result + fi + + $_G_rc_options +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propagate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned). +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + _G_rc_options_prep=false + if func_run_hooks func_options_prep ${1+"$@"}; then + _G_rc_options_prep=: + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result + fi + + $_G_rc_options_prep +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + _G_rc_parse_options=false + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + if func_run_hooks func_parse_options ${1+"$@"}; then + eval set dummy "$func_run_hooks_result"; shift + _G_rc_parse_options=: + fi + + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break + + _G_match_parse_options=: + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; + + --warnings|--warning|-W) + if test $# = 0 && func_missing_arg $_G_opt; then + _G_rc_parse_options=: + break + fi + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) _G_rc_parse_options=: ; break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift + _G_match_parse_options=false + break + ;; + esac + + $_G_match_parse_options && _G_rc_parse_options=: + done + + + if $_G_rc_parse_options; then + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result + fi + + $_G_rc_parse_options +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + _G_rc_validate_options=false + + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" + + if func_run_hooks func_validate_options ${1+"$@"}; then + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result + _G_rc_validate_options=: + fi + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + $_G_rc_validate_options +} + + + +## ----------------- ## +## Helper functions. ## +## ----------------- ## + +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + eval \$ECHO \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message" + exit 0 +} + + +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $debug_cmd + + func_error "Missing argument for '$1'." + exit_cmd=exit +} + + +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_usage +# ---------- +# Echo short help message to standard output and exit. +func_usage () +{ + $debug_cmd + + func_usage_message + $ECHO "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 +} + + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$ECHO \""$usage_message"\" +} + + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n ' + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" + + exit $? +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: + +# Set a version string. +scriptversion='(GNU libtool) 2.4.6' + + +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + $debug_cmd + + $warning_func ${1+"$@"} +} + + +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" + +# Additional text appended to 'usage_message' in response to '--help'. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. + +When reporting a bug, please describe a test case to reproduce it and +include the following information: + + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname $scriptversion Debian-2.4.6-15 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` + +Report bugs to . +GNU libtool home page: . +General help using GNU software: ." + exit 0 +} + + +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. + +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } + + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi + + +# func_fatal_configuration ARG... +# ------------------------------- +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func__fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." +} + + +# func_config +# ----------- +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + + +# func_features +# ------------- +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test yes = "$build_libtool_libs"; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test yes = "$build_old_libs"; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + + +# func_enable_tag TAGNAME +# ----------------------- +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname=$1 + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + + +# func_check_version_match +# ------------------------ +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () +{ + $debug_mode + + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false + + nonopt= + preserve_args= + + _G_rc_lt_options_prep=: + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + *) + _G_rc_lt_options_prep=false + ;; + esac + + if $_G_rc_lt_options_prep; then + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result + fi + + $_G_rc_lt_options_prep +} +func_add_hook func_options_prep libtool_options_prep + + +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () +{ + $debug_cmd + + _G_rc_lt_parse_options=false + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_match_lt_parse_options=: + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"} ; shift + _G_match_lt_parse_options=false + break + ;; + esac + $_G_match_lt_parse_options && _G_rc_lt_parse_options=: + done + + if $_G_rc_lt_parse_options; then + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result + fi + + $_G_rc_lt_parse_options +} +func_add_hook func_parse_options libtool_parse_options + + + +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi + + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" + + case $host in + # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 + # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 + *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } + + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result +} +func_add_hook func_validate_options libtool_validate_options + + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift + + + +## ----------- ## +## Main. ## +## ----------- ## + +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# func_generated_by_libtool +# True iff stdin has been generated by Libtool. This function is only +# a basic sanity check; it will hardly flush out determined imposters. +func_generated_by_libtool_p () +{ + $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if 'file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case $lalib_p_line in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test yes = "$lalib_p" +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + test -f "$1" && + $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $debug_cmd + + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# 'FILE.' does not work on cygwin managed mounts. +func_source () +{ + $debug_cmd + + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case $lt_sysroot:$1 in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result='='$func_stripname_result + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $debug_cmd + + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with '--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' + else + write_lobj=none + fi + + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $debug_cmd + + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result= + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result"; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $debug_cmd + + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $debug_cmd + + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $debug_cmd + + if test -z "$2" && test -n "$1"; then + func_error "Could not determine host file name corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result=$1 + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $debug_cmd + + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " '$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result=$3 + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $debug_cmd + + case $4 in + $1 ) func_to_host_path_result=$3$func_to_host_path_result + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via '$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $debug_cmd + + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $debug_cmd + + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result=$1 +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result=$func_convert_core_msys_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via '$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $debug_cmd + + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd=func_convert_path_$func_stripname_result + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $debug_cmd + + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result=$1 +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_msys_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + +# func_mode_compile arg... +func_mode_compile () +{ + $debug_cmd + + # Get the compilation command and the source file. + base_compile= + srcfile=$nonopt # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg=$arg + arg_mode=normal + ;; + + target ) + libobj=$arg + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify '-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs=$IFS; IFS=, + for arg in $args; do + IFS=$save_ifs + func_append_quoted lastarg "$arg" + done + IFS=$save_ifs + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg=$srcfile + srcfile=$arg + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with '-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj=$func_basename_result + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from '$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name '$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test yes = "$build_old_libs"; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test yes = "$need_locks"; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test warn = "$need_locks"; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test yes = "$build_libtool_libs"; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test no != "$pic_mode"; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test yes = "$suppress_opt"; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test yes = "$compiler_c_o"; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test no != "$need_locks"; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a 'standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix '.c' with the +library object suffix, '.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to '-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the '--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the 'install' or 'cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE use a list of object files found in FILE to specify objects + -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with '-') are ignored. + +Every other argument is treated as a filename. Files ending in '.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in '.la', then a libtool library is created, +only library objects ('.lo' files) may be specified, and '-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. + +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode '$opt_mode'" + ;; + esac + + echo + $ECHO "Try '$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test : = "$opt_help"; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | $SED -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + $SED '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $debug_cmd + + # The first argument is the command name. + cmd=$nonopt + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "'$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "'$file' was not linked with '-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir=$func_dirname_result + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir=$func_dirname_result + ;; + + *) + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir=$absdir + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic=$magic + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file=$progdir/$program + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file=$progdir/$program + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd=\$cmd$args + fi +} + +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $debug_cmd + + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "'$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument '$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and '=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_quiet && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the '$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the '$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the '$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $debug_cmd + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac + then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=false + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=: ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the '$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir=$func_dirname_result + destname=$func_basename_result + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "'$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "'$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir=$func_dirname_result + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking '$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname=$1 + shift + + srcname=$realname + test -n "$relink_command" && srcname=${realname}T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme=$stripme + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme= + ;; + esac + ;; + os2*) + case $realname in + *_dll.a) + tstripme= + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try 'ln -sf' first, because the 'ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib=$destdir/$realname + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name=$func_basename_result + instname=$dir/${name}i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest=$destfile + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to '$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test yes = "$build_old_libs"; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext= + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=.exe + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script '$wrapper'" + + finalize=: + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test no = "$fast_install" && test -n "$relink_command"; then + $opt_dry_run || { + if $finalize; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file=$func_basename_result + outputname=$tmpdir/$file + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_quiet || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink '$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file=$outputname + else + func_warning "cannot relink '$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name=$func_basename_result + + # Set up the ranlib parameters. + oldlib=$destdir/$name + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run '$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test install = "$opt_mode" && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} + my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms=${my_outputname}S.c + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist=$output_objdir/$my_outputname.nm + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* External symbol declarations for the compiler. */\ +" + + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols=$output_objdir/$outputname.exp + $opt_dry_run || { + $RM $export_symbols + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from '$dlprefile'" + func_basename "$dlprefile" + name=$func_basename_result + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename= + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname"; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename=$func_basename_result + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename"; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + $my_pic_p && pic_flag_for_symtable=" $pic_flag" + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' + + # Transform the symbol file into the correct name. + symfileobj=$output_objdir/${my_outputname}S.$objext + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for '$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $debug_cmd + + win32_libid_type=unknown + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s|.*|import| + p + q + } + }'` + ;; + esac + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $debug_cmd + + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $debug_cmd + + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1"; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result= + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test yes = "$lock_old_archive_extraction"; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $debug_cmd + + my_gentop=$1; shift + my_oldlibs=${1+"$@"} + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib=$func_basename_result + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" + cd "$darwin_curdir" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result=$my_oldobjs +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory where it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ that is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options that match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test yes = "$fast_install"; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + \$ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* declarations of non-ANSI functions */ +#if defined __MINGW32__ +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined __CYGWIN__ +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined other_platform || defined ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined _MSC_VER +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +#elif defined __MINGW32__ +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined __CYGWIN__ +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined other platforms ... */ +#endif + +#if defined PATH_MAX +# define LT_PATHMAX PATH_MAX +#elif defined MAXPATHLEN +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free (stale); stale = 0; } \ +} while (0) + +#if defined LT_DEBUGWRAPPER +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + size_t tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined HAVE_DOS_BASED_FILE_SYSTEM + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined HAVE_DOS_BASED_FILE_SYSTEM + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = (size_t) (q - p); + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (STREQ (str, pat)) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + size_t len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + size_t orig_value_len = strlen (orig_value); + size_t add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[--len] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $debug_cmd + + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_suncc_cstd_abi +# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! +# Several compiler flags select an ABI that is incompatible with the +# Cstd library. Avoid specifying it if any are in CXXFLAGS. +func_suncc_cstd_abi () +{ + $debug_cmd + + case " $compile_command " in + *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) + suncc_use_cstd_abi=no + ;; + *) + suncc_use_cstd_abi=yes + ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $debug_cmd + + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # what system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll that has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + os2dllname= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=false + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module=$wl-single_module + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg=$1 + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir=$arg + prev= + continue + ;; + dlfiles|dlprefiles) + $preload || { + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=: + } + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test no = "$dlself"; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test dlprefiles = "$prev"; then + dlself=yes + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test dlfiles = "$prev"; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols=$arg + test -f "$arg" \ + || func_fatal_error "symbol file '$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex=$arg + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + if test none != "$pic_object"; then + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + fi + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file '$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + os2dllname) + os2dllname=$arg + prev= + continue + ;; + precious_regex) + precious_files_regex=$arg + prev= + continue + ;; + release) + release=-$arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test rpath = "$prev"; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds=$arg + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg=$arg + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "'-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test X-export-symbols = "X$arg"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between '-L' and '$1'" + else + func_fatal_error "need path for '-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test X-lc = "X$arg" || test X-lm = "X$arg"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test X-lc = "X$arg" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc due to us having libc/libc_r. + test X-lc = "X$arg" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test X-lc = "X$arg" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test X-lc = "X$arg" && continue + ;; + esac + elif test X-lc_r = "X$arg"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -mllvm) + prev=mllvm + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module=$wl-multi_module + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -os2dllname) + prev=os2dllname + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # -fstack-protector* stack protector flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -specs=* GCC specs files + # -stdlib=* select c++ std lib with clang + # -fsanitize=* Clang/GCC memory and address sanitizer + # -fuse-ld=* Linker select flags for GCC + # -static-* direct GCC to link specific libraries statically + # -fcilkplus Cilk Plus language extension features for C/C++ + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ + -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + -Z*) + if test os2 = "`expr $host : '.*\(os2\)'`"; then + # OS/2 uses -Zxxx to specify OS/2-specific options + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case $arg in + -Zlinker | -Zstack) + prev=xcompiler + ;; + esac + continue + else + # Otherwise treat like 'Some other compiler flag' below + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + fi + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + test none = "$pic_object" || { + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + } + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test dlfiles = "$prev"; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test dlprefiles = "$prev"; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the '$prevarg' option requires an argument" + + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname=$func_basename_result + libobjs_save=$libobjs + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + # Definition is injected by LT_CONFIG during libtool generation. + func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" + + func_dirname "$output" "/" "" + output_objdir=$func_dirname_result$objdir + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test lib = "$linkmode"; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=false + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test lib,link = "$linkmode,$pass"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs=$tmp_deplibs + fi + + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs + deplibs= + fi + if test prog = "$linkmode"; then + case $pass in + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test lib,dlpreopen = "$linkmode,$pass"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs=$dlprefiles + fi + if test dlopen = "$pass"; then + # Collect dlpreopened libraries + save_deplibs=$deplibs + deplibs= + fi + + for deplib in $libs; do + lib= + found=false + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test lib = "$linkmode"; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib=$searchdir/lib$name$search_ext + if test -f "$lib"; then + if test .la = "$search_ext"; then + found=: + else + found=false + fi + break 2 + fi + done + done + if $found; then + # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll=$l + done + if test "X$ll" = "X$old_library"; then # only static version available + found=false + func_dirname "$lib" "" "." + ladir=$func_dirname_result + lib=$ladir/$old_library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + *.ltframework) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test conv = "$pass" && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + if test scan = "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "'-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test link = "$pass"; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=false + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=: + fi + ;; + pass_all) + valid_a_lib=: + ;; + esac + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + fi + ;; + esac + continue + ;; + prog) + if test link != "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=: + continue + ;; + esac # case $deplib + + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "'$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir=$func_dirname_result + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test conv = "$pass"; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib=$l + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + + # This library was specified with -dlopen. + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" + if test -z "$dlname" || + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of '$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir=$ladir + fi + ;; + esac + func_basename "$lib" + laname=$func_basename_result + + # Find the relevant object directory and library name. + if test yes = "$installed"; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir + else + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir + fi + test yes = "$hardcode_automatic" && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir=$ladir + absdir=$abs_ladir + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" + fi + case $host in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test lib = "$linkmode"; then + deplibs="$dir/$old_library $deplibs" + elif test prog,link = "$linkmode,$pass"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test prog = "$linkmode" && test link != "$pass"; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if $linkalldeplibs; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test prog,link = "$linkmode,$pass"; then + if test -n "$library_names" && + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then + # Make sure the rpath contains only unique directories. + case $temp_rpath: in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test built = "$use_static_libs" && test yes = "$installed"; then + use_static_libs=no + fi + if test -n "$library_names" && + { test no = "$use_static_libs" || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc* | *os2*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test no = "$installed"; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule= + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule=$dlpremoduletest + break + fi + done + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then + echo + if test prog = "$linkmode"; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname=$1 + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname=$dlname + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc* | *os2*) + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + esac + eval soname=\"$soname_spec\" + else + soname=$realname + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot=$soname + func_basename "$soroot" + soname=$func_basename_result + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from '$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for '$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test prog = "$linkmode" || test relink != "$opt_mode"; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test no = "$hardcode_direct"; then + add=$dir/$linklib + case $host in + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir=-L$dir ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we cannot + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library"; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add=$dir/$old_library + fi + elif test -n "$old_library"; then + add=$dir/$old_library + fi + fi + esac + elif test no = "$hardcode_minus_L"; then + case $host in + *-*-sunos*) add_shlibpath=$dir ;; + esac + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + relink) + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test yes != "$lib_linked"; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test prog = "$linkmode"; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test prog = "$linkmode" || test relink = "$opt_mode"; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add=-l$name + elif test yes = "$hardcode_automatic"; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib + else + add=$libdir/$linklib + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir=-L$libdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + fi + + if test prog = "$linkmode"; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test prog = "$linkmode"; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test yes = "$build_libtool_libs"; then + # Not a shared library + if test pass_all != "$deplibs_check_method"; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system cannot link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test yes = "$module"; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test lib = "$linkmode"; then + if test -n "$dependency_libs" && + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs=$temp_deplibs + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test no != "$link_all_deplibs"; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path=$deplib ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" + path= + fi + fi + ;; + *) + path=-L$absdir/$objdir + ;; + esac + else + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "'$deplib' seems to be moved" + + path=-L$absdir + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test link = "$pass"; then + if test prog = "$linkmode"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test dlopen != "$pass"; then + test conv = "$pass" || { + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + } + + if test prog,link = "$linkmode,$pass"; then + vars="compile_deplibs finalize_deplibs" + else + vars=deplibs + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + + # Add Sun CC postdeps if required: + test CXX = "$tagname" && { + case $host_os in + linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C++ 5.9 + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + + solaris*) + func_cc_basename "$CC" + case $func_cc_basename_result in + CC* | sunCC*) + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + esac + } + + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i= + ;; + esac + if test -n "$i"; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test prog = "$linkmode"; then + dlfiles=$newdlfiles + fi + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "'-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "'-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs=$output + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form 'libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" + + if test no != "$need_lib_prefix"; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" + + install_libdir=$1 + + oldlibs= + if test -z "$rpath"; then + if test yes = "$build_libtool_libs"; then + # Building a libtool convenience library. + # Some compilers have problems with a '.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "'-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs=$IFS; IFS=: + set dummy $vinfo 0 0 0 + shift + IFS=$save_ifs + + test -n "$7" && \ + func_fatal_help "too many parameters to '-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major=$1 + number_minor=$2 + number_revision=$3 + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # that has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|freebsd-elf|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_revision + ;; + freebsd-aout|qnx|sunos) + current=$number_major + revision=$number_minor + age=0 + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_minor + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type '$version_type'" + ;; + esac + ;; + no) + current=$1 + revision=$2 + age=$3 + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac + ;; + + freebsd-aout) + major=.$current + versuffix=.$current.$revision + ;; + + freebsd-elf) + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + irix | nonstopux) + if test no = "$lt_irix_increment"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring=$verstring_prefix$major.$revision + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test 0 -ne "$loop"; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring_prefix$major.$iface:$verstring + done + + # Before this point, $major must not contain '.'. + major=.$major + versuffix=$major.$revision + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision + + # Add in all the interfaces that we are compatible with. + loop=$age + while test 0 -ne "$loop"; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring:$iface.0 + done + + # Make executables depend on our current version. + func_append verstring ":$current.0" + ;; + + qnx) + major=.$current + versuffix=.$current + ;; + + sco) + major=.$current + versuffix=.$current + ;; + + sunos) + major=.$current + versuffix=.$current.$revision + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 file systems. + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + + *) + func_fatal_configuration "unknown library version type '$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring=0.0 + ;; + esac + if test no = "$need_version"; then + versuffix= + else + versuffix=.0.0 + fi + fi + + # Remove version info from name if versioning should be avoided + if test yes,no = "$avoid_version,$need_version"; then + major= + versuffix= + verstring= + fi + + # Check to see if the archive will have undefined symbols. + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi + fi + else + # Don't allow undefined symbols. + allow_undefined_flag=$no_undefined_flag + fi + + fi + + func_generate_dlsyms "$libname" "$libname" : + func_append libobjs " $symfileobj" + test " " = "$libobjs" && libobjs= + + if test relink != "$opt_mode"; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles=$dlfiles + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles=$dlprefiles + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test yes = "$build_libtool_libs"; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test yes = "$build_libtool_need_lc"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release= + versuffix= + major= + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib=$potent_lib + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib=$potent_lib # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs= + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test none = "$deplibs_check_method"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test yes = "$droppeddeps"; then + if test yes = "$module"; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test no = "$allow_undefined"; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs=$new_libs + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test yes = "$hardcode_into_libs"; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname=$1 + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname=$realname + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib=$output_objdir/$realname + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + func_dll_def_p "$export_symbols" || { + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols=$export_symbols + export_symbols= + always_export_symbols=yes + } + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs=$IFS; IFS='~' + for cmd1 in $cmds; do + IFS=$save_ifs + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test yes = "$try_normal_branch" \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=$output_objdir/$output_la.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs=$tmp_deplibs + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test yes = "$compiler_needs_object" && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test : != "$skipped_export" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test yes = "$compiler_needs_object"; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-$k.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test -z "$objlist" || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test 1 -eq "$k"; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-$k.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-$k.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + } + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs=$IFS; IFS='~' + for cmd in $concat_cmds; do + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + ${skipped_export-false} && { + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + } + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs=$IFS; IFS='~' + for cmd in $cmds; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test yes = "$module" || test yes = "$export_dynamic"; then + # On all known operating systems, these are identical. + dlname=$soname + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "'-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object '$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj=$output + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # if reload_cmds runs $LD directly, get rid of -Wl from + # whole_archive_flag_spec and hope we can get by with turning comma + # into space. + case $reload_cmds in + *\$LD[\ \$]*) wl= ;; + esac + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags + else + gentop=$output_objdir/${obj}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects + + # Create the old-style object. + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs + + output=$obj + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + test yes = "$build_libtool_libs" || { + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + } + + if test -n "$pic_flag" || test default != "$pic_mode"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output=$libobj + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "'-release' is ignored for programs" + + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test CXX = "$tagname"; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs=$new_libs + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath=$rpath + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath=$rpath + + if test -n "$libobjs" && test yes = "$build_old_libs"; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" false + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=: + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=false + ;; + *cygwin* | *mingw* ) + test yes = "$build_libtool_libs" || wrappers_required=false + ;; + *) + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false + fi + ;; + esac + $wrappers_required || { + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command=$compile_command$compile_rpath + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' + fi + + exit $exit_status + } + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test yes = "$no_install"; then + # We don't need to create a wrapper script. + link_command=$compile_var$compile_command$compile_rpath + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host"; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience + build_libtool_libs=no + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) + oldobjs="$old_deplibs $non_pic_objects" + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac + + if test -n "$addlibs"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase=$func_basename_result + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj"; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test -z "$oldobjs"; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test yes = "$build_old_libs" && old_library=$libname.$libext + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test yes = "$hardcode_automatic"; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test yes = "$installed"; then + if test -z "$install_libdir"; then + break + fi + output=$output_objdir/${outputname}i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name=$func_basename_result + func_resolve_sysroot "$deplib" + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs=$newdependency_libs + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles=$newdlprefiles + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles=$newdlprefiles + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test -n "$bindir"; then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result/$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test no,yes = "$installed,$need_relink"; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $debug_cmd + + RM=$nonopt + files= + rmforce=false + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=: ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir + else + odir=$dir/$objdir + fi + func_basename "$file" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir + + # Remember odir for removal later, being careful to avoid duplicates + if test clean = "$opt_mode"; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif $rmforce; then + continue + fi + + rmfiles=$file + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case $opt_mode in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && test none != "$pic_object"; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && test none != "$non_pic_object"; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test clean = "$opt_mode"; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the $objdir's in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi + +test -z "$opt_mode" && { + help=$generic_help + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode '$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# where we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/ext/libpqxx-7.7.3/config/m4/Makefile.am b/ext/libpqxx-7.7.3/config/m4/Makefile.am new file mode 100644 index 000000000..c5dd1572f --- /dev/null +++ b/ext/libpqxx-7.7.3/config/m4/Makefile.am @@ -0,0 +1,3 @@ +MAINTAINERCLEANFILES=Makefile.in config.guess config.sub install-sh \ + ltmain.sh missing mkinstalldirs + diff --git a/ext/libpqxx-7.7.3/config/m4/libtool.m4 b/ext/libpqxx-7.7.3/config/m4/libtool.m4 new file mode 100644 index 000000000..c4c02946d --- /dev/null +++ b/ext/libpqxx-7.7.3/config/m4/libtool.m4 @@ -0,0 +1,8394 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +]) + +# serial 58 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_PREPARE_CC_BASENAME +# ----------------------- +m4_defun([_LT_PREPARE_CC_BASENAME], [ +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in @S|@*""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} +])# _LT_PREPARE_CC_BASENAME + + +# _LT_CC_BASENAME(CC) +# ------------------- +# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, +# but that macro is also expanded into generated libtool script, which +# arranges for $SED and $ECHO to be set by different means. +m4_defun([_LT_CC_BASENAME], +[m4_require([_LT_PREPARE_CC_BASENAME])dnl +AC_REQUIRE([_LT_DECL_SED])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +func_cc_basename $1 +cc_basename=$func_cc_basename_result +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl +m4_require([_LT_CMD_TRUNCATE])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from 'configure', and 'config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain=$ac_aux_dir/ltmain.sh +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the 'libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags='_LT_TAGS'dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# '#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test 0 = "$lt_write_fail" && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +'$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test 0 != $[#] +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try '$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try '$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test yes = "$silent" && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +_LT_COPYING +_LT_LIBTOOL_TAGS + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +_LT_PREPARE_MUNGE_PATH_LIST +_LT_PREPARE_CC_BASENAME + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS=$save_LDFLAGS + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[912]]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[[012]][[,.]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*|11.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + m4_if([$1], [CXX], +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case $ECHO in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([$with_sysroot]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and where our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cr} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test yes = "[$]$2"; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS +]) + +if test yes = "[$]$2"; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n "$lt_cv_sys_max_cmd_len"; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes = "$cross_compiling"; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen=shl_load], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen=dlopen], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then + + # We can hardcode non-existent directories. + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_PREPARE_MUNGE_PATH_LIST +# --------------------------- +# Make sure func_munge_path_list() is defined correctly. +m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], +[[# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x@S|@2 in + x) + ;; + *:) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" + ;; + x:*) + eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" + ;; + *) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + esac +} +]])# _LT_PREPARE_PATH_LIST + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +AC_ARG_VAR([LT_SYS_LIBRARY_PATH], +[User-defined run-time library search path.]) + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a[(]lib.so.V[)]' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], + [Detected run-time system search path for libraries]) +_LT_DECL([], [configure_time_lt_sys_library_path], [2], + [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program that can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac]) +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program that can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test no = "$withval" || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], +[if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi]) +rm -f conftest.i conftest2.i conftest.out]) +])# _LT_PATH_DD + + +# _LT_CMD_TRUNCATE +# ---------------- +# find command to truncate a binary pipe +m4_defun([_LT_CMD_TRUNCATE], +[m4_require([_LT_PATH_DD]) +AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) +_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], + [Command to truncate a binary pipe]) +])# _LT_CMD_TRUNCATE + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[[4-9]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi]) +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM=-lm) + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test yes = "$GCC"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(ld_shlibs, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + osf3*) + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting $shlibpath_var if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC=$CC +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report what library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC=$lt_save_CC +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)=$prev$p + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)=$p + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)=$p + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test no = "$F77"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_F77"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test no = "$FC"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_FC"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_FC" + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code=$lt_simple_compile_test_code + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f "$lt_ac_sed" && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test 10 -lt "$lt_ac_count" && break + lt_ac_count=`expr $lt_ac_count + 1` + if test "$lt_ac_count" -gt "$lt_ac_max"; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine what file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/ext/libpqxx-7.7.3/config/m4/ltoptions.m4 b/ext/libpqxx-7.7.3/config/m4/ltoptions.m4 new file mode 100644 index 000000000..94b082976 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/m4/ltoptions.m4 @@ -0,0 +1,437 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 8 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option '$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], + [_LT_WITH_AIX_SONAME([aix])]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_AIX_SONAME([DEFAULT]) +# ---------------------------------- +# implement the --with-aix-soname flag, and support the `aix-soname=aix' +# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT +# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +m4_define([_LT_WITH_AIX_SONAME], +[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl +shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[[5-9]]*,yes) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + AC_ARG_WITH([aix-soname], + [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) + with_aix_soname=$lt_cv_with_aix_soname]) + AC_MSG_RESULT([$with_aix_soname]) + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + +_LT_DECL([], [shared_archive_member_spec], [0], + [Shared archive member basename, for filename based shared library versioning on AIX])dnl +])# _LT_WITH_AIX_SONAME + +LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' +# LT_INIT options. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [pic_mode=m4_default([$1], [default])]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/ext/libpqxx-7.7.3/config/m4/ltsugar.m4 b/ext/libpqxx-7.7.3/config/m4/ltsugar.m4 new file mode 100644 index 000000000..48bc9344a --- /dev/null +++ b/ext/libpqxx-7.7.3/config/m4/ltsugar.m4 @@ -0,0 +1,124 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59, which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/ext/libpqxx-7.7.3/config/m4/ltversion.m4 b/ext/libpqxx-7.7.3/config/m4/ltversion.m4 new file mode 100644 index 000000000..fa04b52a3 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 4179 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.6]) +m4_define([LT_PACKAGE_REVISION], [2.4.6]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.6' +macro_revision='2.4.6' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/ext/libpqxx-7.7.3/config/m4/lt~obsolete.m4 b/ext/libpqxx-7.7.3/config/m4/lt~obsolete.m4 new file mode 100644 index 000000000..c6b26f88f --- /dev/null +++ b/ext/libpqxx-7.7.3/config/m4/lt~obsolete.m4 @@ -0,0 +1,99 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/ext/libpqxx-7.7.3/config/missing b/ext/libpqxx-7.7.3/config/missing new file mode 100755 index 000000000..1fe1611f1 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/ext/libpqxx-7.7.3/config/mkinstalldirs b/ext/libpqxx-7.7.3/config/mkinstalldirs new file mode 100755 index 000000000..6b3b5fc5d --- /dev/null +++ b/ext/libpqxx-7.7.3/config/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id$ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/ext/libpqxx-7.7.3/config/test-driver b/ext/libpqxx-7.7.3/config/test-driver new file mode 100755 index 000000000..8e575b017 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/test-driver @@ -0,0 +1,148 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2013-07-13.22; # UTC + +# Copyright (C) 2011-2014 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <$log_file 2>&1 +estatus=$? + +if test $enable_hard_errors = no && test $estatus -eq 99; then + tweaked_estatus=1 +else + tweaked_estatus=$estatus +fi + +case $tweaked_estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report the test outcome and exit status in the logs, so that one can +# know whether the test passed or failed simply by looking at the '.log' +# file, without the need of also peaking into the corresponding '.trs' +# file (automake bug#11814). +echo "$res $test_name (exit status: $estatus)" >>$log_file + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/ext/libpqxx-7.7.3/configitems b/ext/libpqxx-7.7.3/configitems new file mode 100644 index 000000000..e6f3925ef --- /dev/null +++ b/ext/libpqxx-7.7.3/configitems @@ -0,0 +1,26 @@ +PACKAGE internal autotools +PACKAGE_BUGREPORT internal autotools +PACKAGE_NAME internal autotools +PACKAGE_STRING internal autotools +PACKAGE_TARNAME internal autotools +PACKAGE_VERSION internal autotools +PQXX_HAVE_CHARCONV_INT internal compiler +PQXX_HAVE_CHARCONV_FLOAT internal compiler +PQXX_HAVE_CMP public compiler +PQXX_HAVE_CONCEPTS public compiler +PQXX_HAVE_CXA_DEMANGLE internal compiler +PQXX_HAVE_GCC_PURE public compiler +PQXX_HAVE_GCC_VISIBILITY public compiler +PQXX_HAVE_LIKELY public compiler +PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT public compiler +PQXX_HAVE_PATH public compiler +PQXX_HAVE_POLL internal compiler +PQXX_HAVE_PQENCRYPTPASSWORDCONN internal libpq +PQXX_HAVE_PQ_PIPELINE internal libpq +PQXX_HAVE_SLEEP_FOR internal compiler +PQXX_HAVE_SPAN public compiler +PQXX_HAVE_STRERROR_R internal compiler +PQXX_HAVE_STRERROR_S internal compiler +PQXX_HAVE_THREAD_LOCAL internal compiler +PQXX_HAVE_YEAR_MONTH_DAY public compiler +VERSION internal autotools diff --git a/ext/libpqxx-7.7.3/configure b/ext/libpqxx-7.7.3/configure new file mode 100755 index 000000000..4c58f19c2 --- /dev/null +++ b/ext/libpqxx-7.7.3/configure @@ -0,0 +1,20443 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for libpqxx 7.7.3. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and Jeroen T. +$0: Vermeulen about your system, including any error +$0: possibly output before this message. Then install a +$0: modern shell, or manually run the script under such a +$0: shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='libpqxx' +PACKAGE_TARNAME='libpqxx' +PACKAGE_VERSION='7.7.3' +PACKAGE_STRING='libpqxx 7.7.3' +PACKAGE_BUGREPORT='Jeroen T. Vermeulen' +PACKAGE_URL='' + +ac_unique_file="src/connection.cxx" +ac_default_prefix=/usr/local +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +with_postgres_lib +POSTGRES_INCLUDE +PG_CONFIG +PKG_CONFIG +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +BUILD_REFERENCE_FALSE +BUILD_REFERENCE_TRUE +HAVE_DOT +DOXYGEN +MKDIR +CXXCPP +CPP +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +ac_ct_CC +CFLAGS +CC +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CXX +CPPFLAGS +LDFLAGS +CXXFLAGS +CXX +PQXX_ABI +PQXXVERSION +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +CSCOPE +ETAGS +CTAGS +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL +am__quote' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_aix_soname +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_documentation +enable_maintainer_mode +enable_audit +enable_suggest +with_postgres_include +with_postgres_lib +' + ac_precious_vars='build_alias +host_alias +target_alias +CXX +CXXFLAGS +LDFLAGS +LIBS +CPPFLAGS +CCC +CC +CFLAGS +LT_SYS_LIBRARY_PATH +CPP +CXXCPP +DOXYGEN +HAVE_DOT' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures libpqxx 7.7.3 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/libpqxx] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of libpqxx 7.7.3:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-shared[=PKGS] build shared libraries [default=no] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-documentation Generate documentation + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer + + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + --with-postgres-include=DIR + Use PostgreSQL includes from DIR. Defaults to + querying pg_config or pkg-config, whichever is + available. + --with-postgres-lib=DIR Use PostgreSQL libraries from DIR. Defaults to + querying pg_config. + +Some influential environment variables: + CXX C++ compiler command + CXXFLAGS C++ compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CC C compiler command + CFLAGS C compiler flags + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + CPP C preprocessor + CXXCPP C++ preprocessor + DOXYGEN Path to doxygen needed to build reference documentation + HAVE_DOT Variable used by doxygen to declare availibility of dot + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +libpqxx configure 7.7.3 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES +# --------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_cxx_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ---------------------------------- ## +## Report this to Jeroen T. Vermeulen ## +## ---------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_header_mongrel +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by libpqxx $as_me 7.7.3, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + +ac_aux_dir= +for ac_dir in config "$srcdir"/config; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + + +am__api_version='1.16' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + MISSING="\${SHELL} '$am_aux_dir/missing'" +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='libpqxx' + VERSION='7.7.3' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + +# Variables for tags utilities; see am/tags.am +if test -z "$CTAGS"; then + CTAGS=ctags +fi + +if test -z "$ETAGS"; then + ETAGS=etags +fi + +if test -z "$CSCOPE"; then + CSCOPE=cscope +fi + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + + +PQXX_ABI=7.7 +PQXXVERSION=$PACKAGE_VERSION + + + +ac_config_headers="$ac_config_headers include/pqxx/config.h" + + +# Default prefix for installs. + + + +# Read test programme from config-test. + + + +# Checks for programs. +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 +$as_echo_n "checking whether the C++ compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C++ compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 +$as_echo_n "checking for C++ compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : + ;; +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +$as_echo "${_am_result}" >&6; } + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + +# Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_shared=no +fi + + + + + + + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cr} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +$as_echo "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +$as_echo_n "checking for a working dd... " >&6; } +if ${ac_cv_path_lt_DD+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in dd; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +$as_echo "$ac_cv_path_lt_DD" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +$as_echo_n "checking how to truncate binary pipes... " >&6; } +if ${lt_cv_truncate_bin+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +$as_echo "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cr libconftest.a conftest.o" >&5 + $AR cr libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[912]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*|11.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + +func_stripname_cnf () +{ + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + pic_mode=default +fi + + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +$as_echo_n "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test "${with_aix_soname+set}" = set; then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else + if ${lt_cv_with_aix_soname+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +$as_echo "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + link_all_deplibs=no + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen=shl_load +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen=dlopen +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +CC=$lt_save_CC + + if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct_CXX=no + hardcode_direct_absolute_CXX=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec_CXX='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + no_undefined_flag_CXX='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' $wl-bernotok' + allow_undefined_flag_CXX=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='$wl--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + if test yes != "$lt_cv_apple_cc_single_mod"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + os2*) + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_minus_L_CXX=yes + allow_undefined_flag_CXX=unsupported + shrext_cmds=.dll + archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes_CXX=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='$wl-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='$wl-E' + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + no_undefined_flag_CXX=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + fi + + hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='$wl-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='$wl-z,text' + allow_undefined_flag_CXX='$wl-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test no = "$ld_shlibs_CXX" && can_build_shared=no + + GCC_CXX=$GXX + LD_CXX=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX=$prev$p + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX=$prev$p + else + postdeps_CXX="${postdeps_CXX} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX=$p + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX=$p + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + lt_prog_compiler_pic_CXX='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static_CXX='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test no = "$ld_shlibs_CXX" && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec_CXX='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test yes = "$hardcode_automatic_CXX"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct_CXX" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && + test no != "$hardcode_minus_L_CXX"; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test relink = "$hardcode_action_CXX" || + test yes = "$inherit_rpath_CXX"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Extract the first word of "mkdir", so it can be a program name with args. +set dummy mkdir; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MKDIR+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MKDIR in + [\\/]* | ?:[\\/]*) + ac_cv_path_MKDIR="$MKDIR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_MKDIR="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +MKDIR=$ac_cv_path_MKDIR +if test -n "$MKDIR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR" >&5 +$as_echo "$MKDIR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +# Documentation. +# Check whether --enable-documentation was given. +if test "${enable_documentation+set}" = set; then : + enableval=$enable_documentation; +else + enable_documentation=auto +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}doxygen", so it can be a program name with args. +set dummy ${ac_tool_prefix}doxygen; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_DOXYGEN+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $DOXYGEN in + [\\/]* | ?:[\\/]*) + ac_cv_path_DOXYGEN="$DOXYGEN" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +DOXYGEN=$ac_cv_path_DOXYGEN +if test -n "$DOXYGEN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 +$as_echo "$DOXYGEN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_DOXYGEN"; then + ac_pt_DOXYGEN=$DOXYGEN + # Extract the first word of "doxygen", so it can be a program name with args. +set dummy doxygen; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_DOXYGEN+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_DOXYGEN in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_DOXYGEN="$ac_pt_DOXYGEN" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_DOXYGEN=$ac_cv_path_ac_pt_DOXYGEN +if test -n "$ac_pt_DOXYGEN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DOXYGEN" >&5 +$as_echo "$ac_pt_DOXYGEN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_DOXYGEN" = x; then + DOXYGEN="nodoxygen" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DOXYGEN=$ac_pt_DOXYGEN + fi +else + DOXYGEN="$ac_cv_path_DOXYGEN" +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dot", so it can be a program name with args. +set dummy ${ac_tool_prefix}dot; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_HAVE_DOT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAVE_DOT"; then + ac_cv_prog_HAVE_DOT="$HAVE_DOT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in NO +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_HAVE_DOT="${ac_tool_prefix}dot" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +HAVE_DOT=$ac_cv_prog_HAVE_DOT +if test -n "$HAVE_DOT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_DOT" >&5 +$as_echo "$HAVE_DOT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_HAVE_DOT"; then + ac_ct_HAVE_DOT=$HAVE_DOT + # Extract the first word of "dot", so it can be a program name with args. +set dummy dot; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_HAVE_DOT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_HAVE_DOT"; then + ac_cv_prog_ac_ct_HAVE_DOT="$ac_ct_HAVE_DOT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in NO +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_HAVE_DOT="dot" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_HAVE_DOT=$ac_cv_prog_ac_ct_HAVE_DOT +if test -n "$ac_ct_HAVE_DOT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_HAVE_DOT" >&5 +$as_echo "$ac_ct_HAVE_DOT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_HAVE_DOT" = x; then + HAVE_DOT="YES" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + HAVE_DOT=$ac_ct_HAVE_DOT + fi +else + HAVE_DOT="$ac_cv_prog_HAVE_DOT" +fi + +if test "$enable_documentation" = "yes" && test "$DOXYGEN" = "nodoxygen"; then : + as_fn_error $? "could not find tools necessary to build documentation" "$LINENO" 5 +fi + if test "$enable_documentation" != "no" -a "$DOXYGEN" != "nodoxygen"; then + BUILD_REFERENCE_TRUE= + BUILD_REFERENCE_FALSE='#' +else + BUILD_REFERENCE_TRUE='#' + BUILD_REFERENCE_FALSE= +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + +# See if we want stricter compiler warnings. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking maintainer mode" >&5 +$as_echo_n "checking maintainer mode... " >&6; } +# Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_maintainer_mode}" >&5 +$as_echo "${enable_maintainer_mode}" >&6; } + +# See if we want runtime debug checking. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking audit" >&5 +$as_echo_n "checking audit... " >&6; } +# Check whether --enable-audit was given. +if test "${enable_audit+set}" = set; then : + enableval=$enable_audit; +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_audit}" >&5 +$as_echo "${enable_audit}" >&6; } + +# See if we want "suggestions," such as "this class could be final." +# (The suggestions are often useful, but can also easily be wrong.) +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking suggest" >&5 +$as_echo_n "checking suggest... " >&6; } +# Check whether --enable-suggest was given. +if test "${enable_suggest+set}" = set; then : + enableval=$enable_suggest; +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_suggest}" >&5 +$as_echo "${enable_suggest}" >&6; } + + +# Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; +fi + +if test "${shared}" = "yes" ; then : + CPPFLAGS="$CPPFLAGS -DPQXX_SHARED" +fi + + +# Add options to compiler command line, if compiler accepts them. +add_compiler_opts_if_ok() { + for option in $* + do + ACO_SAVE_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $option" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts $option" >&5 +$as_echo_n "checking whether $CXX accepts $option... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + has_option=yes +else + has_option=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_option" >&5 +$as_echo "$has_option" >&6; } + if test "$has_option" = "no" ; then : + CXXFLAGS="$ACO_SAVE_CXXFLAGS" +fi + done +} + + +# Add options to compiler command line, unconditionally. +add_compiler_opts() { + CXXFLAGS="$CXXFLAGS $*" +} + + +# It's tempting to use Autoconf Archive's AX_CXX_COMPILE_STDCXX_17 for this, +# but it's 2022 and the C++20 equivalent isn't quite ready for use. +# Seems simpler and more reliable for the user to arrange for the desired +# language versions by setting the appropriate option for their compiler. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sufficient C++ language/library level" >&5 +$as_echo_n "checking for sufficient C++ language/library level... " >&6; } +sufficient_cxx=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #if __cplusplus < 201611L + #error "Need C++17 or better." + #endif + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + sufficient_cxx=yes +else + sufficient_cxx=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sufficient_cxx" >&5 +$as_echo "$sufficient_cxx" >&6; } +if test "$sufficient_cxx" != "yes" +then + as_fn_error $? "This libpqxx version needs at least C++17." "$LINENO" 5 +fi + + +# Let's try to get the compiler to be helpful. +# +# (Omit options -Weffc++ and -Wabi because they currently yield too many +# warnings in gcc's standard headers; omit -Wunreachable-code because it isn't +# always right) +if test "$GCC" = "yes" +then + # In maintainer mode, enable all the warning options we can. + if test "$enable_maintainer_mode" = "yes" + then + # "Eternal" (FLW) g++ options. These have been around for + # ages, and both g++ and clang++ support them. Don't bother + # checking for support; just add them to the compiler options. + add_compiler_opts \ + -fstrict-enums \ + -Werror \ + -Wall \ + -pedantic \ + -Wcast-align \ + -Wcast-qual \ + -Wconversion \ + -Wctor-dtor-privacy \ + -Wendif-labels \ + -Wextra \ + -Wfloat-equal \ + -Wformat=2 \ + -Wformat-security \ + -Wmissing-include-dirs \ + -Wno-div-by-zero \ + -Wnon-virtual-dtor \ + -Wold-style-cast \ + -Woverlength-strings \ + -Woverloaded-virtual \ + -Wpointer-arith \ + -Wredundant-decls \ + -Wshadow \ + -Wsign-promo \ + -Wundef \ + -Wunused \ + -Wwrite-strings + + # "Iffy" g++ options. Some reasonably current g++-like + # compilers may not support these. + add_compiler_opts_if_ok \ + -fnothrow-opt \ + -Wattribute-alias=2 \ + -Wextra-semi \ + -Wlogical-op \ + -Wmismatched-tags \ + -Wnoexcept \ + -Wredundant-tags \ + -Wrestrict \ + -Wstringop-overflow \ + -Wzero-as-null-pointer-constant \ + -Warray-bounds=2 \ + -Wduplicated-branches \ + -Wduplicated-cond \ + -Wsuggest-attribute=noreturn \ + -Wsuggest-override \ + -Wtrampolines + fi + + # In "audit," enable all runtime checks we can. + if test "$enable_audit" = "yes" + then + add_compiler_opts_if_ok \ + -D_FORTIFY_SOURCE=2 \ + -fsanitize=address \ + -fsanitize-address-use-after-scope \ + -fsanitize=alignment \ + -fsanitize=bool \ + -fsanitize=bounds \ + -fsanitize=bounds-strict \ + -fsanitize=builtin \ + -fsanitize=enum \ + -fsanitize=float-cast-overflow \ + -fsanitize=float-divide-by-zero \ + -fsanitize=integer-divide-by-zero \ + -fsanitize=leak \ + -fsanitize=nonnull-attribute \ + -fsanitize=null \ + -fsanitize=object-size \ + -fsanitize=pointer-compare \ + -fsanitize=pointer-overflow \ + -fsanitize=pointer-subtract \ + -fsanitize=return \ + -fsanitize=returns-nonnull-attribute \ + -fsanitize=shift \ + -fsanitize=shift-base \ + -fsanitize=shift-exponent \ + -fsanitize=signed-integer-overflow \ + -fsanitize=undefined \ + -fsanitize=unreachable \ + -fsanitize=vla-bound \ + -fsanitize=vptr \ + -fstack-protector-all + fi + + # In "suggest" mode, enable a bunch of code suggestions. + if test "$enable_suggest" = "yes" + then + add_compiler_opts_if_ok \ + -Wsuggest-attribute=cold \ + -Wsuggest-attribute=const \ + -Wsuggest-attribute=malloc \ + -Wsuggest-attribute=pure \ + -Wsuggest-final-types \ + -Wsuggest-final-methods + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking g++ visibility attribute" >&5 +$as_echo_n "checking g++ visibility attribute... " >&6; } +gcc_visibility=yes +SAVE_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for gcc-style "visibility" attribute. + +struct __attribute__((visibility("hidden"))) D + +{ + + D() {} + + int f() { return 0; } + +}; + + + +int main() + +{ + + D d; + + return d.f(); + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_GCC_VISIBILITY 1" >>confdefs.h + +else + gcc_visibility=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_visibility" >&5 +$as_echo "$gcc_visibility" >&6; } +CXXFLAGS="$SAVE_CXXFLAGS" +if test "$gcc_visibility" = "yes" +then + # Make internal definitions accessible only to the library itself. + # Only definitions marked PQXX_LIBEXPORT will be accessible. + add_compiler_opts -fvisibility=hidden + add_compiler_opts -fvisibility-inlines-hidden +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking g++ pure attribute" >&5 +$as_echo_n "checking g++ pure attribute... " >&6; } +gcc_pure=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for gcc-style "pure" attribute. + +int __attribute__((pure)) f() + +{ + + return 0; + +} + + + +int main() + +{ + + return f(); + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_GCC_PURE 1" >>confdefs.h + +else + gcc_pure=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_pure" >&5 +$as_echo "$gcc_pure" >&6; } + +fi # End of gcc-specific part. + + +# Check for __cxa_demangle. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking __cxa_demangle" >&5 +$as_echo_n "checking __cxa_demangle... " >&6; } +cxa_demangle=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for cross-vendor C++ ABI's __cxa_demangle function. + +#include + +#include + +#include + +#include + + + +#include + + + +int main() + +{ + + int status = 0; + + char *name = + + abi::__cxa_demangle(typeid(10).name(), nullptr, nullptr, &status); + + if (status != 0) + + throw std::runtime_error("Demangle failed!"); + + int result = std::strcmp(name, "int"); + + std::free(name); + + return result; + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_CXA_DEMANGLE 1" >>confdefs.h + +else + cxa_demangle=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cxa_demangle" >&5 +$as_echo "$cxa_demangle" >&6; } + + +# Check for sufficient Concepts support, introduced with C++20. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking concepts" >&5 +$as_echo_n "checking concepts... " >&6; } +concepts=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for concepts support. Not just the language feature; also headers. + +#include + +#include + +#include + + + + + +template + +concept Foo = std::ranges::input_range; + + + + + +template auto foo(F const &r) + +{ + + return std::distance(std::begin(r), std::end(r)); + +} + + + + + +int main() + +{ + + std::vector const v{1, 2, 3}; + + std::cout << foo(v) << '\n'; + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_CONCEPTS 1" >>confdefs.h + +else + concepts=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $concepts" >&5 +$as_echo "$concepts" >&6; } + + +# Check for C++20 std::span. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking std::span" >&5 +$as_echo_n "checking std::span... " >&6; } +span=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for std::span. + +#include + + + +int main(int argc, char **argv) + +{ + + std::span args{argv, static_cast(argc)}; + + return static_cast(std::size(args) - 1u); + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_SPAN 1" >>confdefs.h + +else + span=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $span" >&5 +$as_echo "$span" >&6; } + + +# Check for multidimensional subscript operator support. Proposed for C++23. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for multidimensional subscript operator support" >&5 +$as_echo_n "checking for multidimensional subscript operator support... " >&6; } +multidim_subscript=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for multidimensional subscript operator support. + +// Proposed for C++23: P2128R6. + +struct table + +{ + + int width = 100; + + + + int operator[](int x, int y) const { return x + width * y; } + +}; + + + + + +int main() + +{ + + return table{}[0, 0]; + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT 1" >>confdefs.h + +else + multidim_subscript=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $multidim_subscript" >&5 +$as_echo "$multidim_subscript" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for strerror_r()" >&5 +$as_echo_n "checking for strerror_r()... " >&6; } +strerror_r=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Check for strerror_r. + +// It can be either the POSIX version (which returns int) or the GNU version + +// (which returns char *). + + + +#include + +#include + + + +int main() + +{ + + char buffer[200]; + + auto res{strerror_r(1, buffer, 200)}; + + // Sidestep type differences. We don't really care what the value is. + + return not not res; + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_STRERROR_R 1" >>confdefs.h + +else + strerror_r=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $strerror_r" >&5 +$as_echo "$strerror_r" >&6; } + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for strerror_s()" >&5 +$as_echo_n "checking for strerror_s()... " >&6; } +strerror_s=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for strerror_s, as defined in Windows and C11. + +// Presumably this'll be part of the C++ standard some day. + + + +#include + + + +int main() + +{ + + using namespace std; + + char buf[200]; + + return strerror_s(buf, 200, 1); + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_STRERROR_S 1" >>confdefs.h + +else + strerror_s=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $strerror_s" >&5 +$as_echo "$strerror_s" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::chrono::year_month_day etc" >&5 +$as_echo_n "checking for std::chrono::year_month_day etc... " >&6; } +year_month_day=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for std::chrono::year_month_day etc. + +#include + + + +int main() + +{ + + return int(std::chrono::year{1}); + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_YEAR_MONTH_DAY 1" >>confdefs.h + +else + year_month_day=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $year_month_day" >&5 +$as_echo "$year_month_day" >&6; } + + +# Check for [[likely]] and [[unlikely]] attributes. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking attributes \"likely\" and \"unlikely\"." >&5 +$as_echo_n "checking attributes \"likely\" and \"unlikely\".... " >&6; } +likely=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for C++20 [[likely]] and [[unlikely]] attributes. + + + +int main(int argc, char **) + +{ + +#if __cplusplus < 202002L + + deliberately_fail(because, older, C++, standard); + +#endif + + + + int x = 0; + + if (argc == 1) [[likely]] + + x = 0; + + else + + x = 1; + + return x; + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_LIKELY 1" >>confdefs.h + +else + likely=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $likely" >&5 +$as_echo "$likely" >&6; } + + +# It's mid-2019, and gcc's charconv supports integers but not yet floats. +# So for now, we test for int and float conversion... separately. +# +# It's worse for older clang versions, which compile the integer conversions +# but then fail at link time because of a missing symbol "__muloti4" with the +# "long long" version. I couldn't resolve that symbol by adding -lm either. +# So don't just compile these tests; link them as well. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++17 charconv integer conversion" >&5 +$as_echo_n "checking for C++17 charconv integer conversion... " >&6; } +have_charconv_int=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for std::to_string/std::from_string for integral types. + +#include + +#include + + + +int main() + +{ + + char z[100]; + + auto rt = std::to_chars(std::begin(z), std::end(z), 9ULL); + + if (rt.ec != std::errc{}) + + return 1; + + unsigned long long n; + + auto rf = std::from_chars(std::cbegin(z), std::cend(z), n); + + if (rf.ec != std::errc{}) + + return 2; + + return (n == 9ULL) ? 0 : 1; + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_CHARCONV_INT 1" >>confdefs.h + +else + have_charconv_int=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_charconv_int" >&5 +$as_echo "$have_charconv_int" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++17 charconv floating-point conversion" >&5 +$as_echo_n "checking for C++17 charconv floating-point conversion... " >&6; } +have_charconv_float=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for std::to_string/std::from_string for floating-point types. + +#include + +#include + + + +int main() + +{ + + char z[100]; + + auto rt = std::to_chars(std::begin(z), std::end(z), 3.14159L); + + if (rt.ec != std::errc{}) + + return 1; + + long double n; + + auto rf = std::from_chars(std::cbegin(z), std::cend(z), n); + + if (rf.ec != std::errc{}) + + return 2; + + return (n > 3 and n < 4) ? 0 : 1; + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_CHARCONV_FLOAT 1" >>confdefs.h + +else + have_charconv_float=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_charconv_float" >&5 +$as_echo "$have_charconv_float" >&6; } + +# As per #262, clang with libcxxrt does not support thread_local on non-POD +# objects. Luckily we can live without those, it's just less efficient. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for full thread_local support" >&5 +$as_echo_n "checking for full thread_local support... " >&6; } +have_thread_local=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for std::to_string/std::from_string for floating-point types. + +#include + +#include + + + +int main(int argc, char **) + +{ + +#if defined(__MINGW32__) && defined(__GNUC__) + +# if __GNUC__ < 11 || ((__GNUC__ == 11) && (__GNU_MINOR__ == 0)) + +# error "On MinGW before gcc 11.1, thread_local breaks at run time." + +# endif + +#endif + + thread_local std::stringstream s; + + s << argc; + + std::cout << s.str(); + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_THREAD_LOCAL 1" >>confdefs.h + +else + have_thread_local=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_thread_local" >&5 +$as_echo "$have_thread_local" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::this_thread::sleep_for" >&5 +$as_echo_n "checking for std::this_thread::sleep_for... " >&6; } +have_sleep_for=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for std::this_thread::sleep_for(). + +/* For some reason MinGW's header seems to be broken. + + * + + * But it gets worse. It looks as if we can include without problems + + * in this configuration test. Why does it break when MinGW users try to build + + * the library, but succeed when we try it here? + + * + + * To try and get close to the situation in the library code itself, we try + + * including some standard headers that we don't strictly need here. + + */ + + + +#if __has_include() + +# include + +#endif + + + +#include + +#include + +#include + +#include + +#include + + + +#include + +#include + + + +int main() + +{ + + std::this_thread::sleep_for(std::chrono::microseconds{10u}); + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_SLEEP_FOR 1" >>confdefs.h + +else + have_sleep_for=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_sleep_for" >&5 +$as_echo "$have_sleep_for" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::cmp_greater, std::cmp_less_equal, etc" >&5 +$as_echo_n "checking for std::cmp_greater, std::cmp_less_equal, etc... " >&6; } +have_cmp=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for C++20 std::cmp_greater etc. support. + +#include + + + + + +int main() + +{ + + return std::cmp_greater(-1, 2u) && std::cmp_less_equal(3, 0); + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_CMP 1" >>confdefs.h + +else + have_cmp=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_cmp" >&5 +$as_echo "$have_cmp" >&6; } + + +# Doing my own check for poll(). There's one built into autoconf-archive, but +# it produces warnings in C++ (about unnecessarily using "struct", and using 0 +# as a null pointer constant). In maintainer mode, those warnings turn into +# errors. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for poll()" >&5 +$as_echo_n "checking for poll()... " >&6; } +ax_cv_have_poll=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for poll(). + +#include + + + +int main() + +{ + + return poll(nullptr, 0, 0); + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_POLL 1" >>confdefs.h + +else + ax_cv_have_poll=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have_poll" >&5 +$as_echo "$ax_cv_have_poll" >&6; } + +if test "$ax_cv_have_poll" != "yes" +then +# No poll(); we'll fall back to select(). + +# Some systems keep select() in a separate library which is not linked by +# default. See if we need one of those. +socklibok=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing select" >&5 +$as_echo_n "checking for library containing select... " >&6; } +if ${ac_cv_search_select+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char select (); +int +main () +{ +return select (); + ; + return 0; +} +_ACEOF +for ac_lib in '' socket nsl ws2_32 wsock32 winsock; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_search_select=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_select+:} false; then : + break +fi +done +if ${ac_cv_search_select+:} false; then : + +else + ac_cv_search_select=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_select" >&5 +$as_echo "$ac_cv_search_select" >&6; } +ac_res=$ac_cv_search_select +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + socklibok=yes +fi + + +# Microsoft proprietary libraries do not work with code that is generated with +# autoconf's SEARCH_LIBS macro, so we need to check manually and just use the +# first socket library available. +# We only do this if select() is not available by other means, to avoid picking +# up an unnecessary Windows compatibility library on a non-Windows system. +for l in ws2_32 wsock32 winsock +do + if test "${socklibok}" != "yes" + then + as_ac_Lib=`$as_echo "ac_cv_lib_$l''_main" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -l$l" >&5 +$as_echo_n "checking for main in -l$l... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-l$l $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + LIBS="$LIBS -l$l";socklibok=yes +fi + + fi +done + +if test "${socklibok}" != "yes" +then + as_fn_error $? " +Could not figure out how to link a simple sockets-based program. Please read +the config.log file for more clues as to why this failed. +" "$LINENO" 5 +fi + +fi # No poll() + + +# Find PostgreSQL includes and libraries +# Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +for ac_prog in pg_config +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PG_CONFIG="$PG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PG_CONFIG=$ac_cv_path_PG_CONFIG +if test -n "$PG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PG_CONFIG" >&5 +$as_echo "$PG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PG_CONFIG" && break +done + + + +# Check whether --with-postgres-include was given. +if test "${with_postgres_include+set}" = set; then : + withval=$with_postgres_include; if test "x$with_postgres_include" = "xyes"; then : + with_postgres_include="" +fi +fi + + +if test -n "$with_postgres_include" +then + POSTGRES_INCLUDE="-I$with_postgres_include" +else + if test -x "$PKG_CONFIG" || test -x "$PG_CONFIG" + then + # We should prefer pkg-config over pg_config, but there seems to be a + # problem in pkg-config 1.6.3. Until that's been resolved (#291), go + # with pg_config if we can. + if test -x "$PG_CONFIG" + then + # From pg_config we can either get the C compiler options used to + # compile postgres, which isn't quite what we want; or we can get + # the headers directory, without the full option. That's something + # we can work with. The compiler must support the "-I" option for + # that, but both scripts assume that anyway. + POSTGRES_INCLUDE="-I$($PG_CONFIG --includedir)" + else + # From pkg-config we can get the compiler options to extend the + # include path. We use that. + POSTGRES_INCLUDE=$($PKG_CONFIG libpq --cflags-only-I) + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: finding PostgreSQL headers using $POSTGRES_INCLUDE" >&5 +$as_echo "$as_me: finding PostgreSQL headers using $POSTGRES_INCLUDE" >&6;} + else + POSTGRES_INCLUDE="" + + # We have nothing to tell us where the libpq headers are. That's fine + # if the compiler can find it, but if not, fail here. + +ac_fn_cxx_check_header_mongrel "$LINENO" "libpq-fe.h" "ac_cv_header_libpq_fe_h" "$ac_includes_default" +if test "x$ac_cv_header_libpq_fe_h" = xyes; then : + +else + as_fn_error $? " +Can't find the main PostgreSQL client header, libpq-fe.h. Make sure that it +is installed, and either use the --with-postgres-include option or install +pkg-config. +" "$LINENO" 5 +fi + + + fi +fi + + +# Add the compiler option so we can compile configure tests which rely on the +# libpq headers. +CPPFLAGS="$CPPFLAGS $POSTGRES_INCLUDE" + + + +# Check whether --with-postgres-lib was given. +if test "${with_postgres_lib+set}" = set; then : + withval=$with_postgres_lib; if test "x$with_postgres_lib" = "xyes"; then : + with_postgres_lib="" +fi +fi + + +# If no --with-postgres-lib was given, and we have pkg-config, use that. +if test -z "$with_postgres_lib" -a -x "$PKG_CONFIG"; then : + with_postgres_lib=$($PKG_CONFIG libpq --libs-only-L | sed 's/^-L//') +fi + +# pg_config is deprecated, but for some users it may still provide the only +# right answer. For instance, `pkg-config` may not know where `libpq` is +# installed. +if test -z "$with_postgres_lib" -a -x "$PG_CONFIG"; then : + with_postgres_lib=$($PG_CONFIG --libdir) +fi + +if test -n "$with_postgres_lib"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: using PostgreSQL libraries at $with_postgres_lib" >&5 +$as_echo "$as_me: using PostgreSQL libraries at $with_postgres_lib" >&6;} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: using PostgreSQL libraries in default location" >&5 +$as_echo "$as_me: using PostgreSQL libraries in default location" >&6;} +fi + + + + +ac_fn_cxx_check_header_mongrel "$LINENO" "libpq-fe.h" "ac_cv_header_libpq_fe_h" "$ac_includes_default" +if test "x$ac_cv_header_libpq_fe_h" = xyes; then : + +else + as_fn_error $? " +Can't find the main PostgreSQL client header, libpq-fe.h. Are you sure the +libpq headers are installed correctly, and that we've got the right path? +" "$LINENO" 5 +fi + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ability to compile source files using libpq" >&5 +$as_echo_n "checking for ability to compile source files using libpq... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +PQexec(nullptr,"") + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + as_fn_error $? " +Could not compile a call to a basic libpq function. There must be something +seriously wrong with the headers that \"pg_config --includedir\" or \"pkg-config +libpq --cflags\" pointed to; the contents of config.log may give you a clue +about the nature of the failure. +Source including the libpq header libpq-fe.h can be compiled, but a call to the +most basic libpq function PQexec() failed to compile successfully. This is the +litmus test for a working libpq. +" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + +if test "x${with_postgres_lib}" = "x"; then + with_postgres_libpath="" +else + with_postgres_libpath="-L${with_postgres_lib}" +fi +LDFLAGS="$LDFLAGS ${with_postgres_libpath}" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PQexec in -lpq" >&5 +$as_echo_n "checking for PQexec in -lpq... " >&6; } +if ${ac_cv_lib_pq_PQexec+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpq ${with_postgres_libpath} $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char PQexec (); +int +main () +{ +return PQexec (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_pq_PQexec=yes +else + ac_cv_lib_pq_PQexec=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pq_PQexec" >&5 +$as_echo "$ac_cv_lib_pq_PQexec" >&6; } +if test "x$ac_cv_lib_pq_PQexec" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPQ 1 +_ACEOF + + LIBS="-lpq $LIBS" + +else + as_fn_error $? " +Did not find the PQexec() function in libpq. This is the litmus test for a +working libpq installation. + +A source file using the PQexec() function did compile without problems, and the +libpq library is available for linking, but for some reason a call to PQexec() +failed to link properly to the libpq library. This may be because the libpq +library file is damaged, or in some incorrect format, or if your libpq is much +more recent than libpqxx version $PQXX_ABI, perhaps libpq has undergone a +radical ABI change. + +The last parts of config.log may give you a clue as to what really went wrong, +but be warned that this is no easy reading. Look for the last error message +occurring in the file. +" "$LINENO" 5 +fi + + + +# PQencryptPasswordConn was added in postgres 10. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PQencryptPasswordConn" >&5 +$as_echo_n "checking for PQencryptPasswordConn... " >&6; } +have_pqencryptpasswordconn=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + extern PGconn *conn; + PQencryptPasswordConn( + conn, "pwd", "user", "scram-sha-256") + + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_PQENCRYPTPASSWORDCONN 1" >>confdefs.h + +else + have_pqencryptpasswordconn=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_pqencryptpasswordconn" >&5 +$as_echo "$have_pqencryptpasswordconn" >&6; } + + +# "Pipeline mode" was introduced in libpq 14. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libpq pipeline mode" >&5 +$as_echo_n "checking for libpq pipeline mode... " >&6; } +have_pq_pipeline=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + extern PGconn *conn; + PQenterPipelineMode(conn) + + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_PQ_PIPELINE 1" >>confdefs.h + +else + have_pq_pipeline=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_pq_pipeline" >&5 +$as_echo "$have_pq_pipeline" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for usable std::filesystem::path" >&5 +$as_echo_n "checking for usable std::filesystem::path... " >&6; } +have_path=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Check for working std::filesystem support. + +#include + + + + + +int main() + +{ + + // Apparently some versions of MinGW lack this comparison operator. + + return std::filesystem::path{} != std::filesystem::path{}; + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_PATH 1" >>confdefs.h + +else + have_path=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_path" >&5 +$as_echo "$have_path" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need a link option for support" >&5 +$as_echo_n "checking whether we need a link option for support... " >&6; } +LIBS_SAVE="$LIBS" +found_fslib=no +for l in '' '-lstdc++fs' '-lc++fs' +do + if test "$found_fslib" != "yes" + then + LIBS="$LIBS $l" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Check whether we need to link to the stdc++fs library. + +// + +// We assume that the presence of the header means that we have + +// support for the basics of std::filesystem. This check will succeed if + +// either there is no header, or there is one and it works without + +// any special options. If the link fails, we assume that -lstdc++fs will fix + +// it for us. + + + +#include + + + +#if __has_include() + +# include + +#endif + + + + + +int main() + +{ + +#if __has_include() + + std::cout << std::filesystem::path{"foo.bar"}.c_str() << '\n'; + +#endif + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + found_fslib=yes +else + LIBS="$LIBS_SAVE" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "$found_fslib" = "yes" + then + result_msg="$l" + # (And keep our current value of $LIBS.) + fi + fi +done + +if test "$found_fslib" != "yes" +then + as_fn_error $? " +There seems to be support, but I could not figure out now to make +it work. You'll have to add set your own build options for this. + " "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $result_msg" >&5 +$as_echo "$result_msg" >&6; } + + +# Remove redundant occurrances of -lpq +LIBS=$(echo "$LIBS" | sed -e 's/-lpq * -lpq\>/-lpq/g') + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that type of libpq's Oid is as expected" >&5 +$as_echo_n "checking that type of libpq's Oid is as expected... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include"${srcdir}/include/pqxx/internal/libpq-forward.hxx" + extern void f(pqxx::oid&); + +int +main () +{ +Oid o;f(o) + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + as_fn_error $? " +The Oid typedef in libpq has changed. Please notify the libpqxx authors of the +change! +" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + + +ac_config_files="$ac_config_files Makefile config/Makefile doc/Makefile doc/Doxyfile src/Makefile test/Makefile tools/Makefile include/Makefile include/pqxx/Makefile libpqxx.pc" + + + +ac_config_commands="$ac_config_commands configitems" + + +ac_config_files="$ac_config_files compile_flags" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BUILD_REFERENCE_TRUE}" && test -z "${BUILD_REFERENCE_FALSE}"; then + as_fn_error $? "conditional \"BUILD_REFERENCE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by libpqxx $as_me 7.7.3, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +libpqxx config.status 7.7.3 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "include/pqxx/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/pqxx/config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "config/Makefile") CONFIG_FILES="$CONFIG_FILES config/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "doc/Doxyfile") CONFIG_FILES="$CONFIG_FILES doc/Doxyfile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; + "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; + "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; + "include/pqxx/Makefile") CONFIG_FILES="$CONFIG_FILES include/pqxx/Makefile" ;; + "libpqxx.pc") CONFIG_FILES="$CONFIG_FILES libpqxx.pc" ;; + "configitems") CONFIG_COMMANDS="$CONFIG_COMMANDS configitems" ;; + "compile_flags") CONFIG_FILES="$CONFIG_FILES compile_flags" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$am_mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? + done + if test $am_rc -ne 0; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# The names of the tagged configurations supported by this script. +available_tags='CXX ' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + "configitems":C) "${srcdir}/tools/splitconfig" "${srcdir}" ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/ext/libpqxx-7.7.3/configure.ac b/ext/libpqxx-7.7.3/configure.ac new file mode 100644 index 000000000..d6351faf2 --- /dev/null +++ b/ext/libpqxx-7.7.3/configure.ac @@ -0,0 +1,738 @@ +# Generate configure script for libpqxx. This needs the autoconf archive +# package installed. (The configure script itself does not require it though.) + +AC_PREREQ(2.69) +AC_INIT( + libpqxx, + [m4_esyscmd_s([./tools/extract_version])], + [Jeroen T. Vermeulen]) +AC_LANG(C++) + +AC_CONFIG_SRCDIR([src/connection.cxx]) +AC_CONFIG_AUX_DIR(config) +AC_CONFIG_MACRO_DIR([config/m4]) +AM_INIT_AUTOMAKE([subdir-objects]) + +PQXX_ABI=m4_esyscmd_s([./tools/extract_version --abi]) +AC_SUBST(PQXXVERSION, $PACKAGE_VERSION) +AC_SUBST(PQXX_ABI) + +AC_CONFIG_HEADER([include/pqxx/config.h]) + +# Default prefix for installs. +AC_PREFIX_DEFAULT(/usr/local) + + +# Read test programme from config-test. +AC_DEFUN([read_test], [AC_LANG_SOURCE( + esyscmd(tools/m4esc.py --input=config-tests/$1))]) + + +# Checks for programs. +AC_PROG_CXX +AC_PROG_INSTALL +AC_DISABLE_SHARED +AC_PROG_LIBTOOL +AC_PROG_MAKE_SET +AC_PATH_PROG([MKDIR], [mkdir]) + +# Documentation. +AC_ARG_ENABLE( + documentation, + [AS_HELP_STRING([--enable-documentation], [Generate documentation])], + [], + [enable_documentation=auto]) +AC_ARG_VAR([DOXYGEN], + [Path to doxygen needed to build reference documentation]) +AC_PATH_TOOL([DOXYGEN], [doxygen], [nodoxygen]) +AC_ARG_VAR([HAVE_DOT], + [Variable used by doxygen to declare availibility of dot]) +AC_CHECK_TOOL([HAVE_DOT], [dot], [YES], [NO]) +AS_IF([test "$enable_documentation" = "yes" && test "$DOXYGEN" = "nodoxygen"], + [AC_MSG_ERROR([could not find tools necessary to build documentation])]) +AM_CONDITIONAL([BUILD_REFERENCE], + [test "$enable_documentation" != "no" -a "$DOXYGEN" != "nodoxygen"]) + +AM_MAINTAINER_MODE + +# See if we want stricter compiler warnings. +AC_MSG_CHECKING([maintainer mode]) +AC_ARG_ENABLE(maintainer-mode) +AC_MSG_RESULT(${enable_maintainer_mode}) + +# See if we want runtime debug checking. +AC_MSG_CHECKING([audit]) +AC_ARG_ENABLE(audit) +AC_MSG_RESULT(${enable_audit}) + +# See if we want "suggestions," such as "this class could be final." +# (The suggestions are often useful, but can also easily be wrong.) +AC_MSG_CHECKING([suggest]) +AC_ARG_ENABLE(suggest) +AC_MSG_RESULT(${enable_suggest}) + + +AC_ARG_ENABLE(shared) +AS_IF( + [test "${shared}" = "yes" ], + [CPPFLAGS="$CPPFLAGS -DPQXX_SHARED"]) + + +# Add options to compiler command line, if compiler accepts them. +add_compiler_opts_if_ok() { + for option in $* + do + ACO_SAVE_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $option" + AC_MSG_CHECKING([whether $CXX accepts $option]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([], [])], + has_option=yes, + has_option=no) + AC_MSG_RESULT($has_option) + AS_IF( + [test "$has_option" = "no" ], + [CXXFLAGS="$ACO_SAVE_CXXFLAGS"]) + done +} + + +# Add options to compiler command line, unconditionally. +add_compiler_opts() { + CXXFLAGS="$CXXFLAGS $*" +} + + +# It's tempting to use Autoconf Archive's AX_CXX_COMPILE_STDCXX_17 for this, +# but it's 2022 and the C++20 equivalent isn't quite ready for use. +# Seems simpler and more reliable for the user to arrange for the desired +# language versions by setting the appropriate option for their compiler. +AC_MSG_CHECKING([for sufficient C++ language/library level]) +sufficient_cxx=yes +AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([ + #if __cplusplus < 201611L + #error "Need C++17 or better." + #endif + ])], + sufficient_cxx=yes, + sufficient_cxx=no) +AC_MSG_RESULT($sufficient_cxx) +if test "$sufficient_cxx" != "yes" +then + AC_MSG_ERROR([This libpqxx version needs at least C++17.]) +fi + + +# Let's try to get the compiler to be helpful. +# +# (Omit options -Weffc++ and -Wabi because they currently yield too many +# warnings in gcc's standard headers; omit -Wunreachable-code because it isn't +# always right) +if test "$GCC" = "yes" +then + # In maintainer mode, enable all the warning options we can. + if test "$enable_maintainer_mode" = "yes" + then + # "Eternal" (FLW) g++ options. These have been around for + # ages, and both g++ and clang++ support them. Don't bother + # checking for support; just add them to the compiler options. + add_compiler_opts \ + -fstrict-enums \ + -Werror \ + -Wall \ + -pedantic \ + -Wcast-align \ + -Wcast-qual \ + -Wconversion \ + -Wctor-dtor-privacy \ + -Wendif-labels \ + -Wextra \ + -Wfloat-equal \ + -Wformat=2 \ + -Wformat-security \ + -Wmissing-include-dirs \ + -Wno-div-by-zero \ + -Wnon-virtual-dtor \ + -Wold-style-cast \ + -Woverlength-strings \ + -Woverloaded-virtual \ + -Wpointer-arith \ + -Wredundant-decls \ + -Wshadow \ + -Wsign-promo \ + -Wundef \ + -Wunused \ + -Wwrite-strings + + # "Iffy" g++ options. Some reasonably current g++-like + # compilers may not support these. + add_compiler_opts_if_ok \ + -fnothrow-opt \ + -Wattribute-alias=2 \ + -Wextra-semi \ + -Wlogical-op \ + -Wmismatched-tags \ + -Wnoexcept \ + -Wredundant-tags \ + -Wrestrict \ + -Wstringop-overflow \ + -Wzero-as-null-pointer-constant \ + -Warray-bounds=2 \ + -Wduplicated-branches \ + -Wduplicated-cond \ + -Wsuggest-attribute=noreturn \ + -Wsuggest-override \ + -Wtrampolines + fi + + # In "audit," enable all runtime checks we can. + if test "$enable_audit" = "yes" + then + add_compiler_opts_if_ok \ + -D_FORTIFY_SOURCE=2 \ + -fsanitize=address \ + -fsanitize-address-use-after-scope \ + -fsanitize=alignment \ + -fsanitize=bool \ + -fsanitize=bounds \ + -fsanitize=bounds-strict \ + -fsanitize=builtin \ + -fsanitize=enum \ + -fsanitize=float-cast-overflow \ + -fsanitize=float-divide-by-zero \ + -fsanitize=integer-divide-by-zero \ + -fsanitize=leak \ + -fsanitize=nonnull-attribute \ + -fsanitize=null \ + -fsanitize=object-size \ + -fsanitize=pointer-compare \ + -fsanitize=pointer-overflow \ + -fsanitize=pointer-subtract \ + -fsanitize=return \ + -fsanitize=returns-nonnull-attribute \ + -fsanitize=shift \ + -fsanitize=shift-base \ + -fsanitize=shift-exponent \ + -fsanitize=signed-integer-overflow \ + -fsanitize=undefined \ + -fsanitize=unreachable \ + -fsanitize=vla-bound \ + -fsanitize=vptr \ + -fstack-protector-all + fi + + # In "suggest" mode, enable a bunch of code suggestions. + if test "$enable_suggest" = "yes" + then + add_compiler_opts_if_ok \ + -Wsuggest-attribute=cold \ + -Wsuggest-attribute=const \ + -Wsuggest-attribute=malloc \ + -Wsuggest-attribute=pure \ + -Wsuggest-final-types \ + -Wsuggest-final-methods + fi + +AC_MSG_CHECKING([g++ visibility attribute]) +gcc_visibility=yes +SAVE_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS -Werror" +AC_COMPILE_IFELSE( + [read_test(gcc_visibility.cxx)], + AC_DEFINE( + [PQXX_HAVE_GCC_VISIBILITY], + 1, + [Define if g++ supports visibility attribute.]), + gcc_visibility=no) +AC_MSG_RESULT($gcc_visibility) +CXXFLAGS="$SAVE_CXXFLAGS" +if test "$gcc_visibility" = "yes" +then + # Make internal definitions accessible only to the library itself. + # Only definitions marked PQXX_LIBEXPORT will be accessible. + add_compiler_opts -fvisibility=hidden + add_compiler_opts -fvisibility-inlines-hidden +fi + +AC_MSG_CHECKING([g++ pure attribute]) +gcc_pure=yes +AC_COMPILE_IFELSE( + [read_test(gcc_pure.cxx)], + AC_DEFINE( + [PQXX_HAVE_GCC_PURE], + 1, + [Define if g++ supports pure attribute]), + gcc_pure=no) +AC_MSG_RESULT($gcc_pure) + +fi # End of gcc-specific part. + + +# Check for __cxa_demangle. +AC_MSG_CHECKING([__cxa_demangle]) +cxa_demangle=yes +AC_COMPILE_IFELSE( + [read_test(cxa_demangle.cxx)], + AC_DEFINE( + [PQXX_HAVE_CXA_DEMANGLE], + 1, + [Define if compiler supports __cxa_demangle]), + cxa_demangle=no) +AC_MSG_RESULT($cxa_demangle) + + +# Check for sufficient Concepts support, introduced with C++20. +AC_MSG_CHECKING([concepts]) +concepts=yes +AC_COMPILE_IFELSE( + [read_test(concepts.cxx)], + AC_DEFINE( + [PQXX_HAVE_CONCEPTS], + 1, + [Define if compiler supports Concepts and header.]), + concepts=no) +AC_MSG_RESULT($concepts) + + +# Check for C++20 std::span. +AC_MSG_CHECKING([std::span]) +span=yes +AC_COMPILE_IFELSE( + [read_test(span.cxx)], + AC_DEFINE([PQXX_HAVE_SPAN], 1, [Define if compiler has std::span.]), + span=no) +AC_MSG_RESULT($span) + + +# Check for multidimensional subscript operator support. Proposed for C++23. +AC_MSG_CHECKING([for multidimensional subscript operator support]) +multidim_subscript=yes +AC_COMPILE_IFELSE( + [read_test(multidim-subscript.cxx)], + AC_DEFINE( + [PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT], 1, + [Define if operator[] can take multiple arguments.]), + multidim_subscript=no) +AC_MSG_RESULT($multidim_subscript) + + +AC_MSG_CHECKING([for strerror_r()]) +strerror_r=yes +AC_LINK_IFELSE( + [read_test(strerror_r.cxx)], + AC_DEFINE( + [PQXX_HAVE_STRERROR_R], + 1, + [Define if strerror_r() is available.]), + strerror_r=no) +AC_MSG_RESULT($strerror_r) + + + +AC_MSG_CHECKING([for strerror_s()]) +strerror_s=yes +AC_LINK_IFELSE( + [read_test(strerror_s.cxx)], + AC_DEFINE( + [PQXX_HAVE_STRERROR_S], + 1, + [Define if strerror_s() is available.]), + strerror_s=no) +AC_MSG_RESULT($strerror_s) + + +AC_MSG_CHECKING([for std::chrono::year_month_day etc]) +year_month_day=yes +AC_LINK_IFELSE( + [read_test(year_month_day.cxx)], + AC_DEFINE( + [PQXX_HAVE_YEAR_MONTH_DAY], + 1, + [Define if std::chrono has year_month_day etc.]), + year_month_day=no) +AC_MSG_RESULT($year_month_day) + + +# Check for [[likely]] and [[unlikely]] attributes. +AC_MSG_CHECKING([attributes "likely" and "unlikely".]) +likely=yes +AC_COMPILE_IFELSE( + [read_test(likely.cxx)], + AC_DEFINE([PQXX_HAVE_LIKELY], 1, [Define if likely & unlikely work.]), + likely=no) +AC_MSG_RESULT($likely) + + +# It's mid-2019, and gcc's charconv supports integers but not yet floats. +# So for now, we test for int and float conversion... separately. +# +# It's worse for older clang versions, which compile the integer conversions +# but then fail at link time because of a missing symbol "__muloti4" with the +# "long long" version. I couldn't resolve that symbol by adding -lm either. +# So don't just compile these tests; link them as well. +AC_MSG_CHECKING([for C++17 charconv integer conversion]) +have_charconv_int=yes +AC_LINK_IFELSE( + [read_test(charconv_int.cxx)], + AC_DEFINE( + [PQXX_HAVE_CHARCONV_INT], + 1, + [Define if supports integer conversion.]), + have_charconv_int=no) +AC_MSG_RESULT($have_charconv_int) + +AC_MSG_CHECKING([for C++17 charconv floating-point conversion]) +have_charconv_float=yes +AC_LINK_IFELSE( + [read_test(charconv_float.cxx)], + AC_DEFINE( + [PQXX_HAVE_CHARCONV_FLOAT], + 1, + [Define if supports floating-point conversion.]), + have_charconv_float=no) +AC_MSG_RESULT($have_charconv_float) + +# As per #262, clang with libcxxrt does not support thread_local on non-POD +# objects. Luckily we can live without those, it's just less efficient. +AC_MSG_CHECKING([for full thread_local support]) +have_thread_local=yes +AC_LINK_IFELSE( + [read_test(thread_local.cxx)], + AC_DEFINE( + [PQXX_HAVE_THREAD_LOCAL], + 1, + [Define if thread_local is fully supported.]), + have_thread_local=no) +AC_MSG_RESULT($have_thread_local) + +AC_MSG_CHECKING([for std::this_thread::sleep_for]) +have_sleep_for=yes +AC_LINK_IFELSE( + [read_test(sleep_for.cxx)], + AC_DEFINE( + [PQXX_HAVE_SLEEP_FOR], + 1, + [Define if std::this_thread::sleep_for works.]), + have_sleep_for=no) +AC_MSG_RESULT($have_sleep_for) + + +AC_MSG_CHECKING([for std::cmp_greater, std::cmp_less_equal, etc]) +have_cmp=yes +AC_COMPILE_IFELSE( + [read_test(cmp.cxx)], + AC_DEFINE( + [PQXX_HAVE_CMP], + 1, + [Define if compiler has C++20 std::cmp_greater etc.]), + have_cmp=no) +AC_MSG_RESULT($have_cmp) + + +# Doing my own check for poll(). There's one built into autoconf-archive, but +# it produces warnings in C++ (about unnecessarily using "struct", and using 0 +# as a null pointer constant). In maintainer mode, those warnings turn into +# errors. +AC_MSG_CHECKING([for poll()]) +ax_cv_have_poll=yes +AC_LINK_IFELSE( + [read_test(poll.cxx)], + AC_DEFINE( + [PQXX_HAVE_POLL], + 1, + [Define if poll() is available.]), + ax_cv_have_poll=no) +AC_MSG_RESULT($ax_cv_have_poll) + +if test "$ax_cv_have_poll" != "yes" +then +# No poll(); we'll fall back to select(). + +# Some systems keep select() in a separate library which is not linked by +# default. See if we need one of those. +socklibok=no +AC_SEARCH_LIBS(select, socket nsl ws2_32 wsock32 winsock, [socklibok=yes]) + +# Microsoft proprietary libraries do not work with code that is generated with +# autoconf's SEARCH_LIBS macro, so we need to check manually and just use the +# first socket library available. +# We only do this if select() is not available by other means, to avoid picking +# up an unnecessary Windows compatibility library on a non-Windows system. +for l in ws2_32 wsock32 winsock +do + if test "${socklibok}" != "yes" + then + AC_CHECK_LIB($l,main,LIBS="$LIBS -l$l";[socklibok=yes]) + fi +done + +if test "${socklibok}" != "yes" +then + AC_MSG_ERROR([ +Could not figure out how to link a simple sockets-based program. Please read +the config.log file for more clues as to why this failed. +]) +fi + +fi # No poll() + + +# Find PostgreSQL includes and libraries +AC_PATH_PROG([PKG_CONFIG], [pkg-config]) +AC_PATH_PROGS(PG_CONFIG, pg_config) + +AC_ARG_WITH( + [postgres-include], + [AS_HELP_STRING( + [--with-postgres-include=DIR], + [Use PostgreSQL includes from DIR. Defaults to querying pg_config or pkg-config, whichever is available.])], + AS_IF( + [test "x$with_postgres_include" = "xyes"], + [with_postgres_include=""])) + +if test -n "$with_postgres_include" +then + POSTGRES_INCLUDE="-I$with_postgres_include" +else + if test -x "$PKG_CONFIG" || test -x "$PG_CONFIG" + then + # We should prefer pkg-config over pg_config, but there seems to be a + # problem in pkg-config 1.6.3. Until that's been resolved (#291), go + # with pg_config if we can. + if test -x "$PG_CONFIG" + then + # From pg_config we can either get the C compiler options used to + # compile postgres, which isn't quite what we want; or we can get + # the headers directory, without the full option. That's something + # we can work with. The compiler must support the "-I" option for + # that, but both scripts assume that anyway. + POSTGRES_INCLUDE="-I$($PG_CONFIG --includedir)" + else + # From pkg-config we can get the compiler options to extend the + # include path. We use that. + POSTGRES_INCLUDE=$($PKG_CONFIG libpq --cflags-only-I) + fi + AC_MSG_NOTICE([finding PostgreSQL headers using $POSTGRES_INCLUDE]) + else + POSTGRES_INCLUDE="" + + # We have nothing to tell us where the libpq headers are. That's fine + # if the compiler can find it, but if not, fail here. + AC_CHECK_HEADER( + [libpq-fe.h], + [], + [AC_MSG_ERROR([ +Can't find the main PostgreSQL client header, libpq-fe.h. Make sure that it +is installed, and either use the --with-postgres-include option or install +pkg-config. +])]) + fi +fi +AC_SUBST(POSTGRES_INCLUDE) + +# Add the compiler option so we can compile configure tests which rely on the +# libpq headers. +CPPFLAGS="$CPPFLAGS $POSTGRES_INCLUDE" + + +AC_ARG_WITH( + [postgres-lib], + [AS_HELP_STRING( + [--with-postgres-lib=DIR], + [Use PostgreSQL libraries from DIR. Defaults to querying pg_config.])], + AS_IF( + [test "x$with_postgres_lib" = "xyes"], + [with_postgres_lib=""])) + +# If no --with-postgres-lib was given, and we have pkg-config, use that. +AS_IF( + [test -z "$with_postgres_lib" -a -x "$PKG_CONFIG"], + [with_postgres_lib=$($PKG_CONFIG libpq --libs-only-L | sed 's/^-L//')]) + +# pg_config is deprecated, but for some users it may still provide the only +# right answer. For instance, `pkg-config` may not know where `libpq` is +# installed. +AS_IF( + [test -z "$with_postgres_lib" -a -x "$PG_CONFIG"], + [with_postgres_lib=$($PG_CONFIG --libdir)]) + +AS_IF( + [test -n "$with_postgres_lib"], + [AC_MSG_NOTICE([using PostgreSQL libraries at $with_postgres_lib])], + [AC_MSG_NOTICE([using PostgreSQL libraries in default location])]) + +AC_SUBST(with_postgres_lib) + + +AC_CHECK_HEADER( + [libpq-fe.h], + [], + [AC_MSG_ERROR([ +Can't find the main PostgreSQL client header, libpq-fe.h. Are you sure the +libpq headers are installed correctly, and that we've got the right path? +])]) + + +AC_MSG_CHECKING([for ability to compile source files using libpq]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include]], + [[PQexec(nullptr,"")]] + )], + [], + [AC_MSG_ERROR([ +Could not compile a call to a basic libpq function. There must be something +seriously wrong with the headers that "pg_config --includedir" or "pkg-config +libpq --cflags" pointed to; the contents of config.log may give you a clue +about the nature of the failure. +Source including the libpq header libpq-fe.h can be compiled, but a call to the +most basic libpq function PQexec() failed to compile successfully. This is the +litmus test for a working libpq. +])]) +AC_MSG_RESULT(yes) + + +if test "x${with_postgres_lib}" = "x"; then + with_postgres_libpath="" +else + with_postgres_libpath="-L${with_postgres_lib}" +fi +LDFLAGS="$LDFLAGS ${with_postgres_libpath}" + +AC_CHECK_LIB( + [pq], + [PQexec], + [], + [AC_MSG_ERROR([ +Did not find the PQexec() function in libpq. This is the litmus test for a +working libpq installation. + +A source file using the PQexec() function did compile without problems, and the +libpq library is available for linking, but for some reason a call to PQexec() +failed to link properly to the libpq library. This may be because the libpq +library file is damaged, or in some incorrect format, or if your libpq is much +more recent than libpqxx version $PQXX_ABI, perhaps libpq has undergone a +radical ABI change. + +The last parts of config.log may give you a clue as to what really went wrong, +but be warned that this is no easy reading. Look for the last error message +occurring in the file. +])], + ${with_postgres_libpath}) + + +# PQencryptPasswordConn was added in postgres 10. +AC_MSG_CHECKING([for PQencryptPasswordConn]) +have_pqencryptpasswordconn=yes +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [#include], + [ + extern PGconn *conn; + PQencryptPasswordConn( + conn, "pwd", "user", "scram-sha-256") + ] + )], + AC_DEFINE( + [PQXX_HAVE_PQENCRYPTPASSWORDCONN], + 1, + [Define if libpq has PQencryptPasswordConn (since pg 10).]), + [have_pqencryptpasswordconn=no]) +AC_MSG_RESULT($have_pqencryptpasswordconn) + + +# "Pipeline mode" was introduced in libpq 14. +AC_MSG_CHECKING([for libpq pipeline mode]) +have_pq_pipeline=yes +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [#include], + [ + extern PGconn *conn; + PQenterPipelineMode(conn) + ] + )], + AC_DEFINE( + [PQXX_HAVE_PQ_PIPELINE], + 1, + [Define if libpq has pipeline mode (since pg 14).]), + [have_pq_pipeline=no]) +AC_MSG_RESULT($have_pq_pipeline) + + +AC_MSG_CHECKING([for usable std::filesystem::path]) +have_path=yes +AC_COMPILE_IFELSE( + [read_test(fs.cxx)], + AC_DEFINE( + [PQXX_HAVE_PATH], + 1, + [Define if compiler has usable std::filesystem::path.]), + have_path=no) +AC_MSG_RESULT($have_path) + + +AC_MSG_CHECKING([whether we need a link option for support]) +LIBS_SAVE="$LIBS" +found_fslib=no +for l in '' '-lstdc++fs' '-lc++fs' +do + if test "$found_fslib" != "yes" + then + LIBS="$LIBS $l" + AC_LINK_IFELSE( + [read_test(need_fslib.cxx)], + [found_fslib=yes], + [LIBS="$LIBS_SAVE"]) + if test "$found_fslib" = "yes" + then + result_msg="$l" + # (And keep our current value of $LIBS.) + fi + fi +done + +if test "$found_fslib" != "yes" +then + AC_MSG_ERROR([ +There seems to be support, but I could not figure out now to make +it work. You'll have to add set your own build options for this. + ]) +fi +AC_MSG_RESULT($result_msg) + + +# Remove redundant occurrances of -lpq +LIBS=[$(echo "$LIBS" | sed -e 's/-lpq * -lpq\>/-lpq/g')] + + +AC_MSG_CHECKING([that type of libpq's Oid is as expected]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [ + #include + #include"${srcdir}/include/pqxx/internal/libpq-forward.hxx" + extern void f(pqxx::oid&); + ], + [Oid o;f(o)], + )], + [], + [AC_MSG_ERROR([ +The Oid typedef in libpq has changed. Please notify the libpqxx authors of the +change! +])]) +AC_MSG_RESULT(yes) + + +AC_PROG_MAKE_SET + +AC_CONFIG_FILES([ + Makefile config/Makefile doc/Makefile doc/Doxyfile src/Makefile + test/Makefile tools/Makefile include/Makefile include/pqxx/Makefile + libpqxx.pc]) + + +AC_CONFIG_COMMANDS([configitems], ["${srcdir}/tools/splitconfig" "${srcdir}"]) + +AC_OUTPUT(compile_flags) diff --git a/ext/libpqxx-7.7.3/doc/CMakeLists.txt b/ext/libpqxx-7.7.3/doc/CMakeLists.txt new file mode 100644 index 000000000..d48d2a6f0 --- /dev/null +++ b/ext/libpqxx-7.7.3/doc/CMakeLists.txt @@ -0,0 +1,50 @@ +find_program(HAVE_DOXYGEN doxygen) + +if(NOT HAVE_DOXYGEN) + message(FATAL_ERROR "***************************************************** +Doxygen not found. +Install it, or configure with -DBUILD_DOC=OFF +*****************************************************" + ) +endif() + +set(PQXXVERSION "${CMAKE_PROJECT_VERSION}") +set(top_srcdir "${PROJECT_SOURCE_DIR}") +set(PQXX_ABI "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") +set(PQXX_MAJOR "${PROJECT_VERSION_MAJOR}") +set(PQXX_MINOR "${PROJECT_VERSION_MINOR}") + +find_program(HAVE_DOT dot) +if(HAVE_DOT) + set(HAVE_DOT YES) +else() + set(HAVE_DOT NO) +endif() + +configure_file(Doxyfile.in Doxyfile) + +if(HAVE_DOXYGEN) + file( + GLOB DOXYGEN_SOURCES + "${PROJECT_SOURCE_DIR}/include/pqxx/*.hxx" + "${PROJECT_SOURCE_DIR}/include/pqxx/doc/*.md" + "${PROJECT_SOURCE_DIR}/*.cxx" + ) + set(DOXYGEN_STAMP_FILE "${CMAKE_CURRENT_BINARY_DIR}/doxygen.stamp") + add_custom_command(OUTPUT ${DOXYGEN_STAMP_FILE} + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/html + COMMAND doxygen Doxyfile + COMMAND ${CMAKE_COMMAND} -E touch ${DOXYGEN_STAMP_FILE} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile ${DOXYGEN_SOURCES} + COMMENT "Generate API documentation" + VERBATIM + ) + add_custom_target(doxygen ALL + DEPENDS ${DOXYGEN_STAMP_FILE} + SOURCES ${DOXYGEN_SOURCES} + ) + install( + DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html + DESTINATION ${CMAKE_INSTALL_DOCDIR}/html + ) +endif() diff --git a/ext/libpqxx-7.7.3/doc/Doxyfile.in b/ext/libpqxx-7.7.3/doc/Doxyfile.in new file mode 100644 index 000000000..f349fe80c --- /dev/null +++ b/ext/libpqxx-7.7.3/doc/Doxyfile.in @@ -0,0 +1,1280 @@ +# Doxyfile 1.5.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = libpqxx + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @PQXXVERSION@ + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = html + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, +# and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = ../ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = NO + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = NO + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @top_srcdir@/include/pqxx \ + @top_srcdir@/include/pqxx/doc \ + @top_srcdir@/src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.cxx \ + *.hxx \ + *.h \ + *.md + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = *.o \ + *.lo \ + *.a \ + .cvsignore + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = . + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = YES + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = "../include" "@top_srcdir@/include" + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = *.h *.hxx + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = PQXX_ABI="@PQXX_ABI@" \ + PQXX_LIBEXPORT= \ + PQXX_NOVTABLE= \ + PQXX_PRIVATE= \ + PQXX_TYPENAME=typename \ + PQXX_VERSION="@PQXXVERSION@" \ + PQXX_MAJOR=@PQXX_MAJOR@ \ + PQXX_MINOR=@PQXX_MINOR@ + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = @HAVE_DOT@ + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is enabled by default, which results in a transparent +# background. Warning: Depending on the platform used, enabling this option +# may lead to badly anti-aliased labels on the edges of a graph (i.e. they +# become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/ext/libpqxx-7.7.3/doc/Makefile.am b/ext/libpqxx-7.7.3/doc/Makefile.am new file mode 100644 index 000000000..38caa9181 --- /dev/null +++ b/ext/libpqxx-7.7.3/doc/Makefile.am @@ -0,0 +1,51 @@ +MAINTAINERCLEANFILES = Makefile.in + +maintainer-clean-local: + $(RM) -rf html + $(RM) reference-stamp + $(MKDIR) html + +EXTRA_DIST= Doxyfile.in libpqxx.xml reference-stamp + +all-local: docs + +if BUILD_REFERENCE +DOCS = reference +else +DOCS = +endif + +if MAINTAINER_MODE +REFERENCE_STAMP_DEP = ../src/libpqxx.la +else +REFERENCE_STAMP_DEP = +endif + +docs: $(DOCS) + +reference: reference-stamp +reference-stamp: Doxyfile.in $(REFERENCE_STAMP_DEP) + if [ -x "$(DOXYGEN)" ]; then \ + $(MKDIR_P) html; \ + $(DOXYGEN) Doxyfile; \ + touch $@; \ + else \ + echo >&2; \ + echo >&2 "*****************************************************"; \ + echo >&2; \ + echo >&2 "Doxygen not found."; \ + echo >&2 "Install it, or configure with --disable-documentation"; \ + echo >&2; \ + echo >&2 "*****************************************************"; \ + exit 1; \ + fi + +../src/libpqxx.la: + cd ../src; \ + $(MAKE) libpqxx.la + + +dist-hook: reference + if [ -d $(srcdir)/html ]; then \ + cp -pR html $(distdir)/ ; \ + fi diff --git a/ext/libpqxx-7.7.3/doc/Makefile.in b/ext/libpqxx-7.7.3/doc/Makefile.in new file mode 100644 index 000000000..835845bf7 --- /dev/null +++ b/ext/libpqxx-7.7.3/doc/Makefile.in @@ -0,0 +1,507 @@ +# Makefile.in generated by automake 1.16.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = doc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/pqxx/config.h +CONFIG_CLEAN_FILES = Doxyfile +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Doxyfile.in $(srcdir)/Makefile.in \ + $(top_srcdir)/config/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_DOT = @HAVE_DOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PG_CONFIG = @PG_CONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +POSTGRES_INCLUDE = @POSTGRES_INCLUDE@ +PQXXVERSION = @PQXXVERSION@ +PQXX_ABI = @PQXX_ABI@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_postgres_lib = @with_postgres_lib@ +MAINTAINERCLEANFILES = Makefile.in +EXTRA_DIST = Doxyfile.in libpqxx.xml reference-stamp +@BUILD_REFERENCE_FALSE@DOCS = +@BUILD_REFERENCE_TRUE@DOCS = reference +@MAINTAINER_MODE_FALSE@REFERENCE_STAMP_DEP = +@MAINTAINER_MODE_TRUE@REFERENCE_STAMP_DEP = ../src/libpqxx.la +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu doc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +Doxyfile: $(top_builddir)/config.status $(srcdir)/Doxyfile.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook +check-am: all-am +check: check-am +all-am: Makefile all-local +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic \ + maintainer-clean-local + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am all-local check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags-am dist-hook distclean \ + distclean-generic distclean-libtool distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic maintainer-clean-local mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +maintainer-clean-local: + $(RM) -rf html + $(RM) reference-stamp + $(MKDIR) html + +all-local: docs + +docs: $(DOCS) + +reference: reference-stamp +reference-stamp: Doxyfile.in $(REFERENCE_STAMP_DEP) + if [ -x "$(DOXYGEN)" ]; then \ + $(MKDIR_P) html; \ + $(DOXYGEN) Doxyfile; \ + touch $@; \ + else \ + echo >&2; \ + echo >&2 "*****************************************************"; \ + echo >&2; \ + echo >&2 "Doxygen not found."; \ + echo >&2 "Install it, or configure with --disable-documentation"; \ + echo >&2; \ + echo >&2 "*****************************************************"; \ + exit 1; \ + fi + +../src/libpqxx.la: + cd ../src; \ + $(MAKE) libpqxx.la + +dist-hook: reference + if [ -d $(srcdir)/html ]; then \ + cp -pR html $(distdir)/ ; \ + fi + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ext/libpqxx-7.7.3/doc/conf.py b/ext/libpqxx-7.7.3/doc/conf.py new file mode 100644 index 000000000..1cac1c2ca --- /dev/null +++ b/ext/libpqxx-7.7.3/doc/conf.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- +""" +libpqxx documentation build configuration file, created by +sphinx-quickstart on Sun Dec 3 00:43:33 2017. + +This file is execfile()d with the current directory set to its containing dir. + +All configuration values have a default; values that are commented out serve +to show the default. +""" + +import codecs +import os +from subprocess import check_call + + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import sys +# sys.path.insert(0, os.path.abspath(os.path.curdir)) + + +read_the_docs_build = os.environ.get('READTHEDOCS') == 'True' + +if read_the_docs_build: + check_call( + [os.path.join(os.path.curdir, 'configure'), 'CXXFLAGS=-std=c++17 -O0'], + cwd=os.path.pardir) + check_call('doxygen', cwd=os.path.join(os.path.pardir, 'doc')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + ] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'libpqxx' +copyright = u'2000-2022, Jeroen T. Vermeulen' +author = u'Jeroen T. Vermeulen' + + +def read_version(): + """Return version number as specified in the VERSION file.""" + version_file = os.path.join( + os.path.dirname(__file__), os.path.pardir, 'VERSION') + with codecs.open(version_file, encoding='ascii') as stream: + return stream.read().strip() + + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = read_version() + +# The short X.Y version. +version = '.'.join(release.split('.')[:2]) + +html_title = "libpqxx %s" % release +html_short_title = "libpqxx" + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + '**': [ + 'relations.html', # needs 'show_related': True theme option to display + 'searchbox.html', + ] +} + +# Looks like the setup is that our build generates the HTML itself, and then +# has readthedocs copy the full generated HTML tree to the output directory. +# +# Problem is, that doesn't seem to be working now. This needs debugging. +html_extra_path = ["html"] + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'libpqxxdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + master_doc, + 'libpqxx.tex', + u'libpqxx Documentation', + u'Jeroen T. Vermeulen', + 'manual', + ), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'libpqxx', u'libpqxx Documentation', [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'libpqxx', u'libpqxx Documentation', + author, 'libpqxx', "C++ client API for PostgreSQL.", + 'Miscellaneous'), +] diff --git a/ext/libpqxx-7.7.3/doc/index.rst b/ext/libpqxx-7.7.3/doc/index.rst new file mode 100644 index 000000000..30f2cfdc1 --- /dev/null +++ b/ext/libpqxx-7.7.3/doc/index.rst @@ -0,0 +1,20 @@ +.. x documentation master file, created by + sphinx-quickstart on Sun Dec 3 01:30:12 2017. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +libpqxx +======= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/ext/libpqxx-7.7.3/include/CMakeLists.txt b/ext/libpqxx-7.7.3/include/CMakeLists.txt new file mode 100644 index 000000000..263dd2e9e --- /dev/null +++ b/ext/libpqxx-7.7.3/include/CMakeLists.txt @@ -0,0 +1,68 @@ +# ############################################################################## +# AUTOMATICALLY GENERATED FILE -- DO NOT EDIT. +# +# This file is generated automatically by libpqxx's template2mak.py script, and +# will be rewritten from time to time. +# +# If you modify this file, chances are your modifications will be lost. +# +# The template2mak.py script should be available in the tools directory of the +# libpqxx source archive. +# +# Generated from template './include/CMakeLists.txt.template'. +# ############################################################################## +install( + DIRECTORY pqxx "${PROJECT_BINARY_DIR}/include/pqxx" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING + # For each X.hxx, install both X.hxx itself and plain X. + PATTERN *.hxx + # TODO: Is there any way to do this with CMake's globbing? + PATTERN array + PATTERN binarystring + PATTERN blob + PATTERN composite + PATTERN connection + PATTERN cursor + PATTERN dbtransaction + PATTERN errorhandler + PATTERN except + PATTERN field + PATTERN isolation + PATTERN largeobject + PATTERN nontransaction + PATTERN notification + PATTERN params + PATTERN pipeline + PATTERN prepared_statement + PATTERN range + PATTERN result + PATTERN robusttransaction + PATTERN row + PATTERN separated_list + PATTERN strconv + PATTERN stream_from + PATTERN stream_to + PATTERN subtransaction + PATTERN time + PATTERN transaction + PATTERN transaction_base + PATTERN transaction_focus + PATTERN transactor + PATTERN types + PATTERN util + PATTERN version + PATTERN zview + PATTERN internal/*.hxx + PATTERN internal/gates/*.hxx + PATTERN config-public-compiler.h + PATTERN pqxx + PATTERN doc EXCLUDE +) + +install( + DIRECTORY pqxx/doc/ + DESTINATION ${CMAKE_INSTALL_DOCDIR} + FILES_MATCHING + PATTERN *.md +) diff --git a/ext/libpqxx-7.7.3/include/CMakeLists.txt.template b/ext/libpqxx-7.7.3/include/CMakeLists.txt.template new file mode 100644 index 000000000..5ebc6664e --- /dev/null +++ b/ext/libpqxx-7.7.3/include/CMakeLists.txt.template @@ -0,0 +1,23 @@ +install( + DIRECTORY pqxx "${PROJECT_BINARY_DIR}/include/pqxx" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING + # For each X.hxx, install both X.hxx itself and plain X. + PATTERN *.hxx + # TODO: Is there any way to do this with CMake's globbing? +###MAKTEMPLATE:FOREACH include/pqxx/*.hxx + PATTERN ###BASENAME### +###MAKTEMPLATE:ENDFOREACH + PATTERN internal/*.hxx + PATTERN internal/gates/*.hxx + PATTERN config-public-compiler.h + PATTERN pqxx + PATTERN doc EXCLUDE +) + +install( + DIRECTORY pqxx/doc/ + DESTINATION ${CMAKE_INSTALL_DOCDIR} + FILES_MATCHING + PATTERN *.md +) diff --git a/ext/libpqxx-7.7.3/include/Makefile.am b/ext/libpqxx-7.7.3/include/Makefile.am new file mode 100644 index 000000000..83d2b1970 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/Makefile.am @@ -0,0 +1,79 @@ +SUBDIRS = pqxx + +nobase_include_HEADERS= pqxx/pqxx \ + pqxx/array pqxx/array.hxx \ + pqxx/binarystring pqxx/binarystring.hxx \ + pqxx/blob pqxx/blob.hxx \ + pqxx/composite pqxx/composite.hxx \ + pqxx/connection pqxx/connection.hxx \ + pqxx/cursor pqxx/cursor.hxx \ + pqxx/dbtransaction pqxx/dbtransaction.hxx \ + pqxx/errorhandler pqxx/errorhandler.hxx \ + pqxx/except pqxx/except.hxx \ + pqxx/field pqxx/field.hxx \ + pqxx/isolation pqxx/isolation.hxx \ + pqxx/largeobject pqxx/largeobject.hxx \ + pqxx/nontransaction pqxx/nontransaction.hxx \ + pqxx/notification pqxx/notification.hxx \ + pqxx/params pqxx/params.hxx \ + pqxx/pipeline pqxx/pipeline.hxx \ + pqxx/prepared_statement pqxx/prepared_statement.hxx \ + pqxx/range pqxx/range.hxx \ + pqxx/result pqxx/result.hxx \ + pqxx/robusttransaction pqxx/robusttransaction.hxx \ + pqxx/separated_list pqxx/separated_list.hxx \ + pqxx/strconv pqxx/strconv.hxx \ + pqxx/stream_from pqxx/stream_from.hxx \ + pqxx/stream_to pqxx/stream_to.hxx \ + pqxx/subtransaction pqxx/subtransaction.hxx \ + pqxx/time pqxx/time.hxx \ + pqxx/transaction pqxx/transaction.hxx \ + pqxx/transaction_base pqxx/transaction_base.hxx \ + pqxx/transaction_focus pqxx/transaction_focus.hxx \ + pqxx/transactor pqxx/transactor.hxx \ + pqxx/row pqxx/row.hxx \ + pqxx/util pqxx/util.hxx \ + pqxx/types pqxx/types.hxx \ + pqxx/zview pqxx/zview.hxx \ + pqxx/version pqxx/version.hxx \ + pqxx/internal/array-composite.hxx \ + pqxx/internal/callgate.hxx \ + pqxx/internal/concat.hxx \ + pqxx/internal/conversions.hxx \ + pqxx/internal/encoding_group.hxx \ + pqxx/internal/encodings.hxx \ + pqxx/internal/header-pre.hxx \ + pqxx/internal/header-post.hxx \ + pqxx/internal/ignore-deprecated-post.hxx \ + pqxx/internal/ignore-deprecated-pre.hxx \ + pqxx/internal/libpq-forward.hxx \ + pqxx/internal/result_iter.hxx \ + pqxx/internal/result_iterator.hxx \ + pqxx/internal/sql_cursor.hxx \ + pqxx/internal/statement_parameters.hxx \ + pqxx/internal/stream_iterator.hxx \ + pqxx/internal/wait.hxx \ + pqxx/internal/gates/connection-errorhandler.hxx \ + pqxx/internal/gates/connection-largeobject.hxx \ + pqxx/internal/gates/connection-notification_receiver.hxx \ + pqxx/internal/gates/connection-pipeline.hxx \ + pqxx/internal/gates/connection-sql_cursor.hxx \ + pqxx/internal/gates/connection-transaction.hxx \ + pqxx/internal/gates/errorhandler-connection.hxx \ + pqxx/internal/gates/icursorstream-icursor_iterator.hxx \ + pqxx/internal/gates/icursor_iterator-icursorstream.hxx \ + pqxx/internal/gates/result-connection.hxx \ + pqxx/internal/gates/result-creation.hxx \ + pqxx/internal/gates/result-pipeline.hxx \ + pqxx/internal/gates/result-sql_cursor.hxx \ + pqxx/internal/gates/transaction-sql_cursor.hxx \ + pqxx/internal/gates/transaction-transaction_focus.hxx + + +nobase_nodist_include_HEADERS = \ + pqxx/config-public-compiler.h + +EXTRA_DIST = \ + pqxx/doc/*.md \ + pqxx/doc/mainpage.md.template \ + pqxx/version.hxx.template diff --git a/ext/libpqxx-7.7.3/include/Makefile.in b/ext/libpqxx-7.7.3/include/Makefile.in new file mode 100644 index 000000000..6b9eac914 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/Makefile.in @@ -0,0 +1,802 @@ +# Makefile.in generated by automake 1.16.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(nobase_include_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/pqxx/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)" +HEADERS = $(nobase_include_HEADERS) $(nobase_nodist_include_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/config/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_DOT = @HAVE_DOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PG_CONFIG = @PG_CONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +POSTGRES_INCLUDE = @POSTGRES_INCLUDE@ +PQXXVERSION = @PQXXVERSION@ +PQXX_ABI = @PQXX_ABI@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_postgres_lib = @with_postgres_lib@ +SUBDIRS = pqxx +nobase_include_HEADERS = pqxx/pqxx \ + pqxx/array pqxx/array.hxx \ + pqxx/binarystring pqxx/binarystring.hxx \ + pqxx/blob pqxx/blob.hxx \ + pqxx/composite pqxx/composite.hxx \ + pqxx/connection pqxx/connection.hxx \ + pqxx/cursor pqxx/cursor.hxx \ + pqxx/dbtransaction pqxx/dbtransaction.hxx \ + pqxx/errorhandler pqxx/errorhandler.hxx \ + pqxx/except pqxx/except.hxx \ + pqxx/field pqxx/field.hxx \ + pqxx/isolation pqxx/isolation.hxx \ + pqxx/largeobject pqxx/largeobject.hxx \ + pqxx/nontransaction pqxx/nontransaction.hxx \ + pqxx/notification pqxx/notification.hxx \ + pqxx/params pqxx/params.hxx \ + pqxx/pipeline pqxx/pipeline.hxx \ + pqxx/prepared_statement pqxx/prepared_statement.hxx \ + pqxx/range pqxx/range.hxx \ + pqxx/result pqxx/result.hxx \ + pqxx/robusttransaction pqxx/robusttransaction.hxx \ + pqxx/separated_list pqxx/separated_list.hxx \ + pqxx/strconv pqxx/strconv.hxx \ + pqxx/stream_from pqxx/stream_from.hxx \ + pqxx/stream_to pqxx/stream_to.hxx \ + pqxx/subtransaction pqxx/subtransaction.hxx \ + pqxx/time pqxx/time.hxx \ + pqxx/transaction pqxx/transaction.hxx \ + pqxx/transaction_base pqxx/transaction_base.hxx \ + pqxx/transaction_focus pqxx/transaction_focus.hxx \ + pqxx/transactor pqxx/transactor.hxx \ + pqxx/row pqxx/row.hxx \ + pqxx/util pqxx/util.hxx \ + pqxx/types pqxx/types.hxx \ + pqxx/zview pqxx/zview.hxx \ + pqxx/version pqxx/version.hxx \ + pqxx/internal/array-composite.hxx \ + pqxx/internal/callgate.hxx \ + pqxx/internal/concat.hxx \ + pqxx/internal/conversions.hxx \ + pqxx/internal/encoding_group.hxx \ + pqxx/internal/encodings.hxx \ + pqxx/internal/header-pre.hxx \ + pqxx/internal/header-post.hxx \ + pqxx/internal/ignore-deprecated-post.hxx \ + pqxx/internal/ignore-deprecated-pre.hxx \ + pqxx/internal/libpq-forward.hxx \ + pqxx/internal/result_iter.hxx \ + pqxx/internal/result_iterator.hxx \ + pqxx/internal/sql_cursor.hxx \ + pqxx/internal/statement_parameters.hxx \ + pqxx/internal/stream_iterator.hxx \ + pqxx/internal/wait.hxx \ + pqxx/internal/gates/connection-errorhandler.hxx \ + pqxx/internal/gates/connection-largeobject.hxx \ + pqxx/internal/gates/connection-notification_receiver.hxx \ + pqxx/internal/gates/connection-pipeline.hxx \ + pqxx/internal/gates/connection-sql_cursor.hxx \ + pqxx/internal/gates/connection-transaction.hxx \ + pqxx/internal/gates/errorhandler-connection.hxx \ + pqxx/internal/gates/icursorstream-icursor_iterator.hxx \ + pqxx/internal/gates/icursor_iterator-icursorstream.hxx \ + pqxx/internal/gates/result-connection.hxx \ + pqxx/internal/gates/result-creation.hxx \ + pqxx/internal/gates/result-pipeline.hxx \ + pqxx/internal/gates/result-sql_cursor.hxx \ + pqxx/internal/gates/transaction-sql_cursor.hxx \ + pqxx/internal/gates/transaction-transaction_focus.hxx + +nobase_nodist_include_HEADERS = \ + pqxx/config-public-compiler.h + +EXTRA_DIST = \ + pqxx/doc/*.md \ + pqxx/doc/mainpage.md.template \ + pqxx/version.hxx.template + +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu include/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-nobase_includeHEADERS: $(nobase_include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) +install-nobase_nodist_includeHEADERS: $(nobase_nodist_include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nobase_nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_nodist_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-nobase_includeHEADERS \ + install-nobase_nodist_includeHEADERS + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-nobase_includeHEADERS \ + uninstall-nobase_nodist_includeHEADERS + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-nobase_includeHEADERS \ + install-nobase_nodist_includeHEADERS install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am \ + uninstall-nobase_includeHEADERS \ + uninstall-nobase_nodist_includeHEADERS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ext/libpqxx-7.7.3/include/pqxx/Makefile.am b/ext/libpqxx-7.7.3/include/pqxx/Makefile.am new file mode 100644 index 000000000..c7f68813d --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/Makefile.am @@ -0,0 +1,13 @@ +MAINTAINERCLEANFILES=Makefile.in stamp-h.in + +noinst_HEADERS = \ + config-internal-autotools.h + +nodist_noinst_HEADERS = \ + config.h \ + config-internal-compiler.h + +DISTCLEANFILES = \ + config-internal-autotools.h \ + config-internal-compiler.h \ + config-public-compiler.h diff --git a/ext/libpqxx-7.7.3/include/pqxx/Makefile.in b/ext/libpqxx-7.7.3/include/pqxx/Makefile.in new file mode 100644 index 000000000..4b02fb771 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/Makefile.in @@ -0,0 +1,556 @@ +# Makefile.in generated by automake 1.16.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include/pqxx +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(nodist_noinst_HEADERS) $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/config/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_DOT = @HAVE_DOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PG_CONFIG = @PG_CONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +POSTGRES_INCLUDE = @POSTGRES_INCLUDE@ +PQXXVERSION = @PQXXVERSION@ +PQXX_ABI = @PQXX_ABI@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_postgres_lib = @with_postgres_lib@ +MAINTAINERCLEANFILES = Makefile.in stamp-h.in +noinst_HEADERS = \ + config-internal-autotools.h + +nodist_noinst_HEADERS = \ + config.h \ + config-internal-compiler.h + +DISTCLEANFILES = \ + config-internal-autotools.h \ + config-internal-compiler.h \ + config-public-compiler.h + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/pqxx/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu include/pqxx/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status include/pqxx/config.h +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(HEADERS) config.h +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: all install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ext/libpqxx-7.7.3/include/pqxx/array b/ext/libpqxx-7.7.3/include/pqxx/array new file mode 100644 index 000000000..689f5b27b --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/array @@ -0,0 +1,6 @@ +/** Handling of SQL arrays. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/array.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/array.hxx b/ext/libpqxx-7.7.3/include/pqxx/array.hxx new file mode 100644 index 000000000..8440a244f --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/array.hxx @@ -0,0 +1,103 @@ +/* Handling of SQL arrays. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ARRAY +#define PQXX_H_ARRAY + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/internal/encodings.hxx" + + +namespace pqxx +{ +/// Low-level array parser. +/** Use this to read an array field retrieved from the database. + * + * This parser will only work reliably if your client encoding is UTF-8, ASCII, + * or a single-byte encoding which is a superset of ASCII (such as Latin-1). + * + * Also, the parser only supports array element types which use either a comma + * or a semicolon ("," or ";") as the separator between array elements. All + * built-in types use comma, except for one which uses semicolon, but some + * custom types may not work. + * + * The input is a C-style string containing the textual representation of an + * array, as returned by the database. The parser reads this representation + * on the fly. The string must remain in memory until parsing is done. + * + * Parse the array by making calls to @ref get_next until it returns a + * @ref juncture of "done". The @ref juncture tells you what the parser found + * in that step: did the array "nest" to a deeper level, or "un-nest" back up? + */ +class PQXX_LIBEXPORT array_parser +{ +public: + /// What's the latest thing found in the array? + enum class juncture + { + /// Starting a new row. + row_start, + /// Ending the current row. + row_end, + /// Found a NULL value. + null_value, + /// Found a string value. + string_value, + /// Parsing has completed. + done, + }; + + // TODO: constexpr noexcept. Breaks ABI. + /// Constructor. You don't need this; use @ref field::as_array instead. + /** The parser only remains valid while the data underlying the @ref result + * remains valid. Once all `result` objects referring to that data have been + * destroyed, the parser will no longer refer to valid memory. + */ + explicit array_parser( + std::string_view input, + internal::encoding_group = internal::encoding_group::MONOBYTE); + + /// Parse the next step in the array. + /** Returns what it found. If the juncture is @ref juncture::string_value, + * the string will contain the value. Otherwise, it will be empty. + * + * Call this until the @ref array_parser::juncture it returns is + * @ref juncture::done. + */ + std::pair get_next(); + +private: + std::string_view m_input; + internal::glyph_scanner_func *const m_scan; + + /// Current parsing position in the input. + std::string::size_type m_pos = 0u; + + std::string::size_type scan_single_quoted_string() const; + std::string parse_single_quoted_string(std::string::size_type end) const; + std::string::size_type scan_double_quoted_string() const; + std::string parse_double_quoted_string(std::string::size_type end) const; + std::string::size_type scan_unquoted_string() const; + std::string parse_unquoted_string(std::string::size_type end) const; + + std::string::size_type scan_glyph(std::string::size_type pos) const; + std::string::size_type + scan_glyph(std::string::size_type pos, std::string::size_type end) const; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/binarystring b/ext/libpqxx-7.7.3/include/pqxx/binarystring new file mode 100644 index 000000000..77551d9f7 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/binarystring @@ -0,0 +1,6 @@ +/** BYTEA (binary string) conversions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/binarystring.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/binarystring.hxx b/ext/libpqxx-7.7.3/include/pqxx/binarystring.hxx new file mode 100644 index 000000000..47c82a035 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/binarystring.hxx @@ -0,0 +1,236 @@ +/* Deprecated representation for raw, binary data. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/binarystring instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_BINARYSTRING +#define PQXX_H_BINARYSTRING + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/result.hxx" +#include "pqxx/strconv.hxx" + +namespace pqxx +{ +class binarystring; +template<> struct string_traits; + + +/// Binary data corresponding to PostgreSQL's "BYTEA" binary-string type. +/** @ingroup escaping-functions + * @deprecated Use @c std::basic_string and + * @c std::basic_string_view for binary data. In C++20 or better, + * any @c contiguous_range of @c std::byte will do. + * + * This class represents a binary string as stored in a field of type @c bytea. + * + * Internally a binarystring is zero-terminated, but it may also contain null + * bytes, they're just like any other byte value. So don't assume that it's + * safe to treat the contents as a C-style string. + * + * The binarystring retains its value even if the result it was obtained from + * is destroyed, but it cannot be copied or assigned. + * + * \relatesalso transaction_base::quote_raw + * + * To include a @c binarystring value in an SQL query, escape and quote it + * using the transaction's @c quote_raw function. + * + * @warning This class is implemented as a reference-counting smart pointer. + * Copying, swapping, and destroying binarystring objects that refer to the + * same underlying data block is not thread-safe. If you wish to pass + * binarystrings around between threads, make sure that each of these + * operations is protected against concurrency with similar operations on the + * same object, or other objects pointing to the same data block. + */ +class PQXX_LIBEXPORT binarystring +{ +public: + using char_type = unsigned char; + using value_type = std::char_traits::char_type; + using size_type = std::size_t; + using difference_type = long; + using const_reference = value_type const &; + using const_pointer = value_type const *; + using const_iterator = const_pointer; + using const_reverse_iterator = std::reverse_iterator; + + [[deprecated("Use std::byte for binary data.")]] binarystring( + binarystring const &) = default; + + /// Read and unescape bytea field. + /** The field will be zero-terminated, even if the original bytea field + * isn't. + * @param F the field to read; must be a bytea field + */ + [[deprecated("Use std::byte for binary data.")]] explicit binarystring( + field const &); + + /// Copy binary data from std::string_view on binary data. + /** This is inefficient in that it copies the data to a buffer allocated on + * the heap. + */ + [[deprecated("Use std::byte for binary data.")]] explicit binarystring( + std::string_view); + + /// Copy binary data of given length straight out of memory. + [[deprecated("Use std::byte for binary data.")]] binarystring( + void const *, std::size_t); + + /// Efficiently wrap a buffer of binary data in a @c binarystring. + [[deprecated("Use std::byte for binary data.")]] binarystring( + std::shared_ptr ptr, size_type size) : + m_buf{std::move(ptr)}, m_size{size} + {} + + /// Size of converted string in bytes. + [[nodiscard]] size_type size() const noexcept { return m_size; } + /// Size of converted string in bytes. + [[nodiscard]] size_type length() const noexcept { return size(); } + [[nodiscard]] bool empty() const noexcept { return size() == 0; } + + [[nodiscard]] const_iterator begin() const noexcept { return data(); } + [[nodiscard]] const_iterator cbegin() const noexcept { return begin(); } + [[nodiscard]] const_iterator end() const noexcept { return data() + m_size; } + [[nodiscard]] const_iterator cend() const noexcept { return end(); } + + [[nodiscard]] const_reference front() const noexcept { return *begin(); } + [[nodiscard]] const_reference back() const noexcept + { + return *(data() + m_size - 1); + } + + [[nodiscard]] const_reverse_iterator rbegin() const + { + return const_reverse_iterator{end()}; + } + [[nodiscard]] const_reverse_iterator crbegin() const { return rbegin(); } + [[nodiscard]] const_reverse_iterator rend() const + { + return const_reverse_iterator{begin()}; + } + [[nodiscard]] const_reverse_iterator crend() const { return rend(); } + + /// Unescaped field contents. + [[nodiscard]] value_type const *data() const noexcept { return m_buf.get(); } + + [[nodiscard]] const_reference operator[](size_type i) const noexcept + { + return data()[i]; + } + + [[nodiscard]] PQXX_PURE bool operator==(binarystring const &) const noexcept; + [[nodiscard]] bool operator!=(binarystring const &rhs) const noexcept + { + return not operator==(rhs); + } + + binarystring &operator=(binarystring const &); + + /// Index contained string, checking for valid index. + const_reference at(size_type) const; + + /// Swap contents with other binarystring. + void swap(binarystring &); + + /// Raw character buffer (no terminating zero is added). + /** @warning No terminating zero is added! If the binary data did not end in + * a null character, you will not find one here. + */ + [[nodiscard]] char const *get() const noexcept + { + return reinterpret_cast(m_buf.get()); + } + + /// Read contents as a std::string_view. + [[nodiscard]] std::string_view view() const noexcept + { + return std::string_view(get(), size()); + } + + /// Read as regular C++ string (may include null characters). + /** This creates and returns a new string object. Don't call this + * repeatedly; retrieve your string once and keep it in a local variable. + * Also, do not expect to be able to compare the string's address to that of + * an earlier invocation. + */ + [[nodiscard]] std::string str() const; + + /// Access data as a pointer to @c std::byte. + [[nodiscard]] std::byte const *bytes() const + { + return reinterpret_cast(get()); + } + + /// Read data as a @c std::basic_string_view. + [[nodiscard]] std::basic_string_view bytes_view() const + { + return std::basic_string_view{bytes(), size()}; + } + +private: + std::shared_ptr m_buf; + size_type m_size{0}; +}; + + +template<> struct nullness : no_null +{}; + + +/// String conversion traits for @c binarystring. +/** Defines the conversions between a @c binarystring and its PostgreSQL + * textual format, for communication with the database. + * + * These conversions rely on the "hex" format which was introduced in + * PostgreSQL 9.0. Both your libpq and the server must be recent enough to + * speak this format. + */ +template<> struct string_traits +{ + static std::size_t size_buffer(binarystring const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf(char *begin, char *end, binarystring const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, binarystring const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + std::string_view text{value.view()}; + internal::esc_bin(binary_cast(text), begin); + return begin + budget; + } + + static binarystring from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::shared_ptr buf{ + new unsigned char[size], [](unsigned char const *x) { delete[] x; }}; + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.get())); +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return binarystring{std::move(buf), size}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + } +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/blob b/ext/libpqxx-7.7.3/include/pqxx/blob new file mode 100644 index 000000000..3fd0afac9 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/blob @@ -0,0 +1,6 @@ +/** Binary Large Objects interface. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/blob.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/blob.hxx b/ext/libpqxx-7.7.3/include/pqxx/blob.hxx new file mode 100644 index 000000000..6d77be724 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/blob.hxx @@ -0,0 +1,351 @@ +/* Binary Large Objects interface. + * + * Read or write large objects, stored in their own storage on the server. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_BLOB +#define PQXX_H_BLOB + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#if defined(PQXX_HAVE_PATH) +# include +#endif + +#if defined(PQXX_HAVE_RANGES) && __has_include() +# include +#endif + +#if defined(PQXX_HAVE_SPAN) && __has_include() +# include +#endif + +#include "pqxx/dbtransaction.hxx" + + +namespace pqxx +{ +/** Binary large object. + * + * This is how you store data that may be too large for the `BYTEA` type. + * Access operations are similar to those for a file: you can read, write, + * query or set the current reading/writing position, and so on. + * + * These large objects live in their own storage on the server, indexed by an + * integer object identifier ("oid"). + * + * Two `blob` objects may refer to the same actual large object in the + * database at the same time. Each will have its own reading/writing position, + * but writes to the one will of course affect what the other sees. + */ +class PQXX_LIBEXPORT blob +{ +public: + /// Create a new, empty large object. + /** You may optionally specify an oid for the new blob. If you do, then + * the new object will have that oid -- or creation will fail if there + * already is an object with that oid. + */ + [[nodiscard]] static oid create(dbtransaction &, oid = 0); + + /// Delete a large object, or fail if it does not exist. + static void remove(dbtransaction &, oid); + + /// Open blob for reading. Any attempt to write to it will fail. + [[nodiscard]] static blob open_r(dbtransaction &, oid); + // Open blob for writing. Any attempt to read from it will fail. + [[nodiscard]] static blob open_w(dbtransaction &, oid); + // Open blob for reading and/or writing. + [[nodiscard]] static blob open_rw(dbtransaction &, oid); + + /// You can default-construct a blob, but it won't do anything useful. + /** Most operations on a default-constructed blob will throw @ref + * usage_error. + */ + blob() = default; + + /// You can move a blob, but not copy it. The original becomes unusable. + blob(blob &&); + /// You can move a blob, but not copy it. The original becomes unusable. + blob &operator=(blob &&); + + blob(blob const &) = delete; + blob &operator=(blob const &) = delete; + ~blob(); + + /// Maximum number of bytes that can be read or written at a time. + /** The underlying protocol only supports reads and writes up to 2 GB + * exclusive. + * + * If you need to read or write more data to or from a binary large object, + * you'll have to break it up into chunks. + */ + static constexpr std::size_t chunk_limit = 0x7fffffff; + + /// Read up to `size` bytes of the object into `buf`. + /** Uses a buffer that you provide, resizing it as needed. If it suits you, + * this lets you allocate the buffer once and then re-use it multiple times. + * + * Resizes `buf` as needed. + * + * @warning The underlying protocol only supports reads up to 2GB at a time. + * If you need to read more, try making repeated calls to @ref append_to_buf. + */ + std::size_t read(std::basic_string &buf, std::size_t size); + +#if defined(PQXX_HAVE_SPAN) + /// Read up to `std::size(buf)` bytes from the object. + /** Retrieves bytes from the blob, at the current position, until `buf` is + * full or there are no more bytes to read, whichever comes first. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template + std::span read(std::span buf) + { + return buf.subspan(0, raw_read(std::data(buf), std::size(buf))); + } +#endif // PQXX_HAVE_SPAN + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Read up to `std::size(buf)` bytes from the object. + /** Retrieves bytes from the blob, at the current position, until `buf` is + * full or there are no more bytes to read, whichever comes first. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template std::span read(DATA &buf) + { + return {std::data(buf), raw_read(std::data(buf), std::size(buf))}; + } +#else // PQXX_HAVE_CONCEPTS && PQXX_HAVE_SPAN + /// Read up to `std::size(buf)` bytes from the object. + /** @deprecated As libpqxx moves to C++20 as its baseline language version, + * this will take and return `std::span`. + * + * Retrieves bytes from the blob, at the current position, until `buf` is + * full (i.e. its current size is reached), or there are no more bytes to + * read, whichever comes first. + * + * This function will not change either the size or the capacity of `buf`, + * only its contents. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template + std::basic_string_view read(std::vector &buf) + { + return {std::data(buf), raw_read(std::data(buf), std::size(buf))}; + } +#endif // PQXX_HAVE_CONCEPTS && PQXX_HAVE_SPAN + +#if defined(PQXX_HAVE_CONCEPTS) + /// Write `data` to large object, at the current position. + /** If the writing position is at the end of the object, this will append + * `data` to the object's contents and move the writing position so that + * it's still at the end. + * + * If the writing position was not at the end, writing will overwrite the + * prior data, but it will not remove data that follows the part where you + * wrote your new data. + * + * @warning This is a big difference from writing to a file. You can + * overwrite some data in a large object, but this does not truncate the + * data that was already there. For example, if the object contained binary + * data "abc", and you write "12" at the starting position, the object will + * contain "12c". + * + * @warning The underlying protocol only supports writes up to 2 GB at a + * time. If you need to write more, try making repeated calls to + * @ref append_from_buf. + */ + template void write(DATA const &data) + { + raw_write(std::data(data), std::size(data)); + } +#else + /// Write `data` large object, at the current position. + /** If the writing position is at the end of the object, this will append + * `data` to the object's contents and move the writing position so that + * it's still at the end. + * + * If the writing position was not at the end, writing will overwrite the + * prior data, but it will not remove data that follows the part where you + * wrote your new data. + * + * @warning This is a big difference from writing to a file. You can + * overwrite some data in a large object, but this does not truncate the + * data that was already there. For example, if the object contained binary + * data "abc", and you write "12" at the starting position, the object will + * contain "12c". + * + * @warning The underlying protocol only supports writes up to 2 GB at a + * time. If you need to write more, try making repeated calls to + * @ref append_from_buf. + */ + template void write(DATA const &data) + { + raw_write(std::data(data), std::size(data)); + } +#endif + + /// Resize large object to `size` bytes. + /** If the blob is more than `size` bytes long, this removes the end so as + * to make the blob the desired length. + * + * If the blob is less than `size` bytes long, it adds enough zero bytes to + * make it the desired length. + */ + void resize(std::int64_t size); + + /// Return the current reading/writing position in the large object. + [[nodiscard]] std::int64_t tell() const; + + /// Set the current reading/writing position to an absolute offset. + /** Returns the new file offset. */ + std::int64_t seek_abs(std::int64_t offset = 0); + /// Move the current reading/writing position forwards by an offset. + /** To move backwards, pass a negative offset. + * + * Returns the new file offset. + */ + std::int64_t seek_rel(std::int64_t offset = 0); + /// Set the current position to an offset relative to the end of the blob. + /** You'll probably want an offset of zero or less. + * + * Returns the new file offset. + */ + std::int64_t seek_end(std::int64_t offset = 0); + + /// Create a binary large object containing given `data`. + /** You may optionally specify an oid for the new object. If you do, and an + * object with that oid already exists, creation will fail. + */ + static oid from_buf( + dbtransaction &tx, std::basic_string_view data, oid id = 0); + + /// Append `data` to binary large object. + /** The underlying protocol only supports appending blocks up to 2 GB. + */ + static void append_from_buf( + dbtransaction &tx, std::basic_string_view data, oid id); + + /// Read client-side file and store it server-side as a binary large object. + [[nodiscard]] static oid from_file(dbtransaction &, char const path[]); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Read client-side file and store it server-side as a binary large object. + /** This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + [[nodiscard]] static oid + from_file(dbtransaction &tx, std::filesystem::path const &path) + { + return from_file(tx, path.c_str()); + } +#endif + + /// Read client-side file and store it server-side as a binary large object. + /** In this version, you specify the binary large object's oid. If that oid + * is already in use, the operation will fail. + */ + static oid from_file(dbtransaction &, char const path[], oid); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Read client-side file and store it server-side as a binary large object. + /** In this version, you specify the binary large object's oid. If that oid + * is already in use, the operation will fail. + * + * This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + static oid + from_file(dbtransaction &tx, std::filesystem::path const &path, oid id) + { + return from_file(tx, path.c_str(), id); + } +#endif + + /// Convenience function: Read up to `max_size` bytes from blob with `id`. + /** You could easily do this yourself using the @ref open_r and @ref read + * functions, but it can save you a bit of code to do it this way. + */ + static void to_buf( + dbtransaction &, oid, std::basic_string &, + std::size_t max_size); + + /// Read part of the binary large object with `id`, and append it to `buf`. + /** Use this to break up a large read from one binary large object into one + * massive buffer. Just keep calling this function until it returns zero. + * + * The `offset` is how far into the large object your desired chunk is, and + * `append_max` says how much to try and read in one go. + */ + static std::size_t append_to_buf( + dbtransaction &tx, oid id, std::int64_t offset, + std::basic_string &buf, std::size_t append_max); + + /// Write a binary large object's contents to a client-side file. + static void to_file(dbtransaction &, oid, char const path[]); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Write a binary large object's contents to a client-side file. + /** This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + static void + to_file(dbtransaction &tx, oid id, std::filesystem::path const &path) + { + to_file(tx, id, path.c_str()); + } +#endif + + /// Close this blob. + /** This does not delete the blob from the database; it only terminates your + * local object for accessing the blob. + * + * Resets the blob to a useless state similar to one that was + * default-constructed. + * + * The destructor will do this for you automatically. Still, there is a + * reason to `close()` objects explicitly where possible: if an error should + * occur while closing, `close()` can throw an exception. A destructor + * cannot. + */ + void close(); + +private: + PQXX_PRIVATE blob(connection &conn, int fd) noexcept : + m_conn{&conn}, m_fd{fd} + {} + static PQXX_PRIVATE blob open_internal(dbtransaction &, oid, int); + static PQXX_PRIVATE pqxx::internal::pq::PGconn * + raw_conn(pqxx::connection *) noexcept; + static PQXX_PRIVATE pqxx::internal::pq::PGconn * + raw_conn(pqxx::dbtransaction const &) noexcept; + static PQXX_PRIVATE std::string errmsg(connection const *); + static PQXX_PRIVATE std::string errmsg(dbtransaction const &tx) + { + return errmsg(&tx.conn()); + } + PQXX_PRIVATE std::string errmsg() const { return errmsg(m_conn); } + PQXX_PRIVATE std::int64_t seek(std::int64_t offset, int whence); + std::size_t raw_read(std::byte buf[], std::size_t size); + void raw_write(std::byte const buf[], std::size_t size); + + connection *m_conn = nullptr; + int m_fd = -1; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/composite b/ext/libpqxx-7.7.3/include/pqxx/composite new file mode 100644 index 000000000..2bfa7ade9 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/composite @@ -0,0 +1,6 @@ +/** Handling of SQL "composite types." + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/composite.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/composite.hxx b/ext/libpqxx-7.7.3/include/pqxx/composite.hxx new file mode 100644 index 000000000..439b133a8 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/composite.hxx @@ -0,0 +1,149 @@ +#ifndef PQXX_H_COMPOSITE +#define PQXX_H_COMPOSITE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/internal/array-composite.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Parse a string representation of a value of a composite type. +/** @warning This code is still experimental. Use with care. + * + * You may use this as a helper while implementing your own @ref string_traits + * for a composite type. + * + * This function interprets `text` as the string representation of a value of + * some composite type, and sets each of `fields` to the respective values of + * its fields. The field types must be copy-assignable. + * + * The number of fields must match the number of fields in the composite type, + * and there must not be any other text in the input. The function is meant to + * handle any value string that the backend can produce, but not necessarily + * every valid alternative spelling. + * + * Fields in composite types can be null. When this happens, the C++ type of + * the corresponding field reference must be of a type that can handle nulls. + * If you are working with a type that does not have an inherent null value, + * such as e.g. `int`, consider using `std::optional`. + */ +template +inline void parse_composite( + pqxx::internal::encoding_group enc, std::string_view text, T &...fields) +{ + static_assert(sizeof...(fields) > 0); + + auto const scan{pqxx::internal::get_glyph_scanner(enc)}; + auto const data{std::data(text)}; + auto const size{std::size(text)}; + if (size == 0) + throw conversion_error{"Cannot parse composite value from empty string."}; + + std::size_t here{0}, next{scan(data, size, here)}; + if (next != 1 or data[here] != '(') + throw conversion_error{ + internal::concat("Invalid composite value string: ", text)}; + + here = next; + + constexpr auto num_fields{sizeof...(fields)}; + std::size_t index{0}; + (pqxx::internal::parse_composite_field( + index, text, here, fields, scan, num_fields - 1), + ...); + if (here != std::size(text)) + throw conversion_error{internal::concat( + "Composite value did not end at the closing parenthesis: '", text, + "'.")}; + if (text[here - 1] != ')') + throw conversion_error{internal::concat( + "Composive value did not end in parenthesis: '", text, "'")}; +} + + +/// Parse a string representation of a value of a composite type. +/** @warning This version only works for UTF-8 and single-byte encodings. + * + * For proper encoding support, use the composite-type support in the + * `field` class. + */ +template +inline void parse_composite(std::string_view text, T &...fields) +{ + parse_composite(pqxx::internal::encoding_group::MONOBYTE, text, fields...); +} +} // namespace pqxx + + +namespace pqxx::internal +{ +constexpr char empty_composite_str[]{"()"}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// Estimate the buffer size needed to represent a value of a composite type. +/** Returns a conservative estimate. + */ +template +[[nodiscard]] inline std::size_t +composite_size_buffer(T const &...fields) noexcept +{ + constexpr auto num{sizeof...(fields)}; + + // Size for a multi-field composite includes room for... + // + opening parenthesis + // + field budgets + // + separating comma per field + // - comma after final field + // + closing parenthesis + // + terminating zero + + if constexpr (num == 0) + return std::size(pqxx::internal::empty_composite_str); + else + return 1 + (pqxx::internal::size_composite_field_buffer(fields) + ...) + + num + 1; +} + + +/// Render a series of values as a single composite SQL value. +/** @warning This code is still experimental. Use with care. + * + * You may use this as a helper while implementing your own `string_traits` + * for a composite type. + */ +template +inline char *composite_into_buf(char *begin, char *end, T const &...fields) +{ + if (std::size_t(end - begin) < composite_size_buffer(fields...)) + throw conversion_error{ + "Buffer space may not be enough to represent composite value."}; + + constexpr auto num_fields{sizeof...(fields)}; + if constexpr (num_fields == 0) + { + constexpr char empty[]{"()"}; + std::memcpy(begin, empty, std::size(empty)); + return begin + std::size(empty); + } + + char *pos{begin}; + *pos++ = '('; + + (pqxx::internal::write_composite_field(pos, end, fields), ...); + + // If we've got multiple fields, "backspace" that last comma. + if constexpr (num_fields > 1) + --pos; + *pos++ = ')'; + *pos++ = '\0'; + return pos; +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/config.h.in b/ext/libpqxx-7.7.3/include/pqxx/config.h.in new file mode 100644 index 000000000..743579967 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/config.h.in @@ -0,0 +1,121 @@ +/* include/pqxx/config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `pq' library (-lpq). */ +#undef HAVE_LIBPQ + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define if supports floating-point conversion. */ +#undef PQXX_HAVE_CHARCONV_FLOAT + +/* Define if supports integer conversion. */ +#undef PQXX_HAVE_CHARCONV_INT + +/* Define if compiler has C++20 std::cmp_greater etc. */ +#undef PQXX_HAVE_CMP + +/* Define if compiler supports Concepts and header. */ +#undef PQXX_HAVE_CONCEPTS + +/* Define if compiler supports __cxa_demangle */ +#undef PQXX_HAVE_CXA_DEMANGLE + +/* Define if g++ supports pure attribute */ +#undef PQXX_HAVE_GCC_PURE + +/* Define if g++ supports visibility attribute. */ +#undef PQXX_HAVE_GCC_VISIBILITY + +/* Define if likely & unlikely work. */ +#undef PQXX_HAVE_LIKELY + +/* Define if operator[] can take multiple arguments. */ +#undef PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT + +/* Define if compiler has usable std::filesystem::path. */ +#undef PQXX_HAVE_PATH + +/* Define if poll() is available. */ +#undef PQXX_HAVE_POLL + +/* Define if libpq has PQencryptPasswordConn (since pg 10). */ +#undef PQXX_HAVE_PQENCRYPTPASSWORDCONN + +/* Define if libpq has pipeline mode (since pg 14). */ +#undef PQXX_HAVE_PQ_PIPELINE + +/* Define if std::this_thread::sleep_for works. */ +#undef PQXX_HAVE_SLEEP_FOR + +/* Define if compiler has std::span. */ +#undef PQXX_HAVE_SPAN + +/* Define if strerror_r() is available. */ +#undef PQXX_HAVE_STRERROR_R + +/* Define if strerror_s() is available. */ +#undef PQXX_HAVE_STRERROR_S + +/* Define if thread_local is fully supported. */ +#undef PQXX_HAVE_THREAD_LOCAL + +/* Define if std::chrono has year_month_day etc. */ +#undef PQXX_HAVE_YEAR_MONTH_DAY + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION diff --git a/ext/libpqxx-7.7.3/include/pqxx/connection b/ext/libpqxx-7.7.3/include/pqxx/connection new file mode 100644 index 000000000..82ff43aa5 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/connection @@ -0,0 +1,8 @@ +/** pqxx::connection class. + * + * pqxx::connection encapsulates a connection to a database. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/connection.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/connection.hxx b/ext/libpqxx-7.7.3/include/pqxx/connection.hxx new file mode 100644 index 000000000..92454bb47 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/connection.hxx @@ -0,0 +1,1261 @@ +/* Definition of the connection class. + * + * pqxx::connection encapsulates a connection to a database. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/connection instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_CONNECTION +#define PQXX_H_CONNECTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Double-check in order to suppress an overzealous Visual C++ warning (#418). +#if defined(PQXX_HAVE_CONCEPTS) && __has_include() +# include +#endif + +#include "pqxx/errorhandler.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/params.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + + +/** + * @addtogroup connections + * + * Use of the libpqxx library starts here. + * + * Everything that can be done with a database through libpqxx must go through + * a @ref pqxx::connection object. It connects to a database when you create + * it, and it terminates that communication during destruction. + * + * Many things come together in this class. Handling of error and warning + * messages, for example, is defined by @ref pqxx::errorhandler objects in the + * context of a connection. Prepared statements are also defined here. + * + * When you connect to a database, you pass a connection string containing any + * parameters and options, such as the server address and the database name. + * + * These are identical to the ones in libpq, the C language binding upon which + * libpqxx itself is built: + * + * https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING + * + * There are also environment variables you can set to provide defaults, again + * as defined by libpq: + * + * https://www.postgresql.org/docs/current/libpq-envars.html + * + * You can also create a database connection _asynchronously_ using an + * intermediate @ref pqxx::connecting object. + */ + +namespace pqxx::internal +{ +class sql_cursor; + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: T is a range of pairs of zero-terminated strings. +template +concept ZKey_ZValues = std::ranges::input_range and requires(T t) +{ + {std::cbegin(t)}; + { + std::get<0>(*std::cbegin(t)) + } -> ZString; + { + std::get<1>(*std::cbegin(t)) + } -> ZString; +} and std::tuple_size_v::value_type> +== 2; +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx::internal + + +namespace pqxx::internal::gate +{ +class connection_dbtransaction; +class connection_errorhandler; +class connection_largeobject; +class connection_notification_receiver; +class connection_pipeline; +class connection_sql_cursor; +class connection_stream_from; +class connection_stream_to; +class connection_transaction; +class const_connection_largeobject; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Representation of a PostgreSQL table path. +/** A "table path" consists of a table name, optionally prefixed by a schema + * name, which in turn is optionally prefixed by a database name. + * + * A minimal example of a table path would be `{mytable}`. But a table path + * may also take the forms `{myschema,mytable}` or + * `{mydb,myschema,mytable}`. + */ +using table_path = std::initializer_list; + + +/// Encrypt a password. @deprecated Use connection::encrypt_password instead. +[[nodiscard, + deprecated("Use connection::encrypt_password instead.")]] std::string + PQXX_LIBEXPORT + encrypt_password(char const user[], char const password[]); + +/// Encrypt password. @deprecated Use connection::encrypt_password instead. +[[nodiscard, + deprecated("Use connection::encrypt_password instead.")]] inline std::string +encrypt_password(zview user, zview password) +{ +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return encrypt_password(user.c_str(), password.c_str()); +#include "pqxx/internal/ignore-deprecated-post.hxx" +} + + +/// Error verbosity levels. +enum class error_verbosity : int +{ + // These values must match those in libpq's PGVerbosity enum. + terse = 0, + normal = 1, + verbose = 2 +}; + + +/// Connection to a database. +/** This is the first class to look at when you wish to work with a database + * through libpqxx. The connection opens during construction, and closes upon + * destruction. + * + * When creating a connection, you can pass a connection URI or a postgres + * connection string, to specify the database server's address, a login + * username, and so on. If you don't, the connection will try to obtain them + * from certain environment variables. If those are not set either, the + * default is to try and connect to the local system's port 5432. + * + * Find more about connection strings here: + * + * https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING + * + * The variables are documented here: + * + * https://www.postgresql.org/docs/current/libpq-envars.html + * + * To query or manipulate the database once connected, use one of the + * transaction classes (see pqxx/transaction_base.hxx) and perhaps also the + * transactor framework (see pqxx/transactor.hxx). + * + * When a connection breaks, you will typically get a @ref broken_connection + * exception. This can happen at almost any point. + * + * @warning On Unix-like systems, including GNU and BSD systems, your program + * may receive the SIGPIPE signal when the connection to the backend breaks. By + * default this signal will abort your program. Use "signal(SIGPIPE, SIG_IGN)" + * if you want your program to continue running after a connection fails. + */ +class PQXX_LIBEXPORT connection +{ +public: + connection() : connection{""} {} + + /// Connect to a database, using `options` string. + explicit connection(char const options[]) + { + check_version(); + init(options); + } + + /// Connect to a database, using `options` string. + explicit connection(zview options) : connection{options.c_str()} + { + // (Delegates to other constructor which calls check_version for us.) + } + + /// Move constructor. + /** Moving a connection is not allowed if it has an open transaction, or has + * error handlers or notification receivers registered on it. In those + * situations, other objects may hold references to the old object which + * would become invalid and might produce hard-to-diagnose bugs. + */ + connection(connection &&rhs); + +#if defined(PQXX_HAVE_CONCEPTS) + /// Connect to a database, passing options as a range of key/value pairs. + /** @warning Experimental. Requires C++20 "concepts" support. Define + * `PQXX_HAVE_CONCEPTS` to enable it. + * + * There's no need to escape the parameter values. + * + * See the PostgreSQL libpq documentation for the full list of possible + * options: + * + * https://postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS + * + * The options can be anything that can be iterated as a series of pairs of + * zero-terminated strings: `std::pair`, or + * `std::tuple`, or + * `std::map`, and so on. + */ + template + inline connection(MAPPING const ¶ms); +#endif // PQXX_HAVE_CONCEPTS + + ~connection() + { + try + { + close(); + } + catch (std::exception const &) + {} + } + + /// Move assignment. + /** Neither connection can have an open transaction, registered error + * handlers, or registered notification receivers. + */ + connection &operator=(connection &&rhs); + + connection(connection const &) = delete; + connection &operator=(connection const &) = delete; + + /// Is this connection open at the moment? + /** @warning This function is **not** needed in most code. Resist the + * temptation to check it after opening a connection. The `connection` + * constructor will throw a @ref broken_connection exception if can't connect + * to the database. + */ + [[nodiscard]] bool PQXX_PURE is_open() const noexcept; + + /// Invoke notice processor function. The message should end in newline. + void process_notice(char const[]) noexcept; + /// Invoke notice processor function. Newline at end is recommended. + /** The zview variant, with a message ending in newline, is the most + * efficient way to call process_notice. + */ + void process_notice(zview) noexcept; + + /// Enable tracing to a given output stream, or nullptr to disable. + void trace(std::FILE *) noexcept; + + /** + * @name Connection properties + * + * These are probably not of great interest, since most are derived from + * information supplied by the client program itself, but they are included + * for completeness. + * + * The connection needs to be currently active for these to work. + */ + //@{ + /// Name of database we're connected to, if any. + [[nodiscard]] char const *dbname() const; + + /// Database user ID we're connected under, if any. + [[nodiscard]] char const *username() const; + + /// Address of server, or nullptr if none specified (i.e. default or local) + [[nodiscard]] char const *hostname() const; + + /// Server port number we're connected to. + [[nodiscard]] char const *port() const; + + /// Process ID for backend process, or 0 if inactive. + [[nodiscard]] int PQXX_PURE backendpid() const &noexcept; + + /// Socket currently used for connection, or -1 for none. Use with care! + /** Query the current socket number. This is intended for event loops based + * on functions such as select() or poll(), where you're waiting for any of + * multiple file descriptors to become ready for communication. + * + * Please try to stay away from this function. It is really only meant for + * event loops that need to wait on more than one file descriptor. If all + * you need is to block until a notification arrives, for instance, use + * await_notification(). If you want to issue queries and retrieve results + * in nonblocking fashion, check out the pipeline class. + */ + [[nodiscard]] int PQXX_PURE sock() const &noexcept; + + /// What version of the PostgreSQL protocol is this connection using? + /** The answer can be 0 (when there is no connection); 3 for protocol 3.0; or + * possibly higher values as newer protocol versions come into use. + */ + [[nodiscard]] int PQXX_PURE protocol_version() const noexcept; + + /// What version of the PostgreSQL server are we connected to? + /** The result is a bit complicated: each of the major, medium, and minor + * release numbers is written as a two-digit decimal number, and the three + * are then concatenated. Thus server version 9.4.2 will be returned as the + * decimal number 90402. If there is no connection to the server, this + * returns zero. + * + * @warning When writing version numbers in your code, don't add zero at the + * beginning! Numbers beginning with zero are interpreted as octal (base-8) + * in C++. Thus, 070402 is not the same as 70402, and 080000 is not a number + * at all because there is no digit "8" in octal notation. Use strictly + * decimal notation when it comes to these version numbers. + */ + [[nodiscard]] int PQXX_PURE server_version() const noexcept; + //@} + + /// @name Text encoding + /** + * Each connection is governed by a "client encoding," which dictates how + * strings and other text is represented in bytes. The database server will + * send text data to you in this encoding, and you should use it for the + * queries and data which you send to the server. + * + * Search the PostgreSQL documentation for "character set encodings" to find + * out more about the available encodings, how to extend them, and how to use + * them. Not all server-side encodings are compatible with all client-side + * encodings or vice versa. + * + * Encoding names are case-insensitive, so e.g. "UTF8" is equivalent to + * "utf8". + * + * You can change the client encoding, but this may not work when the + * connection is in a special state, such as when streaming a table. It's + * not clear what happens if you change the encoding during a transaction, + * and then abort the transaction. + */ + //@{ + /// Get client-side character encoding, by name. + [[nodiscard]] std::string get_client_encoding() const; + + /// Set client-side character encoding, by name. + /** + * @param encoding Name of the character set encoding to use. + */ + void set_client_encoding(zview encoding) & + { + set_client_encoding(encoding.c_str()); + } + + /// Set client-side character encoding, by name. + /** + * @param encoding Name of the character set encoding to use. + */ + void set_client_encoding(char const encoding[]) &; + + /// Get the connection's encoding, as a PostgreSQL-defined code. + [[nodiscard]] int PQXX_PRIVATE encoding_id() const; + + //@} + + /// Set session variable, using SQL's `SET` command. + /** @deprecated To set a session variable, use @ref set_session_var. To set + * a transaction-local variable, execute an SQL `SET` command. + * + * @warning When setting a string value, you must escape and quote it first. + * Use the @ref quote() function to do that. + * + * @warning This executes an SQL query, so do not get or set variables while + * a table stream or pipeline is active on the same connection. + * + * @param var Variable to set. + * @param value New value for Var. This can be any SQL expression. If it's + * a string, be sure that it's properly escaped and quoted. + */ + [[deprecated("To set session variables, use set_session_var.")]] void + set_variable(std::string_view var, std::string_view value) &; + + /// Set one of the session variables to a new value. + /** This executes SQL, so do not do it while a pipeline or stream is active + * on the connection. + * + * The value you set here will last for the rest of the connection's + * duration, or until you set a new value. + * + * If you set the value while in a @ref dbtransaction (i.e. any transaction + * that is not a @ref nontransaction), then rolling back the transaction will + * undo the change. + * + * All applies to setting _session_ variables. You can also set the same + * variables as _local_ variables, in which case they will always revert to + * their previous value when the transaction ends (or when you overwrite them + * of course). To set a local variable, simply execute an SQL statement + * along the lines of "`SET LOCAL var = 'value'`" inside your transaction. + * + * @param var The variable to set. + * @param value The new value for the variable. + * @throw @ref variable_set_to_null if the value is null; this is not + * allowed. + */ + template + void set_session_var(std::string_view var, TYPE const &value) & + { + if constexpr (nullness::has_null) + { + if (nullness::is_null(value)) + throw variable_set_to_null{ + internal::concat("Attempted to set variable ", var, " to null.")}; + } + exec(internal::concat("SET ", quote_name(var), "=", quote(value))); + } + + /// Read session variable, using SQL's `SHOW` command. + /** @warning This executes an SQL query, so do not get or set variables while + * a table stream or pipeline is active on the same connection. + */ + [[deprecated("Use get_var instead.")]] std::string + get_variable(std::string_view); + + /// Read currently applicable value of a variable. + /** This function executes an SQL statement, so it won't work while a + * @ref pipeline or query stream is active on the connection. + * + * @return a blank `std::optional` if the variable's value is null, or its + * string value otherwise. + */ + std::string get_var(std::string_view var); + + /// Read currently applicable value of a variable. + /** This function executes an SQL statement, so it won't work while a + * @ref pipeline or query stream is active on the connection. + * + * If there is any possibility that the variable is null, ensure that `TYPE` + * can represent null values. + */ + template TYPE get_var_as(std::string_view var) + { + return from_string(get_var(var)); + } + + /** + * @name Notifications and Receivers + */ + //@{ + /// Check for pending notifications and take appropriate action. + /** This does not block. To wait for incoming notifications, either call + * await_notification() (it calls this function); or wait for incoming data + * on the connection's socket (i.e. wait to read), and then call this + * function repeatedly until it returns zero. After that, there are no more + * pending notifications so you may want to wait again. + * + * If any notifications are pending when you call this function, it + * processes them by finding any receivers that match the notification string + * and invoking those. If no receivers match, there is nothing to invoke but + * we do consider the notification processed. + * + * If any of the client-registered receivers throws an exception, the + * function will report it using the connection's errorhandlers. It does not + * re-throw the exceptions. + * + * @return Number of notifications processed. + */ + int get_notifs(); + + /// Wait for a notification to come in. + /** There are other events that will also terminate the wait, such as the + * backend failing. It will also wake up periodically. + * + * If a notification comes in, the call will process it, along with any other + * notifications that may have been pending. + * + * To wait for notifications into your own event loop instead, wait until + * there is incoming data on the connection's socket to be read, then call + * @ref get_notifs() repeatedly until it returns zero. + * + * @return Number of notifications processed. + */ + int await_notification(); + + /// Wait for a notification to come in, or for given timeout to pass. + /** There are other events that will also terminate the wait, such as the + * backend failing, or timeout expiring. + * + * If a notification comes in, the call will process it, along with any other + * notifications that may have been pending. + * + * To wait for notifications into your own event loop instead, wait until + * there is incoming data on the connection's socket to be read, then call + * @ref get_notifs repeatedly until it returns zero. + * + * @return Number of notifications processed + */ + int await_notification(std::time_t seconds, long microseconds); + //@} + + /** + * @name Password encryption + * + * Use this when setting a new password for the user if password encryption + * is enabled. Inputs are the SQL name for the user for whom you with to + * encrypt a password; the plaintext password; and the hash algorithm. + * + * The algorithm must be one of "md5", "scram-sha-256" (introduced in + * PostgreSQL 10), or `nullptr`. If the pointer is null, this will query + * the `password_encryption setting` from the server, and use the default + * algorithm as defined there. + * + * @return encrypted version of the password, suitable for encrypted + * PostgreSQL authentication. + * + * Thus you can change a user's password with: + * ```cxx + * void setpw(transaction_base &t, string const &user, string const &pw) + * { + * t.exec0("ALTER USER " + user + " " + * "PASSWORD '" + t.conn().encrypt_password(user,pw) + "'"); + * } + * ``` + * + * When building this against a libpq older than version 10, this will use + * an older function which only supports md5. In that case, requesting a + * different algorithm than md5 will result in a @ref feature_not_supported + * exception. + */ + //@{ + /// Encrypt a password for a given user. + [[nodiscard]] std::string + encrypt_password(zview user, zview password, zview algorithm) + { + return encrypt_password(user.c_str(), password.c_str(), algorithm.c_str()); + } + /// Encrypt a password for a given user. + [[nodiscard]] std::string encrypt_password( + char const user[], char const password[], char const *algorithm = nullptr); + //@} + + /** + * @name Prepared statements + * + * PostgreSQL supports prepared SQL statements, i.e. statements that you can + * register under a name you choose, optimized once by the backend, and + * executed any number of times under the given name. + * + * Prepared statement definitions are not sensitive to transaction + * boundaries. A statement defined inside a transaction will remain defined + * outside that transaction, even if the transaction itself is subsequently + * aborted. Once a statement has been prepared, it will only go away if you + * close the connection or explicitly "unprepare" the statement. + * + * Use the `pqxx::transaction_base::exec_prepared` functions to execute a + * prepared statement. See @ref prepared for a full discussion. + * + * @warning Using prepared statements can save time, but if your statement + * takes parameters, it may also make your application significantly slower! + * The reason is that the server works out a plan for executing the query + * when you prepare it. At that time, of course it does not know the values + * for the parameters that you will pass. If you execute a query without + * preparing it, then the server works out the plan on the spot, with full + * knowledge of the parameter values. + * + * A statement's definition can refer to its parameters as `$1`, `$2`, etc. + * The first parameter you pass to the call provides a value for `$1`, and + * so on. + * + * Here's an example of how to use prepared statements. + * + * ```cxx + * using namespace pqxx; + * void foo(connection &c) + * { + * c.prepare("findtable", "select * from pg_tables where name=$1"); + * work tx{c}; + * result r = tx.exec_prepared("findtable", "mytable"); + * if (std::empty(r)) throw runtime_error{"mytable not found!"}; + * } + * ``` + */ + //@{ + + /// Define a prepared statement. + /** + * @param name unique name for the new prepared statement. + * @param definition SQL statement to prepare. + */ + void prepare(zview name, zview definition) & + { + prepare(name.c_str(), definition.c_str()); + } + + /** + * @param name unique name for the new prepared statement. + * @param definition SQL statement to prepare. + */ + void prepare(char const name[], char const definition[]) &; + + /// Define a nameless prepared statement. + /** + * This can be useful if you merely want to pass large binary parameters to a + * statement without otherwise wishing to prepare it. If you use this + * feature, always keep the definition and the use close together to avoid + * the nameless statement being redefined unexpectedly by code somewhere + * else. + */ + void prepare(char const definition[]) &; + void prepare(zview definition) & { return prepare(definition.c_str()); } + + /// Drop prepared statement. + void unprepare(std::string_view name); + + //@} + + // C++20: constexpr. Breaks ABI. + /// Suffix unique number to name to make it unique within session context. + /** Used internally to generate identifiers for SQL objects (such as cursors + * and nested transactions) based on a given human-readable base name. + */ + [[nodiscard]] std::string adorn_name(std::string_view); + + /** + * @defgroup escaping-functions String-escaping functions + */ + //@{ + + /// Escape string for use as SQL string literal on this connection. + /** @warning This accepts a length, and it does not require a terminating + * zero byte. But if there is a zero byte, escaping stops there even if + * it's not at the end of the string! + */ + [[deprecated("Use std::string_view or pqxx:zview.")]] std::string + esc(char const text[], std::size_t maxlen) const + { + return esc(std::string_view{text, maxlen}); + } + + /// Escape string for use as SQL string literal on this connection. + [[nodiscard]] std::string esc(char const text[]) const + { + return esc(std::string_view{text}); + } + +#if defined(PQXX_HAVE_SPAN) + /// Escape string for use as SQL string literal, into `buffer`. + /** Use this variant when you want to re-use the same buffer across multiple + * calls. If that's not the case, or convenience and simplicity are more + * important, use the single-argument variant. + * + * For every byte in `text`, there must be at least 2 bytes of space in + * `buffer`; plus there must be one byte of space for a trailing zero. + * Throws @ref range_error if this space is not available. + * + * Returns a reference to the escaped string, which is actually stored in + * `buffer`. + */ + [[nodiscard]] std::string_view + esc(std::string_view text, std::span buffer) + { + auto const size{std::size(text)}, space{std::size(buffer)}; + auto const needed{2 * size + 1}; + if (space < needed) + throw range_error{internal::concat( + "Not enough room to escape string of ", size, " byte(s): need ", + needed, " bytes of buffer space, but buffer size is ", space, ".")}; + auto const data{buffer.data()}; + return {data, esc_to_buf(text, data)}; + } +#endif + + /// Escape string for use as SQL string literal on this connection. + /** @warning This is meant for text strings only. It cannot contain bytes + * whose value is zero ("nul bytes"). + */ + [[nodiscard]] std::string esc(std::string_view text) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape binary string for use as SQL string literal on this connection. + /** This is identical to `esc_raw(data)`. */ + template [[nodiscard]] std::string esc(DATA const &data) const + { + return esc_raw(data); + } +#endif + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + /** Use this variant when you want to re-use the same buffer across multiple + * calls. If that's not the case, or convenience and simplicity are more + * important, use the single-argument variant. + * + * For every byte in `data`, there must be at least two bytes of space in + * `buffer`; plus there must be two bytes of space for a header and one for + * a trailing zero. Throws @ref range_error if this space is not available. + * + * Returns a reference to the escaped string, which is actually stored in + * `buffer`. + */ + template + [[nodiscard]] zview esc(DATA const &data, std::span buffer) const + { + auto const size{std::size(data)}, space{std::size(buffer)}; + auto const needed{internal::size_esc_bin(std::size(data))}; + if (space < needed) + throw range_error{internal::concat( + "Not enough room to escape binary string of ", size, " byte(s): need ", + needed, " bytes of buffer space, but buffer size is ", space, ".")}; + + std::basic_string_view view{std::data(data), std::size(data)}; + auto const out{std::data(buffer)}; + // Actually, in the modern format, we know beforehand exactly how many + // bytes we're going to fill. Just leave out the trailing zero. + internal::esc_bin(view, out); + return zview{out, needed - 1}; + } +#endif + + /// Escape binary string for use as SQL string literal on this connection. + [[deprecated("Use std::byte for binary data.")]] std::string + esc_raw(unsigned char const bin[], std::size_t len) const; + + /// Escape binary string for use as SQL string literal on this connection. + /** You can also just use @ref esc with a binary string. */ + [[nodiscard]] std::string esc_raw(std::basic_string_view) const; + +#if defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + /** You can also just use @ref esc with a binary string. */ + [[nodiscard]] std::string + esc_raw(std::basic_string_view, std::span buffer) const; +#endif + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape binary string for use as SQL string literal on this connection. + /** You can also just use @ref esc with a binary string. */ + template + [[nodiscard]] std::string esc_raw(DATA const &data) const + { + return esc_raw( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + template + [[nodiscard]] zview esc_raw(DATA const &data, std::span buffer) const + { + return this->esc(binary_cast(data), buffer); + } +#endif + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(zview text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return unesc_raw(text.c_str()); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(char const text[]) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + * + * (The data must be encoded in PostgreSQL's "hex" format. The legacy + * "bytea" escape format, used prior to PostgreSQL 9.0, is no longer + * supported.) + */ + [[nodiscard]] std::basic_string + unesc_bin(std::string_view text) const + { + std::basic_string buf; + buf.resize(pqxx::internal::size_unesc_bin(std::size(text))); + pqxx::internal::unesc_bin(text, buf.data()); + return buf; + } + + /// Escape and quote a string of binary data. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(unsigned char const bin[], std::size_t len) const; + + /// Escape and quote a string of binary data. + std::string quote_raw(std::basic_string_view) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape and quote a string of binary data. + /** You can also just use @ref quote with binary data. */ + template + [[nodiscard]] std::string quote_raw(DATA const &data) const + { + return quote_raw( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote an SQL identifier for use in a query. + [[nodiscard]] std::string quote_name(std::string_view identifier) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote a table name. + /** When passing just a table name, this is just another name for + * @ref quote_name. + */ + [[nodiscard]] std::string quote_table(std::string_view name) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote a table path. + /** A table path consists of a table name, optionally prefixed by a schema + * name; and if both are given, they are in turn optionally prefixed by a + * database name. + * + * Each portion of the path (database name, schema name, table name) will be + * quoted separately, and they will be joined together by dots. So for + * example, `myschema.mytable` will become `"myschema"."mytable"`. + */ + [[nodiscard]] std::string quote_table(table_path) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Quote and comma-separate a series of column names. + /** Use this to save a bit of work in cases where you repeatedly need to pass + * the same list of column names, e.g. with @ref stream_to and @ref + * stream_from. Some functions that need to quote the columns list + * internally, will have a "raw" alternative which let you do the quoting + * yourself. It's a bit of extra work, but it can in rare cases let you + * eliminate some duplicate work in quoting them repeatedly. + */ + template + inline std::string quote_columns(STRINGS const &columns) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Represent object as SQL string, including quoting & escaping. + /** + * Recognises nulls and represents them as SQL nulls. They get no quotes. + */ + template + [[nodiscard]] inline std::string quote(T const &t) const; + + [[deprecated("Use std::byte for binary data.")]] std::string + quote(binarystring const &) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote binary data for use as a BYTEA value in SQL statement. + [[nodiscard]] std::string + quote(std::basic_string_view bytes) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape string for literal LIKE match. + /** Use this when part of an SQL "LIKE" pattern should match only as a + * literal string, not as a pattern, even if it contains "%" or "_" + * characters that would normally act as wildcards. + * + * The string does not get string-escaped or quoted. You do that later. + * + * For instance, let's say you have a string `name` entered by the user, + * and you're searching a `file` column for items that match `name` + * followed by a dot and three letters. Even if `name` contains wildcard + * characters "%" or "_", you only want those to match literally, so "_" + * only matches "_" and "%" only matches a single "%". + * + * You do that by "like-escaping" `name`, appending the wildcard pattern + * `".___"`, and finally, escaping and quoting the result for inclusion in + * your query: + * + * ```cxx + * tx.exec( + * "SELECT file FROM item WHERE file LIKE " + + * tx.quote(tx.esc_like(name) + ".___")); + * ``` + * + * The SQL "LIKE" operator also lets you choose your own escape character. + * This is supported, but must be a single-byte character. + */ + [[nodiscard]] std::string + esc_like(std::string_view text, char escape_char = '\\') const; + //@} + + /// Attempt to cancel the ongoing query, if any. + /** You can use this from another thread, and/or while a query is executing + * in a pipeline, but it's up to you to ensure that you're not canceling the + * wrong query. This may involve locking. + */ + void cancel_query(); + +#if defined(_WIN32) || __has_include() + /// Set socket to blocking (true) or nonblocking (false). + /** @warning Do not use this unless you _really_ know what you're doing. + * @warning This function is available on most systems, but not necessarily + * all. + */ + void set_blocking(bool block) &; +#endif // defined(_WIN32) || __has_include() + + /// Set session verbosity. + /** Set the verbosity of error messages to "terse", "normal" (the default), + * or "verbose." + * + * If "terse", returned messages include severity, primary text, and + * position only; this will normally fit on a single line. "normal" produces + * messages that include the above plus any detail, hint, or context fields + * (these might span multiple lines). "verbose" includes all available + * fields. + */ + void set_verbosity(error_verbosity verbosity) &noexcept; + + /// Return pointers to the active errorhandlers. + /** The entries are ordered from oldest to newest handler. + * + * You may use this to find errorhandlers that your application wants to + * delete when destroying the connection. Be aware, however, that libpqxx + * may also add errorhandlers of its own, and those will be included in the + * list. If this is a problem for you, derive your errorhandlers from a + * custom base class derived from pqxx::errorhandler. Then use dynamic_cast + * to find which of the error handlers are yours. + * + * The pointers point to the real errorhandlers. The container it returns + * however is a copy of the one internal to the connection, not a reference. + */ + [[nodiscard]] std::vector get_errorhandlers() const; + + /// Return a connection string encapsulating this connection's options. + /** The connection must be currently open for this to work. + * + * Returns a reconstruction of this connection's connection string. It may + * not exactly match the connection string you passed in when creating this + * connection. + */ + [[nodiscard]] std::string connection_string() const; + + /// Explicitly close the connection. + /** The destructor will do this for you automatically. Still, there is a + * reason to `close()` objects explicitly where possible: if an error should + * occur while closing, `close()` can throw an exception. A destructor + * cannot. + * + * Closing a connection is idempotent. Closing a connection that's already + * closed does nothing. + */ + void close(); + + /// Seize control of a raw libpq connection. + /** @warning Do not do this. Please. It's for very rare, very specific + * use-cases. The mechanism may change (or break) in unexpected ways in + * future versions. + * + * @param raw_conn a raw libpq `PQconn` pointer. + */ + static connection seize_raw_connection(internal::pq::PGconn *raw_conn) + { + return connection{raw_conn}; + } + + /// Release the raw connection without closing it. + /** @warning Do not do this. It's for very rare, very specific use-cases. + * The mechanism may change (or break) in unexpected ways in future versions. + * + * The `connection` object becomes unusable after this. + */ + internal::pq::PGconn *release_raw_connection() && + { + return std::exchange(m_conn, nullptr); + } + +private: + friend class connecting; + enum connect_mode + { + connect_nonblocking + }; + connection(connect_mode, zview connection_string); + + /// For use by @ref seize_raw_connection. + explicit connection(internal::pq::PGconn *raw_conn) : m_conn{raw_conn} {} + + /// Poll for ongoing connection, try to progress towards completion. + /** Returns a pair of "now please wait to read data from socket" and "now + * please wait to write data to socket." Both will be false when done. + * + * Throws an exception if polling indicates that the connection has failed. + */ + std::pair poll_connect(); + + // Initialise based on connection string. + void init(char const options[]); + // Initialise based on parameter names and values. + void init(char const *params[], char const *values[]); + void complete_init(); + + result make_result( + internal::pq::PGresult *pgr, std::shared_ptr const &query, + std::string_view desc = ""sv); + + void PQXX_PRIVATE set_up_state(); + + int PQXX_PRIVATE PQXX_PURE status() const noexcept; + + /// Escape a string, into a buffer allocated by the caller. + /** The buffer must have room for at least `2*std::size(text) + 1` bytes. + * + * Returns the number of bytes written, including the trailing zero. + */ + std::size_t esc_to_buf(std::string_view text, char *buf) const; + + friend class internal::gate::const_connection_largeobject; + char const *PQXX_PURE err_msg() const noexcept; + + void PQXX_PRIVATE process_notice_raw(char const msg[]) noexcept; + + result exec_prepared(std::string_view statement, internal::c_params const &); + + /// Throw @ref usage_error if this connection is not in a movable state. + void check_movable() const; + /// Throw @ref usage_error if not in a state where it can be move-assigned. + void check_overwritable() const; + + friend class internal::gate::connection_errorhandler; + void PQXX_PRIVATE register_errorhandler(errorhandler *); + void PQXX_PRIVATE unregister_errorhandler(errorhandler *) noexcept; + + friend class internal::gate::connection_transaction; + result exec(std::string_view, std::string_view = ""sv); + result + PQXX_PRIVATE exec(std::shared_ptr, std::string_view = ""sv); + void PQXX_PRIVATE register_transaction(transaction_base *); + void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept; + + friend class internal::gate::connection_stream_from; + std::pair>, std::size_t> + PQXX_PRIVATE read_copy_line(); + + friend class internal::gate::connection_stream_to; + void PQXX_PRIVATE write_copy_line(std::string_view); + void PQXX_PRIVATE end_copy_write(); + + friend class internal::gate::connection_largeobject; + internal::pq::PGconn *raw_connection() const { return m_conn; } + + friend class internal::gate::connection_notification_receiver; + void add_receiver(notification_receiver *); + void remove_receiver(notification_receiver *) noexcept; + + friend class internal::gate::connection_pipeline; + void PQXX_PRIVATE start_exec(char const query[]); + bool PQXX_PRIVATE consume_input() noexcept; + bool PQXX_PRIVATE is_busy() const noexcept; + internal::pq::PGresult *get_result(); + + friend class internal::gate::connection_dbtransaction; + friend class internal::gate::connection_sql_cursor; + + result exec_params(std::string_view query, internal::c_params const &args); + + /// Connection handle. + internal::pq::PGconn *m_conn = nullptr; + + /// Active transaction on connection, if any. + /** We don't use this for anything, except to check for open transactions + * when we close the connection or start a new transaction. + * + * We also don't allow move construction or move assignment while there's a + * transaction, since moving the connection in that case would leave one or + * more pointers back from the transaction to the connection dangling. + */ + transaction_base const *m_trans = nullptr; + + std::list m_errorhandlers; + + using receiver_list = + std::multimap; + /// Notification receivers. + receiver_list m_receivers; + + /// Unique number to use as suffix for identifiers (see adorn_name()). + int m_unique_id = 0; +}; + + +/// @deprecated Old base class for connection. They are now the same class. +using connection_base = connection; + + +/// An ongoing, non-blocking stepping stone to a connection. +/** Use this when you want to create a connection to the database, but without + * blocking your whole thread. It is only available on systems that have + * the `` header, and Windows. + * + * Connecting in this way is probably not "faster" (it's more complicated and + * has some extra overhead), but in some situations you can use it to make your + * application as a whole faster. It all depends on having other useful work + * to do in the same thread, and being able to wait on a socket. If you have + * other I/O going on at the same time, your event loop can wait for both the + * libpqxx socket and your own sockets, and wake up whenever any of them is + * ready to do work. + * + * Connecting in this way is not properly "asynchronous;" it's merely + * "nonblocking." This means it's not a super-high-performance mechanism like + * you might get with e.g. `io_uring`. In particular, if we need to look up + * the database hostname in DNS, that will happen synchronously. + * + * To use this, create the `connecting` object, passing a connection string. + * Then loop: If @ref wait_to_read returns true, wait for the socket to have + * incoming data on it. If @ref wait_to_write returns true, wait for the + * socket to be ready for writing. Then call @ref process to process any + * incoming or outgoing data. Do all of this until @ref done returns true (or + * there is an exception). Finally, call @ref produce to get the completed + * connection. + * + * For example: + * + * ```cxx + * pqxx::connecting cg{}; + * + * // Loop until we're done connecting. + * while (!cg.done()) + * { + * wait_for_fd(cg.sock(), cg.wait_to_read(), cg.wait_to_write()); + * cg.process(); + * } + * + * pqxx::connection conn = std::move(cg).produce(); + * + * // At this point, conn is a working connection. You can no longer use + * // cg at all. + * ``` + */ +class PQXX_LIBEXPORT connecting +{ +public: + /// Start connecting. + connecting(zview connection_string = ""_zv); + + connecting(connecting const &) = delete; + connecting(connecting &&) = default; + connecting &operator=(connecting const &) = delete; + connecting &operator=(connecting &&) = default; + + /// Get the socket. The socket may change during the connection process. + [[nodiscard]] int sock() const &noexcept { return m_conn.sock(); } + + /// Should we currently wait to be able to _read_ from the socket? + [[nodiscard]] constexpr bool wait_to_read() const &noexcept + { + return m_reading; + } + + /// Should we currently wait to be able to _write_ to the socket? + [[nodiscard]] constexpr bool wait_to_write() const &noexcept + { + return m_writing; + } + + /// Progress towards completion (but don't block). + void process() &; + + /// Is our connection finished? + [[nodiscard]] constexpr bool done() const &noexcept + { + return not m_reading and not m_writing; + } + + /// Produce the completed connection object. + /** Use this only once, after @ref done returned `true`. Once you have + * called this, the `connecting` instance has no more use or meaning. You + * can't call any of its member functions afterwards. + * + * This member function is rvalue-qualified, meaning that you can only call + * it on an rvalue instance of the class. If what you have is not an rvalue, + * turn it into one by wrapping it in `std::move()`. + */ + [[nodiscard]] connection produce() &&; + +private: + connection m_conn; + bool m_reading{false}; + bool m_writing{true}; +}; + + +template inline std::string connection::quote(T const &t) const +{ + if constexpr (nullness::always_null) + { + return "NULL"; + } + else + { + if (is_null(t)) + return "NULL"; + auto const text{to_string(t)}; + + // Okay, there's an easy way to do this and there's a hard way. The easy + // way was "quote, esc(to_string(t)), quote". I'm going with the hard way + // because it's going to save some string manipulation that will probably + // incur some unnecessary memory allocations and deallocations. + std::string buf{'\''}; + buf.resize(2 + 2 * std::size(text) + 1); + auto const content_bytes{esc_to_buf(text, buf.data() + 1)}; + auto const closing_quote{1 + content_bytes}; + buf[closing_quote] = '\''; + auto const end{closing_quote + 1}; + buf.resize(end); + return buf; + } +} + + +template +inline std::string connection::quote_columns(STRINGS const &columns) const +{ + return separated_list( + ","sv, std::cbegin(columns), std::cend(columns), + [this](auto col) { return this->quote_name(*col); }); +} + + +#if defined(PQXX_HAVE_CONCEPTS) +template +inline connection::connection(MAPPING const ¶ms) +{ + check_version(); + + std::vector keys, values; + if constexpr (std::ranges::sized_range) + { + auto const size{std::ranges::size(params) + 1}; + keys.reserve(size); + values.reserve(size); + } + for (auto const &[key, value] : params) + { + keys.push_back(internal::as_c_string(key)); + values.push_back(internal::as_c_string(value)); + } + keys.push_back(nullptr); + values.push_back(nullptr); + init(std::data(keys), std::data(values)); +} +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/cursor b/ext/libpqxx-7.7.3/include/pqxx/cursor new file mode 100644 index 000000000..e20b3a4fa --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/cursor @@ -0,0 +1,8 @@ +/** Definition of the iterator/container-style cursor classes. + * + * C++-style wrappers for SQL cursors + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/cursor.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/cursor.hxx b/ext/libpqxx-7.7.3/include/pqxx/cursor.hxx new file mode 100644 index 000000000..b392e2407 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/cursor.hxx @@ -0,0 +1,483 @@ +/* Definition of the iterator/container-style cursor classes. + * + * C++-style wrappers for SQL cursors. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/cursor instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_CURSOR +#define PQXX_H_CURSOR + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/result.hxx" +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +/// Common definitions for cursor types +/** In C++ terms, fetches are always done in pre-increment or pre-decrement + * fashion--i.e. the result does not include the row the cursor is on at the + * beginning of the fetch, and the cursor ends up being positioned on the last + * row in the result. + * + * There are singular positions akin to `end()` at both the beginning and the + * end of the cursor's range of movement, although these fit in so naturally + * with the semantics that one rarely notices them. The cursor begins at the + * first of these, but any fetch in the forward direction will move the cursor + * off this position and onto the first row before returning anything. + */ +class PQXX_LIBEXPORT cursor_base +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + + /// Cursor access-pattern policy + /** Allowing a cursor to move forward only can result in better performance, + * so use this access policy whenever possible. + */ + enum access_policy + { + /// Cursor can move forward only + forward_only, + /// Cursor can move back and forth + random_access + }; + + /// Cursor update policy + /** + * @warning Not all PostgreSQL versions support updatable cursors. + */ + enum update_policy + { + /// Cursor can be used to read data but not to write + read_only, + /// Cursor can be used to update data as well as read it + update + }; + + /// Cursor destruction policy + /** The normal thing to do is to make a cursor object the owner of the SQL + * cursor it represents. There may be cases, however, where a cursor needs + * to persist beyond the end of the current transaction (and thus also beyond + * the lifetime of the cursor object that created it!), where it can be + * "adopted" into a new cursor object. See the basic_cursor documentation + * for an explanation of cursor adoption. + * + * If a cursor is created with "loose" ownership policy, the object + * representing the underlying SQL cursor will not take the latter with it + * when its own lifetime ends, nor will its originating transaction. + * + * @warning Use this feature with care and moderation. Only one cursor + * object should be responsible for any one underlying SQL cursor at any + * given time. + */ + enum ownership_policy + { + /// Destroy SQL cursor when cursor object is closed at end of transaction + owned, + /// Leave SQL cursor in existence after close of object and transaction + loose + }; + + cursor_base() = delete; + cursor_base(cursor_base const &) = delete; + cursor_base &operator=(cursor_base const &) = delete; + + /** + * @name Special movement distances. + */ + //@{ + + // TODO: Make constexpr inline (but breaks ABI). + /// Special value: read until end. + /** @return Maximum value for result::difference_type, so the cursor will + * attempt to read the largest possible result set. + */ + [[nodiscard]] static difference_type all() noexcept; + + /// Special value: read one row only. + /** @return Unsurprisingly, 1. + */ + [[nodiscard]] static constexpr difference_type next() noexcept { return 1; } + + /// Special value: read backwards, one row only. + /** @return Unsurprisingly, -1. + */ + [[nodiscard]] static constexpr difference_type prior() noexcept + { + return -1; + } + + // TODO: Make constexpr inline (but breaks ABI). + /// Special value: read backwards from current position back to origin. + /** @return Minimum value for result::difference_type. + */ + [[nodiscard]] static difference_type backward_all() noexcept; + + //@} + + /// Name of underlying SQL cursor + /** + * @returns Name of SQL cursor, which may differ from original given name. + * @warning Don't use this to access the SQL cursor directly without going + * through the provided wrapper classes! + */ + [[nodiscard]] constexpr std::string const &name() const noexcept + { + return m_name; + } + +protected: + cursor_base(connection &, std::string_view Name, bool embellish_name = true); + + std::string const m_name; +}; +} // namespace pqxx + + +#include + + +namespace pqxx +{ +/// "Stateless cursor" class: easy API for retrieving parts of result sets +/** This is a front-end for SQL cursors, but with a more C++-like API. + * + * Actually, stateless_cursor feels entirely different from SQL cursors. You + * don't keep track of positions, fetches, and moves; you just say which rows + * you want. See the retrieve() member function. + */ +template +class stateless_cursor +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + + /// Create cursor. + /** + * @param tx The transaction within which you want to create the cursor. + * @param query The SQL query whose results the cursor should traverse. + * @param cname A hint for the cursor's name. The actual SQL cursor's name + * will be based on this (though not necessarily identical). + * @param hold Create a `WITH HOLD` cursor? Such cursors stay alive after + * the transaction has ended, so you can continue to use it. + */ + stateless_cursor( + transaction_base &tx, std::string_view query, std::string_view cname, + bool hold) : + m_cur{tx, query, cname, cursor_base::random_access, up, op, hold} + {} + + /// Adopt an existing scrolling SQL cursor. + /** This lets you define a cursor yourself, and then wrap it in a + * libpqxx-managed `stateless_cursor` object. + * + * @param tx The transaction within which you want to manage the cursor. + * @param adopted_cursor Your cursor's SQL name. + */ + stateless_cursor(transaction_base &tx, std::string_view adopted_cursor) : + m_cur{tx, adopted_cursor, op} + { + // Put cursor in known position + m_cur.move(cursor_base::backward_all()); + } + + /// Close this cursor. + /** The destructor will do this for you automatically. + * + * Closing a cursor is idempotent. Closing a cursor that's already closed + * does nothing. + */ + void close() noexcept { m_cur.close(); } + + /// Number of rows in cursor's result set + /** @note This function is not const; it may need to scroll to find the size + * of the result set. + */ + [[nodiscard]] size_type size() + { + return internal::obtain_stateless_cursor_size(m_cur); + } + + /// Retrieve rows from begin_pos (inclusive) to end_pos (exclusive) + /** Rows are numbered starting from 0 to size()-1. + * + * @param begin_pos First row to retrieve. May be one row beyond the end of + * the result set, to avoid errors for empty result sets. Otherwise, must be + * a valid row number in the result set. + * @param end_pos Row up to which to fetch. Rows are returned ordered from + * begin_pos to end_pos, i.e. in ascending order if begin_pos < end_pos but + * in descending order if begin_pos > end_pos. The end_pos may be + * arbitrarily inside or outside the result set; only existing rows are + * included in the result. + */ + result retrieve(difference_type begin_pos, difference_type end_pos) + { + return internal::stateless_cursor_retrieve( + m_cur, result::difference_type(size()), begin_pos, end_pos); + } + + /// Return this cursor's name. + [[nodiscard]] constexpr std::string const &name() const noexcept + { + return m_cur.name(); + } + +private: + internal::sql_cursor m_cur; +}; + + +class icursor_iterator; +} // namespace pqxx + + +namespace pqxx::internal::gate +{ +class icursor_iterator_icursorstream; +class icursorstream_icursor_iterator; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Simple read-only cursor represented as a stream of results +/** SQL cursors can be tricky, especially in C++ since the two languages seem + * to have been designed on different planets. An SQL cursor has two singular + * positions akin to `end()` on either side of the underlying result set. + * + * These cultural differences are hidden from view somewhat by libpqxx, which + * tries to make SQL cursors behave more like familiar C++ entities such as + * iterators, sequences, streams, and containers. + * + * Data is fetched from the cursor as a sequence of result objects. Each of + * these will contain the number of rows defined as the stream's stride, except + * of course the last block of data which may contain fewer rows. + * + * This class can create or adopt cursors that live outside any backend + * transaction, which your backend version may not support. + */ +class PQXX_LIBEXPORT icursorstream +{ +public: + using size_type = cursor_base::size_type; + using difference_type = cursor_base::difference_type; + + /// Set up a read-only, forward-only cursor. + /** Roughly equivalent to a C++ Standard Library istream, this cursor type + * supports only two operations: reading a block of rows while moving + * forward, and moving forward without reading any data. + * + * @param context Transaction context in which this cursor will be active. + * @param query SQL query whose results this cursor shall iterate. + * @param basename Suggested name for the SQL cursor; the library will append + * a unique code to ensure its uniqueness. + * @param sstride Number of rows to fetch per read operation; must be a + * positive number. + */ + icursorstream( + transaction_base &context, std::string_view query, + std::string_view basename, difference_type sstride = 1); + + /// Adopt existing SQL cursor. Use with care. + /** Forms a cursor stream around an existing SQL cursor, as returned by e.g. + * a server-side function. The SQL cursor will be cleaned up by the stream's + * destructor as if it had been created by the stream; cleaning it up by hand + * or adopting the same cursor twice is an error. + * + * Passing the name of the cursor as a string is not allowed, both to avoid + * confusion with the other constructor and to discourage unnecessary use of + * adopted cursors. + * + * @warning It is technically possible to adopt a "WITH HOLD" cursor, i.e. a + * cursor that stays alive outside its creating transaction. However, any + * cursor stream (including the underlying SQL cursor, naturally) must be + * destroyed before its transaction context object is destroyed. Therefore + * the only way to use SQL's WITH HOLD feature is to adopt the cursor, but + * defer doing so until after entering the transaction context that will + * eventually destroy it. + * + * @param context Transaction context in which this cursor will be active. + * @param cname Result field containing the name of the SQL cursor to adopt. + * @param sstride Number of rows to fetch per read operation; must be a + * positive number. + * @param op Ownership policy. Determines whether the cursor underlying this + * stream will be destroyed when the stream is closed. + */ + icursorstream( + transaction_base &context, field const &cname, difference_type sstride = 1, + cursor_base::ownership_policy op = cursor_base::owned); + + /// Return `true` if this stream may still return more data. + constexpr operator bool() const &noexcept { return not m_done; } + + /// Read new value into given result object; same as operator `>>`. + /** The result set may continue any number of rows from zero to the chosen + * stride, inclusive. An empty result will only be returned if there are no + * more rows to retrieve. + * + * @param res Write the retrieved data into this result object. + * @return Reference to this very stream, to facilitate "chained" invocations + * ("C.get(r1).get(r2);") + */ + icursorstream &get(result &res) + { + res = fetchblock(); + return *this; + } + /// Read new value into given result object; same as `get(result&)`. + /** The result set may continue any number of rows from zero to the chosen + * stride, inclusive. An empty result will only be returned if there are no + * more rows to retrieve. + * + * @param res Write the retrieved data into this result object. + * @return Reference to this very stream, to facilitate "chained" invocations + * ("C >> r1 >> r2;") + */ + icursorstream &operator>>(result &res) { return get(res); } + + /// Move given number of rows forward without reading data. + /** Ignores any stride that you may have set. It moves by a given number of + * rows, not a number of strides. + * + * @return Reference to this stream itself, to facilitate "chained" + * invocations. + */ + icursorstream &ignore(std::streamsize n = 1) &; + + /// Change stride, i.e. the number of rows to fetch per read operation. + /** + * @param stride Must be a positive number. + */ + void set_stride(difference_type stride) &; + [[nodiscard]] constexpr difference_type stride() const noexcept + { + return m_stride; + } + +private: + result fetchblock(); + + friend class internal::gate::icursorstream_icursor_iterator; + size_type forward(size_type n = 1); + void insert_iterator(icursor_iterator *) noexcept; + void remove_iterator(icursor_iterator *) const noexcept; + + void service_iterators(difference_type); + + internal::sql_cursor m_cur; + + difference_type m_stride; + difference_type m_realpos, m_reqpos; + + mutable icursor_iterator *m_iterators; + + bool m_done; +}; + + +/// Approximate istream_iterator for icursorstream. +/** Intended as an implementation of an input_iterator (as defined by the C++ + * Standard Library), this class supports only two basic operations: reading + * the current element, and moving forward. In addition to the minimal + * guarantees for istream_iterators, this class supports multiple successive + * reads of the same position (the current result set is cached in the + * iterator) even after copying and even after new data have been read from the + * stream. This appears to be a requirement for input_iterators. Comparisons + * are also supported in the general case. + * + * The iterator does not care about its own position, however. Moving an + * iterator forward moves the underlying stream forward and reads the data from + * the new stream position, regardless of the iterator's old position in the + * stream. + * + * The stream's stride defines the granularity for all iterator movement or + * access operations, i.e. "ici += 1" advances the stream by one stride's worth + * of rows, and "*ici++" reads one stride's worth of rows from the stream. + * + * @warning Do not read from the underlying stream or its cursor, move its read + * position, or change its stride, between the time the first icursor_iterator + * on it is created and the time its last icursor_iterator is destroyed. + * + * @warning Manipulating these iterators within the context of a single cursor + * stream is not thread-safe. Creating a new iterator, copying one, + * or destroying one affects the stream as a whole. + */ +class PQXX_LIBEXPORT icursor_iterator +{ +public: + using iterator_category = std::input_iterator_tag; + using value_type = result; + using pointer = result const *; + using reference = result const &; + using istream_type = icursorstream; + using size_type = istream_type::size_type; + using difference_type = istream_type::difference_type; + + icursor_iterator() noexcept; + explicit icursor_iterator(istream_type &) noexcept; + icursor_iterator(icursor_iterator const &) noexcept; + ~icursor_iterator() noexcept; + + result const &operator*() const + { + refresh(); + return m_here; + } + result const *operator->() const + { + refresh(); + return &m_here; + } + icursor_iterator &operator++(); + icursor_iterator operator++(int); + icursor_iterator &operator+=(difference_type); + icursor_iterator &operator=(icursor_iterator const &) noexcept; + + [[nodiscard]] bool operator==(icursor_iterator const &rhs) const; + [[nodiscard]] bool operator!=(icursor_iterator const &rhs) const noexcept + { + return not operator==(rhs); + } + [[nodiscard]] bool operator<(icursor_iterator const &rhs) const; + [[nodiscard]] bool operator>(icursor_iterator const &rhs) const + { + return rhs < *this; + } + [[nodiscard]] bool operator<=(icursor_iterator const &rhs) const + { + return not(*this > rhs); + } + [[nodiscard]] bool operator>=(icursor_iterator const &rhs) const + { + return not(*this < rhs); + } + +private: + void refresh() const; + + friend class internal::gate::icursor_iterator_icursorstream; + difference_type pos() const noexcept { return m_pos; } + void fill(result const &); + + icursorstream *m_stream{nullptr}; + result m_here; + difference_type m_pos; + icursor_iterator *m_prev{nullptr}, *m_next{nullptr}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/dbtransaction b/ext/libpqxx-7.7.3/include/pqxx/dbtransaction new file mode 100644 index 000000000..fa8d26476 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/dbtransaction @@ -0,0 +1,8 @@ +/** pqxx::dbtransaction abstract base class. + * + * pqxx::dbransaction defines a real transaction on the database. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/dbtransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/dbtransaction.hxx b/ext/libpqxx-7.7.3/include/pqxx/dbtransaction.hxx new file mode 100644 index 000000000..d85cb170f --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/dbtransaction.hxx @@ -0,0 +1,70 @@ +/* Definition of the pqxx::dbtransaction abstract base class. + * + * pqxx::dbransaction defines a real transaction on the database. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/dbtransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_DBTRANSACTION +#define PQXX_H_DBTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/transaction_base.hxx" + +namespace pqxx +{ +/// Abstract transaction base class: bracket transactions on the database. +/** + * @ingroup transactions + * + * Use a dbtransaction-derived object such as "work" (transaction<>) to enclose + * operations on a database in a single "unit of work." This ensures that the + * whole series of operations either succeeds as a whole or fails completely. + * In no case will it leave half-finished work behind in the database. + * + * Once processing on a transaction has succeeded and any changes should be + * allowed to become permanent in the database, call commit(). If something + * has gone wrong and the changes should be forgotten, call abort() instead. + * If you do neither, an implicit abort() is executed at destruction time. + * + * It is an error to abort a transaction that has already been committed, or to + * commit a transaction that has already been aborted. Aborting an already + * aborted transaction or committing an already committed one is allowed, to + * make error handling easier. Repeated aborts or commits have no effect after + * the first one. + * + * Database transactions are not suitable for guarding long-running processes. + * If your transaction code becomes too long or too complex, consider ways to + * break it up into smaller ones. Unfortunately there is no universal recipe + * for this. + * + * The actual operations for committing/aborting the backend transaction are + * implemented by a derived class. The implementing concrete class must also + * call @ref close from its destructor. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE dbtransaction : public transaction_base +{ +protected: + /// Begin transaction. + explicit dbtransaction(connection &c) : transaction_base{c} {} + /// Begin transaction. + dbtransaction(connection &c, std::string_view tname) : + transaction_base{c, tname} + {} + /// Begin transaction. + dbtransaction( + connection &c, std::string_view tname, + std::shared_ptr rollback_cmd) : + transaction_base{c, tname, rollback_cmd} + {} +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/accessing-results.md b/ext/libpqxx-7.7.3/include/pqxx/doc/accessing-results.md new file mode 100644 index 000000000..920fb6f3b --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/accessing-results.md @@ -0,0 +1,157 @@ +Accessing results and result rows {#accessing-results} +--------------------------------- + +When you execute a query using one of the transaction `exec` functions, you +normally get a `result` object back. A `result` is a container of `row`s. + +(There are exceptions. The `exec1` functions expect exactly one row of data, +so they return just a `row`, not a full `result`.) + +Result objects are an all-or-nothing affair. The `exec` function waits until +it's received all the result data, and then gives it to you in the form of the +`result`. _(There is a faster, easier way of executing simple queries, so see +"streaming rows" below as well.)_ + +For example, your code might do: + +```cxx + pqxx::result r = tx.exec("SELECT * FROM mytable"); +``` + +Now, how do you access the data inside `r`? + +Result sets act as standard C++ containers of rows. Rows act as standard +C++ containers of fields. So the easiest way to go through them is: + +```cxx + for (auto const &row: r) + { + for (auto const &field: row) std::cout << field.c_str() << '\t'; + std::cout << '\n'; + } +``` + +But results and rows also support other kinds of access. Array-style +indexing, for instance, such as `r[rownum]`: + +```cxx + std::size_t const num_rows = std::size(r); + for (std::size_t rownum=0u; rownum < num_rows; ++rownum) + { + pqxx::row const row = r[rownum]; + std::size_t const num_cols = std::size(row); + for (std::size_t colnum=0u; colnum < num_cols; ++colnum) + { + pqxx::field const field = row[colnum]; + std::cout << field.c_str() << '\t'; + } + + std::cout << '\n'; + } +``` + +Every row in the result has the same number of columns, so you don't need to +look up the number of fields again for each one: + +```cxx + std::size_t const num_rows = std::size(r); + std::size_t const num_cols = r.columns(); + for (std::size_t rownum=0u; rownum < num_rows; ++rownum) + { + pqxx::row const row = r[rownum]; + for (std::size_t colnum=0u; colnum < num_cols; ++colnum) + { + pqxx::field const field = row[colnum]; + std::cout << field.c_str() << '\t'; + } + + std::cout << '\n'; + } +``` + +You can even address a field by indexing the `row` using the field's _name:_ + +```cxx + std::cout << row["salary"] << '\n'; +``` + +But try not to do that if speed matters, because looking up the column by name +takes time. At least you'd want to look up the column index before your loop +and then use numerical indexes inside the loop. + +For C++23 or better, there's also a two-dimensional array access operator: + +```cxx + for (std::size_t rownum=0u; rownum < num_rows; ++rownum) + { + for (std::size_t colnum=0u; colnum < num_cols; ++colnum) + std::cout result[rownum, colnum].c_str() << '\t'; + std::cout << '\n'; + } +``` + +And of course you can use classic "begin/end" loops: + +```cxx + for (auto row = std::begin(r); row != std::end(r); row++) + { + for (auto field = std::begin(row); field != std::end(row); field++) + std::cout << field->c_str() << '\t'; + std::cout << '\n'; + } +``` + +Result sets are immutable, so all iterators on results and rows are actually +`const_iterator`s. There are also `const_reverse_iterator` types, which +iterate backwards from `rbegin()` to `rend()` exclusive. + +All these iterator types provide one extra bit of convenience that you won't +normally find in C++ iterators: referential transparency. You don't need to +dereference them to get to the row or field they refer to. That is, instead +of `row->end()` you can also choose to say `row.end()`. Similarly, you +may prefer `field.c_str()` over `field->c_str()`. + +This becomes really helpful with the array-indexing operator. With regular +C++ iterators you would need ugly expressions like `(*row)[0]` or +`row->operator[](0)`. With the iterator types defined by the result and +row classes you can simply say `row[0]`. + + +Streaming rows +-------------- + +There's another way to go through the rows coming out of a query. It's +usually easier and faster, but there are drawbacks. + +**One,** you start getting rows before all the data has come in from the +database. That speeds things up, but what happens if you lose your network +connection while transferring the data? Your application may already have +processed some of the data before finding out that the rest isn't coming. If +that is a problem for your application, streaming may not be the right choice. + +**Two,** streaming only works for some types of query. The `stream()` function +wraps your query in a PostgreSQL `COPY` command, and `COPY` only supports a few +commands: `SELECT`, `VALUES`, `or an `INSERT`, `UPDATE`, or `DELETE` with a +`RETURNING` clause. See the `COPY` documentation here: +https://www.postgresql.org/docs/current/sql-copy.html + +**Three,** when you convert a field to a "view" type (such as +`std::string_view` or `std::basic_string_view`), the view points to +underlying data which only stays valid until you iterate to the next row or +exit the loop. So if you want to use that data for longer than a single +iteration of the streaming loop, you'll have to store it somewhere yourself. + +Now for the good news. Streaming does make it very easy to query data and loop +over it: + +```cxx + for (auto [id, name, x, y] : + tx.stream( + "SELECT id, name, x, y FROM point")) + process(id + 1, "point-" + name, x * 10.0, y * 10.0); +``` + +The conversion to C++ types (here `int`, `std::string_view`, and two `float`s) +is built into the function. You never even see `row` objects, `field` objects, +iterators, or conversion methods. You just put in your query and you receive +your data. diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/binary-data.md b/ext/libpqxx-7.7.3/include/pqxx/doc/binary-data.md new file mode 100644 index 000000000..20da8dc0c --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/binary-data.md @@ -0,0 +1,56 @@ +Binary data {#binary} +=========== + +The database has two ways of storing binary data: `BYTEA` is like a string, but +containing bytes rather than text characters. And _large objects_ are more +like a separate table containing binary objects. + +Generally you'll want to use `BYTEA` for reasonably-sized values, and large +objects for very large values. + +That's the database side. On the C++ side, in libpqxx, all binary data must be +either `std::basic_string` or `std::basic_string_view`; +or if you're building in C++20 or better, anything that's a block of +contiguous `std::byte` in memory. + +So for example, if you want to write a large object, you'd create a +`pqxx::blob` object. And you might use that to write data in the form of +`std::basic_string_view`. + +Your particular binary data may look different though. You may have it in a +`std::string`, or a `std::vector`, or a pointer to `char` +accompanied by a size (which could be signed or unsigned, and of any of a few +different widths). Sometimes that's your choice, or sometimes some other +library will dictate what form it takes. + +So long as it's _basically_ still a block of bytes though, you can use +`pqxx::binary_cast` to construct a `std::basic_string_view` from it. + +There are two forms of `binary_cast`. One takes a single argument that must +support `std::data()` and `std::size()`: + + std::string hi{"Hello binary world"}; + my_blob.write(pqxx::binary_cast(hi); + +The other takes a pointer and a size: + + char const greeting[] = "Hello binary world"; + char const *hi = greeting; + my_blob.write(pqxx::binary_cast(hi, sizeof(greeting))); + + +Caveats +------- + +There are some restrictions on `binary_cast` that you must be aware of. + +First, your data must of a type that gives us _bytes._ So: `char`, +`unsigned char`, `signed char`, `int8_t`, `uint8_t`, or of course `std::byte`. +You can't feed in a vector of `double`, or anything like that. + +Second, the data must be laid out as a contiguous block in memory. If there's +no `std::data()` implementation for your type, it's not suitable. + +Third, `binary_cast` only constructs something like a `std::string_view`. It +does not make a copy of your actual data. So, make sure that your data remains +alive and in the same place while you're using it. diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/datatypes.md b/ext/libpqxx-7.7.3/include/pqxx/doc/datatypes.md new file mode 100644 index 000000000..bc14c8b90 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/datatypes.md @@ -0,0 +1,373 @@ +Supporting additional data types {#datatypes} +================================ + +Communication with the database mostly happens in a text format. When you +include an integer value in a query, you use `to_string` to convert it to that +text format. When you get a query result field "as a float," it converts from +the text format to a floating-point type. These conversions are everywhere in +libpqxx. + +The conversion sydstem supports many built-in types, but it is also extensible. +You can "teach" libpqxx (in the scope of your own application) to convert +additional types of values to and from PostgreSQL's string format. + +This is massively useful, but it's not for the faint of heart. You'll need to +specialise some templates. And, **the API for doing this can change with any +major libpqxx release.** + + +Converting types +---------------- + +In your application, a conversion is driven entirely by a C++ type you specify. +The value's SQL type has nothing to do with it, nor is there anything in the +string that would identify its type. + +So, if you've SELECTed a 64-bit integer from the database, and you try to +convert it to a C++ "short," one of two things will happen: either the number +is small enough to fit in your `short` (and it just works), or else it throws a +conversion exception. + +Or, your database table might have a text column, but a given field may contain +a string that _looks_ just like a number. You can convert that value to an +integer type just fine. Or to a floating-point type. All that matters to the +conversion is the actual value, and the type. + +In some cases the templates for these conversions can tell the type from the +arguments you pass them: + + auto x = to_string(99); + +In other cases you may need to instantiate template explicitly: + + auto y = from_string("99"); + + +Supporting a new type +--------------------- + +Let's say you have some other SQL type which you want to be able to store in, +or retrieve from, the database. What would it take to support that? + +Sometimes you do not need _complete_ support. You might need a conversion _to_ +a string but not _from_ a string, for example. The conversion is defined at +compile time, so don't be too afraid to be incomplete. If you leave out one of +these steps, it's not going to crash at run time or mess up your data. The +worst that can happen is that your code won't build. + +So what do you need for a complete conversion? + +First off, of course, you need a C++ type. It may be your own, but it +doesn't have to be. It could be a type from a third-party library, or even one +from the standard library that libpqxx does not yet support. + +You also specialise the `pqxx::type_name` variable to specify the type's name. +This is important for all code which mentions your type in human-readable text, +such as error messages. + +Then, does your type have a built-in null value? You specialise the +`pqxx::nullness` template to specify the details. + +Finally, you specialise the `pqxx::string_traits` template. This is where you +define the actual conversions. + +Let's go through these steps one by one. + + +Your type +--------- + +You'll need a type for which the conversions are not yet defined, because the +C++ type is what determines the right conversion. One type, one set of +conversions. + +The type doesn't have to be one that you create. The conversion logic was +designed such that you can build it around any type. So you can just as +easily build a conversion for a type that's defined somewhere else. There's +no need to include any special methods or other members inside it. That's also +how libpqxx can support converting built-in types like `int`. + +By the way, if the type is an enum, you don't need to do any of this. Just +invoke the preprocessor macro `PQXX_DECLARE_ENUM_CONVERSION`, from the global +namespace near the top of your translation unit, and pass the type as an +argument. + +The library also provides specialisations for `std::optional`, +`std::shared_ptr`, and `std::unique_ptr`. If you have conversions for +`T`, you'll also have conversions for those. + + +Specialise `type_name` +---------------------- + +When errors happen during conversion, libpqxx will compose error messages for +the user. Sometimes these will include the name of the type that's being +converted. + +To tell libpqxx the name of each type, there's a template variable called +`pqxx::type_name`. For any given type `T`, it should have a specialisation +that provides that `T`'s human-readable name: + + namespace pqxx + { + template<> std::string const type_name{"T"}; + } + +(Yes, this means that you need to define something inside the pqxx namespace. +Future versions of libpqxx may move this into a separate namespace.) + +Define this early on in your translation unit, before any code that might cause +libpqxx to need the name. That way, the libpqxx code which needs to know the +type's name can see your definition. + + +Specialise `nullness` +--------------------- + +A struct template `pqxx::nullness` defines whether your type has a natural +"null value" built in. If so, it also provides member functions for producing +and recognising null values. + +The simplest scenario is also the most common: most types don't have a null +value built in. In that case, derive your nullness traits from +`pqxx::no_null`: + + namespace pqxx + { + template<> struct nullness : pqxx::no_null {}; + } + +(Here again you're defining this in the pqxx namespace.) + +If your type does have a natural null value, the definition gets a little more +complex: + + namespace pqxx + { + template<> struct nullness + { + static constexpr bool has_null{true}; + static constexpr bool always_null{false}; + + static bool is_null(T const &value) + { + // Return whether "value" is null. + return ...; + } + + [[nodiscard]] static T null() + { + // Return a null value. + return ...; + } + }; + } + +You may be wondering why there's a function to produce a null value, but also a +function to check whether a value is null. Why not just compare the value to +the result of `null()`? Because two null values may not be equal. `T` may +have several different null values. Or it may override the comparison +operator, similar to SQL where NULL is not equal to NULL. + +As a third case, your type may be one that _always_ represents a null value. +This is the case for `std::nullptr_t` and `std::nullopt_t`. In that case, you +set `nullness::always_null` to `true` (as well as `has_null` of course), +and you won't need to define any actual conversions. + + +Specialise `string_traits` +------------------------- + +This part is more work. (You can skip it for types that are _always_ null, +but those will be rare.) Specialise the `pqxx::string_traits` template: + + namespace pqxx + { + template<> struct string_traits + { + static T from_string(std::string_view text); + static zview to_buf(char *begin, char *end, T const &value); + static char *into_buf(char *begin, char *end, T const &value); + static std::size_t size_buffer(T const &value) noexcept; + }; + } + +You'll also need to write those member functions, or as many of them as needed +to get your code to build. + + +### `from_string` + +We start off simple: `from_string` parses a string as a value of `T`, and +returns that value. + +The string may not be zero-terminated; it's just the `string_view` from +beginning to end (exclusive). In your tests, cover cases where the string +does not end in a zero byte. + +It's perfectly possible that the string isn't actually a `T` value. Mistakes +happen. In that case, throw a `pqxx::conversion_error`. + +(Of course it's also possible that you run into some other error, so it's fine +to throw different exceptions as well. But when it's definitely "this is not +the right format for a `T`," throw `conversion_error`.) + + +### `to_buf` + +In this function, you convert a value of `T` into a string that the postgres +server will understand. + +The caller will provide you with a buffer where you can write the string, if +you need it: from `begin` to `end` exclusive. It's a half-open interval, so +don't access `*end`. + +If the buffer is insufficient for you to do the conversion, throw a +`pqxx::conversion_overrun`. It doesn't have to be exact: you can be a little +pessimistic and demand a bit more space than you need. Just be sure to throw +the exception if there's any risk of overrunning the buffer. + +You don't _have_ to use the buffer for this function though. For example, +`pqxx::string_traits::to_buf` returns a compile-time constant string and +ignores the buffer. + +Even if you do use the buffer, your string does not _have_ to start at the +beginning of the buffer. For example, the integer conversions start by writing +the _least_ significant digit to the _end_ of the buffer, and then writes the +more significant digits before it. It was just more convenient. + +Return a `pqxx::zview`. This is basically a `std::string_view`, but with one +difference: a `zview` guarantees that there will be a valid zero byte right +after the `string_view`. The zero byte is not counted as part of its size, but +it will be there. + +Expressed in code, this rule must hold: + + void invariant(zview z) + { + assert(z[std::size(z)] == 0); + } + +Make sure you write your trailing zero _before_ the `end`. If the trailing +zero doesn't fit in the buffer, then there's just not enough room to perform +the conversion. + +Beware of locales when converting. If you use standard library features like +`sprintf`, they may obey whatever locale is currently set on the system. That +means that a simple integer like 1000000 may come out as "1000000" on your +system, but as "1,000,000" on mine, or as "1.000.000" for somebody else, and on +an Indian system it may be "1,00,000". Values coming from or going to the +database should be in non-localised formats. You can use libpqxx functions for +those conversions: `pqxx::from_string`, `pqxx::to_string`, `pqxx::to_buf`. + + +### `into_buf` + +This is a stricter version of `to_buf`. All the same requirements apply, but +in addition you must write your string into the buffer provided, starting +_exactly_ at `begin`. + +That's why this function returns just a simple pointer: the address right +behind the trailing zero. If the caller wants to use the string, they can +find it at `begin`. If they want to write a different value into the rest of +the buffer, they can start at the location you returned. + + +### `size_buffer` + +Here you estimate how much buffer space you need for converting a `T` to a +string. Be precise if you can, but pessimistic if you must. It's usually +better to waste a few unnecessary bytes than to spend a lot of time computing +the exact buffer space you need. And failing the conversion because you +under-budgeted the buffer is worst of all. + +Include the trailing zero in the buffer size. If your `to_buf` takes more +space than just what's needed to store the result, include that too. + +Make `size_buffer` a `constexpr` function if you can. It can allow the caller +to allocate the buffer on the stack, with a size known at compile time. + + +Optional: Specialise `is_unquoted_safe` +--------------------------------------- + +When converting arrays or composite values to strings, libpqxx may need to +quote values and escape any special characters. This takes time. + +Some types though, such as integral or floating-point types, can never have +any special characters such as quotes, commas, or backslashes in their string +representations. In such cases, there's no need to quote or escape such values +in arrays or composite types. + +If your type is like that, you can tell libpqxx about this by defining: + + namespace pqxx + { + template<> inline constexpr bool is_unquoted_safe{true}; + } + +The code that converts this type of field to strings in an array or a composite +type can then use a simpler, more efficient variant of the code. It's always +safe to leave this out; it's _just_ an optimisation for when you're completely +sure that it's safe. + +Do not do this if a string representation of your type may contain a comma; +semicolon; parenthesis; brace; quote; backslash; newline; or any other +character that might need escaping. + + +Optional: Specialise `param_format` +----------------------------------- + +This one you don't generally need to worry about. Read on if you're writing a +type which represents raw binary data, or if you're writing a template where +_some specialisations_ may contain raw binary data. + +When you call parameterised statements, or prepared statements with parameters, +libpqxx needs to your parameters on to libpq, the underlying C-level PostgreSQL +client library. + +There are two formats for doing that: _text_ and _binary._ In the first, we +represent all values as strings, and the server then converts them into its own +internal binary representation. That's what the string conversions are all +about, and it's what we do for almost all types of parameters. + +But we do it differently when the parameter is a contiguous series of raw bytes +and the corresponding SQL type is `BYTEA`. There is a text format for those, +but we bypass it for efficiency. The server can use the binary data in the +exact same form, without any conversion or extra processing. The binary data +is also twice as compact during transport. + +(People sometimes ask why we can't just treat all types as binary. However the +general case isn't so clear-cut. The binary formats are not documented, there +are no guarantees that they will be platform-independent or that they will +remain stable, and there's no really solid way to detect when we might get the +format wrong. But also, the conversions aren't necessarily as straightforward +and efficient as they sound. So, for the general case, libpqxx sticks with the +text formats. Raw binary data alone stands out as a clear win.) + +Long story short, the machinery for passing parameters needs to know: is this +parameter a binary string, or not? In the normal case it can assume "no," and +that's what it does. The text format is always a safe choice; we just try to +use the binary format where it's faster. + +The `param_format` function template is what makes the decision. We specialise +it for types which may be binary strings, and use the default for all other +types. + +"Types which _may_ be binary"? You might think we know whether a type is a +binary type or not. But there are some complications with generic types. + +Templates like `std::shared_ptr`, `std::optional`, and so on act like +"wrappers" for another type. A `std::optional` is binary if `T` is binary. +Otherwise, it's not. If you're building support for a template of this nature, +you'll probably want to implement `param_format` for it. + +The decision to use binary format is made based on a given object, not +necessarily based on the type in general. Look at `std::variant`. If you have +a `std::variant` type which can hold an `int` or a binary string, is that a +binary parameter? We can't decide without knowing the individual object. + +Containers are another hard case. Should we pass `std::vector` in binary? +Even when `T` is a binary type, we don't currently have any way to pass an +array in binary format, so we always pass it as text. diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/escaping.md b/ext/libpqxx-7.7.3/include/pqxx/doc/escaping.md new file mode 100644 index 000000000..2ad9fe3db --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/escaping.md @@ -0,0 +1,74 @@ +String escaping {#escaping} +=============== + +Writing queries as strings is easy. But sometimes you need a variable in +there: `"SELECT id FROM user WHERE name = '" + name + "'"`. + +This is dangerous. See the bug? If `name` can contain quotes, you may have +an SQL injection vulnerability there, where users can enter nasty stuff like +"`.'; DROP TABLE user`". Or if you're lucky, it's just a nasty bug that you +discover when `name` happens to be "d'Arcy". + +So, you'll need to _escape_ the `name` before you insert it. This is where +quotes and other problematic characters are marked as "this is just a character +in the string, not the end of the string." There are +[several functions](@ref escaping-functions) in libpqxx to do this for you. + + +SQL injection +------------- + +To understand what SQL injection vulnerabilities are and why they should be +prevented, imagine you use the following SQL statement somewhere in your +program: + + TX.exec( + "SELECT number,amount " + "FROM accounts " + "WHERE allowed_to_see('" + userid + "','" + password + "')"); + +This shows a logged-in user important information on all accounts he is +authorized to view. The userid and password strings are variables entered +by the user himself. + +Now, if the user is actually an attacker who knows (or can guess) the +general shape of this SQL statement, imagine he enters the following +password: + + x') OR ('x' = 'x + +Does that make sense to you? Probably not. But if this is inserted into +the SQL string by the C++ code above, the query becomes: + + SELECT number,amount + FROM accounts + WHERE allowed_to_see('user','x') OR ('x' = 'x') + +Is this what you wanted to happen? Probably not! The neat `allowed_to_see()` +clause is completely circumvented by the "`OR ('x' = 'x')`" clause, which is +always `true`. Therefore, the attacker will get to see all accounts in the +database! + + +Using the esc functions +----------------------- + +Here's how you can fix the problem in the example above: + + TX.exec( + "SELECT number,amount " + "FROM accounts " + "WHERE allowed_to_see('" + TX.esc(userid) + "', " + "'" + TX.esc(password) + "')"); + +Now, the quotes embedded in the attacker's string will be neatly escaped so +they can't "break out" of the quoted SQL string they were meant to go into: + + SELECT number,amount + FROM accounts + WHERE allowed_to_see('user', 'x'') OR (''x'' = ''x') + +If you look carefully, you'll see that thanks to the added escape characters +(a single-quote is escaped in SQL by doubling it) all we get is a very +strange-looking password string--but not a change in the SQL statement. + diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/getting-started.md b/ext/libpqxx-7.7.3/include/pqxx/doc/getting-started.md new file mode 100644 index 000000000..1b87b881f --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/getting-started.md @@ -0,0 +1,142 @@ +Getting started {#getting-started} +=============== + +The most basic three types in libpqxx are the _connection_, the _transaction_, +and the _result_. + +They fit together as follows: +* You connect to the database by creating a `pqxx::connection` object (see + @ref connections). + +* You create a transaction object (see @ref transactions) operating on that + connection. You'll usually want the `pqxx::work` variety. + + Once you're done you call the transaction's `commit` function to make its + work final. If you don't call this, the work will be rolled back when the + transaction object is destroyed. + +* Until then, use the transaction's `exec`, `query_value`, and `stream` + functions (and variants) to execute SQL statements. You pass the statements + themselves in as simple strings. (See @ref streams for more about data + streaming). + +* Most of the `exec` functions return a `pqxx::result` object, which acts + as a standard container of rows: `pqxx::row`. + + Each row in a result, in turn, acts as a container of fields: `pqxx::field`. + See @ref accessing-results for more about results, rows, and fields. + +* Each field's data is stored internally as a text string, in a format defined + by PostgreSQL. You can convert field or row values using their `as()` and + `to()` member functions. + +* After you've closed the transaction, the connection is free to run a next + transaction. + +Here's a very basic example. It connects to the default database (you'll +need to have one set up), queries it for a very simple result, converts it to +an `int`, and prints it out. It also contains some basic error handling. + + #include + #include + + int main() + { + try + { + // Connect to the database. In practice we may have to pass some + // arguments to say where the database server is, and so on. + // The constructor parses options exactly like libpq's + // PQconnectdb/PQconnect, see: + // https://www.postgresql.org/docs/10/static/libpq-connect.html + pqxx::connection c; + + // Start a transaction. In libpqxx, you always work in one. + pqxx::work w(c); + + // work::exec1() executes a query returning a single row of data. + // We'll just ask the database to return the number 1 to us. + pqxx::row r = w.exec1("SELECT 1"); + + // Commit your transaction. If an exception occurred before this + // point, execution will have left the block, and the transaction will + // have been destroyed along the way. In that case, the failed + // transaction would implicitly abort instead of getting to this point. + w.commit(); + + // Look at the first and only field in the row, parse it as an integer, + // and print it. + // + // "r[0]" returns the first field, which has an "as<...>()" member + // function template to convert its contents from their string format + // to a type of your choice. + std::cout << r[0].as() << std::endl; + } + catch (std::exception const &e) + { + std::cerr << e.what() << std::endl; + return 1; + } + } + +This prints the number 1. Notice that you can keep the result object around +after you've closed the transaction or even the connection. There are +situations where you can't do it, but generally it's fine. If you're +interested: you can install your own callbacks for receiving error messages +from the database, and in that case you'll have to keep the connection object +alive. But otherwise, it's nice to be able to "fire and forget" your +connection and deal with the data. + +You can also convert an entire row to a series of C++-side types in one go, +using the @c as member function on the row: + + pqxx::connection c; + pqxx::work w(c); + pqxx::row r = w.exec1("SELECT 1, 2, 'Hello'"); + auto [one, two, hello] = r.as(); + std::cout << (one + two) << ' ' << std::strlen(hello) << std::endl; + +Here's a slightly more complicated example. It takes an argument from the +command line and retrieves a string with that value. The interesting part is +that it uses the escaping-and-quoting function `quote` to embed this +string value in SQL safely. It also reads the result field's value as a +plain C-style string using its `c_str` function. + + #include + #include + #include + + int main(int argc, char *argv[]) + { + try + { + if (!argv[1]) throw std::runtime_error("Give me a string!"); + + pqxx::connection c; + pqxx::work w(c); + + // work::exec() returns a full result set, which can consist of any + // number of rows. + pqxx::result r = w.exec("SELECT " + w.quote(argv[1])); + + // End our transaction here. We can still use the result afterwards. + w.commit(); + + // Print the first field of the first row. Read it as a C string, + // just like std::string::c_str() does. + std::cout << r[0][0].c_str() << std::endl; + } + catch (std::exception const &e) + { + std::cerr << e.what() << std::endl; + return 1; + } + } + +You can find more about converting field values to native types, or +converting values to strings for use with libpqxx, under +@ref stringconversion. More about getting to the rows and fields of a +result is under @ref accessing-results. + +If you want to handle exceptions thrown by libpqxx in more detail, for +example to print the SQL contents of a query that failed, see @ref exception. diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md b/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md new file mode 100644 index 000000000..5d4b8f9b2 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md @@ -0,0 +1,28 @@ +libpqxx {#mainpage} +======= + +@version 7.7.3 +@author Jeroen T. Vermeulen +@see http://pqxx.org +@see https://github.com/jtv/libpqxx + +Welcome to libpqxx, the C++ API to the PostgreSQL database management system. + +Compiling this package requires PostgreSQL to be installed -- including the +C headers for client development. The library builds on top of PostgreSQL's +standard C API, libpq. The libpq headers are not needed to compile client +programs, however. + +For a quick introduction to installing and using libpqxx, see the README.md +file. The latest information can be found at http://pqxx.org/ + + +Some links that should help you find your bearings: +* @ref getting-started +* @ref thread-safety +* @ref connections +* @ref transactions +* @ref escaping +* @ref performance +* @ref transactor +* @ref datatypes diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md.template b/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md.template new file mode 100644 index 000000000..d5afb2427 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md.template @@ -0,0 +1,28 @@ +libpqxx {#mainpage} +======= + +@version @PQXXVERSION@ +@author Jeroen T. Vermeulen +@see http://pqxx.org +@see https://github.com/jtv/libpqxx + +Welcome to libpqxx, the C++ API to the PostgreSQL database management system. + +Compiling this package requires PostgreSQL to be installed -- including the +C headers for client development. The library builds on top of PostgreSQL's +standard C API, libpq. The libpq headers are not needed to compile client +programs, however. + +For a quick introduction to installing and using libpqxx, see the README.md +file. The latest information can be found at http://pqxx.org/ + + +Some links that should help you find your bearings: +* @ref getting-started +* @ref thread-safety +* @ref connections +* @ref transactions +* @ref escaping +* @ref performance +* @ref transactor +* @ref datatypes diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/parameters.md b/ext/libpqxx-7.7.3/include/pqxx/doc/parameters.md new file mode 100644 index 000000000..7ac792025 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/parameters.md @@ -0,0 +1,90 @@ +Statement parameters {#parameters} +==================== + +When you execute a prepared statement (see @ref prepared), or a parameterised +statement (using functions like `pqxx::connection::exec_params`), you may write +special _placeholders_ in the query text. They look like `$1`, `$2`, and so +on. + +If you execute the query and pass parameter values, the call will respectively +substitute the first where it finds `$1`, the second where it finds `$2`, et +cetera. + +Doing this saves you work. If you don't use statement parameters, you'll need +to quote and escape your values (see `connection::quote()` and friends) as you +insert them into your query as literal values. + +Or if you forget to do that, you leave yourself open to horrible +[SQL injection attacks](https://xkcd.com/327/). Trust me, I was born in a town +whose name started with an apostrophe! + +Statement parameters save you this work. With these parameters you can pass +your values as-is, and they will go across the wire to the database in a safe +format. + +In some cases it may even be faster! When a parameter represents binary data +(as in the SQL `BYTEA` type), libpqxx will send it directly as binary, which is +a bit more efficient. If you insert the binary data directly in your query +text, your CPU will have some extra work to do, converting the data into a text +format, escaping it, and adding quotes. + + +Dynamic parameter lists +----------------------- + +In rare cases you may just not know how many parameters you'll pass into your +statement when you call it. + +For these situations, have a look at `params`. It lets you compose your +parameters list on the fly, even add whole ranges of parameters at a time. + +You can pass a `params` into your statement as a normal parameter. It will +fill in all the parameter values it contains into that position of the +statement's overall parameter list. + +So if you call your statement passing a regular parameter `a`, a +`params` containing just a parameter `b`, and another regular parameter `c`, +then your call will pass parameters `a`, `b`, and `c`. Or if the params object +is empty, it will pass just `a` and `c`. If the params object contains `x` and +`y`, your call will pass `a, x, y, c`. + +You can mix static and dynamic parameters freely. Don't go overboard though: +complexity is where bugs happen! + + +Generating placeholders +----------------------- + +If your code gets particularly complex, it may sometimes happen that it becomes +hard to track which parameter value belongs with which placeholder. Did you +intend to pass this numeric value as `$7`, or as `$8`? The answer may depend +on an `if` that happened earlier in a different function. + +(Generally if things get that complex, it's a good idea to look for simpler +solutions. But especially when performance matters, sometimes you can't avoid +complexity like that.) + +There's a little helper class called `placeholders`. You can use it as a +counter which produces those placeholder strings, `$1`, `$2`, `$3`, et cetera. +When you start generating a complex statement, you can create both a `params` +and a `placeholders`: + + pqxx::params values; + pqxx::placeholders name; + +Let's say you've got some complex code to generate the conditions for an SQL +"WHERE" clause. You'll generally want to do these things close together in +your, so that you don't accidentally update one part and forget another: + + if (extra_clause) + { + // Extend the query text, using the current placeholder. + query += " AND x = " + name.get(); + // Add the parameter value. + values.append(my_x); + // Move on to the next placeholder value. + name.next(); + } + +Depending on the starting value of `name`, this might add to `query` a fragment +like "` AND x = $3`" or "` AND x = $5`". diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/performance.md b/ext/libpqxx-7.7.3/include/pqxx/doc/performance.md new file mode 100644 index 000000000..6c403684f --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/performance.md @@ -0,0 +1,24 @@ +Performance features {#performance} +==================== + +If your program's database interaction is not as efficient as it needs to be, +the first place to look is usually the SQL you're executing. But libpqxx +has a few specialized features to help you squeeze more performance out +of how you issue commands and retrieve data: + +* @ref streams. Use these as a faster way to transfer data between your + code and the database. +* `std::string_view` and `pqxx::zview`. In places where traditional C++ worked + with `std::string`, see whether `std::string_view` or `pqxx::zview` will + do. Of course that means that you'll have to look at the data's lifetime + more carefully, but it'll save the computer a lot of copying. +* @ref prepared. These can be executed many times without the server + parsing and planning them anew each time. They also save you having to + escape string parameters. +* `pqxx::pipeline` lets you send queries to the database in batches, and + continue other processing while they are executing. +* `pqxx::connecting` lets you start setting up a database connection, but + without blocking the thread. + +As always of course, don't risk the quality of your code for optimizations +that you don't need! diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/prepared-statement.md b/ext/libpqxx-7.7.3/include/pqxx/doc/prepared-statement.md new file mode 100644 index 000000000..5193866a6 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/prepared-statement.md @@ -0,0 +1,125 @@ +Prepared statements {#prepared} +=================== + +Prepared statements are SQL queries that you define once and then invoke +as many times as you like, typically with varying parameters. It's basically +a function that you can define ad hoc. + +If you have an SQL statement that you're going to execute many times in +quick succession, it may be more efficient to prepare it once and reuse it. +This saves the database backend the effort of parsing complex SQL and +figuring out an efficient execution plan. Another nice side effect is that +you don't need to worry about escaping parameters. Some corporate coding +standards require all SQL parameters to be passed in this way, to reduce the +risk of programmer mistakes leaving room for SQL injections. + + +Preparing a statement +--------------------- + +You create a prepared statement by preparing it on the connection (using the +`pqxx::connection::prepare` functions), passing an identifier and its SQL text. + +The identifier is the name by which the prepared statement will be known; it +should consist of ASCII letters, digits, and underscores only, and start with +an ASCII letter. The name is case-sensitive. + +```cxx + void prepare_my_statement(pqxx::connection &c) + { + c.prepare( + "my_statement", + "SELECT * FROM Employee WHERE name = 'Xavier'"); + } +``` + +Once you've done this, you'll be able to call `my_statement` from any +transaction you execute on the same connection. For this, use the +`pqxx::transaction_base::exec_prepared` functions. + +```cxx + pqxx::result execute_my_statement(pqxx::transaction_base &t) + { + return t.exec_prepared("my_statement"); + } +``` + + +Parameters +---------- + +Did I mention that prepared statements can have parameters? The query text +can contain `$1`, `$2` etc. as placeholders for parameter values that you +will provide when you invoke the prepared satement. + +See @ref parameters for more about this. And here's a simple example of +preparing a statement and invoking it with parameters: + +```cxx + void prepare_find(pqxx::connection &c) + { + // Prepare a statement called "find" that looks for employees with a + // given name (parameter 1) whose salary exceeds a given number + // (parameter 2). + c.prepare( + "find", + "SELECT * FROM Employee WHERE name = $1 AND salary > $2"); + } +``` + +This example looks up the prepared statement "find," passes `name` and +`min_salary` as parameters, and invokes the statement with those values: + +```cxx + pqxx::result execute_find( + pqxx::transaction_base &t, std::string name, int min_salary) + { + return t.exec_prepared("find", name, min_salary); + } +``` + + +A special prepared statement +---------------------------- + +There is one special case: the _nameless_ prepared statement. You may prepare +a statement without a name, i.e. whose name is an empty string. The unnamed +statement can be redefined at any time, without un-preparing it first. + + +Performance note +---------------- + +Don't assume that using prepared statements will speed up your application. +There are cases where prepared statements are actually slower than plain SQL. + +The reason is that the backend can often produce a better execution plan when +it knows the statement's actual parameter values. + +For example, say you've got a web application and you're querying for users +with status "inactive" who have email addresses in a given domain name X. If +X is a very popular provider, the best way for the database engine to plan the +query may be to list the inactive users first and then filter for the email +addresses you're looking for. But in other cases, it may be much faster to +find matching email addresses first and then see which of their owners are +"inactive." A prepared statement must be planned to fit either case, but a +direct query will be optimised based on table statistics, partial indexes, etc. + + +Zero bytes +---------- + +@warning Beware of "nul" bytes! + +Any string you pass as a parameter will end at the _first char with value +zero._ If you pass a string that contains a zero byte, the last byte in the +value will be the one just before the zero. + +So, if you need a zero byte in a string, consider that it's really a _binary +string,_ which is not the same thing as a text string. SQL represents binary +data as the `BYTEA` type, or in binary large objects ("blobs"). + +In libpqxx, you represent binary data as a range of `std::byte`. They must be +contiguous in memory, so that libpqxx can pass pointers to the underlying C +library. So you might use `std::basic_string`, or +`std::basic_string_view`, or `std::vector`. diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/streams.md b/ext/libpqxx-7.7.3/include/pqxx/doc/streams.md new file mode 100644 index 000000000..3df4d6126 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/streams.md @@ -0,0 +1,107 @@ +Streams {#streams} +======= + +Most of the time it's fine to retrieve data from the database using `SELECT` +queries, and store data using `INSERT`. But for those cases where efficiency +matters, there are two classes to help you do this better: `stream_from` and +`stream_to`. They're less flexible than SQL queries, and there's the risk of +losing your connection while you're in mid-stream, but you get some speed and +memory efficiencies in return. + +Both stream classes do data conversion for you: `stream_from` receives values +from the database in PostgreSQL's text format, and converts them to the C++ +types you specify. Likewise, `stream_to` converts C++ values you provide to +PostgreSQL's text format for transfer. (On its end, the database of course +converts values to and from their SQL types.) + + +Null values +----------- + +So how do you deal with nulls? It depends on the C++ type you're using. Some +types may have a built-in null value. For instance, if you have a +`char const *` value and you convert it to an SQL string, then converting a +`nullptr` will produce a NULL SQL value. + +But what do you do about C++ types which don't have a built-in null value, such +as `int`? The trick is to wrap it in `std::optional`. The difference between +`int` and `std::optional` is that the former always has an `int` value, +and the latter doesn't have to. + +Actually it's not just `std::optional`. You can do the same thing with +`std::unique_ptr` or `std::shared_ptr`. A smart pointer is less efficient than +`std::optional` in most situations because they allocate their value on the +heap, but sometimes that's what you want in order to save moving or copying +large values around. + +This part is not generic though. It won't work with just any smart-pointer +type, just the ones which are explicitly supported: `shared_ptr` and +`unique_ptr`. If you really need to, you can build support for additional +wrappers and smart pointers by copying the implementation patterns from the +existing smart-pointer support. + + +stream\_from +------------ + +Use `stream_from` to read data directly from the database. It's faster than +the transaction's `exec` functions if the result contains enough rows. But +also, you won't need to keep your full result set in memory. That can really +matter with larger data sets. + +And, you can start processing your data right after the first row of data comes +in from the server. With `exec()` you need to wait to receive all data, and +then you begin processing. With `stream_from` you can be processing data on +the client side while the server is still sending you the rest. + +You don't actually need to create a `stream_from` object yourself, though you +can. Two shorthand functions, @ref pqxx::transaction_base::stream +and @ref pqxx::transaction_base::for_each, can create the streams for you with +a minimum of overhead. + +Not all kinds of queries will work in a stream. Internally the streams make +use of PostgreSQL's `COPY` command, so see the PostgreSQL documentation for +`COPY` for the exact limitations. Basic `SELECT` and `UPDATE ... RETURNING` +queries should just work. + +As you read a row, the stream converts its fields to a tuple type containing +the value types you ask for: + + auto stream pqxx::stream_from::query( + tx, "SELECT name, points FROM score"); + std::tuple row; + while (stream >> row) + process(row); + stream.complete(); + +As the stream reads each row, it converts that row's data into your tuple, +goes through your loop body, and then promptly forgets that row's data. This +means you can easily process more data than will fit in memory. + + +stream\_to +---------- + +Use `stream_to` to write data directly to a database table. This saves you +having to perform an `INSERT` for every row, and so it can be significantly +faster if you want to insert more than just one or two rows at a time. + +As with `stream_from`, you can specify the table and the columns, and not much +else. You insert tuple-like objects of your choice: + + pqxx::stream_to stream{ + tx, + "score", + std::vector{"name", "points"}}; + for (auto const &entry: scores) + stream << entry; + stream.complete(); + +Each row is processed as you provide it, and not retained in memory after that. + +The call to `complete()` is more important here than it is for `stream_from`. +It's a lot like a "commit" or "abort" at the end of a transaction. If you omit +it, it will be done automatically during the stream's destructor. But since +destructors can't throw exceptions, any failures at that stage won't be visible +in your code. So, always call `complete()` on a `stream_to` to close it off +properly! diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/thread-safety.md b/ext/libpqxx-7.7.3/include/pqxx/doc/thread-safety.md new file mode 100644 index 000000000..07c7f9984 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/thread-safety.md @@ -0,0 +1,29 @@ +Thread safety {#thread-safety} +============= + +This library does not contain any locking code to protect objects against +simultaneous modification in multi-threaded programs. Therefore it is up +to you, the user of the library, to ensure that your threaded client +programs perform no conflicting operations concurrently. + +Most of the time this isn't hard. Result sets are immutable, so you can +share them between threads without problem. The main rule is: + +@li Treat a connection, together with any and all objects related to it, as +a "world" of its own. You should generally make sure that the same "world" +is never accessed by another thread while you're doing anything non-const +in there. + +That means: don't issue a query on a transaction while you're also opening +a subtransaction, don't access a cursor while you may also be committing, +and so on. + +In particular, cursors are tricky. It's easy to perform a non-const +operation without noticing. So, if you're going to share cursors or +cursor-related objects between threads, lock very conservatively! + +Use `pqxx::describe_thread_safety` to find out at runtime what level of +thread safety is implemented in your build and version of libpqxx. It +returns a `pqxx::thread_safety_model` describing what you can and cannot rely +on. A command-line utility `tools/pqxxthreadsafety` prints out the same +information. diff --git a/ext/libpqxx-7.7.3/include/pqxx/errorhandler b/ext/libpqxx-7.7.3/include/pqxx/errorhandler new file mode 100644 index 000000000..ea572ee79 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/errorhandler @@ -0,0 +1,8 @@ +/** pqxx::errorhandler class. + * + * Callbacks for handling errors and warnings. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/errorhandler.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/errorhandler.hxx b/ext/libpqxx-7.7.3/include/pqxx/errorhandler.hxx new file mode 100644 index 000000000..2ffb5703c --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/errorhandler.hxx @@ -0,0 +1,92 @@ +/* Definition of the pqxx::errorhandler class. + * + * pqxx::errorhandler handlers errors and warnings in a database session. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/errorhandler instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ERRORHANDLER +#define PQXX_H_ERRORHANDLER + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/types.hxx" + + +namespace pqxx::internal::gate +{ +class errorhandler_connection; +} + + +namespace pqxx +{ +/** + * @addtogroup errorhandler + */ +//@{ + +/// Base class for error-handler callbacks. +/** To receive errors and warnings from a connection, subclass this with your + * own error-handler functor, and instantiate it for the connection. Destroying + * the handler un-registers it. + * + * A connection can have multiple error handlers at the same time. When the + * database connection emits an error or warning message, it passes the message + * to each error handler, starting with the most recently registered one and + * progressing towards the oldest one. However an error handler may also + * instruct the connection not to pass the message to further handlers by + * returning "false." + * + * @warning Strange things happen when a result object outlives its parent + * connection. If you register an error handler on a connection, then you must + * not access the result after destroying the connection. This applies even if + * you destroy the error handler first! + */ +class PQXX_LIBEXPORT errorhandler +{ +public: + explicit errorhandler(connection &); + virtual ~errorhandler(); + + /// Define in subclass: receive an error or warning message from the + /// database. + /** + * @return Whether the same error message should also be passed to the + * remaining, older errorhandlers. + */ + virtual bool operator()(char const msg[]) noexcept = 0; + + errorhandler() = delete; + errorhandler(errorhandler const &) = delete; + errorhandler &operator=(errorhandler const &) = delete; + +private: + connection *m_home; + + friend class internal::gate::errorhandler_connection; + void unregister() noexcept; +}; + + +/// An error handler that suppresses any previously registered error handlers. +class quiet_errorhandler : public errorhandler +{ +public: + /// Suppress error notices. + quiet_errorhandler(connection &conn) : errorhandler{conn} {} + + /// Revert to previous handling of error notices. + virtual bool operator()(char const[]) noexcept override { return false; } +}; + +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/except b/ext/libpqxx-7.7.3/include/pqxx/except new file mode 100644 index 000000000..e5dd508bf --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/except @@ -0,0 +1,8 @@ +/** libpqxx exception classes. + * + * pqxx::sql_error, pqxx::broken_connection, pqxx::in_doubt_error, ... + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/except.hxx b/ext/libpqxx-7.7.3/include/pqxx/except.hxx new file mode 100644 index 000000000..24f959437 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/except.hxx @@ -0,0 +1,447 @@ +/* Definition of libpqxx exception classes. + * + * pqxx::sql_error, pqxx::broken_connection, pqxx::in_doubt_error, ... + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/except instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_EXCEPT +#define PQXX_H_EXCEPT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + + +namespace pqxx +{ +/** + * @addtogroup exception Exception classes + * + * These exception classes follow, roughly, the two-level hierarchy defined by + * the PostgreSQL SQLSTATE error codes (see Appendix A of the PostgreSQL + * documentation corresponding to your server version). This is not a complete + * mapping though. There are other differences as well, e.g. the error code + * for `statement_completion_unknown` has a separate status in libpqxx as + * @ref in_doubt_error, and `too_many_connections` is classified as a + * `broken_connection` rather than a subtype of `insufficient_resources`. + * + * @see http://www.postgresql.org/docs/9.4/interactive/errcodes-appendix.html + * + * @{ + */ + +/// Run-time failure encountered by libpqxx, similar to std::runtime_error. +struct PQXX_LIBEXPORT failure : std::runtime_error +{ + explicit failure(std::string const &); +}; + + +/// Exception class for lost or failed backend connection. +/** + * @warning When this happens on Unix-like systems, you may also get a SIGPIPE + * signal. That signal aborts the program by default, so if you wish to be + * able to continue after a connection breaks, be sure to disarm this signal. + * + * If you're working on a Unix-like system, see the manual page for + * `signal` (2) on how to deal with SIGPIPE. The easiest way to make this + * signal harmless is to make your program ignore it: + * + * ```cxx + * #include + * + * int main() + * { + * signal(SIGPIPE, SIG_IGN); + * // ... + * ``` + */ +struct PQXX_LIBEXPORT broken_connection : failure +{ + broken_connection(); + explicit broken_connection(std::string const &); +}; + + +/// The caller attempted to set a variable to null, which is not allowed. +struct PQXX_LIBEXPORT variable_set_to_null : failure +{ + variable_set_to_null(); + explicit variable_set_to_null(std::string const &); +}; + + +/// Exception class for failed queries. +/** Carries, in addition to a regular error message, a copy of the failed query + * and (if available) the SQLSTATE value accompanying the error. + */ +class PQXX_LIBEXPORT sql_error : public failure +{ + /// Query string. Empty if unknown. + std::string const m_query; + /// SQLSTATE string describing the error type, if known; or empty string. + std::string const m_sqlstate; + +public: + explicit sql_error( + std::string const &whatarg = "", std::string const &Q = "", + char const sqlstate[] = nullptr); + virtual ~sql_error() noexcept override; + + /// The query whose execution triggered the exception + [[nodiscard]] PQXX_PURE std::string const &query() const noexcept; + + /// SQLSTATE error code if known, or empty string otherwise. + [[nodiscard]] PQXX_PURE std::string const &sqlstate() const noexcept; +}; + + +/// "Help, I don't know whether transaction was committed successfully!" +/** Exception that might be thrown in rare cases where the connection to the + * database is lost while finishing a database transaction, and there's no way + * of telling whether it was actually executed by the backend. In this case + * the database is left in an indeterminate (but consistent) state, and only + * manual inspection will tell which is the case. + */ +struct PQXX_LIBEXPORT in_doubt_error : failure +{ + explicit in_doubt_error(std::string const &); +}; + + +/// The backend saw itself forced to roll back the ongoing transaction. +struct PQXX_LIBEXPORT transaction_rollback : sql_error +{ + explicit transaction_rollback( + std::string const &whatarg, std::string const &q = "", + char const sqlstate[] = nullptr); +}; + + +/// Transaction failed to serialize. Please retry it. +/** Can only happen at transaction isolation levels REPEATABLE READ and + * SERIALIZABLE. + * + * The current transaction cannot be committed without violating the guarantees + * made by its isolation level. This is the effect of a conflict with another + * ongoing transaction. The transaction may still succeed if you try to + * perform it again. + */ +struct PQXX_LIBEXPORT serialization_failure : transaction_rollback +{ + explicit serialization_failure( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// We can't tell whether our last statement succeeded. +struct PQXX_LIBEXPORT statement_completion_unknown : transaction_rollback +{ + explicit statement_completion_unknown( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// The ongoing transaction has deadlocked. Retrying it may help. +struct PQXX_LIBEXPORT deadlock_detected : transaction_rollback +{ + explicit deadlock_detected( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// Internal error in libpqxx library +struct PQXX_LIBEXPORT internal_error : std::logic_error +{ + explicit internal_error(std::string const &); +}; + + +/// Error in usage of libpqxx library, similar to std::logic_error +struct PQXX_LIBEXPORT usage_error : std::logic_error +{ + explicit usage_error(std::string const &); +}; + + +/// Invalid argument passed to libpqxx, similar to std::invalid_argument +struct PQXX_LIBEXPORT argument_error : std::invalid_argument +{ + explicit argument_error(std::string const &); +}; + + +/// Value conversion failed, e.g. when converting "Hello" to int. +struct PQXX_LIBEXPORT conversion_error : std::domain_error +{ + explicit conversion_error(std::string const &); +}; + + +/// Could not convert value to string: not enough buffer space. +struct PQXX_LIBEXPORT conversion_overrun : conversion_error +{ + explicit conversion_overrun(std::string const &); +}; + + +/// Something is out of range, similar to std::out_of_range +struct PQXX_LIBEXPORT range_error : std::out_of_range +{ + explicit range_error(std::string const &); +}; + + +/// Query returned an unexpected number of rows. +struct PQXX_LIBEXPORT unexpected_rows : public range_error +{ + explicit unexpected_rows(std::string const &msg) : range_error{msg} {} +}; + + +/// Database feature not supported in current setup. +struct PQXX_LIBEXPORT feature_not_supported : sql_error +{ + explicit feature_not_supported( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Error in data provided to SQL statement. +struct PQXX_LIBEXPORT data_exception : sql_error +{ + explicit data_exception( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT integrity_constraint_violation : sql_error +{ + explicit integrity_constraint_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT restrict_violation : integrity_constraint_violation +{ + explicit restrict_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT not_null_violation : integrity_constraint_violation +{ + explicit not_null_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT foreign_key_violation : integrity_constraint_violation +{ + explicit foreign_key_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT unique_violation : integrity_constraint_violation +{ + explicit unique_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT check_violation : integrity_constraint_violation +{ + explicit check_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_cursor_state : sql_error +{ + explicit invalid_cursor_state( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_sql_statement_name : sql_error +{ + explicit invalid_sql_statement_name( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_cursor_name : sql_error +{ + explicit invalid_cursor_name( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT syntax_error : sql_error +{ + /// Approximate position in string where error occurred, or -1 if unknown. + int const error_position; + + explicit syntax_error( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr, int pos = -1) : + sql_error{err, Q, sqlstate}, error_position{pos} + {} +}; + +struct PQXX_LIBEXPORT undefined_column : syntax_error +{ + explicit undefined_column( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT undefined_function : syntax_error +{ + explicit undefined_function( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT undefined_table : syntax_error +{ + explicit undefined_table( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT insufficient_privilege : sql_error +{ + explicit insufficient_privilege( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Resource shortage on the server +struct PQXX_LIBEXPORT insufficient_resources : sql_error +{ + explicit insufficient_resources( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT disk_full : insufficient_resources +{ + explicit disk_full( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + insufficient_resources{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT out_of_memory : insufficient_resources +{ + explicit out_of_memory( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + insufficient_resources{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT too_many_connections : broken_connection +{ + explicit too_many_connections(std::string const &err) : + broken_connection{err} + {} +}; + +/// PL/pgSQL error +/** Exceptions derived from this class are errors from PL/pgSQL procedures. + */ +struct PQXX_LIBEXPORT plpgsql_error : sql_error +{ + explicit plpgsql_error( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Exception raised in PL/pgSQL procedure +struct PQXX_LIBEXPORT plpgsql_raise : plpgsql_error +{ + explicit plpgsql_raise( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT plpgsql_no_data_found : plpgsql_error +{ + explicit plpgsql_no_data_found( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT plpgsql_too_many_rows : plpgsql_error +{ + explicit plpgsql_too_many_rows( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT blob_already_exists : failure +{ + explicit blob_already_exists(std::string const &); +}; + +/** + * @} + */ +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/field b/ext/libpqxx-7.7.3/include/pqxx/field new file mode 100644 index 000000000..37cb69e84 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/field @@ -0,0 +1,8 @@ +/** pqxx::field class. + * + * pqxx::field refers to a field in a query result. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/field.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/field.hxx b/ext/libpqxx-7.7.3/include/pqxx/field.hxx new file mode 100644 index 000000000..b8b869fe4 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/field.hxx @@ -0,0 +1,542 @@ +/* Definitions for the pqxx::field class. + * + * pqxx::field refers to a field in a query result. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_FIELD +#define PQXX_H_FIELD + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/array.hxx" +#include "pqxx/composite.hxx" +#include "pqxx/result.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/types.hxx" + +namespace pqxx +{ +/// Reference to a field in a result set. +/** A field represents one entry in a row. It represents an actual value + * in the result set, and can be converted to various types. + */ +class PQXX_LIBEXPORT field +{ +public: + using size_type = field_size_type; + + /// Constructor. Do not call this yourself; libpqxx will do it for you. + /** Create field as reference to a field in a result set. + * @param r Row that this field is part of. + * @param c Column number of this field. + */ + [[deprecated( + "Do not construct fields yourself. Get them from the row.")]] field(row const &r, row_size_type c) noexcept; + + /// Constructor. Do not call this yourself; libpqxx will do it for you. + [[deprecated( + "Do not construct fields yourself. Get them from the " + "row.")]] field() noexcept = default; + + /** + * @name Comparison + */ + //@{ + // TODO: noexcept. Breaks ABI. + /// Byte-by-byte comparison of two fields (all nulls are considered equal) + /** @warning null handling is still open to discussion and change! + * + * Handling of null values differs from that in SQL where a comparison + * involving a null value yields null, so nulls are never considered equal + * to one another or even to themselves. + * + * Null handling also probably differs from the closest equivalent in C++, + * which is the NaN (Not-a-Number) value, a singularity comparable to + * SQL's null. This is because the builtin == operator demands that a == a. + * + * The usefulness of this operator is questionable. No interpretation + * whatsoever is imposed on the data; 0 and 0.0 are considered different, + * as are null vs. the empty string, or even different (but possibly + * equivalent and equally valid) encodings of the same Unicode character + * etc. + */ + [[nodiscard]] PQXX_PURE bool operator==(field const &) const; + + /// Byte-by-byte comparison (all nulls are considered equal) + /** @warning See operator==() for important information about this operator + */ + [[nodiscard]] PQXX_PURE bool operator!=(field const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + /** + * @name Column information + */ + //@{ + /// Column name. + [[nodiscard]] PQXX_PURE char const *name() const &; + + /// Column type. + [[nodiscard]] oid PQXX_PURE type() const; + + /// What table did this column come from? + [[nodiscard]] PQXX_PURE oid table() const; + + /// Return row number. The first row is row 0, the second is row 1, etc. + PQXX_PURE constexpr row_size_type num() const noexcept { return col(); } + + /// What column number in its originating table did this column come from? + [[nodiscard]] PQXX_PURE row_size_type table_column() const; + //@} + + /** + * @name Content access + */ + //@{ + /// Read as `string_view`, or an empty one if null. + /** The result only remains usable while the data for the underlying + * @ref result exists. Once all `result` objects referring to that data have + * been destroyed, the `string_view` will no longer point to valid memory. + */ + [[nodiscard]] PQXX_PURE std::string_view view() const & + { + return std::string_view(c_str(), size()); + } + + /// Read as plain C string. + /** Since the field's data is stored internally in the form of a + * zero-terminated C string, this is the fastest way to read it. Use the + * to() or as() functions to convert the string to other types such as + * `int`, or to C++ strings. + * + * Do not use this for BYTEA values, or other binary values. To read those, + * convert the value to your desired type using `to()` or `as()`. For + * example: `f.as>()`. + */ + [[nodiscard]] PQXX_PURE char const *c_str() const &; + + /// Is this field's value null? + [[nodiscard]] PQXX_PURE bool is_null() const noexcept; + + /// Return number of bytes taken up by the field's value. + [[nodiscard]] PQXX_PURE size_type size() const noexcept; + + /// Read value into obj; or if null, leave obj untouched and return `false`. + /** This can be used with optional types (except pointers other than C-style + * strings). + */ + template + auto to(T &obj) const -> typename std::enable_if_t< + (not std::is_pointer::value or std::is_same::value), + bool> + { + if (is_null()) + { + return false; + } + else + { + auto const bytes{c_str()}; + from_string(bytes, obj); + return true; + } + } + + /// Read field as a composite value, write its components into `fields`. + /** @warning This is still experimental. It may change or be replaced. + * + * Returns whether the field was null. If it was, it will not touch the + * values in `fields`. + */ + template bool composite_to(T &...fields) const + { + if (is_null()) + { + return false; + } + else + { + parse_composite(m_home.m_encoding, view(), fields...); + return true; + } + } + + /// Read value into obj; or leave obj untouched and return `false` if null. + template bool operator>>(T &obj) const { return to(obj); } + + /// Read value into obj; or if null, use default value and return `false`. + /** This can be used with `std::optional`, as well as with standard smart + * pointer types, but not with raw pointers. If the conversion from a + * PostgreSQL string representation allocates a pointer (e.g. using `new`), + * then the object's later deallocation should be baked in as well, right + * from the point where the object is created. So if you want a pointer, use + * a smart pointer, not a raw pointer. + * + * There is one exception, of course: C-style strings. Those are just + * pointers to the field's internal text data. + */ + template + auto to(T &obj, T const &default_value) const -> typename std::enable_if_t< + (not std::is_pointer::value or std::is_same::value), + bool> + { + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = from_string(this->view()); + return not null; + } + + /// Return value as object of given type, or default value if null. + /** Note that unless the function is instantiated with an explicit template + * argument, the Default value's type also determines the result type. + */ + template T as(T const &default_value) const + { + if (is_null()) + return default_value; + else + return from_string(this->view()); + } + + /// Return value as object of given type, or throw exception if null. + /** Use as `as>()` or `as()` as + * an alternative to `get()`; this is disabled for use with raw pointers + * (other than C-strings) because storage for the value can't safely be + * allocated here + */ + template T as() const + { + if (is_null()) + { + if constexpr (not nullness::has_null) + internal::throw_null_conversion(type_name); + else + return nullness::null(); + } + else + { + return from_string(this->view()); + } + } + + /// Return value wrapped in some optional type (empty for nulls). + /** Use as `get()` as before to obtain previous behavior, or specify + * container type with `get()` + */ + template class O = std::optional> + constexpr O get() const + { + return as>(); + } + + // TODO: constexpr noexcept, once array_parser constructor gets those. + /// Parse the field as an SQL array. + /** Call the parser to retrieve values (and structure) from the array. + * + * Make sure the @ref result object stays alive until parsing is finished. If + * you keep the @ref row of `field` object alive, it will keep the @ref + * result object alive as well. + */ + array_parser as_array() const & + { + return array_parser{c_str(), m_home.m_encoding}; + } + //@} + + +protected: + constexpr result const &home() const noexcept { return m_home; } + constexpr result::size_type idx() const noexcept { return m_row; } + constexpr row_size_type col() const noexcept { return m_col; } + + // TODO: Create gates. + friend class pqxx::result; + friend class pqxx::row; + field( + result const &r, result_size_type row_num, row_size_type col_num) noexcept + : + m_col{col_num}, m_home{r}, m_row{row_num} + {} + + /** + * You'd expect this to be unsigned, but due to the way reverse iterators + * are related to regular iterators, it must be allowed to underflow to -1. + */ + row_size_type m_col; + +private: + result m_home; + result::size_type m_row; +}; + + +template<> inline bool field::to(std::string &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = std::string{view()}; + return not null; +} + + +template<> +inline bool field::to( + std::string &obj, std::string const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = std::string{view()}; + return not null; +} + + +/// Specialization: `to(char const *&)`. +/** The buffer has the same lifetime as the data in this result (i.e. of this + * result object, or the last remaining one copied from it etc.), so take care + * not to use it after the last result object referring to this query result is + * destroyed. + */ +template<> inline bool field::to(char const *&obj) const +{ + bool const null{is_null()}; + if (not null) + obj = c_str(); + return not null; +} + + +template<> inline bool field::to(std::string_view &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = view(); + return not null; +} + + +template<> +inline bool field::to( + std::string_view &obj, std::string_view const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = view(); + return not null; +} + + +template<> inline std::string_view field::as() const +{ + if (is_null()) + PQXX_UNLIKELY + internal::throw_null_conversion(type_name); + return view(); +} + + +template<> +inline std::string_view +field::as(std::string_view const &default_value) const +{ + return is_null() ? default_value : view(); +} + + +template<> inline bool field::to(zview &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = zview{c_str(), size()}; + return not null; +} + + +template<> +inline bool field::to(zview &obj, zview const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = zview{c_str(), size()}; + return not null; +} + + +template<> inline zview field::as() const +{ + if (is_null()) + PQXX_UNLIKELY + internal::throw_null_conversion(type_name); + return zview{c_str(), size()}; +} + + +template<> inline zview field::as(zview const &default_value) const +{ + return is_null() ? default_value : zview{c_str(), size()}; +} + + +template> +class field_streambuf : public std::basic_streambuf +{ +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + using openmode = std::ios::openmode; + using seekdir = std::ios::seekdir; + + explicit field_streambuf(field const &f) : m_field{f} { initialize(); } + +protected: + virtual int sync() override { return traits_type::eof(); } + + virtual pos_type seekoff(off_type, seekdir, openmode) override + { + return traits_type::eof(); + } + virtual pos_type seekpos(pos_type, openmode) override + { + return traits_type::eof(); + } + virtual int_type overflow(int_type) override { return traits_type::eof(); } + virtual int_type underflow() override { return traits_type::eof(); } + +private: + field const &m_field; + + int_type initialize() + { + auto g{static_cast(const_cast(m_field.c_str()))}; + this->setg(g, g, g + std::size(m_field)); + return int_type(std::size(m_field)); + } +}; + + +/// Input stream that gets its data from a result field +/** Use this class exactly as you would any other istream to read data from a + * field. All formatting and streaming operations of `std::istream` are + * supported. What you'll typically want to use, however, is the fieldstream + * alias (which defines a @ref basic_fieldstream for `char`). This is similar + * to how e.g. `std::ifstream` relates to `std::basic_ifstream`. + * + * This class has only been tested for the char type (and its default traits). + */ +template> +class basic_fieldstream : public std::basic_istream +{ + using super = std::basic_istream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + + basic_fieldstream(field const &f) : super{nullptr}, m_buf{f} + { + super::init(&m_buf); + } + +private: + field_streambuf m_buf; +}; + +using fieldstream = basic_fieldstream; + +/// Write a result field to any type of stream +/** This can be convenient when writing a field to an output stream. More + * importantly, it lets you write a field to e.g. a `stringstream` which you + * can then use to read, format and convert the field in ways that to() does + * not support. + * + * Example: parse a field into a variable of the nonstandard + * "long long" type. + * + * ```cxx + * extern result R; + * long long L; + * stringstream S; + * + * // Write field's string into S + * S << R[0][0]; + * + * // Parse contents of S into L + * S >> L; + * ``` + */ +template +inline std::basic_ostream & +operator<<(std::basic_ostream &s, field const &value) +{ + s.write(value.c_str(), std::streamsize(std::size(value))); + return s; +} + + +/// Convert a field's value to type `T`. +/** Unlike the "regular" `from_string`, this knows how to deal with null + * values. + */ +template inline T from_string(field const &value) +{ + if (value.is_null()) + { + if constexpr (nullness::has_null) + return nullness::null(); + else + internal::throw_null_conversion(type_name); + } + else + { + return from_string(value.view()); + } +} + + +/// Convert a field's value to `nullptr_t`. +/** Yes, you read that right. This conversion does nothing useful. It always + * returns `nullptr`. + * + * Except... what if the field is not null? In that case, this throws + * @ref conversion_error. + */ +template<> +inline std::nullptr_t from_string(field const &value) +{ + if (not value.is_null()) + throw conversion_error{ + "Extracting non-null field into nullptr_t variable."}; + return nullptr; +} + + +/// Convert a field to a string. +template<> PQXX_LIBEXPORT std::string to_string(field const &value); +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/array-composite.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/array-composite.hxx new file mode 100644 index 000000000..d2b6603e5 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/array-composite.hxx @@ -0,0 +1,305 @@ +#if !defined(PQXX_ARRAY_COMPOSITE_HXX) +# define PQXX_ARRAY_COMPOSITE_HXX + +# include + +# include "pqxx/strconv.hxx" + +namespace pqxx::internal +{ +// Find the end of a double-quoted string. +/** `input[pos]` must be the opening double quote. + * + * Returns the offset of the first position after the closing quote. + */ +inline std::size_t scan_double_quoted_string( + char const input[], std::size_t size, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + // XXX: find_char<'"', '\\'>(). + auto next{scan(input, size, pos)}; + bool at_quote{false}; + for (pos = next, next = scan(input, size, pos); pos < size; + pos = next, next = scan(input, size, pos)) + { + if (at_quote) + { + if (next - pos == 1 and input[pos] == '"') + { + // We just read a pair of double quotes. Carry on. + at_quote = false; + } + else + { + // We just read one double quote, and now we're at a character that's + // not a second double quote. Ergo, that last character was the + // closing double quote and this is the position right after it. + return pos; + } + } + else if (next - pos == 1) + { + switch (input[pos]) + { + case '\\': + // Backslash escape. Skip ahead by one more character. + pos = next; + next = scan(input, size, pos); + break; + + case '"': + // This is either the closing double quote, or the first of a pair of + // double quotes. + at_quote = true; + break; + } + } + else + { + // Multibyte character. Carry on. + } + } + if (not at_quote) + throw argument_error{ + "Missing closing double-quote: " + std::string{input}}; + return pos; +} + + +/// Un-quote and un-escape a double-quoted SQL string. +inline std::string parse_double_quoted_string( + char const input[], std::size_t end, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + std::string output; + // Maximum output size is same as the input size, minus the opening and + // closing quotes. Or in the extreme opposite case, the real number could be + // half that. Usually it'll be a pretty close estimate. + output.reserve(std::size_t(end - pos - 2)); + + for (auto here{scan(input, end, pos)}, next{scan(input, end, here)}; + here < end - 1; here = next, next = scan(input, end, here)) + { + // A backslash here is always an escape. So is a double-quote, since we're + // inside the double-quoted string. In either case, we can just ignore the + // escape character and use the next character. This is the one redeeming + // feature of SQL's escaping system. + if ((next - here == 1) and (input[here] == '\\' or input[here] == '"')) + { + // Skip escape. + here = next; + next = scan(input, end, here); + } + output.append(input + here, input + next); + } + return output; +} + + +/// Find the end of an unquoted string in an array or composite-type value. +/** Stops when it gets to the end of the input; or when it sees any of the + * characters in STOP which has not been escaped. + * + * For array values, STOP is a comma, a semicolon, or a closing brace. For + * a value of a composite type, STOP is a comma or a closing parenthesis. + */ +template +inline std::size_t scan_unquoted_string( + char const input[], std::size_t size, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + bool at_backslash{false}; + auto next{scan(input, size, pos)}; + while ((pos < size) and + ((next - pos) > 1 or at_backslash or ((input[pos] != STOP) and ...))) + { + pos = next; + next = scan(input, size, pos); + at_backslash = + ((not at_backslash) and ((next - pos) == 1) and (input[pos] == '\\')); + } + return pos; +} + + +/// Parse an unquoted array entry or cfield of a composite-type field. +inline std::string parse_unquoted_string( + char const input[], std::size_t end, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + std::string output; + bool at_backslash{false}; + output.reserve(end - pos); + for (auto next{scan(input, end, pos)}; pos < end; + pos = next, next = scan(input, end, pos)) + { + at_backslash = + ((not at_backslash) and ((next - pos) == 1) and (input[pos] == '\\')); + if (not at_backslash) + output.append(input + pos, next - pos); + } + return output; +} + + +/// Parse a field of a composite-type value. +/** `T` is the C++ type of the field we're parsing, and `index` is its + * zero-based number. + * + * Strip off the leading parenthesis or bracket yourself before parsing. + * However, this function will parse the lcosing parenthesis or bracket. + * + * After a successful parse, `pos` will point at `std::end(text)`. + * + * For the purposes of parsing, ranges and arrays count as compositve values, + * so this function supports parsing those. If you specifically need a closing + * parenthesis, check afterwards that `text` did not end in a bracket instead. + * + * @param index Index of the current field, zero-based. It will increment for + * the next field. + * @param input Full input text for the entire composite-type value. + * @param pos Starting position (in `input`) of the field that we're parsing. + * After parsing, this will point at the beginning of the next field if + * there is one, or one position past the last character otherwise. + * @param field Destination for the parsed value. + * @param scan Glyph scanning function for the relevant encoding type. + * @param last_field Number of the last field in the value (zero-based). When + * parsing the last field, this will equal `index`. + */ +template +inline void parse_composite_field( + std::size_t &index, std::string_view input, std::size_t &pos, T &field, + glyph_scanner_func *scan, std::size_t last_field) +{ + assert(index <= last_field); + auto next{scan(std::data(input), std::size(input), pos)}; + if ((next - pos) != 1) + throw conversion_error{"Non-ASCII character in composite-type syntax."}; + + // Expect a field. + switch (input[pos]) + { + case ',': + case ')': + case ']': + // The field is empty, i.e, null. + if constexpr (nullness::has_null) + field = nullness::null(); + else + throw conversion_error{ + "Can't read composite field " + to_string(index) + ": C++ type " + + type_name + " does not support nulls."}; + break; + + case '"': { + auto const stop{scan_double_quoted_string( + std::data(input), std::size(input), pos, scan)}; + auto const text{ + parse_double_quoted_string(std::data(input), stop, pos, scan)}; + field = from_string(text); + pos = stop; + } + break; + + default: { + auto const stop{scan_unquoted_string<',', ')', ']'>( + std::data(input), std::size(input), pos, scan)}; + auto const text{parse_unquoted_string(std::data(input), stop, pos, scan)}; + field = from_string(text); + pos = stop; + } + break; + } + + // Expect a comma or a closing parenthesis. + next = scan(std::data(input), std::size(input), pos); + + if ((next - pos) != 1) + throw conversion_error{ + "Unexpected non-ASCII character after composite field: " + + std::string{input}}; + + if (index < last_field) + { + if (input[pos] != ',') + throw conversion_error{ + "Found '" + std::string{input[pos]} + + "' in composite value where comma was expected: " + std::data(input)}; + } + else + { + if (input[pos] == ',') + throw conversion_error{ + "Composite value contained more fields than the expected " + + to_string(last_field) + ": " + std::data(input)}; + if (input[pos] != ')' and input[pos] != ']') + throw conversion_error{ + "Composite value has unexpected characters where closing parenthesis " + "was expected: " + + std::string{input}}; + if (next != std::size(input)) + throw conversion_error{ + "Composite value has unexpected text after closing parenthesis: " + + std::string{input}}; + } + + pos = next; + ++index; +} + + +/// Conservatively estimate buffer size needed for a composite field. +template +inline std::size_t size_composite_field_buffer(T const &field) +{ + if constexpr (is_unquoted_safe) + { + // Safe to copy, without quotes or escaping. Drop the terminating zero. + return size_buffer(field) - 1; + } + else + { + // + Opening quote. + // + Field budget. + // - Terminating zero. + // + Escaping for each byte in the field's string representation. + // - Escaping for terminating zero. + // + Closing quote. + return 1 + 2 * (size_buffer(field) - 1) + 1; + } +} + + +template +inline void write_composite_field(char *&pos, char *end, T const &field) +{ + if constexpr (is_unquoted_safe) + { + // No need for quoting or escaping. Convert it straight into its final + // place in the buffer, and "backspace" the trailing zero. + pos = string_traits::into_buf(pos, end, field) - 1; + } + else + { + // The field may need escaping, which means we need an intermediate buffer. + // To avoid allocating that at run time, we use the end of the buffer that + // we have. + auto const budget{size_buffer(field)}; + *pos++ = '"'; + + // Now escape buf into its final position. + for (char const c : string_traits::to_buf(end - budget, end, field)) + { + if ((c == '"') or (c == '\\')) + *pos++ = '\\'; + + *pos++ = c; + } + + *pos++ = '"'; + } + + *pos++ = ','; +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/callgate.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/callgate.hxx new file mode 100644 index 000000000..42f7703e3 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/callgate.hxx @@ -0,0 +1,70 @@ +#ifndef PQXX_H_CALLGATE +#define PQXX_H_CALLGATE + +/* +Here's what a typical gate class definition looks like: + +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE @gateclass@ : callgate<@host@> +{ + friend class @client@; + + @gateclass@(reference x) : super(x) {} + + // Methods here. Use home() to access the host-class object. +}; +} // namespace pqxx::internal::gate +*/ + +namespace pqxx::internal +{ +/// Base class for call gates. +/** + * A call gate defines a limited, private interface on the host class that + * specified client classes can access. + * + * The metaphor works as follows: the gate stands in front of a "home," which + * is really a class, and only lets specific friends in. + * + * To implement a call gate that gives client C access to host H, + * * derive a gate class from callgate; + * * make the gate class a friend of H; + * * make C a friend of the gate class; and + * * implement "stuff C can do with H" as private members in the gate class. + * + * This special kind of "gated" friendship gives C private access to H, but + * only through an expressly limited interface. The gate class can access its + * host object as home(). + * + * Keep gate classes entirely stateless. They should be ultra-lightweight + * wrappers for their host classes, and be optimized away as much as possible + * by the compiler. Once you start adding state, you're on a slippery slope + * away from the pure, clean, limited interface pattern that gate classes are + * meant to implement. + * + * Ideally, all member functions of the gate class should be one-liners passing + * calls straight on to the host class. It can be useful however to break this + * rule temporarily during inter-class refactoring. + */ +template class PQXX_PRIVATE callgate +{ +protected: + /// This class, to keep constructors easy. + using super = callgate; + /// A reference to the host class. Helps keep constructors easy. + using reference = HOME &; + + callgate(reference x) : m_home(x) {} + + /// The home object. The gate class has full "private" access. + reference home() const noexcept { return m_home; } + +private: + reference m_home; +}; +} // namespace pqxx::internal + +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/concat.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/concat.hxx new file mode 100644 index 000000000..cd28bde7c --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/concat.hxx @@ -0,0 +1,45 @@ +#if !defined(PQXX_CONCAT_HXX) +# define PQXX_CONCAT_HXX + +# include +# include + +# include "pqxx/strconv.hxx" + +namespace pqxx::internal +{ +/// Convert item to a string, write it into [here, end). +template +void render_item(TYPE const &item, char *&here, char *end) +{ + here = string_traits::into_buf(here, end, item) - 1; +} + + +// C++20: Support non-random_access_range ranges. +/// Efficiently combine a bunch of items into one big string. +/** Use this as an optimised version of string concatentation. It takes just + * about any type; it will represent each item as a string according to its + * @ref string_traits. + * + * This is a simpler, more specialised version of @ref separated_list for a + * statically known series of items, possibly of different types. + */ +template +[[nodiscard]] inline std::string concat(TYPE... item) +{ + std::string buf; + // Size to accommodate string representations of all inputs, minus their + // terminating zero bytes. + buf.resize(size_buffer(item...)); + + char *const data{buf.data()}; + char *here = data; + char *end = data + std::size(buf); + (render_item(item, here, end), ...); + + buf.resize(static_cast(here - data)); + return buf; +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/conversions.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/conversions.hxx new file mode 100644 index 000000000..1df4fdead --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/conversions.hxx @@ -0,0 +1,1188 @@ +#include +#include +#include +#include +#include +#include + +#if defined(PQXX_HAVE_SPAN) && __has_include() +# include +#endif + +#include +#include +#include + +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" + + +/* Internal helpers for string conversion, and conversion implementations. + * + * Do not include this header directly. The libpqxx headers do it for you. + */ +namespace pqxx::internal +{ +/// Convert a number in [0, 9] to its ASCII digit. +inline constexpr char number_to_digit(int i) noexcept +{ + return static_cast(i + '0'); +} + + +/// Compute numeric value of given textual digit (assuming that it is a digit). +constexpr int digit_to_number(char c) noexcept +{ + return c - '0'; +} + + +/// Summarize buffer overrun. +/** Don't worry about the exact parameter types: the sizes will be reasonably + * small, and nonnegative. + */ +std::string PQXX_LIBEXPORT +state_buffer_overrun(int have_bytes, int need_bytes); + + +template +inline std::string state_buffer_overrun(HAVE have_bytes, NEED need_bytes) +{ + return state_buffer_overrun( + static_cast(have_bytes), static_cast(need_bytes)); +} + + +/// Throw exception for attempt to convert null to given type. +[[noreturn]] PQXX_LIBEXPORT void +throw_null_conversion(std::string const &type); + + +/// Deliberately nonfunctional conversion traits for `char` types. +/** There are no string conversions for `char` and its signed and unsigned + * variants. Such a conversion would be dangerously ambiguous: should we treat + * it as text, or as a small integer? It'd be an open invitation for bugs. + * + * But the error message when you get this wrong is very cryptic. So, we + * derive dummy @ref string_traits implementations from this dummy type, and + * ensure that the compiler disallows their use. The compiler error message + * will at least contain a hint of the root of the problem. + */ +template struct disallowed_ambiguous_char_conversion +{ + static char *into_buf(char *, char *, CHAR_TYPE) = delete; + static constexpr zview + to_buf(char *, char *, CHAR_TYPE const &) noexcept = delete; + + static constexpr std::size_t + size_buffer(CHAR_TYPE const &) noexcept = delete; + static CHAR_TYPE from_string(std::string_view) = delete; +}; + + +template PQXX_LIBEXPORT extern std::string to_string_float(T); + + +/// Generic implementation for into_buf, on top of to_buf. +template +inline char *generic_into_buf(char *begin, char *end, T const &value) +{ + zview const text{string_traits::to_buf(begin, end, value)}; + auto const space{end - begin}; + // Include the trailing zero. + auto const len = std::size(text) + 1; + if (internal::cmp_greater(len, space)) + throw conversion_overrun{ + "Not enough buffer space to insert " + type_name + ". " + + state_buffer_overrun(space, len)}; + std::memmove(begin, text.data(), len); + return begin + len; +} + + +/// String traits for builtin integral types (though not bool). +template struct integral_traits +{ + static PQXX_LIBEXPORT T from_string(std::string_view text); + static PQXX_LIBEXPORT zview to_buf(char *begin, char *end, T const &value); + static PQXX_LIBEXPORT char *into_buf(char *begin, char *end, T const &value); + + static constexpr std::size_t size_buffer(T const &) noexcept + { + /** Includes a sign if needed; the number of base-10 digits which the type + * can reliably represent; the one extra base-10 digit which the type can + * only partially represent; and the terminating zero. + */ + return std::is_signed_v + std::numeric_limits::digits10 + 1 + 1; + } +}; + + +/// String traits for builtin floating-point types. +template struct float_traits +{ + static PQXX_LIBEXPORT T from_string(std::string_view text); + static PQXX_LIBEXPORT zview to_buf(char *begin, char *end, T const &value); + static PQXX_LIBEXPORT char *into_buf(char *begin, char *end, T const &value); + + // Return a nonnegative integral value's number of decimal digits. + static constexpr std::size_t digits10(std::size_t value) noexcept + { + if (value < 10) + return 1; + else + return 1 + digits10(value / 10); + } + + static constexpr std::size_t size_buffer(T const &) noexcept + { + using lims = std::numeric_limits; + // See #328 for a detailed discussion on the maximum number of digits. + // + // In a nutshell: for the big cases, the scientific notation is always + // the shortest one, and therefore the one that to_chars will pick. + // + // So... How long can the scientific notation get? 1 (for sign) + 1 (for + // decimal point) + 1 (for 'e') + 1 (for exponent sign) + max_digits10 + + // max number of digits in the exponent + 1 (terminating zero). + // + // What's the max number of digits in the exponent? It's the max number of + // digits out of the most negative exponent and the most positive one. + // + // The longest positive exponent is easy: 1 + ceil(log10(max_exponent10)). + // (The extra 1 is because 10^n takes up 1 + n digits, not n.) + // + // The longest negative exponent is a bit harder: min_exponent10 gives us + // the smallest power of 10 which a normalised version of T can represent. + // But the smallest denormalised power of 10 that T can represent is + // another max_digits10 powers of 10 below that. + // needs a minus sign. + // + // All this stuff messes with my head a bit because it's on the order of + // log10(log10(n)). It's easy to get the number of logs wrong. + auto const max_pos_exp{digits10(lims::max_exponent10)}; + // Really want std::abs(lims::min_exponent10), but MSVC 2017 apparently has + // problems with std::abs. So we use -lims::min_exponent10 instead. + auto const max_neg_exp{ + digits10(lims::max_digits10 - lims::min_exponent10)}; + return 1 + // Sign. + 1 + // Decimal point. + std::numeric_limits::max_digits10 + // Mantissa digits. + 1 + // Exponent "e". + 1 + // Exponent sign. + // Spell this weirdly to stop Windows compilers from reading this as + // a call to their "max" macro when NOMINMAX is not defined. + (std::max)(max_pos_exp, max_neg_exp) + // Exponent digits. + 1; // Terminating zero. + } +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// The built-in arithmetic types do not have inherent null values. +template +struct nullness>> : no_null +{}; + + +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits + : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits + : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; + + +template<> struct string_traits +{ + static PQXX_LIBEXPORT bool from_string(std::string_view text); + + static constexpr zview to_buf(char *, char *, bool const &value) noexcept + { + return value ? "true"_zv : "false"_zv; + } + + static char *into_buf(char *begin, char *end, bool const &value) + { + return pqxx::internal::generic_into_buf(begin, end, value); + } + + static constexpr std::size_t size_buffer(bool const &) noexcept { return 6; } +}; + + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + + +template<> inline constexpr bool is_unquoted_safe{true}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + /// Technically, you could have an optional of an always-null type. + static constexpr bool always_null = nullness::always_null; + static constexpr bool is_null(std::optional const &v) noexcept + { + return ((not v.has_value()) or pqxx::is_null(*v)); + } + static constexpr std::optional null() { return {}; } +}; + + +template +inline constexpr format param_format(std::optional const &value) +{ + return param_format(*value); +} + + +template struct string_traits> +{ + static char *into_buf(char *begin, char *end, std::optional const &value) + { + return string_traits::into_buf(begin, end, *value); + } + + static zview to_buf(char *begin, char *end, std::optional const &value) + { + if (value.has_value()) + return string_traits::to_buf(begin, end, *value); + else + return {}; + } + + static std::optional from_string(std::string_view text) + { + return std::optional{ + std::in_place, string_traits::from_string(text)}; + } + + static std::size_t size_buffer(std::optional const &value) noexcept + { + return pqxx::size_buffer(value.value()); + } +}; + + +template +inline constexpr bool is_unquoted_safe>{is_unquoted_safe}; + + +template struct nullness> +{ + static constexpr bool has_null = (nullness::has_null or ...); + static constexpr bool always_null = (nullness::always_null and ...); + static constexpr bool is_null(std::variant const &value) noexcept + { + return std::visit( + [](auto const &i) noexcept { + return nullness>::is_null(i); + }, + value); + } + + // We don't support `null()` for `std::variant`. + /** It would be technically possible to have a `null` in the case where just + * one of the types has a null, but it gets complicated and arbitrary. + */ + static constexpr std::variant null() = delete; +}; + + +template struct string_traits> +{ + static char * + into_buf(char *begin, char *end, std::variant const &value) + { + return std::visit( + [begin, end](auto const &i) { + return string_traits>::into_buf(begin, end, i); + }, + value); + } + static zview to_buf(char *begin, char *end, std::variant const &value) + { + return std::visit( + [begin, end](auto const &i) { + return string_traits>::to_buf(begin, end, i); + }, + value); + } + static std::size_t size_buffer(std::variant const &value) noexcept + { + return std::visit( + [](auto const &i) noexcept { return pqxx::size_buffer(i); }, value); + } + + /** There's no from_string for std::variant. We could have one with a rule + * like "pick the first type which fits the value," but we'd have to look + * into how natural that API feels to users. + */ + static std::variant from_string(std::string_view) = delete; +}; + + +template +inline constexpr format param_format(std::variant const &value) +{ + return std::visit([](auto &v) { return param_format(v); }, value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + (is_unquoted_safe and ...)}; + + +template inline T from_string(std::stringstream const &text) +{ + return from_string(text.str()); +} + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::nullptr_t) = delete; + + static constexpr zview + to_buf(char *, char *, std::nullptr_t const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::nullptr_t = nullptr) noexcept + { + return 0; + } + static std::nullptr_t from_string(std::string_view) = delete; +}; + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::nullopt_t) = delete; + + static constexpr zview + to_buf(char *, char *, std::nullopt_t const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::nullopt_t) noexcept + { + return 0; + } + static std::nullopt_t from_string(std::string_view) = delete; +}; + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::monostate) = delete; + + static constexpr zview + to_buf(char *, char *, std::monostate const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::monostate) noexcept + { + return 0; + } + static std::monostate from_string(std::string_view) = delete; +}; + + +template<> inline constexpr bool is_unquoted_safe{true}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(char const *t) noexcept + { + return t == nullptr; + } + static constexpr char const *null() noexcept { return nullptr; } +}; + + +/// String traits for C-style string ("pointer to char const"). +template<> struct string_traits +{ + static char const *from_string(std::string_view text) { return text.data(); } + + static zview to_buf(char *begin, char *end, char const *const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, char const *const &value) + { + auto const space{end - begin}; + // Count the trailing zero, even though std::strlen() and friends don't. + auto const len{std::strlen(value) + 1}; + if (space < ptrdiff_t(len)) + throw conversion_overrun{ + "Could not copy string: buffer too small. " + + pqxx::internal::state_buffer_overrun(space, len)}; + std::memmove(begin, value, len); + return begin + len; + } + + static std::size_t size_buffer(char const *const &value) noexcept + { + return std::strlen(value) + 1; + } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(char const *t) noexcept + { + return t == nullptr; + } + static constexpr char const *null() { return nullptr; } +}; + + +/// String traits for non-const C-style string ("pointer to char"). +template<> struct string_traits +{ + static char *into_buf(char *begin, char *end, char *const &value) + { + return string_traits::into_buf(begin, end, value); + } + static zview to_buf(char *begin, char *end, char *const &value) + { + return string_traits::to_buf(begin, end, value); + } + static std::size_t size_buffer(char *const &value) noexcept + { + return string_traits::size_buffer(value); + } + + /// Don't allow conversion to this type since it breaks const-safety. + static char *from_string(std::string_view) = delete; +}; + + +template struct nullness : no_null +{}; + + +/// String traits for C-style string constant ("array of char"). +/** @warning This assumes that every array-of-char is a C-style string literal. + * So, it must include a trailing zero. and it must have static duration. + */ +template struct string_traits +{ + static constexpr zview + to_buf(char *, char *, char const (&value)[N]) noexcept + { + return zview{value, N - 1}; + } + + static char *into_buf(char *begin, char *end, char const (&value)[N]) + { + if (internal::cmp_less(end - begin, size_buffer(value))) + throw conversion_overrun{ + "Could not convert char[] to string: too long for buffer."}; + std::memcpy(begin, value, N); + return begin + N; + } + static constexpr std::size_t size_buffer(char const (&)[N]) noexcept + { + return N; + } + + /// Don't allow conversion to this type. + static void from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +template<> struct string_traits +{ + static std::string from_string(std::string_view text) + { + return std::string{text}; + } + + static char *into_buf(char *begin, char *end, std::string const &value) + { + if (internal::cmp_greater_equal(std::size(value), end - begin)) + throw conversion_overrun{ + "Could not convert string to string: too long for buffer."}; + // Include the trailing zero. + value.copy(begin, std::size(value)); + begin[std::size(value)] = '\0'; + return begin + std::size(value) + 1; + } + + static zview to_buf(char *begin, char *end, std::string const &value) + { + return generic_to_buf(begin, end, value); + } + + static std::size_t size_buffer(std::string const &value) noexcept + { + return std::size(value) + 1; + } +}; + + +/// There's no real null for `std::string_view`. +/** I'm not sure how clear-cut this is: a `string_view` may have a null + * data pointer, which is analogous to a null `char` pointer. + */ +template<> struct nullness : no_null +{}; + + +/// String traits for `string_view`. +template<> struct string_traits +{ + static constexpr std::size_t + size_buffer(std::string_view const &value) noexcept + { + return std::size(value) + 1; + } + + static char *into_buf(char *begin, char *end, std::string_view const &value) + { + if (internal::cmp_greater_equal(std::size(value), end - begin)) + throw conversion_overrun{ + "Could not store string_view: too long for buffer."}; + value.copy(begin, std::size(value)); + begin[std::size(value)] = '\0'; + return begin + std::size(value) + 1; + } + + /// Don't convert to this type; it has nowhere to store its contents. + static std::string_view from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +/// String traits for `zview`. +template<> struct string_traits +{ + static constexpr std::size_t + size_buffer(std::string_view const &value) noexcept + { + return std::size(value) + 1; + } + + static char *into_buf(char *begin, char *end, zview const &value) + { + auto const size{std::size(value)}; + if (internal::cmp_less_equal(end - begin, std::size(value))) + throw conversion_overrun{"Not enough buffer space to store this zview."}; + value.copy(begin, size); + begin[size] = '\0'; + return begin + size + 1; + } + + static std::string_view to_buf(char *begin, char *end, zview const &value) + { + return {into_buf(begin, end, value), std::size(value)}; + } + + /// Don't convert to this type; it has nowhere to store its contents. + static zview from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +template<> struct string_traits +{ + static std::size_t size_buffer(std::stringstream const &) = delete; + + static std::stringstream from_string(std::string_view text) + { + std::stringstream stream; + stream.write(text.data(), std::streamsize(std::size(text))); + return stream; + } + + static char *into_buf(char *, char *, std::stringstream const &) = delete; + static std::string_view + to_buf(char *, char *, std::stringstream const &) = delete; +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::nullptr_t const &) noexcept + { + return true; + } + static constexpr std::nullptr_t null() noexcept { return nullptr; } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::nullopt_t const &) noexcept + { + return true; + } + static constexpr std::nullopt_t null() noexcept { return std::nullopt; } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::monostate const &) noexcept + { + return true; + } + static constexpr std::monostate null() noexcept { return {}; } +}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(std::unique_ptr const &t) noexcept + { + return not t or pqxx::is_null(*t); + } + static constexpr std::unique_ptr null() { return {}; } +}; + + +template +struct string_traits> +{ + static std::unique_ptr from_string(std::string_view text) + { + return std::make_unique(string_traits::from_string(text)); + } + + static char * + into_buf(char *begin, char *end, std::unique_ptr const &value) + { + return string_traits::into_buf(begin, end, *value); + } + + static zview + to_buf(char *begin, char *end, std::unique_ptr const &value) + { + if (value) + return string_traits::to_buf(begin, end, *value); + else + return {}; + } + + static std::size_t + size_buffer(std::unique_ptr const &value) noexcept + { + return pqxx::size_buffer(*value.get()); + } +}; + + +template +inline format param_format(std::unique_ptr const &value) +{ + return param_format(*value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + is_unquoted_safe}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(std::shared_ptr const &t) noexcept + { + return not t or pqxx::is_null(*t); + } + static constexpr std::shared_ptr null() { return {}; } +}; + + +template struct string_traits> +{ + static std::shared_ptr from_string(std::string_view text) + { + return std::make_shared(string_traits::from_string(text)); + } + + static zview to_buf(char *begin, char *end, std::shared_ptr const &value) + { + return string_traits::to_buf(begin, end, *value); + } + static char * + into_buf(char *begin, char *end, std::shared_ptr const &value) + { + return string_traits::into_buf(begin, end, *value); + } + static std::size_t size_buffer(std::shared_ptr const &value) noexcept + { + return pqxx::size_buffer(*value); + } +}; + + +template format param_format(std::shared_ptr const &value) +{ + return param_format(*value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + is_unquoted_safe}; + + +template<> +struct nullness> + : no_null> +{}; + + +#if defined(PQXX_HAVE_CONCEPTS) +template struct nullness : no_null +{}; + + +template inline constexpr format param_format(DATA const &) +{ + return format::binary; +} + + +template struct string_traits +{ + static std::size_t size_buffer(DATA const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf(char *begin, char *end, DATA const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, DATA const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + static DATA from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::basic_string buf; + buf.resize(size); + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.data())); + return buf; + } +}; +#endif // PQXX_HAVE_CONCEPTS + + +template<> struct string_traits> +{ + static std::size_t + size_buffer(std::basic_string const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview + to_buf(char *begin, char *end, std::basic_string const &value) + { + return generic_to_buf(begin, end, value); + } + + static char * + into_buf(char *begin, char *end, std::basic_string const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + static std::basic_string from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::basic_string buf; + buf.resize(size); + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.data())); + return buf; + } +}; + + +template<> +inline constexpr format param_format(std::basic_string const &) +{ + return format::binary; +} + + +template<> +struct nullness> + : no_null> +{}; + + +template<> struct string_traits> +{ + static std::size_t + size_buffer(std::basic_string_view const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf( + char *begin, char *end, std::basic_string_view const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf( + char *begin, char *end, std::basic_string_view const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + // There's no from_string, because there's nobody to hold the data. +}; + +template<> +inline constexpr format param_format(std::basic_string_view const &) +{ + return format::binary; +} +} // namespace pqxx + + +namespace pqxx::internal +{ +/// String traits for SQL arrays. +template struct array_string_traits +{ +private: + using elt_type = strip_t>; + using elt_traits = string_traits; + static constexpr zview s_null{"NULL"}; + +public: + static zview to_buf(char *begin, char *end, Container const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, Container const &value) + { + std::size_t const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to convert array to string."}; + + char *here = begin; + *here++ = '{'; + + bool nonempty{false}; + for (auto const &elt : value) + { + if (is_null(elt)) + { + s_null.copy(here, std::size(s_null)); + here += std::size(s_null); + } + else if constexpr (is_sql_array) + { + // Render nested array in-place. Then erase the trailing zero. + here = elt_traits::into_buf(here, end, elt) - 1; + } + else if constexpr (is_unquoted_safe) + { + // No need to quote or escape. Just convert the value straight into + // its place in the array, and "backspace" the trailing zero. + here = elt_traits::into_buf(here, end, elt) - 1; + } + else + { + *here++ = '"'; + + // Use the tail end of the destination buffer as an intermediate + // buffer. + auto const elt_budget{pqxx::size_buffer(elt)}; + for (char const c : elt_traits::to_buf(end - elt_budget, end, elt)) + { + if (c == '\\' or c == '"') + *here++ = '\\'; + *here++ = c; + } + *here++ = '"'; + } + *here++ = array_separator; + nonempty = true; + } + + // Erase that last comma, if present. + if (nonempty) + here--; + + *here++ = '}'; + *here++ = '\0'; + + return here; + } + + static std::size_t size_buffer(Container const &value) noexcept + { + if constexpr (is_unquoted_safe) + return 3 + std::accumulate( + std::begin(value), std::end(value), std::size_t{}, + [](std::size_t acc, elt_type const &elt) { + return acc + + (pqxx::is_null(elt) ? + std::size(s_null) : + elt_traits::size_buffer(elt)) - + 1; + }); + else + return 3 + std::accumulate( + std::begin(value), std::end(value), std::size_t{}, + [](std::size_t acc, elt_type const &elt) { + // Opening and closing quotes, plus worst-case escaping, + // but don't count the trailing zeroes. + std::size_t const elt_size{ + pqxx::is_null(elt) ? std::size(s_null) : + elt_traits::size_buffer(elt) - 1}; + return acc + 2 * elt_size + 2; + }); + } + + // We don't yet support parsing of array types using from_string. Doing so + // would require a reference to the connection. +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +template +struct nullness> : no_null> +{}; + + +template +struct string_traits> + : internal::array_string_traits> +{}; + + +/// We don't know how to pass array params in binary format, so pass as text. +template +inline constexpr format param_format(std::vector const &) +{ + return format::text; +} + + +/// A `std::vector` is a binary string. Other vectors are not. +template +inline constexpr format param_format(std::vector const &) +{ + return format::binary; +} + + +template inline constexpr bool is_sql_array>{true}; + + +template +struct nullness> : no_null> +{}; + + +template +struct string_traits> + : internal::array_string_traits> +{}; + + +/// We don't know how to pass array params in binary format, so pass as text. +template +inline constexpr format param_format(std::array const &) +{ + return format::text; +} + + +/// An array of `std::byte` is a binary string. +template +inline constexpr format param_format(std::array const &) +{ + return format::binary; +} + + +template +inline constexpr bool is_sql_array>{true}; +} // namespace pqxx + + +namespace pqxx +{ +template inline std::string to_string(T const &value) +{ + if (is_null(value)) + throw conversion_error{ + "Attempt to convert null " + type_name + " to a string."}; + + std::string buf; + // We can't just reserve() space; modifying the terminating zero leads to + // undefined behaviour. + buf.resize(size_buffer(value)); + auto const data{buf.data()}; + auto const end{ + string_traits::into_buf(data, data + std::size(buf), value)}; + buf.resize(static_cast(end - data - 1)); + return buf; +} + + +template<> inline std::string to_string(float const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(double const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(long double const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(std::stringstream const &value) +{ + return value.str(); +} + + +template inline void into_string(T const &value, std::string &out) +{ + if (is_null(value)) + throw conversion_error{ + "Attempt to convert null " + type_name + " to a string."}; + + // We can't just reserve() data; modifying the terminating zero leads to + // undefined behaviour. + out.resize(size_buffer(value) + 1); + auto const data{out.data()}; + auto const end{ + string_traits::into_buf(data, data + std::size(out), value)}; + out.resize(static_cast(end - data - 1)); +} +} // namespace pqxx diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/encoding_group.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/encoding_group.hxx new file mode 100644 index 000000000..e17736e5b --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/encoding_group.hxx @@ -0,0 +1,60 @@ +/** Enum type for supporting encodings in libpqxx + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ENCODING_GROUP +#define PQXX_H_ENCODING_GROUP + +#include + +namespace pqxx::internal +{ +// Types of encodings supported by PostgreSQL, see +// https://www.postgresql.org/docs/current/static/multibyte.html#CHARSET-TABLE +enum class encoding_group +{ + // Handles all single-byte fixed-width encodings + MONOBYTE, + + // Multibyte encodings. + // Many of these can embed ASCII-like bytes inside multibyte characters, + // notably Big5, SJIS, SHIFT_JIS_2004, GP18030, GBK, JOHAB, UHC. + BIG5, + EUC_CN, + // TODO: Merge EUC_JP and EUC_JIS_2004? + EUC_JP, + EUC_JIS_2004, + EUC_KR, + EUC_TW, + GB18030, + GBK, + JOHAB, + MULE_INTERNAL, + // TODO: Merge SJIS and SHIFT_JIS_2004? + SJIS, + SHIFT_JIS_2004, + UHC, + UTF8, +}; + + +// TODO:: Can we just use string_view now? +/// Function type: "find the end of the current glyph." +/** This type of function takes a text buffer, and a location in that buffer, + * and returns the location one byte past the end of the current glyph. + * + * The start offset marks the beginning of the current glyph. It must fall + * within the buffer. + * + * There are multiple different glyph scanner implementations, for different + * kinds of encodings. + */ +using glyph_scanner_func = + std::size_t(char const buffer[], std::size_t buffer_len, std::size_t start); +} // namespace pqxx::internal + +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/encodings.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/encodings.hxx new file mode 100644 index 000000000..ba7fecc70 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/encodings.hxx @@ -0,0 +1,90 @@ +/** Internal string encodings support for libpqxx + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ENCODINGS +#define PQXX_H_ENCODINGS + +#include "pqxx/internal/encoding_group.hxx" + +#include +#include + + +namespace pqxx::internal +{ +char const *name_encoding(int encoding_id); + +/// Convert libpq encoding enum or encoding name to its libpqxx group. +encoding_group enc_group(int /* libpq encoding ID */); +encoding_group enc_group(std::string_view); + + +/// Look up the glyph scanner function for a given encoding group. +/** To identify the glyph boundaries in a buffer, call this to obtain the + * scanner function appropriate for the buffer's encoding. Then, repeatedly + * call the scanner function to find the glyphs. + */ +PQXX_LIBEXPORT glyph_scanner_func *get_glyph_scanner(encoding_group); + + +// TODO: For ASCII search, treat UTF8/EUC_*/MULE_INTERNAL as MONOBYTE. + +/// Find any of the ASCII characters `NEEDLE` in `haystack`. +/** Scans through `haystack` until it finds a single-byte character that + * matches any value in `NEEDLE`. + * + * If it finds one, returns its offset. If not, returns the end of the + * haystack. + */ +template +inline std::size_t find_char( + glyph_scanner_func *scanner, std::string_view haystack, + std::size_t here = 0u) +{ + auto const sz{std::size(haystack)}; + auto const data{std::data(haystack)}; + while (here < sz) + { + auto next{scanner(data, sz, here)}; + // (For some reason gcc had a problem with a right-fold here. But clang + // was fine.) + if ((... or (data[here] == NEEDLE))) + { + // Also check against a multibyte character starting with a bytes which + // just happens to match one of the ASCII bytes we're looking for. It'd + // be cleaner to check that first, but either works. So, let's apply the + // most selective filter first and skip this check in almost all cases. + if (next == here + 1) + return here; + } + + // Nope, no hit. Move on. + here = next; + } + return sz; +} + + +/// Iterate over the glyphs in a buffer. +/** Scans the glyphs in the buffer, and for each, passes its begin and its + * one-past-end pointers to `callback`. + */ +template +inline void for_glyphs( + encoding_group enc, CALLABLE callback, char const buffer[], + std::size_t buffer_len, std::size_t start = 0) +{ + auto const scan{get_glyph_scanner(enc)}; + for (std::size_t here = start, next; here < buffer_len; here = next) + { + next = scan(buffer, buffer_len, here); + callback(buffer + here, buffer + next); + } +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-errorhandler.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-errorhandler.hxx new file mode 100644 index 000000000..ffc12a6cf --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-errorhandler.hxx @@ -0,0 +1,26 @@ +#include + +namespace pqxx +{ +class connection; +class errorhandler; +} // namespace pqxx + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_errorhandler : callgate +{ + friend class pqxx::errorhandler; + + connection_errorhandler(reference x) : super(x) {} + + void register_errorhandler(errorhandler *h) + { + home().register_errorhandler(h); + } + void unregister_errorhandler(errorhandler *h) + { + home().unregister_errorhandler(h); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-largeobject.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-largeobject.hxx new file mode 100644 index 000000000..49feaf9e6 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-largeobject.hxx @@ -0,0 +1,35 @@ +#include + +#include +#include + +namespace pqxx +{ +class blob; +class largeobject; +} // namespace pqxx + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_largeobject : callgate +{ + friend class pqxx::blob; + friend class pqxx::largeobject; + + connection_largeobject(reference x) : super(x) {} + + pq::PGconn *raw_connection() const { return home().raw_connection(); } +}; + + +class PQXX_PRIVATE const_connection_largeobject : callgate +{ + friend class pqxx::blob; + friend class pqxx::largeobject; + + const_connection_largeobject(reference x) : super(x) {} + + std::string error_message() const { return home().err_msg(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-notification_receiver.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-notification_receiver.hxx new file mode 100644 index 000000000..0bcb2db17 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-notification_receiver.hxx @@ -0,0 +1,29 @@ +#include + +#include "pqxx/connection.hxx" + + +namespace pqxx +{ +class notification_receiver; +} + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_notification_receiver : callgate +{ + friend class pqxx::notification_receiver; + + connection_notification_receiver(reference x) : super(x) {} + + void add_receiver(notification_receiver *receiver) + { + home().add_receiver(receiver); + } + void remove_receiver(notification_receiver *receiver) noexcept + { + home().remove_receiver(receiver); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-pipeline.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-pipeline.hxx new file mode 100644 index 000000000..c6ae6e17a --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-pipeline.hxx @@ -0,0 +1,23 @@ +#include "pqxx/internal/libpq-forward.hxx" +#include + +#include "pqxx/pipeline.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_pipeline : callgate +{ + friend class pqxx::pipeline; + + connection_pipeline(reference x) : super(x) {} + + void start_exec(char const query[]) { home().start_exec(query); } + pqxx::internal::pq::PGresult *get_result() { return home().get_result(); } + void cancel_query() { home().cancel_query(); } + + bool consume_input() noexcept { return home().consume_input(); } + bool is_busy() const noexcept { return home().is_busy(); } + + int encoding_id() { return home().encoding_id(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-sql_cursor.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-sql_cursor.hxx new file mode 100644 index 000000000..51a889844 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-sql_cursor.hxx @@ -0,0 +1,19 @@ +#include + +namespace pqxx::internal +{ +class sql_cursor; +} + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + + connection_sql_cursor(reference x) : super(x) {} + + result exec(char const query[]) { return home().exec(query); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_from.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_from.hxx new file mode 100644 index 000000000..8961e7146 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_from.hxx @@ -0,0 +1,15 @@ +#include + +#include "pqxx/connection.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_stream_from : callgate +{ + friend class pqxx::stream_from; + + connection_stream_from(reference x) : super{x} {} + + auto read_copy_line() { return home().read_copy_line(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_to.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_to.hxx new file mode 100644 index 000000000..a6974fb21 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_to.hxx @@ -0,0 +1,17 @@ +#include + +#include "pqxx/stream_to.hxx" + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_stream_to : callgate +{ + friend class pqxx::stream_to; + + connection_stream_to(reference x) : super(x) {} + + void write_copy_line(std::string_view line) { home().write_copy_line(line); } + void end_copy_write() { home().end_copy_write(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-transaction.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-transaction.hxx new file mode 100644 index 000000000..74d659253 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-transaction.hxx @@ -0,0 +1,44 @@ +#include + +namespace pqxx +{ +class connection; +} + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_transaction : callgate +{ + friend class pqxx::transaction_base; + + connection_transaction(reference x) : super(x) {} + + template result exec(STRING query, std::string_view desc) + { + return home().exec(query, desc); + } + + void register_transaction(transaction_base *t) + { + home().register_transaction(t); + } + void unregister_transaction(transaction_base *t) noexcept + { + home().unregister_transaction(t); + } + + auto read_copy_line() { return home().read_copy_line(); } + void write_copy_line(std::string_view line) { home().write_copy_line(line); } + void end_copy_write() { home().end_copy_write(); } + + result exec_prepared(zview statement, internal::c_params const &args) + { + return home().exec_prepared(statement, args); + } + + result exec_params(zview query, internal::c_params const &args) + { + return home().exec_params(query, args); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/errorhandler-connection.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/errorhandler-connection.hxx new file mode 100644 index 000000000..5560cedec --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/errorhandler-connection.hxx @@ -0,0 +1,13 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE errorhandler_connection : callgate +{ + friend class pqxx::connection; + + errorhandler_connection(reference x) : super(x) {} + + void unregister() noexcept { home().unregister(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx new file mode 100644 index 000000000..296d22145 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx @@ -0,0 +1,24 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE icursor_iterator_icursorstream : callgate +{ + friend class pqxx::icursorstream; + + icursor_iterator_icursorstream(reference x) : super(x) {} + + icursor_iterator::difference_type pos() const noexcept + { + return home().pos(); + } + + icursor_iterator *get_prev() { return home().m_prev; } + void set_prev(icursor_iterator *i) { home().m_prev = i; } + + icursor_iterator *get_next() { return home().m_next; } + void set_next(icursor_iterator *i) { home().m_next = i; } + + void fill(result const &r) { home().fill(r); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx new file mode 100644 index 000000000..56056d5ef --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx @@ -0,0 +1,32 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE icursorstream_icursor_iterator : callgate +{ + friend class pqxx::icursor_iterator; + + icursorstream_icursor_iterator(reference x) : super(x) {} + + void insert_iterator(icursor_iterator *i) noexcept + { + home().insert_iterator(i); + } + + void remove_iterator(icursor_iterator *i) const noexcept + { + home().remove_iterator(i); + } + + icursorstream::size_type forward() { return home().forward(); } + icursorstream::size_type forward(icursorstream::size_type n) + { + return home().forward(n); + } + + void service_iterators(icursorstream::difference_type p) + { + home().service_iterators(p); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-connection.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-connection.hxx new file mode 100644 index 000000000..daa0808c0 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-connection.hxx @@ -0,0 +1,14 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_connection : callgate +{ + friend class pqxx::connection; + + result_connection(reference x) : super(x) {} + + operator bool() const { return bool(home()); } + bool operator!() const { return not home(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-creation.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-creation.hxx new file mode 100644 index 000000000..3d9205f2c --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-creation.hxx @@ -0,0 +1,24 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_creation : callgate +{ + friend class pqxx::connection; + friend class pqxx::pipeline; + + result_creation(reference x) : super(x) {} + + static result create( + internal::pq::PGresult *rhs, std::shared_ptr const &query, + encoding_group enc) + { + return result(rhs, query, enc); + } + + void check_status(std::string_view desc = ""sv) const + { + return home().check_status(desc); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-pipeline.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-pipeline.hxx new file mode 100644 index 000000000..3ebe436d2 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-pipeline.hxx @@ -0,0 +1,16 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_pipeline : callgate +{ + friend class pqxx::pipeline; + + result_pipeline(reference x) : super(x) {} + + std::shared_ptr query_ptr() const + { + return home().query_ptr(); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-sql_cursor.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-sql_cursor.hxx new file mode 100644 index 000000000..78b450739 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-sql_cursor.hxx @@ -0,0 +1,13 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + + result_sql_cursor(reference x) : super(x) {} + + char const *cmd_status() const noexcept { return home().cmd_status(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-sql_cursor.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-sql_cursor.hxx new file mode 100644 index 000000000..4ed78dc93 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-sql_cursor.hxx @@ -0,0 +1,10 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE transaction_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + transaction_sql_cursor(reference x) : super(x) {} +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-transaction_focus.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-transaction_focus.hxx new file mode 100644 index 000000000..ca7939a99 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-transaction_focus.hxx @@ -0,0 +1,30 @@ +#include + +#include "pqxx/transaction_base.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE transaction_transaction_focus : callgate +{ + friend class pqxx::transaction_focus; + + transaction_transaction_focus(reference x) : super(x) {} + + void register_focus(transaction_focus *focus) + { + home().register_focus(focus); + } + void unregister_focus(transaction_focus *focus) noexcept + { + home().unregister_focus(focus); + } + void register_pending_error(zview error) + { + home().register_pending_error(error); + } + void register_pending_error(std::string &&error) + { + home().register_pending_error(std::move(error)); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/header-post.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/header-post.hxx new file mode 100644 index 000000000..ff6bf8986 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/header-post.hxx @@ -0,0 +1,22 @@ +/* Compiler deficiency workarounds for compiling libpqxx headers. + * + * To be included at the end of each libpqxx header, in order to restore the + * client program's settings. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +// NO GUARDS HERE! This code should be executed every time! + +#if defined(_MSC_VER) +# pragma warning(pop) // Restore compiler's warning state +#endif + +#if !defined(PQXX_HEADER_PRE) +# error "Include pqxx/internal/header-post.hxx AFTER its 'pre' counterpart." +#endif + +#undef PQXX_HEADER_PRE diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/header-pre.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/header-pre.hxx new file mode 100644 index 000000000..abc1a398d --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/header-pre.hxx @@ -0,0 +1,169 @@ +/* Compiler settings for compiling libpqxx headers, and workarounds for all. + * + * Include this before including any other libpqxx headers from within libpqxx. + * And to balance it out, also include header-post.hxx at the end of the batch + * of headers. + * + * The public libpqxx headers (e.g. ``) include this already; + * there's no need to do this from within an application. + * + * Include this file at the highest aggregation level possible to avoid nesting + * and to keep things simple. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ + +// NO GUARD HERE! This part should be included every time this file is. +#if defined(_MSC_VER) + +// Save compiler's warning state, and set warning level 4 for maximum +// sensitivity to warnings. +# pragma warning(push, 4) + +// Visual C++ generates some entirely unreasonable warnings. Disable them. +// Copy constructor could not be generated. +# pragma warning(disable : 4511) +// Assignment operator could not be generated. +# pragma warning(disable : 4512) +// Can't expose outside classes without exporting them. Except the MSVC docs +// say please ignore the warning if it's a standard library class. +# pragma warning(disable : 4251) +// Can't derive library classes from outside classes without exporting them. +// Except the MSVC docs say please ignore the warning if the parent class is +// in the standard library. +# pragma warning(disable : 4275) +// Can't inherit from non-exported class. +# pragma warning(disable : 4275) + +#endif // _MSC_VER + + +#if defined(PQXX_HEADER_PRE) +# error "Avoid nesting #include of pqxx/internal/header-pre.hxx." +#endif + +#define PQXX_HEADER_PRE + + +// Workarounds & definitions that need to be included even in library's headers +#include "pqxx/config-public-compiler.h" + +// Enable ISO-646 alternative operaotr representations: "and" instead of "&&" +// etc. on older compilers. C++20 removes this header. +#if __has_include() +# include +#endif + + +#if defined(PQXX_HAVE_GCC_PURE) +/// Declare function "pure": no side effects, only reads globals and its args. +# define PQXX_PURE __attribute__((pure)) +#else +# define PQXX_PURE /* pure */ +#endif + + +#if defined(__GNUC__) +/// Tell the compiler to optimise a function for size, not speed. +# define PQXX_COLD __attribute__((cold)) +#else +# define PQXX_COLD /* cold */ +#endif + + +// Workarounds for Windows +#ifdef _WIN32 + +/* For now, export DLL symbols if _DLL is defined. This is done automatically + * by the compiler when linking to the dynamic version of the runtime library, + * according to "gzh" + */ +# if defined(PQXX_SHARED) && !defined(PQXX_LIBEXPORT) +# define PQXX_LIBEXPORT __declspec(dllimport) +# endif // PQXX_SHARED && !PQXX_LIBEXPORT + + +// Workarounds for Microsoft Visual C++ +# ifdef _MSC_VER + +// Suppress vtables on abstract classes. +# define PQXX_NOVTABLE __declspec(novtable) + +// Automatically link with the appropriate libpq (static or dynamic, debug or +// release). The default is to use the release DLL. Define PQXX_PQ_STATIC to +// link to a static version of libpq, and _DEBUG to link to a debug version. +// The two may be combined. +# if defined(PQXX_AUTOLINK) +# if defined(PQXX_PQ_STATIC) +# ifdef _DEBUG +# pragma comment(lib, "libpqd") +# else +# pragma comment(lib, "libpq") +# endif +# else +# ifdef _DEBUG +# pragma comment(lib, "libpqddll") +# else +# pragma comment(lib, "libpqdll") +# endif +# endif +# endif + +// If we're not compiling libpqxx itself, automatically link with the +// appropriate libpqxx library. To link with the libpqxx DLL, define +// PQXX_SHARED; the default is to link with the static library. A static link +// is the recommended practice. +// +// The preprocessor macro PQXX_INTERNAL is used to detect whether we +// are compiling the libpqxx library itself. When you compile the library +// yourself using your own project file, make sure to include this macro. +# if defined(PQXX_AUTOLINK) && !defined(PQXX_INTERNAL) +# ifdef PQXX_SHARED +# ifdef _DEBUG +# pragma comment(lib, "libpqxxD") +# else +# pragma comment(lib, "libpqxx") +# endif +# else // !PQXX_SHARED +# ifdef _DEBUG +# pragma comment(lib, "libpqxx_staticD") +# else +# pragma comment(lib, "libpqxx_static") +# endif +# endif +# endif + +# endif // _MSC_VER + +#elif defined(PQXX_HAVE_GCC_VISIBILITY) // !_WIN32 + +# define PQXX_LIBEXPORT __attribute__((visibility("default"))) +# define PQXX_PRIVATE __attribute__((visibility("hidden"))) + +#endif // PQXX_HAVE_GCC_VISIBILITY + + +#ifndef PQXX_LIBEXPORT +# define PQXX_LIBEXPORT /* libexport */ +#endif + +#ifndef PQXX_PRIVATE +# define PQXX_PRIVATE /* private */ +#endif + +#ifndef PQXX_NOVTABLE +# define PQXX_NOVTABLE /* novtable */ +#endif + +// C++20: Assume support. +#if defined(PQXX_HAVE_LIKELY) +# define PQXX_LIKELY [[likely]] +# define PQXX_UNLIKELY [[unlikely]] +#else +# define PQXX_LIKELY /* [[likely]] */ +# define PQXX_UNLIKELY /* [[unlikely]] */ +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-post.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-post.hxx new file mode 100644 index 000000000..cebcf0594 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-post.hxx @@ -0,0 +1,15 @@ +/// End a code block started by "ignore-deprecated-pre.hxx". + +#if !defined(PQXX_IGNORING_DEPRECATED) +# error "Ended an 'ignore-deprecated' block while none was active." +#endif + +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif // __GNUC__ + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#undef PQXX_IGNORING_DEPRECATED diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-pre.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-pre.hxx new file mode 100644 index 000000000..8ac57afaa --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-pre.hxx @@ -0,0 +1,28 @@ +/** Start a block of deprecated code which may call other deprecated code. + * + * Most compilers will emit warnings when deprecated code is invoked from + * non-deprecated code. But some compilers (notably gcc) will always emit the + * warning even when the calling code is also deprecated. + * + * This header starts a block where those warnings are suppressed. It can be + * included inside a code block. + * + * Always match the #include with a closing #include of + * "ignore-deprecated-post.hxx". To avoid mistakes, keep the enclosed area as + * small as possible. + */ +#if defined(PQXX_IGNORING_DEPRECATED) +# error "Started an 'ignore-deprecated' block inside another." +#endif + +#define PQXX_IGNORING_DEPRECATED + +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // __GNUC__ + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4996) +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/libpq-forward.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/libpq-forward.hxx new file mode 100644 index 000000000..9e74f79ec --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/libpq-forward.hxx @@ -0,0 +1,31 @@ +/** Minimal forward declarations of libpq types needed in libpqxx headers. + * + * DO NOT INCLUDE THIS FILE when building client programs. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +extern "C" +{ + struct pg_conn; + struct pg_result; + struct pgNotify; +} + +/// Forward declarations of libpq types as needed in libpqxx headers. +namespace pqxx::internal::pq +{ +using PGconn = pg_conn; +using PGresult = pg_result; +using PGnotify = pgNotify; +using PQnoticeProcessor = void (*)(void *, char const *); +} // namespace pqxx::internal::pq + +namespace pqxx +{ +/// PostgreSQL database row identifier. +using oid = unsigned int; +} // namespace pqxx diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/result_iter.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/result_iter.hxx new file mode 100644 index 000000000..1fa1f7d8a --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/result_iter.hxx @@ -0,0 +1,124 @@ +/** Result loops. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT_ITER +#define PQXX_H_RESULT_ITER + +#include + +#include "pqxx/strconv.hxx" + +namespace pqxx +{ +class result; +} // namespace pqxx + + +namespace pqxx::internal +{ +// C++20: Replace with generator? +/// Iterator for looped unpacking of a result. +template class result_iter +{ +public: + using value_type = std::tuple; + + /// Construct an "end" iterator. + result_iter() = default; + + explicit result_iter(result const &home) : + m_home{&home}, m_size{std::size(home)} + { + if (not std::empty(home)) + read(); + } + result_iter(result_iter const &) = default; + + result_iter &operator++() + { + m_index++; + if (m_index >= m_size) + m_home = nullptr; + else + read(); + return *this; + } + + /// Comparison only works for comparing to end(). + bool operator==(result_iter const &rhs) const + { + return m_home == rhs.m_home; + } + bool operator!=(result_iter const &rhs) const { return not(*this == rhs); } + + value_type const &operator*() const { return m_value; } + +private: + void read() { (*m_home)[m_index].convert(m_value); } + + result const *m_home{nullptr}; + result::size_type m_index{0}; + result::size_type m_size; + value_type m_value; +}; + + +template class result_iteration +{ +public: + using iterator = result_iter; + explicit result_iteration(result const &home) : m_home{home} + { + constexpr auto tup_size{sizeof...(TYPE)}; + if (home.columns() != tup_size) + throw usage_error{internal::concat( + "Tried to extract ", to_string(tup_size), + " field(s) from a result with ", to_string(home.columns()), + " column(s).")}; + } + iterator begin() const + { + if (std::size(m_home) == 0) + return end(); + else + return iterator{m_home}; + } + iterator end() const { return {}; } + +private: + pqxx::result const &m_home; +}; +} // namespace pqxx::internal + + +template inline auto pqxx::result::iter() const +{ + return pqxx::internal::result_iteration{*this}; +} + + +template +inline void pqxx::result::for_each(CALLABLE &&func) const +{ + using args_tuple = internal::args_t; + constexpr auto sz{std::tuple_size_v}; + static_assert( + sz > 0, + "Callback for for_each must take parameters, one for each column in the " + "result."); + + auto const cols{this->columns()}; + if (sz != cols) + throw usage_error{internal::concat( + "Callback to for_each takes ", sz, "parameter", (sz == 1) ? "" : "s", + ", but result set has ", cols, "field", (cols == 1) ? "" : "s", ".")}; + + using pass_tuple = pqxx::internal::strip_types_t; + for (auto const r : *this) std::apply(func, r.as_tuple()); +} +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/result_iterator.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/result_iterator.hxx new file mode 100644 index 000000000..3f27a1d3f --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/result_iterator.hxx @@ -0,0 +1,389 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT_ITERATOR +#define PQXX_H_RESULT_ITERATOR + +#include "pqxx/row.hxx" + + +/* Result iterator. + * + * Don't include this header from your own application; it is included for you + * by other libpqxx headers. + */ + +namespace pqxx +{ +/// Iterator for rows in a result. Use as result::const_iterator. +/** A result, once obtained, cannot be modified. Therefore there is no + * plain iterator type for result. However its const_iterator type can be + * used to inspect its rows without changing them. + */ +class PQXX_LIBEXPORT const_result_iterator : public row +{ +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = row const; + using pointer = row const *; + using reference = row; + using size_type = result_size_type; + using difference_type = result_difference_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create an iterator, but in an unusable state. + const_result_iterator() noexcept = default; + /// Copy an iterator. + const_result_iterator(const_result_iterator const &) noexcept = default; + /// Move an iterator. + const_result_iterator(const_result_iterator &&) noexcept = default; + + /// Begin iterating a @ref row. + const_result_iterator(row const &t) noexcept : row{t} {} +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /** + * @name Dereferencing operators + * + * An iterator "points to" its own row, which is also itself. This makes it + * easy to address a @ref result as a two-dimensional container, without + * going through the intermediate step of dereferencing the iterator. It + * makes the interface similar to C pointer/array semantics. + * + * IIRC Alex Stepanov, the inventor of the STL, once remarked that having + * this as standard behaviour for pointers would be useful in some + * algorithms. So even if this makes me look foolish, I would seem to be in + * distinguished company. + */ + //@{ + /// Dereference the iterator. + [[nodiscard]] pointer operator->() const { return this; } + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Dereference the iterator. + [[nodiscard]] reference operator*() const { return *this; } +#include "pqxx/internal/ignore-deprecated-post.hxx" + //@} + + /** + * @name Field access + */ + //@{ + using row::back; + using row::front; + using row::operator[]; + using row::at; + using row::rownumber; + //@} + + /** + * @name Manipulations + */ + //@{ + const_result_iterator &operator=(const_result_iterator const &rhs) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::operator=(rhs); +#include "pqxx/internal/ignore-deprecated-post.hxx" + return *this; + } + + const_result_iterator &operator=(const_result_iterator &&rhs) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::operator=(std::move(rhs)); +#include "pqxx/internal/ignore-deprecated-post.hxx" + return *this; + } + + const_result_iterator operator++(int); + const_result_iterator &operator++() + { + ++m_index; + return *this; + } + const_result_iterator operator--(int); + const_result_iterator &operator--() + { + --m_index; + return *this; + } + + const_result_iterator &operator+=(difference_type i) + { + m_index += i; + return *this; + } + const_result_iterator &operator-=(difference_type i) + { + m_index -= i; + return *this; + } + + /// Interchange two iterators in an exception-safe manner. + void swap(const_result_iterator &other) noexcept + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::swap(other); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool operator==(const_result_iterator const &i) const + { + return m_index == i.m_index; + } + [[nodiscard]] bool operator!=(const_result_iterator const &i) const + { + return m_index != i.m_index; + } + [[nodiscard]] bool operator<(const_result_iterator const &i) const + { + return m_index < i.m_index; + } + [[nodiscard]] bool operator<=(const_result_iterator const &i) const + { + return m_index <= i.m_index; + } + [[nodiscard]] bool operator>(const_result_iterator const &i) const + { + return m_index > i.m_index; + } + [[nodiscard]] bool operator>=(const_result_iterator const &i) const + { + return m_index >= i.m_index; + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] inline const_result_iterator operator+(difference_type) const; + friend const_result_iterator + operator+(difference_type, const_result_iterator const &); + [[nodiscard]] inline const_result_iterator operator-(difference_type) const; + [[nodiscard]] inline difference_type + operator-(const_result_iterator const &) const; + //@} + +private: + friend class pqxx::result; + const_result_iterator(pqxx::result const *r, result_size_type i) noexcept : + row{*r, i, r->columns()} + {} +}; + + +/// Reverse iterator for result. Use as result::const_reverse_iterator. +class PQXX_LIBEXPORT const_reverse_result_iterator + : private const_result_iterator +{ +public: + using super = const_result_iterator; + using iterator_type = const_result_iterator; + using iterator_type::difference_type; + using iterator_type::iterator_category; + using iterator_type::pointer; + using value_type = iterator_type::value_type; + using reference = iterator_type::reference; + + /// Create an iterator, but in an unusable state. + const_reverse_result_iterator() = default; + /// Copy an iterator. + const_reverse_result_iterator(const_reverse_result_iterator const &rhs) = + default; + /// Copy a reverse iterator from a regular iterator. + explicit const_reverse_result_iterator(const_result_iterator const &rhs) : + const_result_iterator{rhs} + { + super::operator--(); + } + + /// Move a regular iterator into a reverse iterator. + explicit const_reverse_result_iterator(const_result_iterator const &&rhs) : + const_result_iterator{std::move(rhs)} + { + super::operator--(); + } + + /// Return the underlying "regular" iterator (as per standard library). + [[nodiscard]] PQXX_PURE const_result_iterator base() const noexcept; + + /** + * @name Dereferencing operators + */ + //@{ + /// Dereference iterator. + using const_result_iterator::operator->; + /// Dereference iterator. + using const_result_iterator::operator*; + //@} + + /** + * @name Field access + */ + //@{ + using const_result_iterator::back; + using const_result_iterator::front; + using const_result_iterator::operator[]; + using const_result_iterator::at; + using const_result_iterator::rownumber; + //@} + + /** + * @name Manipulations + */ + //@{ + const_reverse_result_iterator & + operator=(const_reverse_result_iterator const &r) + { + iterator_type::operator=(r); + return *this; + } + const_reverse_result_iterator &operator=(const_reverse_result_iterator &&r) + { + iterator_type::operator=(std::move(r)); + return *this; + } + const_reverse_result_iterator &operator++() + { + iterator_type::operator--(); + return *this; + } + const_reverse_result_iterator operator++(int); + const_reverse_result_iterator &operator--() + { + iterator_type::operator++(); + return *this; + } + const_reverse_result_iterator operator--(int); + const_reverse_result_iterator &operator+=(difference_type i) + { + iterator_type::operator-=(i); + return *this; + } + const_reverse_result_iterator &operator-=(difference_type i) + { + iterator_type::operator+=(i); + return *this; + } + + void swap(const_reverse_result_iterator &other) noexcept + { + const_result_iterator::swap(other); + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] const_reverse_result_iterator + operator+(difference_type i) const + { + return const_reverse_result_iterator(base() - i); + } + [[nodiscard]] const_reverse_result_iterator operator-(difference_type i) + { + return const_reverse_result_iterator(base() + i); + } + [[nodiscard]] difference_type + operator-(const_reverse_result_iterator const &rhs) const + { + return rhs.const_result_iterator::operator-(*this); + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool + operator==(const_reverse_result_iterator const &rhs) const noexcept + { + return iterator_type::operator==(rhs); + } + [[nodiscard]] bool + operator!=(const_reverse_result_iterator const &rhs) const noexcept + { + return not operator==(rhs); + } + + [[nodiscard]] bool operator<(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator>(rhs); + } + [[nodiscard]] bool operator<=(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator>=(rhs); + } + [[nodiscard]] bool operator>(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator<(rhs); + } + [[nodiscard]] bool operator>=(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator<=(rhs); + } + //@} +}; + + +inline const_result_iterator +const_result_iterator::operator+(result::difference_type o) const +{ + return {&m_result, size_type(result::difference_type(m_index) + o)}; +} + +inline const_result_iterator +operator+(result::difference_type o, const_result_iterator const &i) +{ + return i + o; +} + +inline const_result_iterator +const_result_iterator::operator-(result::difference_type o) const +{ + return {&m_result, result_size_type(result::difference_type(m_index) - o)}; +} + +inline result::difference_type +const_result_iterator::operator-(const const_result_iterator &i) const +{ + return result::difference_type(num() - i.num()); +} + +inline const_result_iterator result::end() const noexcept +{ + return {this, size()}; +} + + +inline const_result_iterator result::cend() const noexcept +{ + return end(); +} + + +inline const_reverse_result_iterator +operator+(result::difference_type n, const_reverse_result_iterator const &i) +{ + return const_reverse_result_iterator{i.base() - n}; +} + +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/sql_cursor.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/sql_cursor.hxx new file mode 100644 index 000000000..a26d06306 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/sql_cursor.hxx @@ -0,0 +1,118 @@ +/** Internal wrapper for SQL cursors. Supports higher-level cursor classes. + * + * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SQL_CURSOR +#define PQXX_H_SQL_CURSOR + +namespace pqxx::internal +{ +/// Cursor with SQL positioning semantics. +/** Thin wrapper around an SQL cursor, with SQL's ideas of positioning. + * + * SQL cursors have pre-increment/pre-decrement semantics, with on either end + * of the result set a special position that does not repesent a row. This + * class models SQL cursors for the purpose of implementing more C++-like + * semantics on top. + * + * Positions of actual rows are numbered starting at 1. Position 0 exists but + * does not refer to a row. There is a similar non-row position at the end of + * the result set. + * + * Don't use this at home. You deserve better. Use the stateles_cursor + * instead. + */ +class PQXX_LIBEXPORT sql_cursor : public cursor_base +{ +public: + sql_cursor( + transaction_base &t, std::string_view query, std::string_view cname, + cursor_base::access_policy ap, cursor_base::update_policy up, + cursor_base::ownership_policy op, bool hold); + + sql_cursor( + transaction_base &t, std::string_view cname, + cursor_base::ownership_policy op); + + ~sql_cursor() noexcept { close(); } + + result fetch(difference_type rows, difference_type &displacement); + result fetch(difference_type rows) + { + difference_type d = 0; + return fetch(rows, d); + } + difference_type move(difference_type rows, difference_type &displacement); + difference_type move(difference_type rows) + { + difference_type d = 0; + return move(rows, d); + } + + /// Current position, or -1 for unknown + /** + * The starting position, just before the first row, counts as position zero. + * + * Position may be unknown if (and only if) this cursor was adopted, and has + * never hit its starting position (position zero). + */ + difference_type pos() const noexcept { return m_pos; } + + /// End position, or -1 for unknown + /** + * Returns the final position, just after the last row in the result set. The + * starting position, just before the first row, counts as position zero. + * + * End position is unknown until it is encountered during use. + */ + difference_type endpos() const noexcept { return m_endpos; } + + /// Return zero-row result for this cursor. + result const &empty_result() const noexcept { return m_empty_result; } + + void close() noexcept; + +private: + difference_type adjust(difference_type hoped, difference_type actual); + static std::string stridestring(difference_type); + /// Initialize cached empty result. Call only at beginning or end! + void init_empty_result(transaction_base &); + + /// Connection in which this cursor lives. + connection &m_home; + + /// Zero-row result from this cursor (or plain empty one if cursor is + /// adopted) + result m_empty_result; + + result m_cached_current_row; + + /// Is this cursor adopted (as opposed to created by this cursor object)? + bool m_adopted; + + /// Will this cursor object destroy its SQL cursor when it dies? + cursor_base::ownership_policy m_ownership; + + /// At starting position (-1), somewhere in the middle (0), or past end (1) + int m_at_end; + + /// Position, or -1 for unknown + difference_type m_pos; + + /// End position, or -1 for unknown + difference_type m_endpos = -1; +}; + + +PQXX_LIBEXPORT result_size_type obtain_stateless_cursor_size(sql_cursor &); +PQXX_LIBEXPORT result stateless_cursor_retrieve( + sql_cursor &, result::difference_type size, + result::difference_type begin_pos, result::difference_type end_pos); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/statement_parameters.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/statement_parameters.hxx new file mode 100644 index 000000000..b078bf6e0 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/statement_parameters.hxx @@ -0,0 +1,131 @@ +/** Common implementation for statement parameter lists. + * + * These are used for both prepared statements and parameterized statements. + * + * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STATEMENT_PARAMETER +#define PQXX_H_STATEMENT_PARAMETER + +#include +#include +#include +#include +#include + +#include "pqxx/binarystring.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/util.hxx" + + +namespace pqxx::internal +{ +template +constexpr inline auto const iterator_identity{ + [](decltype(*std::declval()) x) { return x; }}; + + +/// Marker type: pass a dynamically-determined number of statement parameters. +/** @deprecated Use @ref params instead. + * + * Normally when invoking a prepared or parameterised statement, the number + * of parameters is known at compile time. For instance, + * `t.exec_prepared("foo", 1, "x");` executes statement `foo` with two + * parameters, an `int` and a C string. + * + * But sometimes you may want to pass a number of parameters known only at run + * time. In those cases, a @ref dynamic_params encodes a dynamically + * determined number of parameters. You can mix these with regular, static + * parameter lists, and you can re-use them for multiple statement invocations. + * + * A dynamic_params object does not store copies of its parameters, so make + * sure they remain accessible until you've executed the statement. + * + * The ACCESSOR is an optional callable (such as a lambda). If you pass an + * accessor `a`, then each parameter `p` goes into your statement as `a(p)`. + */ +template)> +class dynamic_params +{ +public: + /// Wrap a sequence of pointers or iterators. + constexpr dynamic_params(IT begin, IT end) : + m_begin(begin), m_end(end), m_accessor(iterator_identity) + {} + + /// Wrap a sequence of pointers or iterators. + /** This version takes an accessor callable. If you pass an accessor `acc`, + * then any parameter `p` will go into the statement's parameter list as + * `acc(p)`. + */ + constexpr dynamic_params(IT begin, IT end, ACCESSOR &acc) : + m_begin(begin), m_end(end), m_accessor(acc) + {} + + /// Wrap a container. + template + explicit constexpr dynamic_params(C &container) : + dynamic_params(std::begin(container), std::end(container)) + {} + + /// Wrap a container. + /** This version takes an accessor callable. If you pass an accessor `acc`, + * then any parameter `p` will go into the statement's parameter list as + * `acc(p)`. + */ + template + explicit constexpr dynamic_params(C &container, ACCESSOR &acc) : + dynamic_params(std::begin(container), std::end(container), acc) + {} + + constexpr IT begin() const noexcept { return m_begin; } + constexpr IT end() const noexcept { return m_end; } + + constexpr auto access(decltype(*std::declval()) value) const + -> decltype(std::declval()(value)) + { + return m_accessor(value); + } + +private: + IT const m_begin, m_end; + ACCESSOR m_accessor = iterator_identity; +}; + + +/// Internal type: encode statement parameters. +/** Compiles arguments for prepared statements and parameterised queries into + * a format that can be passed into libpq. + * + * Objects of this type are meant to be short-lived: a `c_params` lives and + * dies entirely within the call to execute. So, for example, if you pass in a + * non-null pointer as a parameter, @ref params may simply use that pointer as + * a parameter value, without arranging longer-term storage for the data to + * which it points. All values referenced by parameters must remain "live" + * until the parameterised or prepared statement has been executed. + */ +struct PQXX_LIBEXPORT c_params +{ + c_params() = default; + /// Copying these objects is pointless and expensive. Don't do it. + c_params(c_params const &) = delete; + c_params(c_params &&) = default; + + /// Pre-allocate storage for `n` parameters. + void reserve(std::size_t n) &; + + /// As used by libpq: pointers to parameter values. + std::vector values; + /// As used by libpq: lengths of non-null arguments, in bytes. + std::vector lengths; + /// As used by libpq: effectively boolean "is this a binary parameter?" + std::vector formats; +}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/stream_iterator.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/stream_iterator.hxx new file mode 100644 index 000000000..f240dcfa7 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/stream_iterator.hxx @@ -0,0 +1,105 @@ +/** Stream iterators. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_ITERATOR +#define PQXX_H_STREAM_ITERATOR + +#include + +namespace pqxx +{ +class stream_from; +} + + +namespace pqxx::internal +{ +// C++20: Replace with generator? +/// Input iterator for stream_from. +/** Just barely enough to support range-based "for" loops. Don't assume that + * any of the usual behaviour works beyond that. + */ +template class stream_input_iterator +{ +public: + using value_type = std::tuple; + + /// Construct an "end" iterator. + stream_input_iterator() = default; + + explicit stream_input_iterator(stream_from &home) : m_home(&home) + { + advance(); + } + stream_input_iterator(stream_input_iterator const &) = default; + + stream_input_iterator &operator++() + { + advance(); + return *this; + } + + value_type const &operator*() const { return m_value; } + + /// Comparison only works for comparing to end(). + bool operator==(stream_input_iterator const &rhs) const + { + return m_home == rhs.m_home; + } + /// Comparison only works for comparing to end(). + bool operator!=(stream_input_iterator const &rhs) const + { + return not(*this == rhs); + } + +private: + void advance() + { + if (m_home == nullptr) + throw usage_error{"Moving stream_from iterator beyond end()."}; + if (not((*m_home) >> m_value)) + m_home = nullptr; + } + + stream_from *m_home{nullptr}; + value_type m_value; +}; + + +// C++20: Replace with generator? +/// Iteration over a @ref stream_from. +template class stream_input_iteration +{ +public: + using iterator = stream_input_iterator; + explicit stream_input_iteration(stream_from &home) : m_home{home} {} + iterator begin() const { return iterator{m_home}; } + iterator end() const { return {}; } + +private: + stream_from &m_home; +}; + + +// C++20: Replace with generator? +/// Iteration over a @ref stream_from, deleting it once done. +template class owning_stream_input_iteration +{ +public: + using iterator = stream_input_iterator; + explicit owning_stream_input_iteration(std::unique_ptr &&home) : + m_home{std::move(home)} + {} + iterator begin() const { return iterator{*m_home.get()}; } + iterator end() const { return {}; } + +private: + std::unique_ptr m_home; +}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/wait.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/wait.hxx new file mode 100644 index 000000000..7a82e6553 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/wait.hxx @@ -0,0 +1,18 @@ +#if !defined(PQXX_WAIT_HXX) +# define PQXX_WAIT_HXX + +namespace pqxx::internal +{ +/// Wait. +/** This is normally `std::this_thread::sleep_for()`. But MinGW's `thread` + * header doesn't work, so we must be careful about including it. + */ +void PQXX_LIBEXPORT wait_for(unsigned int microseconds); + + +/// Wait for a socket to be ready for reading/writing, or timeout. +PQXX_LIBEXPORT void wait_fd( + int fd, bool for_read, bool for_write, unsigned seconds = 1, + unsigned microseconds = 0); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/isolation b/ext/libpqxx-7.7.3/include/pqxx/isolation new file mode 100644 index 000000000..1b801329b --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/isolation @@ -0,0 +1,8 @@ +/** Transaction isolation levels. + * + * Policies and traits describing SQL transaction isolation levels + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/isolation.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/isolation.hxx b/ext/libpqxx-7.7.3/include/pqxx/isolation.hxx new file mode 100644 index 000000000..0698c6ab4 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/isolation.hxx @@ -0,0 +1,75 @@ +/* Definitions for transaction isolation levels, and such. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/isolation instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ISOLATION +#define PQXX_H_ISOLATION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Should a transaction be read-only, or read-write? +/** No, this is not an isolation level. So it really doesn't belong here. + * But it's not really worth a separate header. + */ +enum class write_policy +{ + read_only, + read_write +}; + + +/// Transaction isolation levels. +/** These are as defined in the SQL standard. But there are a few notes + * specific to PostgreSQL. + * + * First, postgres does not support "read uncommitted." The lowest level you + * can get is "read committed," which is better. PostgreSQL is built on the + * MVCC paradigm, which guarantees "read committed" isolation without any + * additional performance overhead, so there was no point in providing the + * lower level. + * + * Second, "repeatable read" also makes more isolation guarantees than the + * standard requires. According to the standard, this level prevents "dirty + * reads" and "nonrepeatable reads," but not "phantom reads." In postgres, + * it actually prevents all three. + * + * Third, "serializable" is only properly supported starting at postgres 9.1. + * If you request "serializable" isolation on an older backend, you will get + * the same isolation as in "repeatable read." It's better than the + * "repeatable read" defined in the SQL standard, but not a complete + * implementation of the standard's "serializable" isolation level. + * + * In general, a lower isolation level will allow more surprising interactions + * between ongoing transactions, but improve performance. A higher level + * gives you more protection from subtle concurrency bugs, but sometimes it + * may not be possible to complete your transaction without avoiding paradoxes + * in the data. In that case a transaction may fail, and the application will + * have to re-do the whole thing based on the latest state of the database. + * (If you want to retry your code in that situation, have a look at the + * transactor framework.) + * + * Study the levels and design your application with the right level in mind. + */ +enum isolation_level +{ + // PostgreSQL only has the better isolation levels. + // read_uncommitted, + + read_committed, + repeatable_read, + serializable, +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/largeobject b/ext/libpqxx-7.7.3/include/pqxx/largeobject new file mode 100644 index 000000000..1f2f94790 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/largeobject @@ -0,0 +1,8 @@ +/** Large Objects interface. + * + * Supports direct access to large objects, as well as through I/O streams + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/largeobject.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/largeobject.hxx b/ext/libpqxx-7.7.3/include/pqxx/largeobject.hxx new file mode 100644 index 000000000..ebafc51d8 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/largeobject.hxx @@ -0,0 +1,735 @@ +/* Large Objects interface. Deprecated; use blob instead. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_LARGEOBJECT +#define PQXX_H_LARGEOBJECT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/dbtransaction.hxx" + + +namespace pqxx +{ +/// Identity of a large object. +/** @deprecated Use the @ref blob class instead. + * + * Encapsulates the identity of a large object. + * + * A largeobject must be accessed only from within a backend transaction, but + * the object's identity remains valid as long as the object exists. + */ +class PQXX_LIBEXPORT largeobject +{ +public: + using size_type = large_object_size_type; + + /// Refer to a nonexistent large object (similar to what a null pointer + /// does). + [[deprecated("Use blob instead.")]] largeobject() noexcept = default; + + /// Create new large object. + /** @param t Backend transaction in which the object is to be created. + */ + [[deprecated("Use blob instead.")]] explicit largeobject(dbtransaction &t); + + /// Wrap object with given oid. + /** Convert combination of a transaction and object identifier into a + * large object identity. Does not affect the database. + * @param o Object identifier for the given object. + */ + [[deprecated("Use blob instead.")]] explicit largeobject(oid o) noexcept : + m_id{o} + {} + + /// Import large object from a local file. + /** Creates a large object containing the data found in the given file. + * @param t Backend transaction in which the large object is to be created. + * @param file A filename on the client program's filesystem. + */ + [[deprecated("Use blob instead.")]] largeobject( + dbtransaction &t, std::string_view file); + + /// Take identity of an opened large object. + /** Copy identity of already opened large object. Note that this may be done + * as an implicit conversion. + * @param o Already opened large object to copy identity from. + */ + [[deprecated("Use blob instead.")]] largeobject( + largeobjectaccess const &o) noexcept; + + /// Object identifier. + /** The number returned by this function identifies the large object in the + * database we're connected to (or oid_none is returned if we refer to the + * null object). + */ + [[nodiscard]] oid id() const noexcept { return m_id; } + + /** + * @name Identity comparisons + * + * These operators compare the object identifiers of large objects. This has + * nothing to do with the objects' actual contents; use them only for keeping + * track of containers of references to large objects and such. + */ + //@{ + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator==(largeobject const &other) const + { + return m_id == other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator!=(largeobject const &other) const + { + return m_id != other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator<=(largeobject const &other) const + { + return m_id <= other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator>=(largeobject const &other) const + { + return m_id >= other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator<(largeobject const &other) const + { + return m_id < other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator>(largeobject const &other) const + { + return m_id > other.m_id; + } + //@} + + /// Export large object's contents to a local file + /** Writes the data stored in the large object to the given file. + * @param t Transaction in which the object is to be accessed + * @param file A filename on the client's filesystem + */ + void to_file(dbtransaction &t, std::string_view file) const; + + /// Delete large object from database + /** Unlike its low-level equivalent cunlink, this will throw an exception if + * deletion fails. + * @param t Transaction in which the object is to be deleted + */ + void remove(dbtransaction &t) const; + +protected: + PQXX_PURE static internal::pq::PGconn * + raw_connection(dbtransaction const &T); + + PQXX_PRIVATE std::string reason(connection const &, int err) const; + +private: + oid m_id = oid_none; +}; + + +/// Accessor for large object's contents. +/** @deprecated Use the `blob` class instead. + */ +class PQXX_LIBEXPORT largeobjectaccess : private largeobject +{ +public: + using largeobject::size_type; + using off_type = size_type; + using pos_type = size_type; + + /// Open mode: `in`, `out` (can be combined using "bitwise or"). + /** According to the C++ standard, these should be in `std::ios_base`. We + * take them from derived class `std::ios` instead, which is easier on the + * eyes. + * + * Historical note: taking it from std::ios was originally a workaround for a + * problem with gcc 2.95. + */ + using openmode = std::ios::openmode; + + /// Default open mode: in, out, binary. + static constexpr auto default_mode{ + std::ios::in | std::ios::out | std::ios::binary}; + + /// Seek direction: `beg`, `cur`, `end`. + using seekdir = std::ios::seekdir; + + /// Create new large object and open it. + /** + * @param t Backend transaction in which the object is to be created. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] explicit largeobjectaccess( + dbtransaction &t, openmode mode = default_mode); + + /// Open large object with given oid. + /** Convert combination of a transaction and object identifier into a + * large object identity. Does not affect the database. + * @param t Transaction in which the object is to be accessed. + * @param o Object identifier for the given object. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, oid o, openmode mode = default_mode); + + /// Open given large object. + /** Open a large object with the given identity for reading and/or writing. + * @param t Transaction in which the object is to be accessed. + * @param o Identity for the large object to be accessed. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, largeobject o, openmode mode = default_mode); + + /// Import large object from a local file and open it. + /** Creates a large object containing the data found in the given file. + * @param t Backend transaction in which the large object is to be created. + * @param file A filename on the client program's filesystem. + * @param mode Access mode, defaults to ios_base::in | ios_base::out. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, std::string_view file, openmode mode = default_mode); + + ~largeobjectaccess() noexcept { close(); } + + /// Object identifier. + /** The number returned by this function uniquely identifies the large object + * in the context of the database we're connected to. + */ + using largeobject::id; + + /// Export large object's contents to a local file. + /** Writes the data stored in the large object to the given file. + * @param file A filename on the client's filesystem. + */ + void to_file(std::string_view file) const + { + largeobject::to_file(m_trans, file); + } + + using largeobject::to_file; + + /** + * @name High-level access to object contents. + */ + //@{ + /// Write data to large object. + /** @warning The size of a write is currently limited to 2GB. + * + * @param buf Data to write. + * @param len Number of bytes from Buf to write. + */ + void write(char const buf[], std::size_t len); + + /// Write string to large object. + /** If not all bytes could be written, an exception is thrown. + * @param buf Data to write; no terminating zero is written. + */ + void write(std::string_view buf) { write(std::data(buf), std::size(buf)); } + + /// Read data from large object. + /** Throws an exception if an error occurs while reading. + * @param buf Location to store the read data in. + * @param len Number of bytes to try and read. + * @return Number of bytes read, which may be less than the number requested + * if the end of the large object is reached. + */ + size_type read(char buf[], std::size_t len); + + /// Seek in large object's data stream. + /** Throws an exception if an error occurs. + * @return The new position in the large object + */ + size_type seek(size_type dest, seekdir dir); + + /// Report current position in large object's data stream. + /** Throws an exception if an error occurs. + * @return The current position in the large object. + */ + [[nodiscard]] size_type tell() const; + //@} + + /** + * @name Low-level access to object contents. + * + * These functions provide a more "C-like" access interface, returning + * special values instead of throwing exceptions on error. These functions + * are generally best avoided in favour of the high-level access functions, + * which behave more like C++ functions should. + * + * Due to libpq's underlying API, some operations are limited to "int" + * sizes, typically 2 GB, even though a large object can grow much larger. + */ + //@{ + /// Seek in large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param dest Offset to go to. + * @param dir Origin to which dest is relative: ios_base::beg (from beginning + * of the object), ios_base::cur (from current access position), or + * ios_base;:end (from end of object). + * @return New position in large object, or -1 if an error occurred. + */ + pos_type cseek(off_type dest, seekdir dir) noexcept; + + /// Write to large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param buf Data to write. + * @param len Number of bytes to write. + * @return Number of bytes actually written, or -1 if an error occurred. + */ + off_type cwrite(char const buf[], std::size_t len) noexcept; + + /// Read from large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param buf Area where incoming bytes should be stored. + * @param len Number of bytes to read. + * @return Number of bytes actually read, or -1 if an error occurred.. + */ + off_type cread(char buf[], std::size_t len) noexcept; + + /// Report current position in large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @return Current position in large object, of -1 if an error occurred. + */ + [[nodiscard]] pos_type ctell() const noexcept; + //@} + + /** + * @name Error/warning output + */ + //@{ + /// Issue message to transaction's notice processor. + void process_notice(zview) noexcept; + //@} + + using largeobject::remove; + + using largeobject::operator==; + using largeobject::operator!=; + using largeobject::operator<; + using largeobject::operator<=; + using largeobject::operator>; + using largeobject::operator>=; + + largeobjectaccess() = delete; + largeobjectaccess(largeobjectaccess const &) = delete; + largeobjectaccess operator=(largeobjectaccess const &) = delete; + +private: + PQXX_PRIVATE std::string reason(int err) const; + internal::pq::PGconn *raw_connection() const + { + return largeobject::raw_connection(m_trans); + } + + PQXX_PRIVATE void open(openmode mode); + void close() noexcept; + + dbtransaction &m_trans; + int m_fd = -1; +}; + + +/// Streambuf to use large objects in standard I/O streams. +/** @deprecated Access large objects directly using the @ref blob class. + * + * The standard streambuf classes provide uniform access to data storage such + * as files or string buffers, so they can be accessed using standard input or + * output streams. This streambuf implementation provided similar access to + * large objects, so they could be read and written using the same stream + * classes. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class largeobject_streambuf : public std::basic_streambuf +{ + using size_type = largeobject::size_type; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + using openmode = largeobjectaccess::openmode; + using seekdir = largeobjectaccess::seekdir; + + /// Default open mode: in, out, binary. + static constexpr auto default_mode{ + std::ios::in | std::ios::out | std::ios::binary}; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + [[deprecated("Use blob instead.")]] largeobject_streambuf( + dbtransaction &t, largeobject o, openmode mode = default_mode, + size_type buf_size = 512) : + m_bufsize{buf_size}, m_obj{t, o, mode}, m_g{nullptr}, m_p{nullptr} + { + initialize(mode); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + [[deprecated("Use blob instead.")]] largeobject_streambuf( + dbtransaction &t, oid o, openmode mode = default_mode, + size_type buf_size = 512) : + m_bufsize{buf_size}, m_obj{t, o, mode}, m_g{nullptr}, m_p{nullptr} + { + initialize(mode); + } + + virtual ~largeobject_streambuf() noexcept + { + delete[] m_p; + delete[] m_g; + } + + /// For use by large object stream classes. + void process_notice(zview const &s) { m_obj.process_notice(s); } + +protected: + virtual int sync() override + { + // setg() sets eback, gptr, egptr. + this->setg(this->eback(), this->eback(), this->egptr()); + return overflow(eof()); + } + + virtual pos_type seekoff(off_type offset, seekdir dir, openmode) override + { + return adjust_eof(m_obj.cseek(largeobjectaccess::off_type(offset), dir)); + } + + virtual pos_type seekpos(pos_type pos, openmode) override + { + largeobjectaccess::pos_type const newpos{ + m_obj.cseek(largeobjectaccess::off_type(pos), std::ios::beg)}; + return adjust_eof(newpos); + } + + virtual int_type overflow(int_type ch) override + { + auto *const pp{this->pptr()}; + if (pp == nullptr) + return eof(); + auto *const pb{this->pbase()}; + int_type res{0}; + + if (pp > pb) + { + auto const write_sz{pp - pb}; + auto const written_sz{ + m_obj.cwrite(pb, static_cast(pp - pb))}; + if (internal::cmp_less_equal(written_sz, 0)) + throw internal_error{ + "pqxx::largeobject: write failed " + "(is transaction still valid on write or flush?), " + "libpq reports error"}; + else if (write_sz != written_sz) + throw internal_error{ + "pqxx::largeobject: write failed " + "(is transaction still valid on write or flush?), " + + std::to_string(written_sz) + "/" + std::to_string(write_sz) + + " bytes written"}; + auto const out{adjust_eof(written_sz)}; + + if constexpr (std::is_arithmetic_v) + res = check_cast(out, "largeobject position"sv); + else + res = int_type(out); + } + this->setp(m_p, m_p + m_bufsize); + + // Write that one more character, if it's there. + if (ch != eof()) + { + *this->pptr() = static_cast(ch); + this->pbump(1); + } + return res; + } + + virtual int_type overflow() { return overflow(eof()); } + + virtual int_type underflow() override + { + if (this->gptr() == nullptr) + return eof(); + auto *const eb{this->eback()}; + auto const res{adjust_eof( + m_obj.cread(this->eback(), static_cast(m_bufsize)))}; + this->setg( + eb, eb, eb + (res == eof() ? 0 : static_cast(res))); + return (res == eof() or res == 0) ? eof() : traits_type::to_int_type(*eb); + } + +private: + /// Shortcut for traits_type::eof(). + static int_type eof() { return traits_type::eof(); } + + /// Helper: change error position of -1 to EOF (probably a no-op). + template static std::streampos adjust_eof(INTYPE pos) + { + bool const at_eof{pos == -1}; + if constexpr (std::is_arithmetic_v) + { + return check_cast( + (at_eof ? eof() : pos), "large object seek"sv); + } + else + { + return std::streampos(at_eof ? eof() : pos); + } + } + + void initialize(openmode mode) + { + if ((mode & std::ios::in) != 0) + { + m_g = new char_type[unsigned(m_bufsize)]; + this->setg(m_g, m_g, m_g); + } + if ((mode & std::ios::out) != 0) + { + m_p = new char_type[unsigned(m_bufsize)]; + this->setp(m_p, m_p + m_bufsize); + } + } + + size_type const m_bufsize; + largeobjectaccess m_obj; + + /// Get & put buffers. + char_type *m_g, *m_p; +}; + + +/// Input stream that gets its data from a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This class worked like any other istream, but to read data from a large + * object. It supported all formatting and streaming operations of + * `std::istream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_ilostream : public std::basic_istream +{ + using super = std::basic_istream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create a basic_ilostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_ilostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::in | std::ios::binary, buf_size} + { + super::init(&m_buf); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// Create a basic_ilostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Identifier of a large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_ilostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::in | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + +private: + largeobject_streambuf m_buf; +}; + +using ilostream = basic_ilostream; + + +/// Output stream that writes data back to a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This worked like any other ostream, but to write data to a large object. + * It supported all formatting and streaming operations of `std::ostream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_olostream : public std::basic_ostream +{ + using super = std::basic_ostream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create a basic_olostream. + /** + * @param t transaction in which this stream is to exist. + * @param o a large object to access. + * @param buf_size size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_olostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// Create a basic_olostream. + /** + * @param t transaction in which this stream is to exist. + * @param o a large object to access. + * @param buf_size size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_olostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + ~basic_olostream() + { + try + { + m_buf.pubsync(); + m_buf.pubsync(); + } + catch (std::exception const &e) + { + m_buf.process_notice(e.what()); + } + } + +private: + largeobject_streambuf m_buf; +}; + +using olostream = basic_olostream; + + +/// Stream that reads and writes a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This worked like a std::iostream, but to read data from, or write data to, a + * large object. It supported all formatting and streaming operations of + * `std::iostream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_lostream : public std::basic_iostream +{ + using super = std::basic_iostream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + + /// Create a basic_lostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_lostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{ + t, o, std::ios::in | std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + /// Create a basic_lostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_lostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{ + t, o, std::ios::in | std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + ~basic_lostream() + { + try + { + m_buf.pubsync(); + m_buf.pubsync(); + } + catch (std::exception const &e) + { + m_buf.process_notice(e.what()); + } + } + +private: + largeobject_streambuf m_buf; +}; + +using lostream = basic_lostream; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/nontransaction b/ext/libpqxx-7.7.3/include/pqxx/nontransaction new file mode 100644 index 000000000..bb5b79724 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/nontransaction @@ -0,0 +1,8 @@ +/** pqxx::nontransaction class. + * + * pqxx::nontransaction provides nontransactional database access. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/nontransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/nontransaction.hxx b/ext/libpqxx-7.7.3/include/pqxx/nontransaction.hxx new file mode 100644 index 000000000..c50715594 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/nontransaction.hxx @@ -0,0 +1,76 @@ +/* Definition of the pqxx::nontransaction class. + * + * pqxx::nontransaction provides nontransactional database access + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/nontransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_NONTRANSACTION +#define PQXX_H_NONTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/connection.hxx" +#include "pqxx/result.hxx" +#include "pqxx/transaction.hxx" + +namespace pqxx +{ +using namespace std::literals; + +/// Simple "transaction" class offering no transactional integrity. +/** + * @ingroup transactions + * + * nontransaction, like transaction or any other transaction_base-derived + * class, provides access to a database through a connection. Unlike its + * siblings, however, nontransaction does not maintain any kind of + * transactional integrity. This may be useful eg. for read-only access to the + * database that does not require a consistent, atomic view on its data; or for + * operations that are not allowed within a backend transaction, such as + * creating tables. + * + * For queries that update the database, however, a real transaction is likely + * to be faster unless the transaction consists of only a single record update. + * + * Also, you can keep a nontransaction open for as long as you like. Actual + * back-end transactions are limited in lifespan, and will sometimes fail just + * because they took too long to execute or were left idle for too long. This + * will not happen with a nontransaction (although the connection may still + * time out, e.g. when the network is unavailable for a very long time). + * + * Any query executed in a nontransaction is committed immediately, and neither + * commit() nor abort() has any effect. + * + * Database features that require a backend transaction, such as cursors or + * large objects, will not work in a nontransaction. + */ +class PQXX_LIBEXPORT nontransaction final : public transaction_base +{ +public: + /// Constructor. + /** Create a "dummy" transaction. + * @param c Connection in which this "transaction" will operate. + * @param tname Optional tname for the transaction, beginning with a letter + * and containing only letters and digits. + */ + nontransaction(connection &c, std::string_view tname = ""sv) : + transaction_base{c, tname, std::shared_ptr{}} + { + register_transaction(); + } + + virtual ~nontransaction() override { close(); } + +private: + virtual void do_commit() override {} +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/notification b/ext/libpqxx-7.7.3/include/pqxx/notification new file mode 100644 index 000000000..a0bd1c73e --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/notification @@ -0,0 +1,8 @@ +/** pqxx::notification_receiver functor interface. + * + * pqxx::notification_receiver handles incoming notifications. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/notification.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/notification.hxx b/ext/libpqxx-7.7.3/include/pqxx/notification.hxx new file mode 100644 index 000000000..b59b8567a --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/notification.hxx @@ -0,0 +1,94 @@ +/* Definition of the pqxx::notification_receiver functor interface. + * + * pqxx::notification_receiver handles incoming notifications. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/notification instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_NOTIFICATION +#define PQXX_H_NOTIFICATION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/types.hxx" + + +namespace pqxx +{ +/// "Observer" base class for notifications. +/** @addtogroup notification Notifications and Receivers + * + * To listen on a notification issued using the NOTIFY command, derive your own + * class from notification_receiver and define its function-call operator to + * perform whatever action you wish to take when the given notification + * arrives. Then create an object of that class and pass it to your connection. + * DO NOT use raw SQL to listen for notifications, or your attempts to listen + * won't be resumed when a connection fails--and you'll have no way to notice. + * + * Notifications never arrive inside a transaction, not even in a + * nontransaction. Therefore, you are free to open a transaction of your own + * inside your receiver's function invocation operator. + * + * Notifications you are listening for may arrive anywhere within libpqxx code, + * but be aware that **PostgreSQL defers notifications occurring inside + * transactions.** (This was done for excellent reasons; just think about what + * happens if the transaction where you happen to handle an incoming + * notification is later rolled back for other reasons). So if you're keeping + * a transaction open, don't expect any of your receivers on the same + * connection to be notified. + * + * (For very similar reasons, outgoing notifications are also not sent until + * the transaction that sends them commits.) + * + * Multiple receivers on the same connection may listen on a notification of + * the same name. An incoming notification is processed by invoking all + * receivers (zero or more) of the same name. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE notification_receiver +{ +public: + /// Register the receiver with a connection. + /** + * @param c Connnection to operate on. + * @param channel Name of the notification to listen for. + */ + notification_receiver(connection &c, std::string_view channel); + /// Register the receiver with a connection. + notification_receiver(notification_receiver const &) = delete; + /// Register the receiver with a connection. + notification_receiver &operator=(notification_receiver const &) = delete; + /// Deregister the receiver. + virtual ~notification_receiver(); + + /// The channel that this receiver listens on. + [[nodiscard]] std::string const &channel() const & { return m_channel; } + + // TODO: Change API to take payload as zview instead of string ref. + /// Overridable: action to invoke when notification arrives. + /** + * @param payload An optional string that may have been passed to the NOTIFY + * command. + * @param backend_pid Process ID of the database backend process that served + * our connection when the notification arrived. The actual process ID + * behind the connection may have changed by the time this method is called. + */ + virtual void operator()(std::string const &payload, int backend_pid) = 0; + +protected: + connection &conn() const noexcept { return m_conn; } + +private: + connection &m_conn; + std::string m_channel; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/params b/ext/libpqxx-7.7.3/include/pqxx/params new file mode 100644 index 000000000..4098782aa --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/params @@ -0,0 +1,8 @@ +/** Helper classes for passing statement parameters. + * + * Use these for prepared statements and parameterised statements. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/params.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/params.hxx b/ext/libpqxx-7.7.3/include/pqxx/params.hxx new file mode 100644 index 000000000..2d29cdfed --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/params.hxx @@ -0,0 +1,383 @@ +/* Helpers for prepared statements and parameterised statements. + * + * See the connection class for more about such statements. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_PARAMS +#define PQXX_H_PARAMS + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/statement_parameters.hxx" +#include "pqxx/types.hxx" + + +/// @deprecated The new @ref params class replaces all of this. +namespace pqxx::prepare +{ +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * sequence ranging from `begin` to `end` exclusively. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic sequences. + * + * @param begin A pointer or iterator for iterating parameters. + * @param end A pointer or iterator for iterating parameters. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(IT begin, IT end) +{ + return pqxx::internal::dynamic_params(begin, end); +} + + +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * container of parameter values. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic containers. + * + * @param container A container of parameter values. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(C const &container) +{ + using IT = typename C::const_iterator; +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return pqxx::internal::dynamic_params{container}; +#include "pqxx/internal/ignore-deprecated-post.hxx" +} + + +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * container of parameter values. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic containers. + * + * @param container A container of parameter values. + * @param accessor For each parameter `p`, pass `accessor(p)`. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(C &container, ACCESSOR accessor) +{ + using IT = decltype(std::begin(container)); +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return pqxx::internal::dynamic_params{container, accessor}; +#include "pqxx/internal/ignore-deprecated-post.hxx" +} +} // namespace pqxx::prepare + + +namespace pqxx +{ +/// Generate parameter placeholders for use in an SQL statement. +/** When you want to pass parameters to a prepared statement or a parameterised + * statement, you insert placeholders into the SQL. During invocation, the + * database replaces those with the respective parameter values you passed. + * + * The placeholders look like `$1` (for the first parameter value), `$2` (for + * the second), and so on. You can just write those directly in your + * statement. But for those rare cases where it becomes difficult to track + * which number a placeholder should have, you can use a `placeholders` object + * to count and generate them in order. + */ +template class placeholders +{ +public: + /// Maximum number of parameters we support. + static inline constexpr unsigned int max_params{ + (std::numeric_limits::max)()}; + + placeholders() + { + static constexpr auto initial{"$1\0"sv}; + initial.copy(std::data(m_buf), std::size(initial)); + } + + /// Read an ephemeral version of the current placeholder text. + /** @warning Changing the current placeholder number will overwrite this. + * Use the view immediately, or lose it. + */ + constexpr zview view() const &noexcept + { + return zview{std::data(m_buf), m_len}; + } + + /// Read the current placeholder text, as a `std::string`. + /** This will be slightly slower than converting to a `zview`. With most + * C++ implementations however, until you get into ridiculous numbers of + * parameters, the string will benefit from the Short String Optimization, or + * SSO. + */ + std::string get() const { return std::string(std::data(m_buf), m_len); } + + /// Move on to the next parameter. + void next() & + { + if (m_current >= max_params) + throw range_error{pqxx::internal::concat( + "Too many parameters in one statement: limit is ", max_params, ".")}; + ++m_current; + if (m_current % 10 == 0) + { + // Carry the 1. Don't get too clever for this relatively rare + // case, just rewrite the entire number. Leave the $ in place + // though. + char *const data{std::data(m_buf)}; + char *const end{string_traits::into_buf( + data + 1, data + std::size(m_buf), m_current)}; + // (Subtract because we don't include the trailing zero.) + m_len = check_cast(end - data, "placeholders counter") - 1; + } + else + { + PQXX_LIKELY + // Shortcut for the common case: just increment that last digit. + ++m_buf[m_len - 1]; + } + } + + /// Return the current placeholder number. The initial placeholder is 1. + COUNTER count() const noexcept { return m_current; } + +private: + /// Current placeholder number. Starts at 1. + COUNTER m_current = 1; + + /// Length of the current placeholder string, not including trailing zero. + COUNTER m_len = 2; + + /// Text buffer where we render the placeholders, with a trailing zero. + /** We keep reusing this for every subsequent placeholder, just because we + * don't like string allocations. + * + * Maximum length is the maximum base-10 digits that COUNTER can fully + * represent, plus 1 more for the extra digit that it can only partially + * fill up, plus room for the dollar sign and the trailing zero. + */ + std::array::digits10 + 3> m_buf; +}; + + +/// Build a parameter list for a parameterised or prepared statement. +/** When calling a parameterised statement or a prepared statement, you can + * pass parameters into the statement directly in the invocation, as + * additional arguments to `exec_prepared` or `exec_params`. But in + * complex cases, sometimes that's just not convenient. + * + * In those situations, you can create a `params` and append your parameters + * into that, one by one. Then you pass the `params` to `exec_prepared` or + * `exec_params`. + * + * Combinations also work: if you have a `params` containing a string + * parameter, and you call `exec_params` with an `int` argument followed by + * your `params`, you'll be passing the `int` as the first parameter and + * the string as the second. You can even insert a `params` in a `params`, + * or pass two `params` objects to a statement. + */ +class PQXX_LIBEXPORT params +{ +public: + params() = default; + + /// Pre-populate a `params` with `args`. Feel free to add more later. + template constexpr params(Args &&...args) + { + reserve(sizeof...(args)); + append_pack(std::forward(args)...); + } + + /// Pre-allocate room for at least `n` parameters. + /** This is not needed, but it may improve efficiency. + * + * Reserve space if you're going to add parameters individually, and you've + * got some idea of how many there are going to be. It may save some + * memory re-allocations. + */ + void reserve(std::size_t n) &; + + // C++20: constexpr. + /// Get the number of parameters currently in this `params`. + [[nodiscard]] auto size() const noexcept { return m_params.size(); } + + // C++20: Use the vector's ssize() directly and go noexcept+constexpr. + /// Get the number of parameters (signed). + /** Unlike `size()`, this is not yet `noexcept`. That's because C++17's + * `std::vector` does not have a `ssize()` member function. These member + * functions are `noexcept`, but `std::size()` and `std::ssize()` are + * not. + */ + [[nodiscard]] auto ssize() const { return pqxx::internal::ssize(m_params); } + + /// Append a null value. + void append() &; + + /// Append a non-null zview parameter. + /** The underlying data must stay valid for as long as the `params` + * remains active. + */ + void append(zview) &; + + /// Append a non-null string parameter. + /** Copies the underlying data into internal storage. For best efficiency, + * use the @ref zview variant if you can, or `std::move()` + */ + void append(std::string const &) &; + + /// Append a non-null string parameter. + void append(std::string &&) &; + + /// Append a non-null binary parameter. + /** The underlying data must stay valid for as long as the `params` + * remains active. + */ + void append(std::basic_string_view) &; + + /// Append a non-null binary parameter. + /** Copies the underlying data into internal storage. For best efficiency, + * use the `std::basic_string_view` variant if you can, or + * `std::move()`. + */ + void append(std::basic_string const &) &; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Append a non-null binary parameter. + /** The `data` object must stay in place and unchanged, for as long as the + * `params` remains active. + */ + template void append(DATA const &data) & + { + append( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif // PQXX_HAVE_CONCEPTS + + /// Append a non-null binary parameter. + void append(std::basic_string &&) &; + + /// @deprecated Append binarystring parameter. + /** The binarystring must stay valid for as long as the `params` remains + * active. + */ + void append(binarystring const &value) &; + + /// Append all parameters from value. + template + void append(pqxx::internal::dynamic_params const &value) & + { + for (auto ¶m : value) append(value.access(param)); + } + + void append(params const &value) &; + + void append(params &&value) &; + + /// Append a non-null parameter, converting it to its string + /// representation. + template void append(TYPE const &value) & + { + // TODO: Pool storage for multiple string conversions in one buffer? + if constexpr (nullness>::always_null) + { + ignore_unused(value); + m_params.emplace_back(); + } + else if (is_null(value)) + { + m_params.emplace_back(); + } + else + { + m_params.emplace_back(entry{to_string(value)}); + } + } + + /// Append all elements of `range` as parameters. + template void append_multi(RANGE const &range) & + { +#if defined(PQXX_HAVE_CONCEPTS) + if constexpr (std::ranges::sized_range) + reserve(std::size(*this) + std::size(range)); +#endif + for (auto &value : range) append(value); + } + + /// For internal use: Generate a `params` object for use in calls. + /** The params object encapsulates the pointers which we will need to pass + * to libpq when calling a parameterised or prepared statement. + * + * The pointers in the params will refer to storage owned by either the + * params object, or the caller. This is not a problem because a + * `c_params` object is guaranteed to live only while the call is going on. + * As soon as we climb back out of that call tree, we're done with that + * data. + */ + pqxx::internal::c_params make_c_params() const; + +private: + /// Recursively append a pack of params. + template + void append_pack(Arg &&arg, More &&...args) + { + this->append(std::forward(arg)); + // Recurse for remaining args. + append_pack(std::forward(args)...); + } + + /// Terminating case: append an empty parameter pack. It's not hard BTW. + constexpr void append_pack() noexcept {} + + // The way we store a parameter depends on whether it's binary or text + // (most types are text), and whether we're responsible for storing the + // contents. + using entry = std::variant< + std::nullptr_t, zview, std::string, std::basic_string_view, + std::basic_string>; + std::vector m_params; + + static constexpr std::string_view s_overflow{ + "Statement parameter length overflow."sv}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/pipeline b/ext/libpqxx-7.7.3/include/pqxx/pipeline new file mode 100644 index 000000000..bf828843a --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/pipeline @@ -0,0 +1,8 @@ +/** pqxx::pipeline class. + * + * Throughput-optimized query interface. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/pipeline.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/pipeline.hxx b/ext/libpqxx-7.7.3/include/pqxx/pipeline.hxx new file mode 100644 index 000000000..049dcdd58 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/pipeline.hxx @@ -0,0 +1,237 @@ +/* Definition of the pqxx::pipeline class. + * + * Throughput-optimized mechanism for executing queries. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/pipeline instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_PIPELINE +#define PQXX_H_PIPELINE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +// TODO: libpq 14 introduced a similar "pipeline mode." Can we use that? + +/// Processes several queries in FIFO manner, optimized for high throughput. +/** Use a pipeline if you want to keep doing useful work while your queries are + * executing. Result retrieval is decoupled from execution request; queries + * "go in at the front" and results "come out the back." + * + * Actually, you can retrieve the results in any order if you want, but it may + * lead to surprising "time travel" effects if any of the queries fails. In + * particular, syntax errors in the queries can confuse things and show up too + * early in the stream of results. + * + * Generally, if any of the queries fails, it will throw an exception at the + * point where you request its result. But it may happen earlier, especially + * if you request results out of chronological order. + * + * @warning While a pipeline is active, you cannot execute queries, open + * streams, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT pipeline : public transaction_focus +{ +public: + /// Identifying numbers for queries. + using query_id = long; + + pipeline(pipeline const &) = delete; + pipeline &operator=(pipeline const &) = delete; + + /// Start a pipeline. + explicit pipeline(transaction_base &t) : transaction_focus{t, s_classname} + { + init(); + } + /// Start a pipeline. Assign it a name, for more helpful error messages. + pipeline(transaction_base &t, std::string_view tname) : + transaction_focus{t, s_classname, tname} + { + init(); + } + + /// Close the pipeline. + ~pipeline() noexcept; + + /// Add query to the pipeline. + /** Queries accumulate in the pipeline, which sends them to the backend in a + * batch separated by semicolons. The queries you insert must not use this + * trick themselves, or the pipeline will get hopelessly confused! + * + * @return Identifier for this query, unique only within this pipeline. + */ + query_id insert(std::string_view) &; + + /// Wait for all ongoing or pending operations to complete, and detach. + /** Detaches from the transaction when done. + * + * This does not produce the queries' results, so it may not report any + * errors which may have occurred in their execution. To be sure that your + * statements succeeded, call @ref retrieve until the pipeline is empty. + */ + void complete(); + + /// Forget all ongoing or pending operations and retrieved results. + /** Queries already sent to the backend may still be completed, depending + * on implementation and timing. + * + * Any error state (unless caused by an internal error) will also be cleared. + * This is mostly useful in a nontransaction, since a backend transaction is + * aborted automatically when an error occurs. + * + * Detaches from the transaction when done. + */ + void flush(); + + /// Cancel ongoing query, if any. + /** May cancel any or all of the queries that have been inserted at this + * point whose results have not yet been retrieved. If the pipeline lives in + * a backend transaction, that transaction may be left in a nonfunctional + * state in which it can only be aborted. + * + * Therefore, either use this function in a nontransaction, or abort the + * transaction after calling it. + */ + void cancel(); + + /// Is result for given query available? + [[nodiscard]] bool is_finished(query_id) const; + + /// Retrieve result for given query. + /** If the query failed for whatever reason, this will throw an exception. + * The function will block if the query has not finished yet. + * @warning If results are retrieved out-of-order, i.e. in a different order + * than the one in which their queries were inserted, errors may "propagate" + * to subsequent queries. + */ + result retrieve(query_id qid) + { + return retrieve(m_queries.find(qid)).second; + } + + /// Retrieve oldest unretrieved result (possibly wait for one). + /** @return The query's identifier and its result set. */ + std::pair retrieve(); + + [[nodiscard]] bool empty() const noexcept { return std::empty(m_queries); } + + /// Set maximum number of queries to retain before issuing them to the + /// backend. + /** The pipeline will perform better if multiple queries are issued at once, + * but retaining queries until the results are needed (as opposed to issuing + * them to the backend immediately) may negate any performance benefits the + * pipeline can offer. + * + * Recommended practice is to set this value no higher than the number of + * queries you intend to insert at a time. + * @param retain_max A nonnegative "retention capacity;" passing zero will + * cause queries to be issued immediately + * @return Old retention capacity + */ + int retain(int retain_max = 2) &; + + + /// Resume retained query emission. Harmless when not needed. + void resume() &; + +private: + struct PQXX_PRIVATE Query + { + explicit Query(std::string_view q) : + query{std::make_shared(q)} + {} + + std::shared_ptr query; + result res; + }; + + using QueryMap = std::map; + + void init(); + void attach(); + void detach(); + + /// Upper bound to query id's. + static constexpr query_id qid_limit() noexcept + { + // Parenthesise this to work around an eternal Visual C++ problem: + // Without the extra parentheses, unless NOMINMAX is defined, the + // preprocessor will mistake this "max" for its annoying built-in macro + // of the same name. + return (std::numeric_limits::max)(); + } + + /// Create new query_id. + PQXX_PRIVATE query_id generate_id(); + + bool have_pending() const noexcept + { + return m_issuedrange.second != m_issuedrange.first; + } + + PQXX_PRIVATE void issue(); + + /// The given query failed; never issue anything beyond that. + void set_error_at(query_id qid) noexcept + { + PQXX_UNLIKELY + if (qid < m_error) + m_error = qid; + } + + /// Throw pqxx::internal_error. + [[noreturn]] PQXX_PRIVATE void internal_error(std::string const &err); + + PQXX_PRIVATE bool obtain_result(bool expect_none = false); + + PQXX_PRIVATE void obtain_dummy(); + PQXX_PRIVATE void get_further_available_results(); + PQXX_PRIVATE void check_end_results(); + + /// Receive any results that happen to be available; it's not urgent. + PQXX_PRIVATE void receive_if_available(); + + /// Receive results, up to stop if possible. + PQXX_PRIVATE void receive(pipeline::QueryMap::const_iterator stop); + std::pair retrieve(pipeline::QueryMap::iterator); + + QueryMap m_queries; + std::pair m_issuedrange; + int m_retain = 0; + int m_num_waiting = 0; + query_id m_q_id = 0; + + /// Is there a "dummy query" pending? + bool m_dummy_pending = false; + + /// Point at which an error occurred; no results beyond it will be available + query_id m_error = qid_limit(); + + /// Encoding. + /** We store this in the object to avoid the risk of exceptions at awkward + * moments. + */ + internal::encoding_group m_encoding; + + static constexpr std::string_view s_classname{"pipeline"}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/pqxx b/ext/libpqxx-7.7.3/include/pqxx/pqxx new file mode 100644 index 000000000..17a8eaa9c --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/pqxx @@ -0,0 +1,28 @@ +/// Convenience header: include all libpqxx definitions. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/array.hxx" +#include "pqxx/binarystring.hxx" +#include "pqxx/blob.hxx" +#include "pqxx/connection.hxx" +#include "pqxx/cursor.hxx" +#include "pqxx/errorhandler.hxx" +#include "pqxx/except.hxx" +#include "pqxx/largeobject.hxx" +#include "pqxx/nontransaction.hxx" +#include "pqxx/notification.hxx" +#include "pqxx/params.hxx" +#include "pqxx/pipeline.hxx" +#include "pqxx/prepared_statement.hxx" +#include "pqxx/result.hxx" +#include "pqxx/internal/result_iterator.hxx" +#include "pqxx/internal/result_iter.hxx" +#include "pqxx/robusttransaction.hxx" +#include "pqxx/row.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/stream_to.hxx" +#include "pqxx/subtransaction.hxx" +#include "pqxx/transaction.hxx" +#include "pqxx/transactor.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/prepared_statement b/ext/libpqxx-7.7.3/include/pqxx/prepared_statement new file mode 100644 index 000000000..674be7090 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/prepared_statement @@ -0,0 +1,3 @@ +/// @deprecated Include @c instead. + +#include "params.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/prepared_statement.hxx b/ext/libpqxx-7.7.3/include/pqxx/prepared_statement.hxx new file mode 100644 index 000000000..674be7090 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/prepared_statement.hxx @@ -0,0 +1,3 @@ +/// @deprecated Include @c instead. + +#include "params.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/range b/ext/libpqxx-7.7.3/include/pqxx/range new file mode 100644 index 000000000..11985eca4 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/range @@ -0,0 +1,6 @@ +/** Client-side support for SQL range types. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/range.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/range.hxx b/ext/libpqxx-7.7.3/include/pqxx/range.hxx new file mode 100644 index 000000000..dc480e4b7 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/range.hxx @@ -0,0 +1,515 @@ +#ifndef PQXX_H_RANGE +#define PQXX_H_RANGE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/internal/array-composite.hxx" +#include "pqxx/internal/concat.hxx" + +namespace pqxx +{ +/// An _unlimited_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should extend + * to infinity on that side. + * + * An unlimited boundary is always inclusive of "infinity" values, if the + * range's value type supports them. + */ +struct no_bound +{ + template constexpr bool extends_down_to(TYPE const &) const + { + return true; + } + template constexpr bool extends_up_to(TYPE const &) const + { + return true; + } +}; + + +/// An _inclusive_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should include + * the value. + */ +template class inclusive_bound +{ +public: + inclusive_bound() = delete; + explicit inclusive_bound(TYPE const &value) : m_value{value} + { + if (is_null(value)) + throw argument_error{"Got null value as an inclusive range bound."}; + } + + [[nodiscard]] constexpr TYPE const &get() const &noexcept { return m_value; } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as a lower bound, include value? + [[nodiscard]] bool extends_down_to(TYPE const &value) const + { + return not(value < m_value); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as an upper bound, include value? + [[nodiscard]] bool extends_up_to(TYPE const &value) const + { + return not(m_value < value); + } + +private: + TYPE m_value; +}; + + +/// An _exclusive_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should _not_ + * include the value. + */ +template class exclusive_bound +{ +public: + exclusive_bound() = delete; + explicit exclusive_bound(TYPE const &value) : m_value{value} + { + if (is_null(value)) + throw argument_error{"Got null value as an exclusive range bound."}; + } + + [[nodiscard]] constexpr TYPE const &get() const &noexcept { return m_value; } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as a lower bound, include value? + [[nodiscard]] bool extends_down_to(TYPE const &value) const + { + return m_value < value; + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as an upper bound, include value? + [[nodiscard]] bool extends_up_to(TYPE const &value) const + { + return value < m_value; + } + +private: + TYPE m_value; +}; + + +/// A range boundary value. +/** A range bound is either no bound at all; or an inclusive bound; or an + * exclusive bound. Pass one of the three to the constructor. + */ +template class range_bound +{ +public: + range_bound() = delete; + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(no_bound) : m_bound{} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(inclusive_bound const &bound) : m_bound{bound} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(exclusive_bound const &bound) : m_bound{bound} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(range_bound const &) = default; + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(range_bound &&) = default; + + // TODO: constexpr and/or noexcept if underlying operators support it. + bool operator==(range_bound const &rhs) const + { + if (this->is_limited()) + return ( + rhs.is_limited() and (this->is_inclusive() == rhs.is_inclusive()) and + (*this->value() == *rhs.value())); + else + return not rhs.is_limited(); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + bool operator!=(range_bound const &rhs) const { return not(*this == rhs); } + range_bound &operator=(range_bound const &) = default; + range_bound &operator=(range_bound &&) = default; + + /// Is this a finite bound? + constexpr bool is_limited() const noexcept + { + return not std::holds_alternative(m_bound); + } + + /// Is this boundary an inclusive one? + constexpr bool is_inclusive() const noexcept + { + return std::holds_alternative>(m_bound); + } + + /// Is this boundary an exclusive one? + constexpr bool is_exclusive() const noexcept + { + return std::holds_alternative>(m_bound); + } + + // TODO: constexpr/noexcept if underlying function supports it. + /// Would this bound, as a lower bound, include `value`? + bool extends_down_to(TYPE const &value) const + { + return std::visit( + [&value](auto const &bound) { return bound.extends_down_to(value); }, + m_bound); + } + + // TODO: constexpr/noexcept if underlying function supports it. + /// Would this bound, as an upper bound, include `value`? + bool extends_up_to(TYPE const &value) const + { + return std::visit( + [&value](auto const &bound) { return bound.extends_up_to(value); }, + m_bound); + } + + /// Return bound value, or `nullptr` if it's not limited. + [[nodiscard]] constexpr TYPE const *value() const &noexcept + { + return std::visit( + [](auto const &bound) noexcept { + using bound_t = std::decay_t; + if constexpr (std::is_same_v) + return static_cast(nullptr); + else + return &bound.get(); + }, + m_bound); + } + +private: + std::variant, exclusive_bound> m_bound; +}; + + +// C++20: Concepts for comparisons, construction, etc. +/// A C++ equivalent to PostgreSQL's range types. +/** You can use this as a client-side representation of a "range" in SQL. + * + * PostgreSQL defines several range types, differing in the data type over + * which they range. You can also define your own range types. + * + * Usually you'll want the server to deal with ranges. But on occasions where + * you need to work with them client-side, you may want to use @ref + * pqxx::range. (In cases where all you do is pass them along to the server + * though, it's not worth the complexity. In that case you might as well treat + * ranges as just strings.) + * + * For documentation on PostgreSQL's range types, see: + * https://www.postgresql.org/docs/current/rangetypes.html + * + * The value type must be copyable and default-constructible, and support the + * less-than (`<`) and equals (`==`) comparisons. Value initialisation must + * produce a consistent value. + */ +template class range +{ +public: + /// Create a range. + /** For each of the two bounds, pass a @ref no_bound, @ref inclusive_bound, + * or + * @ref exclusive_bound. + */ + range(range_bound lower, range_bound upper) : + m_lower{lower}, m_upper{upper} + { + if ( + lower.is_limited() and upper.is_limited() and + (*upper.value() < *lower.value())) + throw range_error{internal::concat( + "Range's lower bound (", *lower.value(), + ") is greater than its upper bound (", *upper.value(), ").")}; + } + + // TODO: constexpr and/or noexcept if underlying constructor supports it. + /// Create an empty range. + /** SQL has a separate literal to denote an empty range, but any range which + * encompasses no values is an empty range. + */ + range() : + m_lower{exclusive_bound{TYPE{}}}, + m_upper{exclusive_bound{TYPE{}}} + {} + + // TODO: constexpr and/or noexcept if underlying operators support it. + bool operator==(range const &rhs) const + { + return (this->lower_bound() == rhs.lower_bound() and + this->upper_bound() == rhs.upper_bound()) or + (this->empty() and rhs.empty()); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + bool operator!=(range const &rhs) const { return !(*this == rhs); } + + range(range const &) = default; + range(range &&) = default; + range &operator=(range const &) = default; + range &operator=(range &&) = default; + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Is this range clearly empty? + /** An empty range encompasses no values. + * + * It is possible to "fool" this. For example, if your range is of an + * integer type and has exclusive bounds of 0 and 1, it encompasses no values + * but its `empty()` will return false. The PostgreSQL implementation, by + * contrast, will notice that it is empty. Similar things can happen for + * floating-point types, but with more subtleties and edge cases. + */ + bool empty() const + { + return (m_lower.is_exclusive() or m_upper.is_exclusive()) and + m_lower.is_limited() and m_upper.is_limited() and + not(*m_lower.value() < *m_upper.value()); + } + + // TODO: constexpr and/or noexcept if underlying functions support it. + /// Does this range encompass `value`? + bool contains(TYPE value) const + { + return m_lower.extends_down_to(value) and m_upper.extends_up_to(value); + } + + // TODO: constexpr and/or noexcept if underlying operators support it. + /// Does this range encompass all of `other`? + /** This function is not particularly smart. It does not know, for example, + * that integer ranges `[0,9]` and `[0,10)` contain the same values. + */ + bool contains(range const &other) const + { + return (*this & other) == other; + } + + [[nodiscard]] constexpr range_bound const & + lower_bound() const &noexcept + { + return m_lower; + } + [[nodiscard]] constexpr range_bound const & + upper_bound() const &noexcept + { + return m_upper; + } + + // TODO: constexpr and/or noexcept if underlying operators support it. + /// Intersection of two ranges. + /** Returns a range describing those values which are in both ranges. + */ + range operator&(range const &other) const + { + range_bound lower{no_bound{}}; + if (not this->lower_bound().is_limited()) + lower = other.lower_bound(); + else if (not other.lower_bound().is_limited()) + lower = this->lower_bound(); + else if (*this->lower_bound().value() < *other.lower_bound().value()) + lower = other.lower_bound(); + else if (*other.lower_bound().value() < *this->lower_bound().value()) + lower = this->lower_bound(); + else if (this->lower_bound().is_exclusive()) + lower = this->lower_bound(); + else + lower = other.lower_bound(); + + range_bound upper{no_bound{}}; + if (not this->upper_bound().is_limited()) + upper = other.upper_bound(); + else if (not other.upper_bound().is_limited()) + upper = this->upper_bound(); + else if (*other.upper_bound().value() < *this->upper_bound().value()) + upper = other.upper_bound(); + else if (*this->upper_bound().value() < *other.upper_bound().value()) + upper = this->upper_bound(); + else if (this->upper_bound().is_exclusive()) + upper = this->upper_bound(); + else + upper = other.upper_bound(); + + if ( + lower.is_limited() and upper.is_limited() and + (*upper.value() < *lower.value())) + return {}; + else + return {lower, upper}; + } + + /// Convert to another base type. + template operator range() const + { + range_bound lower{no_bound{}}, upper{no_bound{}}; + if (lower_bound().is_inclusive()) + lower = inclusive_bound{*lower_bound().value()}; + else if (lower_bound().is_exclusive()) + lower = exclusive_bound{*lower_bound().value()}; + + if (upper_bound().is_inclusive()) + upper = inclusive_bound{*upper_bound().value()}; + else if (upper_bound().is_exclusive()) + upper = exclusive_bound{*upper_bound().value()}; + + return {lower, upper}; + } + +private: + range_bound m_lower, m_upper; +}; + + +/// String conversions for a @ref range type. +/** Conversion assumes that either your client encoding is UTF-8, or the values + * are pure ASCII. + */ +template struct string_traits> +{ + [[nodiscard]] static inline zview + to_buf(char *begin, char *end, range const &value) + { + return generic_to_buf(begin, end, value); + } + + static inline char * + into_buf(char *begin, char *end, range const &value) + { + if (value.empty()) + { + if ((end - begin) <= internal::ssize(s_empty)) + throw conversion_overrun{s_overrun.c_str()}; + char *here = begin + s_empty.copy(begin, std::size(s_empty)); + *here++ = '\0'; + return here; + } + else + { + if (end - begin < 4) + throw conversion_overrun{s_overrun.c_str()}; + char *here = begin; + *here++ = + (static_cast(value.lower_bound().is_inclusive() ? '[' : '(')); + TYPE const *lower{value.lower_bound().value()}; + // Convert bound (but go back to overwrite that trailing zero). + if (lower != nullptr) + here = string_traits::into_buf(here, end, *lower) - 1; + *here++ = ','; + TYPE const *upper{value.upper_bound().value()}; + // Convert bound (but go back to overwrite that trailing zero). + if (upper != nullptr) + here = string_traits::into_buf(here, end, *upper) - 1; + if ((end - here) < 2) + throw conversion_overrun{s_overrun.c_str()}; + *here++ = + static_cast(value.upper_bound().is_inclusive() ? ']' : ')'); + *here++ = '\0'; + return here; + } + } + + [[nodiscard]] static inline range from_string(std::string_view text) + { + if (std::size(text) < 3) + throw pqxx::conversion_error{err_bad_input(text)}; + bool left_inc{false}; + switch (text[0]) + { + case '[': left_inc = true; break; + + case '(': break; + + case 'e': + case 'E': + if ( + (std::size(text) != std::size(s_empty)) or + (text[1] != 'm' and text[1] != 'M') or + (text[2] != 'p' and text[2] != 'P') or + (text[3] != 't' and text[3] != 'T') or + (text[4] != 'y' and text[4] != 'Y')) + throw pqxx::conversion_error{err_bad_input(text)}; + return {}; + break; + + default: throw pqxx::conversion_error{err_bad_input(text)}; + } + + auto scan{internal::get_glyph_scanner(internal::encoding_group::UTF8)}; + // The field parser uses this to track which field it's parsing, and + // when not to expect a field separator. + std::size_t index{0}; + // The last field we expect to see. + static constexpr std::size_t last{1}; + // Current parsing position. We skip the opening parenthesis or bracket. + std::size_t pos{1}; + // The string may leave out either bound to indicate that it's unlimited. + std::optional lower, upper; + // We reuse the same field parser we use for composite values and arrays. + internal::parse_composite_field(index, text, pos, lower, scan, last); + internal::parse_composite_field(index, text, pos, upper, scan, last); + + // We need one more character: the closing parenthesis or bracket. + if (pos != std::size(text)) + throw pqxx::conversion_error{err_bad_input(text)}; + char const closing{text[pos - 1]}; + if (closing != ')' and closing != ']') + throw pqxx::conversion_error{err_bad_input(text)}; + bool const right_inc{closing == ']'}; + + range_bound lower_bound{no_bound{}}, upper_bound{no_bound{}}; + if (lower) + { + if (left_inc) + lower_bound = inclusive_bound{*lower}; + else + lower_bound = exclusive_bound{*lower}; + } + if (upper) + { + if (right_inc) + upper_bound = inclusive_bound{*upper}; + else + upper_bound = exclusive_bound{*upper}; + } + + return {lower_bound, upper_bound}; + } + + [[nodiscard]] static inline constexpr std::size_t + size_buffer(range const &value) noexcept + { + TYPE const *lower{value.lower_bound().value()}, + *upper{value.upper_bound().value()}; + std::size_t const lsz{ + lower == nullptr ? 0 : string_traits::size_buffer(*lower) - 1}, + usz{upper == nullptr ? 0 : string_traits::size_buffer(*upper) - 1}; + + if (value.empty()) + return std::size(s_empty) + 1; + else + return 1 + lsz + 1 + usz + 2; + } + +private: + static constexpr zview s_empty{"empty"_zv}; + static constexpr auto s_overrun{"Not enough space in buffer for range."_zv}; + + /// Compose error message for invalid range input. + static std::string err_bad_input(std::string_view text) + { + return internal::concat("Invalid range input: '", text, "'"); + } +}; + + +/// A range type does not have an innate null value. +template struct nullness> : no_null> +{}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/result b/ext/libpqxx-7.7.3/include/pqxx/result new file mode 100644 index 000000000..523394b72 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/result @@ -0,0 +1,16 @@ +/** pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/result.hxx" + +// Now include some types which depend on result, but which the user will +// expect to see defined after including this header. +#include "pqxx/internal/result_iterator.hxx" +#include "pqxx/field.hxx" +#include "pqxx/internal/result_iter.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/result.hxx b/ext/libpqxx-7.7.3/include/pqxx/result.hxx new file mode 100644 index 000000000..6c41cc096 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/result.hxx @@ -0,0 +1,335 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT +#define PQXX_H_RESULT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include + +#include "pqxx/except.hxx" +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + +#include "pqxx/internal/encodings.hxx" + + +namespace pqxx::internal +{ +// TODO: Make noexcept (but breaks ABI). +PQXX_LIBEXPORT void clear_result(pq::PGresult const *); +} // namespace pqxx::internal + + +namespace pqxx::internal::gate +{ +class result_connection; +class result_creation; +class result_pipeline; +class result_row; +class result_sql_cursor; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Result set containing data returned by a query or command. +/** This behaves as a container (as defined by the C++ standard library) and + * provides random access const iterators to iterate over its rows. You can + * also access a row by indexing a `result R` by the row's zero-based + * number: + * + * + * for (result::size_type i=0; i < std::size(R); ++i) Process(R[i]); + * + * + * Result sets in libpqxx are lightweight, reference-counted wrapper objects + * which are relatively small and cheap to copy. Think of a result object as + * a "smart pointer" to an underlying result set. + * + * @warning The result set that a result object points to is not thread-safe. + * If you copy a result object, it still refers to the same underlying result + * set. So never copy, destroy, query, or otherwise access a result while + * another thread may be copying, destroying, querying, or otherwise accessing + * the same result set--even if it is doing so through a different result + * object! + */ +class PQXX_LIBEXPORT result +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + using reference = row; + using const_iterator = const_result_iterator; + using pointer = const_iterator; + using iterator = const_iterator; + using const_reverse_iterator = const_reverse_result_iterator; + using reverse_iterator = const_reverse_iterator; + + result() noexcept : + m_data{make_data_pointer()}, + m_query{}, + m_encoding{internal::encoding_group::MONOBYTE} + {} + + result(result const &rhs) noexcept = default; + result(result &&rhs) noexcept = default; + + /// Assign one result to another. + /** Copying results is cheap: it copies only smart pointers, but the actual + * data stays in the same place. + */ + result &operator=(result const &rhs) noexcept = default; + + /// Assign one result to another, invaliding the old one. + result &operator=(result &&rhs) noexcept = default; + + /** + * @name Comparisons + * + * You can compare results for equality. Beware: this is a very strict, + * dumb comparison. The smallest difference between two results (such as a + * string "Foo" versus a string "foo") will make them unequal. + */ + //@{ + /// Compare two results for equality. + [[nodiscard]] bool operator==(result const &) const noexcept; + /// Compare two results for inequality. + [[nodiscard]] bool operator!=(result const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + /// Iterate rows, reading them directly into a tuple of "TYPE...". + /** Converts the fields to values of the given respective types. + * + * Use this only with a ranged "for" loop. The iteration produces + * std::tuple which you can "unpack" to a series of `auto` + * variables. + */ + template auto iter() const; + + [[nodiscard]] const_reverse_iterator rbegin() const; + [[nodiscard]] const_reverse_iterator crbegin() const; + [[nodiscard]] const_reverse_iterator rend() const; + [[nodiscard]] const_reverse_iterator crend() const; + + [[nodiscard]] const_iterator begin() const noexcept; + [[nodiscard]] const_iterator cbegin() const noexcept; + [[nodiscard]] inline const_iterator end() const noexcept; + [[nodiscard]] inline const_iterator cend() const noexcept; + + [[nodiscard]] reference front() const noexcept; + [[nodiscard]] reference back() const noexcept; + + [[nodiscard]] PQXX_PURE size_type size() const noexcept; + [[nodiscard]] PQXX_PURE bool empty() const noexcept; + [[nodiscard]] size_type capacity() const noexcept { return size(); } + + /// Exchange two `result` values in an exception-safe manner. + /** If the swap fails, the two values will be exactly as they were before. + * + * The swap is not necessarily thread-safe. + */ + void swap(result &) noexcept; + + /// Index a row by number. + /** This returns a @ref row object. Generally you should not keep the row + * around as a variable, but if you do, make sure that your variable is a + * `row`, not a `row&`. + */ + [[nodiscard]] row operator[](size_type i) const noexcept; + +#if defined(PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT) + // TODO: If C++23 will let us, also accept string for the column. + [[nodiscard]] field + operator[](size_type row_num, row_size_type col_num) const noexcept; +#endif + + /// Index a row by number, but check that the row number is valid. + row at(size_type) const; + + /// Index a field by row number and column number. + field at(size_type, row_size_type) const; + + /// Let go of the result's data. + /** Use this if you need to deallocate the result data earlier than you can + * destroy the `result` object itself. + * + * Multiple `result` objects can refer to the same set of underlying data. + * The underlying data will be deallocated once all `result` objects that + * refer to it are cleared or destroyed. + */ + void clear() noexcept + { + m_data.reset(); + m_query = nullptr; + } + + /** + * @name Column information + */ + //@{ + /// Number of columns in result. + [[nodiscard]] PQXX_PURE row_size_type columns() const noexcept; + + /// Number of given column (throws exception if it doesn't exist). + [[nodiscard]] row_size_type column_number(zview name) const; + + /// Name of column with this number (throws exception if it doesn't exist) + [[nodiscard]] char const *column_name(row_size_type number) const &; + + /// Return column's type, as an OID from the system catalogue. + [[nodiscard]] oid column_type(row_size_type col_num) const; + + /// Return column's type, as an OID from the system catalogue. + [[nodiscard]] oid column_type(zview col_name) const + { + return column_type(column_number(col_name)); + } + + /// What table did this column come from? + [[nodiscard]] oid column_table(row_size_type col_num) const; + + /// What table did this column come from? + [[nodiscard]] oid column_table(zview col_name) const + { + return column_table(column_number(col_name)); + } + + /// What column in its table did this column come from? + [[nodiscard]] row_size_type table_column(row_size_type col_num) const; + + /// What column in its table did this column come from? + [[nodiscard]] row_size_type table_column(zview col_name) const + { + return table_column(column_number(col_name)); + } + //@} + + /// Query that produced this result, if available (empty string otherwise) + [[nodiscard]] PQXX_PURE std::string const &query() const &noexcept; + + /// If command was an `INSERT` of 1 row, return oid of the inserted row. + /** @return Identifier of inserted row if exactly one row was inserted, or + * @ref oid_none otherwise. + */ + [[nodiscard]] PQXX_PURE oid inserted_oid() const; + + /// If command was `INSERT`, `UPDATE`, or `DELETE`: number of affected rows. + /** @return Number of affected rows if last command was `INSERT`, `UPDATE`, + * or `DELETE`; zero for all other commands. + */ + [[nodiscard]] PQXX_PURE size_type affected_rows() const; + + // C++20: Concept like std::invocable, but without specifying param types. + /// Run `func` on each row, passing the row's fields as parameters. + /** Goes through the rows from first to last. You provide a callable `func`. + * + * For each row in the `result`, `for_each` will call `func`. It converts + * the row's fields to the types of `func`'s parameters, and pass them to + * `func`. + * + * (Therefore `func` must have a _single_ signature. It can't be a generic + * lambda, or an object of a class with multiple overloaded function call + * operators. Otherwise, `for_each` will have no way to detect a parameter + * list without ambiguity.) + * + * If any of your parameter types is `std::string_view`, it refers to the + * underlying storage of this `result`. + * + * If any of your parameter types is a reference type, its argument will + * refer to a temporary value which only lives for the duration of that + * single invocation to `func`. If the reference is an lvalue reference, it + * must be `const`. + * + * For example, this queries employee names and salaries from the database + * and prints how much each would like to earn instead: + * ```cxx + * tx.exec("SELECT name, salary FROM employee").for_each( + * [](std::string_view name, float salary){ + * std::cout << name << " would like " << salary * 2 << ".\n"; + * }) + * ``` + * + * If `func` throws an exception, processing stops at that point and + * propagates the exception. + * + * @throws usage_error if `func`'s number of parameters does not match the + * number of columns in this result. + */ + template inline void for_each(CALLABLE &&func) const; + +private: + using data_pointer = std::shared_ptr; + + /// Underlying libpq result set. + data_pointer m_data; + + /// Factory for data_pointer. + static data_pointer + make_data_pointer(internal::pq::PGresult const *res = nullptr) noexcept + { + return {res, internal::clear_result}; + } + + friend class pqxx::internal::gate::result_pipeline; + PQXX_PURE std::shared_ptr query_ptr() const noexcept + { + return m_query; + } + + /// Query string. + std::shared_ptr m_query; + + internal::encoding_group m_encoding; + + static std::string const s_empty_string; + + friend class pqxx::field; + // TODO: noexcept. Breaks ABI. + PQXX_PURE char const *get_value(size_type row, row_size_type col) const; + // TODO: noexcept. Breaks ABI. + PQXX_PURE bool get_is_null(size_type row, row_size_type col) const; + PQXX_PURE + field_size_type get_length(size_type, row_size_type) const noexcept; + + friend class pqxx::internal::gate::result_creation; + result( + internal::pq::PGresult *rhs, std::shared_ptr query, + internal::encoding_group enc); + + PQXX_PRIVATE void check_status(std::string_view desc = ""sv) const; + + friend class pqxx::internal::gate::result_connection; + friend class pqxx::internal::gate::result_row; + bool operator!() const noexcept { return m_data.get() == nullptr; } + operator bool() const noexcept { return m_data.get() != nullptr; } + + [[noreturn]] PQXX_PRIVATE void + throw_sql_error(std::string const &Err, std::string const &Query) const; + PQXX_PRIVATE PQXX_PURE int errorposition() const; + PQXX_PRIVATE std::string status_error() const; + + friend class pqxx::internal::gate::result_sql_cursor; + PQXX_PURE char const *cmd_status() const noexcept; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/robusttransaction b/ext/libpqxx-7.7.3/include/pqxx/robusttransaction new file mode 100644 index 000000000..04b71d7cc --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/robusttransaction @@ -0,0 +1,8 @@ +/** pqxx::robusttransaction class. + * + * pqxx::robusttransaction is a slower but safer transaction class. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/robusttransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/robusttransaction.hxx b/ext/libpqxx-7.7.3/include/pqxx/robusttransaction.hxx new file mode 100644 index 000000000..faf6dbf5e --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/robusttransaction.hxx @@ -0,0 +1,120 @@ +/* Definition of the pqxx::robusttransaction class. + * + * pqxx::robusttransaction is a slower but safer transaction class. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/robusttransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ROBUSTTRANSACTION +#define PQXX_H_ROBUSTTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx::internal +{ +/// Helper base class for the @ref robusttransaction class template. +class PQXX_LIBEXPORT PQXX_NOVTABLE basic_robusttransaction + : public dbtransaction +{ +public: + virtual ~basic_robusttransaction() override = 0; + +protected: + basic_robusttransaction( + connection &c, zview begin_command, std::string_view tname); + basic_robusttransaction(connection &c, zview begin_command); + +private: + using IDType = unsigned long; + + std::string m_conn_string; + std::string m_xid; + int m_backendpid = -1; + + void init(zview begin_command); + + // @warning This function will become `final`. + virtual void do_commit() override; +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @ingroup transactions + * + * @{ + */ + +/// Slightly slower, better-fortified version of transaction. +/** Requires PostgreSQL 10 or better. + * + * robusttransaction is similar to transaction, but spends more time and effort + * to deal with the hopefully rare case that the connection to the backend is + * lost just while it's trying to commit. In such cases, the client does not + * know whether the backend (on the other side of the broken connection) + * managed to commit the transaction. + * + * When this happens, robusttransaction tries to reconnect to the database and + * figure out what happened. + * + * This service level was made optional since you may not want to pay the + * overhead where it is not necessary. Certainly the use of this class makes + * no sense for local connections, or for transactions that read the database + * but never modify it, or for noncritical database manipulations. + * + * Besides being slower, it's also more complex. Which means that in practice + * a robusttransaction could actually fail more instead of less often than a + * normal transaction. What robusttransaction tries to achieve is to give you + * certainty, not just be more successful per se. + */ +template +class robusttransaction final : public internal::basic_robusttransaction +{ +public: + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + * @param tname optional human-readable name for this transaction. + */ + robusttransaction(connection &c, std::string_view tname) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd, + tname} + {} + + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + * @param tname optional human-readable name for this transaction. + */ + robusttransaction(connection &c, std::string &&tname) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd, + std::move(tname)} + {} + + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + */ + explicit robusttransaction(connection &c) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd} + {} + + virtual ~robusttransaction() noexcept override { close(); } +}; + +/** + * @} + */ +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/row b/ext/libpqxx-7.7.3/include/pqxx/row new file mode 100644 index 000000000..62a950ac8 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/row @@ -0,0 +1,11 @@ +/** pqxx::row class. + * + * pqxx::row refers to a row in a result. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/result.hxx" +#include "pqxx/row.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/row.hxx b/ext/libpqxx-7.7.3/include/pqxx/row.hxx new file mode 100644 index 000000000..5be5132e3 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/row.hxx @@ -0,0 +1,561 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ROW +#define PQXX_H_ROW + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/except.hxx" +#include "pqxx/field.hxx" +#include "pqxx/result.hxx" + +#include "pqxx/internal/concat.hxx" + +namespace pqxx::internal +{ +template class result_iter; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// Reference to one row in a result. +/** A row represents one row (also called a row) in a query result set. + * It also acts as a container mapping column numbers or names to field + * values (see below): + * + * ```cxx + * cout << row["date"].c_str() << ": " << row["name"].c_str() << endl; + * ``` + * + * The row itself acts like a (non-modifyable) container, complete with its + * own const_iterator and const_reverse_iterator. + */ +class PQXX_LIBEXPORT row +{ +public: + using size_type = row_size_type; + using difference_type = row_difference_type; + using const_iterator = const_row_iterator; + using iterator = const_iterator; + using reference = field; + using pointer = const_row_iterator; + using const_reverse_iterator = const_reverse_row_iterator; + using reverse_iterator = const_reverse_iterator; + + row() noexcept = default; + row(row &&) noexcept = default; + row(row const &) noexcept = default; + row &operator=(row const &) noexcept = default; + row &operator=(row &&) noexcept = default; + + /** + * @name Comparison + */ + //@{ + [[nodiscard]] PQXX_PURE bool operator==(row const &) const noexcept; + [[nodiscard]] bool operator!=(row const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + [[nodiscard]] const_iterator begin() const noexcept; + [[nodiscard]] const_iterator cbegin() const noexcept; + [[nodiscard]] const_iterator end() const noexcept; + [[nodiscard]] const_iterator cend() const noexcept; + + /** + * @name Field access + */ + //@{ + [[nodiscard]] reference front() const noexcept; + [[nodiscard]] reference back() const noexcept; + + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator rbegin() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator crbegin() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator rend() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator crend() const; + + [[nodiscard]] reference operator[](size_type) const noexcept; + /** Address field by name. + * @warning This is much slower than indexing by number, or iterating. + */ + [[nodiscard]] reference operator[](zview col_name) const; + + reference at(size_type) const; + /** Address field by name. + * @warning This is much slower than indexing by number, or iterating. + */ + reference at(zview col_name) const; + + [[nodiscard]] constexpr size_type size() const noexcept + { + return m_end - m_begin; + } + + [[deprecated("Swap iterators, not rows.")]] void swap(row &) noexcept; + + /// Row number, assuming this is a real row and not end()/rend(). + [[nodiscard]] constexpr result::size_type rownumber() const noexcept + { + return m_index; + } + + /** + * @name Column information + */ + //@{ + /// Number of given column (throws exception if it doesn't exist). + [[nodiscard]] size_type column_number(zview col_name) const; + + /// Return a column's type. + [[nodiscard]] oid column_type(size_type) const; + + /// Return a column's type. + [[nodiscard]] oid column_type(zview col_name) const + { + return column_type(column_number(col_name)); + } + + /// What table did this column come from? + [[nodiscard]] oid column_table(size_type col_num) const; + + /// What table did this column come from? + [[nodiscard]] oid column_table(zview col_name) const + { + return column_table(column_number(col_name)); + } + + /// What column number in its table did this result column come from? + /** A meaningful answer can be given only if the column in question comes + * directly from a column in a table. If the column is computed in any + * other way, a logic_error will be thrown. + * + * @param col_num a zero-based column number in this result set + * @return a zero-based column number in originating table + */ + [[nodiscard]] size_type table_column(size_type) const; + + /// What column number in its table did this result column come from? + [[nodiscard]] size_type table_column(zview col_name) const + { + return table_column(column_number(col_name)); + } + //@} + + [[nodiscard]] constexpr result::size_type num() const noexcept + { + return rownumber(); + } + + /** Produce a slice of this row, containing the given range of columns. + * + * @deprecated I haven't heard of anyone caring about row slicing at all in + * at least the last 15 years. Yet it adds complexity, so unless anyone + * files a bug explaining why they really need this feature, I'm going to + * remove it. Even if they do, the feature may need an update. + * + * The slice runs from the range's starting column to the range's end + * column, exclusive. It looks just like a normal result row, except + * slices can be empty. + */ + [[deprecated("Row slicing is going away. File a bug if you need it.")]] row + slice(size_type sbegin, size_type send) const; + + /// Is this a row without fields? Can only happen to a slice. + [[nodiscard, deprecated("Row slicing is going away.")]] PQXX_PURE bool + empty() const noexcept; + + /// Extract entire row's values into a tuple. + /** Converts to the types of the tuple's respective fields. + */ + template void to(Tuple &t) const + { + check_size(std::tuple_size_v); + convert(t); + } + + template std::tuple as() const + { + check_size(sizeof...(TYPE)); + using seq = std::make_index_sequence; + return get_tuple>(seq{}); + } + +protected: + friend class const_row_iterator; + friend class result; + row(result const &r, result_size_type index, size_type cols) noexcept; + + /// Throw @ref usage_error if row size is not `expected`. + void check_size(size_type expected) const + { + if (size() != expected) + throw usage_error{internal::concat( + "Tried to extract ", expected, " field(s) from a row of ", size(), + ".")}; + } + + /// Convert to a given tuple of values, don't check sizes. + /** We need this for cases where we have a full tuple of field types, but + * not a parameter pack. + */ + template TUPLE as_tuple() const + { + using seq = std::make_index_sequence>; + return get_tuple(seq{}); + } + + template friend class pqxx::internal::result_iter; + /// Convert entire row to tuple fields, without checking row size. + template void convert(Tuple &t) const + { + extract_fields(t, std::make_index_sequence>{}); + } + + friend class field; + + /// Result set of which this is one row. + result m_result; + + /// Row number. + /** + * You'd expect this to be unsigned, but due to the way reverse iterators + * are related to regular iterators, it must be allowed to underflow to -1. + */ + result::size_type m_index = 0; + + // TODO: Remove m_begin and (if possible) m_end when we remove slice(). + /// First column in slice. This row ignores lower-numbered columns. + size_type m_begin = 0; + /// End column in slice. This row only sees lower-numbered columns. + size_type m_end = 0; + +private: + template + void extract_fields(Tuple &t, std::index_sequence) const + { + (extract_value(t), ...); + } + + template + void extract_value(Tuple &t) const; + + /// Convert row's values as a new tuple. + template + auto get_tuple(std::index_sequence) const + { + return std::make_tuple(get_field()...); + } + + /// Extract and convert a field. + template auto get_field() const + { + return (*this)[index].as>(); + } +}; + + +/// Iterator for fields in a row. Use as row::const_iterator. +class PQXX_LIBEXPORT const_row_iterator : public field +{ +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = field const; + using pointer = field const *; + using size_type = row_size_type; + using difference_type = row_difference_type; + using reference = field; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + const_row_iterator() = default; +#include "pqxx/internal/ignore-deprecated-post.hxx" + const_row_iterator(row const &t, row_size_type c) noexcept : + field{t.m_result, t.m_index, c} + {} + const_row_iterator(field const &F) noexcept : field{F} {} + const_row_iterator(const_row_iterator const &) noexcept = default; + const_row_iterator(const_row_iterator &&) noexcept = default; + + /** + * @name Dereferencing operators + */ + //@{ + [[nodiscard]] constexpr pointer operator->() const noexcept { return this; } + [[nodiscard]] reference operator*() const noexcept { return {*this}; } + //@} + + /** + * @name Manipulations + */ + //@{ + const_row_iterator &operator=(const_row_iterator const &) noexcept = default; + const_row_iterator &operator=(const_row_iterator &&) noexcept = default; + + // TODO: noexcept. Breaks ABI. + const_row_iterator operator++(int); + const_row_iterator &operator++() noexcept + { + ++m_col; + return *this; + } + // TODO: noexcept. Breaks ABI. + const_row_iterator operator--(int); + const_row_iterator &operator--() noexcept + { + --m_col; + return *this; + } + + const_row_iterator &operator+=(difference_type i) noexcept + { + m_col = size_type(difference_type(m_col) + i); + return *this; + } + const_row_iterator &operator-=(difference_type i) noexcept + { + m_col = size_type(difference_type(m_col) - i); + return *this; + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] constexpr bool + operator==(const_row_iterator const &i) const noexcept + { + return col() == i.col(); + } + [[nodiscard]] constexpr bool + operator!=(const_row_iterator const &i) const noexcept + { + return col() != i.col(); + } + [[nodiscard]] constexpr bool + operator<(const_row_iterator const &i) const noexcept + { + return col() < i.col(); + } + [[nodiscard]] constexpr bool + operator<=(const_row_iterator const &i) const noexcept + { + return col() <= i.col(); + } + [[nodiscard]] constexpr bool + operator>(const_row_iterator const &i) const noexcept + { + return col() > i.col(); + } + [[nodiscard]] constexpr bool + operator>=(const_row_iterator const &i) const noexcept + { + return col() >= i.col(); + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] inline const_row_iterator + operator+(difference_type) const noexcept; + + friend const_row_iterator + operator+(difference_type, const_row_iterator const &) noexcept; + + [[nodiscard]] inline const_row_iterator + operator-(difference_type) const noexcept; + [[nodiscard]] inline difference_type + operator-(const_row_iterator const &) const noexcept; + //@} +}; + + +/// Reverse iterator for a row. Use as row::const_reverse_iterator. +class PQXX_LIBEXPORT const_reverse_row_iterator : private const_row_iterator +{ +public: + using super = const_row_iterator; + using iterator_type = const_row_iterator; + using iterator_type::difference_type; + using iterator_type::iterator_category; + using iterator_type::pointer; + using value_type = iterator_type::value_type; + using reference = iterator_type::reference; + + const_reverse_row_iterator() noexcept = default; + const_reverse_row_iterator(const_reverse_row_iterator const &) noexcept = + default; + const_reverse_row_iterator(const_reverse_row_iterator &&) noexcept = default; + + explicit const_reverse_row_iterator(super const &rhs) noexcept : + const_row_iterator{rhs} + { + super::operator--(); + } + + [[nodiscard]] PQXX_PURE iterator_type base() const noexcept; + + /** + * @name Dereferencing operators + */ + //@{ + using iterator_type::operator->; + using iterator_type::operator*; + //@} + + /** + * @name Manipulations + */ + //@{ + const_reverse_row_iterator & + operator=(const_reverse_row_iterator const &r) noexcept + { + iterator_type::operator=(r); + return *this; + } + const_reverse_row_iterator operator++() noexcept + { + iterator_type::operator--(); + return *this; + } + // TODO: noexcept. Breaks ABI. + const_reverse_row_iterator operator++(int); + const_reverse_row_iterator &operator--() noexcept + { + iterator_type::operator++(); + return *this; + } + const_reverse_row_iterator operator--(int); + // TODO: noexcept. Breaks ABI. + const_reverse_row_iterator &operator+=(difference_type i) noexcept + { + iterator_type::operator-=(i); + return *this; + } + const_reverse_row_iterator &operator-=(difference_type i) noexcept + { + iterator_type::operator+=(i); + return *this; + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] const_reverse_row_iterator + operator+(difference_type i) const noexcept + { + return const_reverse_row_iterator{base() - i}; + } + [[nodiscard]] const_reverse_row_iterator + operator-(difference_type i) noexcept + { + return const_reverse_row_iterator{base() + i}; + } + [[nodiscard]] difference_type + operator-(const_reverse_row_iterator const &rhs) const noexcept + { + return rhs.const_row_iterator::operator-(*this); + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool + operator==(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator==(rhs); + } + [[nodiscard]] bool + operator!=(const_reverse_row_iterator const &rhs) const noexcept + { + return !operator==(rhs); + } + + [[nodiscard]] constexpr bool + operator<(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator>(rhs); + } + [[nodiscard]] constexpr bool + operator<=(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator>=(rhs); + } + [[nodiscard]] constexpr bool + operator>(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator<(rhs); + } + [[nodiscard]] constexpr bool + operator>=(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator<=(rhs); + } + //@} +}; + + +const_row_iterator +const_row_iterator::operator+(difference_type o) const noexcept +{ + // TODO:: More direct route to home().columns()? + return { + row{home(), idx(), home().columns()}, + size_type(difference_type(col()) + o)}; +} + +inline const_row_iterator operator+( + const_row_iterator::difference_type o, const_row_iterator const &i) noexcept +{ + return i + o; +} + +inline const_row_iterator +const_row_iterator::operator-(difference_type o) const noexcept +{ + // TODO:: More direct route to home().columns()? + return { + row{home(), idx(), home().columns()}, + size_type(difference_type(col()) - o)}; +} + +inline const_row_iterator::difference_type +const_row_iterator::operator-(const_row_iterator const &i) const noexcept +{ + return difference_type(num() - i.num()); +} + + +template +inline void row::extract_value(Tuple &t) const +{ + using field_type = strip_t(t))>; + field const f{m_result, m_index, index}; + std::get(t) = from_string(f); +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/separated_list b/ext/libpqxx-7.7.3/include/pqxx/separated_list new file mode 100644 index 000000000..1bdf51c6a --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/separated_list @@ -0,0 +1,6 @@ +/** Helper similar to Python's @c str.join(). + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/separated_list.hxx b/ext/libpqxx-7.7.3/include/pqxx/separated_list.hxx new file mode 100644 index 000000000..d4230ea08 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/separated_list.hxx @@ -0,0 +1,142 @@ +/* Helper similar to Python's `str.join()`. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/separated_list instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SEPARATED_LIST +#define PQXX_H_SEPARATED_LIST + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/strconv.hxx" + +// C++20: Simplify using std::ranges::range. +// C++20: Optimise buffer allocation using random_access_range/iterator. +namespace pqxx +{ +/** + * @defgroup utility Utility functions + */ +//@{ + +/// Represent sequence of values as a string, joined by a given separator. +/** + * Use this to turn e.g. the numbers 1, 2, and 3 into a string "1, 2, 3". + * + * @param sep separator string (to be placed between items) + * @param begin beginning of items sequence + * @param end end of items sequence + * @param access functor defining how to dereference sequence elements + */ +template +[[nodiscard]] inline std::string +separated_list(std::string_view sep, ITER begin, ITER end, ACCESS access) +{ + if (end == begin) + return {}; + auto next{begin}; + ++next; + if (next == end) + return to_string(access(begin)); + + // From here on, we've got at least 2 elements -- meaning that we need sep. + using elt_type = strip_t; + using traits = string_traits; + + std::size_t budget{0}; + for (ITER cnt{begin}; cnt != end; ++cnt) + budget += traits::size_buffer(access(cnt)); + budget += + static_cast(std::distance(begin, end)) * std::size(sep); + + std::string result; + result.resize(budget); + + char *const data{result.data()}; + char *here{data}; + char *stop{data + budget}; + here = traits::into_buf(here, stop, access(begin)) - 1; + for (++begin; begin != end; ++begin) + { + here += sep.copy(here, std::size(sep)); + here = traits::into_buf(here, stop, access(begin)) - 1; + } + result.resize(static_cast(here - data)); + return result; +} + + +/// Render sequence as a string, using given separator between items. +template +[[nodiscard]] inline std::string +separated_list(std::string_view sep, ITER begin, ITER end) +{ + return separated_list(sep, begin, end, [](ITER i) { return *i; }); +} + + +/// Render items in a container as a string, using given separator. +template +[[nodiscard]] inline auto +separated_list(std::string_view sep, CONTAINER const &c) + /* + Always std::string; necessary because SFINAE doesn't work with the + contents of function bodies, so the check for iterability has to be in + the signature. + */ + -> typename std::enable_if< + (not std::is_void::value and + not std::is_void::value), + std::string>::type +{ + return separated_list(sep, std::begin(c), std::end(c)); +} + + +/// Render items in a tuple as a string, using given separator. +template< + typename TUPLE, std::size_t INDEX = 0, typename ACCESS, + typename std::enable_if< + (INDEX == std::tuple_size::value - 1), int>::type = 0> +[[nodiscard]] inline std::string separated_list( + std::string_view /* sep */, TUPLE const &t, ACCESS const &access) +{ + return to_string(access(&std::get(t))); +} + +template< + typename TUPLE, std::size_t INDEX = 0, typename ACCESS, + typename std::enable_if< + (INDEX < std::tuple_size::value - 1), int>::type = 0> +[[nodiscard]] inline std::string +separated_list(std::string_view sep, TUPLE const &t, ACCESS const &access) +{ + std::string out{to_string(access(&std::get(t)))}; + out.append(sep); + out.append(separated_list(sep, t, access)); + return out; +} + +template< + typename TUPLE, std::size_t INDEX = 0, + typename std::enable_if< + (INDEX <= std::tuple_size::value), int>::type = 0> +[[nodiscard]] inline std::string +separated_list(std::string_view sep, TUPLE const &t) +{ + // TODO: Optimise allocation. + return separated_list(sep, t, [](TUPLE const &tup) { return *tup; }); +} +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/strconv b/ext/libpqxx-7.7.3/include/pqxx/strconv new file mode 100644 index 000000000..aa2c40ed5 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/strconv @@ -0,0 +1,6 @@ +/** String conversion definitions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/strconv.hxx b/ext/libpqxx-7.7.3/include/pqxx/strconv.hxx new file mode 100644 index 000000000..863711228 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/strconv.hxx @@ -0,0 +1,468 @@ +/* String conversion definitions. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STRCONV +#define PQXX_H_STRCONV + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include + +#if __has_include() +# include +#endif + +#if defined(PQXX_HAVE_RANGES) && __has_include() +# include +#endif + +#include "pqxx/except.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + + +namespace pqxx::internal +{ +/// Attempt to demangle @c std::type_info::name() to something human-readable. +PQXX_LIBEXPORT std::string demangle_type_name(char const[]); +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @defgroup stringconversion String conversion + * + * The PostgreSQL server accepts and represents data in string form. It has + * its own formats for various data types. The string conversions define how + * various C++ types translate to and from their respective PostgreSQL text + * representations. + * + * Each conversion is defined by a specialisations of @c string_traits. It + * gets complicated if you want top performance, but until you do, all you + * really need to care about when converting values between C++ in-memory + * representations such as @c int and the postgres string representations is + * the @c pqxx::to_string and @c pqxx::from_string functions. + * + * If you need to convert a type which is not supported out of the box, you'll + * need to define your own specialisations for these templates, similar to the + * ones defined here and in `pqxx/conversions.hxx`. Any conversion code which + * "sees" your specialisation will now support your conversion. In particular, + * you'll be able to read result fields into a variable of the new type. + * + * There is a macro to help you define conversions for individual enumeration + * types. The conversion will represent enumeration values as numeric strings. + */ +//@{ + +/// A human-readable name for a type, used in error messages and such. +/** Actually this may not always be very user-friendly. It uses + * @c std::type_info::name(). On gcc-like compilers we try to demangle its + * output. Visual Studio produces human-friendly names out of the box. + * + * This variable is not inline. Inlining it gives rise to "memory leak" + * warnings from asan, the address sanitizer, possibly from use of + * @c std::type_info::name. + */ +template +std::string const type_name{internal::demangle_type_name(typeid(TYPE).name())}; + + +/// Traits describing a type's "null value," if any. +/** Some C++ types have a special value or state which correspond directly to + * SQL's NULL. + * + * The @c nullness traits describe whether it exists, and whether a particular + * value is null. + */ +template struct nullness +{ + /// Does this type have a null value? + static bool has_null; + + /// Is this type always null? + static bool always_null; + + /// Is @c value a null? + static bool is_null(TYPE const &value); + + /// Return a null value. + /** Don't use this in generic code to compare a value and see whether it is + * null. Some types may have multiple null values which do not compare as + * equal, or may define a null value which is not equal to anything including + * itself, like in SQL. + */ + [[nodiscard]] static TYPE null(); +}; + + +/// Nullness traits describing a type which does not have a null value. +template struct no_null +{ + /// Does @c TYPE have a "built-in null value"? + /** For example, a pointer can equal @c nullptr, which makes a very natural + * representation of an SQL null value. For such types, the code sometimes + * needs to make special allowances. + * + * for most types, such as @c int or @c std::string, there is no built-in + * null. If you want to represent an SQL null value for such a type, you + * would have to wrap it in something that does have a null value. For + * example, you could use @c std::optional for "either an @c int or a + * null value." + */ + static constexpr bool has_null = false; + + /// Are all values of this type null? + /** There are a few special C++ types which are always null - mainly + * @c std::nullptr_t. + */ + static constexpr bool always_null = false; + + /// Does a given value correspond to an SQL null value? + /** Most C++ types, such as @c int or @c std::string, have no inherent null + * value. But some types such as C-style string pointers do have a natural + * equivalent to an SQL null. + */ + [[nodiscard]] static constexpr bool is_null(TYPE const &) noexcept + { + return false; + } +}; + + +/// Traits class for use in string conversions. +/** Specialize this template for a type for which you wish to add to_string + * and from_string support. + * + * String conversions are not meant to work for nulls. Check for null before + * converting a value of @c TYPE to a string, or vice versa. + */ +template struct string_traits +{ + /// Return a @c string_view representing value, plus terminating zero. + /** Produces a @c string_view containing the PostgreSQL string representation + * for @c value. + * + * Uses the space from @c begin to @c end as a buffer, if needed. The + * returned string may lie somewhere in that buffer, or it may be a + * compile-time constant, or it may be null if value was a null value. Even + * if the string is stored in the buffer, its @c begin() may or may not be + * the same as @c begin. + * + * The @c string_view is guaranteed to be valid as long as the buffer from + * @c begin to @c end remains accessible and unmodified. + * + * @throws pqxx::conversion_overrun if the provided buffer space may not be + * enough. For maximum performance, this is a conservative estimate. It may + * complain about a buffer which is actually large enough for your value, if + * an exact check gets too expensive. + */ + [[nodiscard]] static inline zview + to_buf(char *begin, char *end, TYPE const &value); + + /// Write value's string representation into buffer at @c begin. + /** Assumes that value is non-null. + * + * Writes value's string representation into the buffer, starting exactly at + * @c begin, and ensuring a trailing zero. Returns the address just beyond + * the trailing zero, so the caller could use it as the @c begin for another + * call to @c into_buf writing a next value. + */ + static inline char *into_buf(char *begin, char *end, TYPE const &value); + + /// Parse a string representation of a @c TYPE value. + /** Throws @c conversion_error if @c value does not meet the expected format + * for a value of this type. + */ + [[nodiscard]] static inline TYPE from_string(std::string_view text); + + // C++20: Can we make these all constexpr? + /// Estimate how much buffer space is needed to represent value. + /** The estimate may be a little pessimistic, if it saves time. + * + * The estimate includes the terminating zero. + */ + [[nodiscard]] static inline std::size_t + size_buffer(TYPE const &value) noexcept; +}; + + +/// Nullness: Enums do not have an inherent null value. +template +struct nullness>> : no_null +{}; +} // namespace pqxx + + +namespace pqxx::internal +{ +/// Helper class for defining enum conversions. +/** The conversion will convert enum values to numeric strings, and vice versa. + * + * To define a string conversion for an enum type, derive a @c string_traits + * specialisation for the enum from this struct. + * + * There's usually an easier way though: the @c PQXX_DECLARE_ENUM_CONVERSION + * macro. Use @c enum_traits manually only if you need to customise your + * traits type in more detail. + */ +template struct enum_traits +{ + using impl_type = std::underlying_type_t; + using impl_traits = string_traits; + + [[nodiscard]] static constexpr zview + to_buf(char *begin, char *end, ENUM const &value) + { + return impl_traits::to_buf(begin, end, to_underlying(value)); + } + + static constexpr char *into_buf(char *begin, char *end, ENUM const &value) + { + return impl_traits::into_buf(begin, end, to_underlying(value)); + } + + [[nodiscard]] static ENUM from_string(std::string_view text) + { + return static_cast(impl_traits::from_string(text)); + } + + [[nodiscard]] static std::size_t size_buffer(ENUM const &value) noexcept + { + return impl_traits::size_buffer(to_underlying(value)); + } + +private: + // C++23: Replace with std::to_underlying. + static constexpr impl_type to_underlying(ENUM const &value) noexcept + { + return static_cast(value); + } +}; +} // namespace pqxx::internal + + +/// Macro: Define a string conversion for an enum type. +/** This specialises the @c pqxx::string_traits template, so use it in the + * @c ::pqxx namespace. + * + * For example: + * + * #include + * #include + * enum X { xa, xb }; + * namespace pqxx { PQXX_DECLARE_ENUM_CONVERSION(x); } + * int main() { std::cout << pqxx::to_string(xa) << std::endl; } + */ +#define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \ + template<> struct string_traits : pqxx::internal::enum_traits \ + {}; \ + template<> inline std::string const type_name { #ENUM } + + +namespace pqxx +{ +/// Parse a value in postgres' text format as a TYPE. +/** If the form of the value found in the string does not match the expected + * type, e.g. if a decimal point is found when converting to an integer type, + * the conversion fails. Overflows (e.g. converting "9999999999" to a 16-bit + * C++ type) are also treated as errors. If in some cases this behaviour + * should be inappropriate, convert to something bigger such as @c long @c int + * first and then truncate the resulting value. + * + * Only the simplest possible conversions are supported. Fancy features like + * hexadecimal or octal, spurious signs, or exponent notation won't work. + * Whitespace is not stripped away. Only the kinds of strings that come out of + * PostgreSQL and out of to_string() can be converted. + */ +template +[[nodiscard]] inline TYPE from_string(std::string_view text) +{ + return string_traits::from_string(text); +} + + +/// "Convert" a std::string_view to a std::string_view. +/** Just returns its input. + * + * @warning Of course the result is only valid for as long as the original + * string remains valid! Never access the string referenced by the return + * value after the original has been destroyed. + */ +template<> +[[nodiscard]] inline std::string_view from_string(std::string_view text) +{ + return text; +} + + +/// Attempt to convert postgres-generated string to given built-in object. +/** This is like the single-argument form of the function, except instead of + * returning the value, it sets @c value. + * + * You may find this more convenient in that it infers the type you want from + * the argument you pass. But there are disadvantages: it requires an + * assignment operator, and it may be less efficient. + */ +template inline void from_string(std::string_view text, T &value) +{ + value = from_string(text); +} + + +/// Convert a value to a readable string that PostgreSQL will understand. +/** The conversion does no special formatting, and ignores any locale settings. + * The resulting string will be human-readable and in a format suitable for use + * in SQL queries. It won't have niceties such as "thousands separators" + * though. + */ +template inline std::string to_string(TYPE const &value); + + +/// Convert multiple values to strings inside a single buffer. +/** There must be enough room for all values, or this will throw + * @c conversion_overrun. You can obtain a conservative estimate of the buffer + * space required by calling @c size_buffer() on the values. + * + * The @c std::string_view results may point into the buffer, so don't assume + * that they will remain valid after you destruct or move the buffer. + */ +template +[[nodiscard]] inline std::vector +to_buf(char *here, char const *end, TYPE... value) +{ + return {[&here, end](auto v) { + auto begin = here; + here = string_traits::into_buf(begin, end, v); + // Exclude the trailing zero out of the string_view. + auto len{static_cast(here - begin) - 1}; + return std::string_view{begin, len}; + }(value)...}; +} + +/// Convert a value to a readable string that PostgreSQL will understand. +/** This variant of to_string can sometimes save a bit of time in loops, by + * re-using a std::string for multiple conversions. + */ +template +inline void into_string(TYPE const &value, std::string &out); + + +/// Is @c value null? +template +[[nodiscard]] inline constexpr bool is_null(TYPE const &value) noexcept +{ + return nullness>::is_null(value); +} + + +/// Estimate how much buffer space is needed to represent values as a string. +/** The estimate may be a little pessimistic, if it saves time. It also + * includes room for a terminating zero after each value. + */ +template +[[nodiscard]] inline std::size_t size_buffer(TYPE const &...value) noexcept +{ + return (string_traits>::size_buffer(value) + ...); +} + + +/// Does this type translate to an SQL array? +/** Specialisations may override this to be true for container types. + * + * This may not always be a black-and-white choice. For instance, a + * @c std::string is a container, but normally it translates to an SQL string, + * not an SQL array. + */ +template inline constexpr bool is_sql_array{false}; + + +/// Can we use this type in arrays and composite types without quoting them? +/** Define this as @c true only if values of @c TYPE can never contain any + * special characters that might need escaping or confuse the parsing of array + * or composite * types, such as commas, quotes, parentheses, braces, newlines, + * and so on. + * + * When converting a value of such a type to a string in an array or a field in + * a composite type, we do not need to add quotes, nor escape any special + * characters. + * + * This is just an optimisation, so it defaults to @c false to err on the side + * of slow correctness. + */ +template inline constexpr bool is_unquoted_safe{false}; + + +/// Element separator between SQL array elements of this type. +template inline constexpr char array_separator{','}; + + +/// What's the preferred format for passing non-null parameters of this type? +/** This affects how we pass parameters of @c TYPE when calling parameterised + * statements or prepared statements. + * + * Generally we pass parameters in text format, but binary strings are the + * exception. We also pass nulls in binary format, so this function need not + * handle null values. + */ +template inline constexpr format param_format(TYPE const &) +{ + return format::text; +} + + +/// Implement @c string_traits::to_buf by calling @c into_buf. +/** When you specialise @c string_traits for a new type, most of the time its + * @c to_buf implementation has no special optimisation tricks and just writes + * its text into the buffer it receives from the caller, starting at the + * beginning. + * + * In that common situation, you can implement @c to_buf as just a call to + * @c generic_to_buf. It will call @c into_buf and return the right result for + * @c to_buf. + */ +template +inline zview generic_to_buf(char *begin, char *end, TYPE const &value) +{ + using traits = string_traits; + // The trailing zero does not count towards the zview's size, so subtract 1 + // from the result we get from into_buf(). + if (is_null(value)) + return {}; + else + return {begin, traits::into_buf(begin, end, value) - begin - 1}; +} + + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: Binary string, akin to @c std::string for binary data. +/** Any type that satisfies this concept can represent an SQL BYTEA value. + * + * A @c binary has a @c begin(), @c end(), @c size(), and @data(). Each byte + * is a @c std::byte, and they must all be laid out contiguously in memory so + * we can reference them by a pointer. + */ +template +concept binary = std::ranges::contiguous_range and + std::is_same_v>, std::byte>; +#endif +//@} +} // namespace pqxx + + +#include "pqxx/internal/conversions.hxx" +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/stream_from b/ext/libpqxx-7.7.3/include/pqxx/stream_from new file mode 100644 index 000000000..972762443 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/stream_from @@ -0,0 +1,8 @@ +/** pqxx::stream_from class. + * + * pqxx::stream_from enables optimized batch reads from a database table. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/stream_from.hxx b/ext/libpqxx-7.7.3/include/pqxx/stream_from.hxx new file mode 100644 index 000000000..ff4a93d2e --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/stream_from.hxx @@ -0,0 +1,361 @@ +/* Definition of the pqxx::stream_from class. + * + * pqxx::stream_from enables optimized batch reads from a database table. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_from instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_FROM +#define PQXX_H_STREAM_FROM + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/connection.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/internal/stream_iterator.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/transaction_focus.hxx" + + +namespace pqxx +{ +class transaction_base; + + +/// Pass this to a `stream_from` constructor to stream table contents. +/** @deprecated Use @ref stream_from::table() instead. + */ +constexpr from_table_t from_table; +/// Pass this to a `stream_from` constructor to stream query results. +/** @deprecated Use stream_from::query() instead. + */ +constexpr from_query_t from_query; + + +/// Stream data from the database. +/** For larger data sets, retrieving data this way is likely to be faster than + * executing a query and then iterating and converting the rows fields. You + * will also be able to start processing before all of the data has come in. + * + * There are also downsides. Not all kinds of query will work in a stream. + * But straightforward `SELECT` and `UPDATE ... RETURNING` queries should work. + * This function makes use of @ref pqxx::stream_from, which in turn uses + * PostgreSQL's `COPY` command, so see the documentation for those to get the + * full details. + * + * There are other downsides. If there stream encounters an error, it may + * leave the entire connection in an unusable state, so you'll have to give the + * whole thing up. Finally, opening a stream puts the connection in a special + * state, so you won't be able to do many other things with the connection or + * the transaction while the stream is open. + * + * There are two ways of starting a stream: you stream either all rows in a + * table (using one of the factories, `table()` or `raw_table()`), or the + * results of a query (using the `query()` factory). + * + * Usually you'll want the `stream` convenience wrapper in + * @ref transaction_base, * so you don't need to deal with this class directly. + * + * @warning While a stream is active, you cannot execute queries, open a + * pipeline, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT stream_from : transaction_focus +{ +public: + using raw_line = + std::pair>, std::size_t>; + + /// Factory: Execute query, and stream the results. + /** The query can be a SELECT query or a VALUES query; or it can be an + * UPDATE, INSERT, or DELETE with a RETURNING clause. + * + * The query is executed as part of a COPY statement, so there are additional + * restrictions on what kind of query you can use here. See the PostgreSQL + * documentation for the COPY command: + * + * https://www.postgresql.org/docs/current/sql-copy.html + */ + static stream_from query(transaction_base &tx, std::string_view q) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return {tx, from_query, q}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /** + * @name Streaming data from tables + * + * You can use `stream_from` to read a table's contents. This is a quick + * and easy way to read a table, but it comes with limitations. It cannot + * stream from a view, only from a table. It does not support conditions. + * And there are no guarantees about ordering. If you need any of those + * things, consider streaming from a query instead. + */ + //@{ + + /// Factory: Stream data from a pre-quoted table and columns. + /** Use this factory if you need to create multiple streams using the same + * table path and/or columns list, and you want to save a bit of work on + * composing the internal SQL statement for starting the stream. It lets you + * compose the string representations for the table path and the columns + * list, so you can compute these once and then re-use them later. + * + * @param tx The transaction within which the stream will operate. + * @param path Name or path for the table upon which the stream will + * operate. If any part of the table path may contain special + * characters or be case-sensitive, quote the path using + * pqxx::connection::quote_table(). + * @param columns Columns which the stream will read. They should be + * comma-separated and, if needed, quoted. You can produce the string + * using pqxx::connection::quote_columns(). If you omit this argument, + * the stream will read all columns in the table, in schema order. + */ + static stream_from raw_table( + transaction_base &tx, std::string_view path, + std::string_view columns = ""sv); + + /// Factory: Stream data from a given table. + /** This is the convenient way to stream from a table. + */ + static stream_from table( + transaction_base &tx, table_path path, + std::initializer_list columns = {}); + //@} + + /// Execute query, and stream over the results. + /** @deprecated Use factory function @ref query instead. + */ + [[deprecated("Use query() factory instead.")]] stream_from( + transaction_base &, from_query_t, std::string_view query); + + /// Stream all rows in table, all columns. + /** @deprecated Use factories @ref table or @ref raw_table instead. + */ + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &, from_table_t, std::string_view table); + + /// Stream given columns from all rows in table. + /** @deprecated Use factories @ref table or @ref raw_table instead. + */ + template + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &, from_table_t, std::string_view table, + Iter columns_begin, Iter columns_end); + + /// Stream given columns from all rows in table. + /** @deprecated Use factory function @ref query instead. + */ + template + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &tx, from_table_t, std::string_view table, + Columns const &columns); + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// @deprecated Use factories @ref table or @ref raw_table instead. + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &tx, std::string_view table) : + stream_from{tx, from_table, table} + {} +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// @deprecated Use factories @ref table or @ref raw_table instead. + template + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &tx, std::string_view table, Columns const &columns) : + stream_from{tx, from_table, table, columns} + {} + + /// @deprecated Use factories @ref table or @ref raw_table instead. + template + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &, std::string_view table, Iter columns_begin, + Iter columns_end); + + ~stream_from() noexcept; + + /// May this stream still produce more data? + [[nodiscard]] constexpr operator bool() const noexcept + { + return not m_finished; + } + /// Has this stream produced all the data it is going to produce? + [[nodiscard]] constexpr bool operator!() const noexcept + { + return m_finished; + } + + /// Finish this stream. Call this before continuing to use the connection. + /** Consumes all remaining lines, and closes the stream. + * + * This may take a while if you're abandoning the stream before it's done, so + * skip it in error scenarios where you're not planning to use the connection + * again afterwards. + */ + void complete(); + + /// Read one row into a tuple. + /** Converts the row's fields into the fields making up the tuple. + * + * For a column which can contain nulls, be sure to give the corresponding + * tuple field a type which can be null. For example, to read a field as + * `int` when it may contain nulls, read it as `std::optional`. + * Using `std::shared_ptr` or `std::unique_ptr` will also work. + */ + template stream_from &operator>>(Tuple &); + + /// Doing this with a `std::variant` is going to be horrifically borked. + template + stream_from &operator>>(std::variant &) = delete; + + /// Iterate over this stream. Supports range-based "for" loops. + /** Produces an input iterator over the stream. + * + * Do not call this yourself. Use it like "for (auto data : stream.iter())". + */ + template [[nodiscard]] auto iter() & + { + return pqxx::internal::stream_input_iteration{*this}; + } + + /// Read a row. Return fields as views, valid until you read the next row. + /** Returns `nullptr` when there are no more rows to read. Do not attempt + * to read any further rows after that. + * + * Do not access the vector, or the storage referenced by the views, after + * closing or completing the stream, or after attempting to read a next row. + * + * A @ref pqxx::zview is like a `std::string_view`, but with the added + * guarantee that if its data pointer is non-null, the string is followed by + * a terminating zero (which falls just outside the view itself). + * + * If any of the views' data pointer is null, that means that the + * corresponding SQL field is null. + * + * @warning The return type may change in the future, to support C++20 + * coroutine-based usage. + */ + std::vector const *read_row() &; + + /// Read a raw line of text from the COPY command. + /** @warning Do not use this unless you really know what you're doing. */ + raw_line get_raw_line(); + +private: + // TODO: Clean up this signature once we cull the deprecated constructors. + /// @deprecated + stream_from( + transaction_base &tx, std::string_view table, std::string_view columns, + from_table_t); + + // TODO: Clean up this signature once we cull the deprecated constructors. + /// @deprecated + stream_from( + transaction_base &, std::string_view unquoted_table, + std::string_view columns, from_table_t, int); + + template + void extract_fields(Tuple &t, std::index_sequence) const + { + (extract_value(t), ...); + } + + pqxx::internal::glyph_scanner_func *m_glyph_scanner; + + /// Current row's fields' text, combined into one reusable string. + std::string m_row; + + /// The current row's fields. + std::vector m_fields; + + bool m_finished = false; + + void close(); + + template + void extract_value(Tuple &) const; + + /// Read a line of COPY data, write `m_row` and `m_fields`. + void parse_line(); +}; + + +template +inline stream_from::stream_from( + transaction_base &tx, from_table_t, std::string_view table_name, + Columns const &columns) : + stream_from{ + tx, from_table, table_name, std::begin(columns), std::end(columns)} +{} + + +template +inline stream_from::stream_from( + transaction_base &tx, from_table_t, std::string_view table, + Iter columns_begin, Iter columns_end) : + stream_from{ + tx, table, separated_list(",", columns_begin, columns_end), + from_table, 1} +{} + + +template inline stream_from &stream_from::operator>>(Tuple &t) +{ + if (m_finished) + return *this; + static constexpr auto tup_size{std::tuple_size_v}; + m_fields.reserve(tup_size); + parse_line(); + if (m_finished) + return *this; + + if (std::size(m_fields) != tup_size) + throw usage_error{internal::concat( + "Tried to extract ", tup_size, " field(s) from a stream of ", + std::size(m_fields), ".")}; + + extract_fields(t, std::make_index_sequence{}); + return *this; +} + + +template +inline void stream_from::extract_value(Tuple &t) const +{ + using field_type = strip_t(t))>; + using nullity = nullness; + assert(index < std::size(m_fields)); + if constexpr (nullity::always_null) + { + if (std::data(m_fields[index]) != nullptr) + throw conversion_error{"Streaming non-null value into null field."}; + } + else if (std::data(m_fields[index]) == nullptr) + { + if constexpr (nullity::has_null) + std::get(t) = nullity::null(); + else + internal::throw_null_conversion(type_name); + } + else + { + // Don't ever try to convert a non-null value to nullptr_t! + std::get(t) = from_string(m_fields[index]); + } +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/stream_to b/ext/libpqxx-7.7.3/include/pqxx/stream_to new file mode 100644 index 000000000..8760cf1f4 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/stream_to @@ -0,0 +1,8 @@ +/** pqxx::stream_to class. + * + * pqxx::stream_to enables optimized batch updates to a database table. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/stream_to.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/stream_to.hxx b/ext/libpqxx-7.7.3/include/pqxx/stream_to.hxx new file mode 100644 index 000000000..2a49d8f85 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/stream_to.hxx @@ -0,0 +1,455 @@ +/* Definition of the pqxx::stream_to class. + * + * pqxx::stream_to enables optimized batch updates to a database table. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_to.hxx instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_TO +#define PQXX_H_STREAM_TO + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/separated_list.hxx" +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +/// Efficiently write data directly to a database table. +/** If you wish to insert rows of data into a table, you can compose INSERT + * statements and execute them. But it's slow and tedious, and you need to + * worry about quoting and escaping the data. + * + * If you're just inserting a single row, it probably won't matter much. You + * can use prepared or parameterised statements to take care of the escaping + * for you. But if you're inserting large numbers of rows you will want + * something better. + * + * Inserting rows one by one using INSERT statements involves a lot of + * pointless overhead, especially when you are working with a remote database + * server over the network. You may end up sending each row over the network + * as a separate query, and waiting for a reply. Do it "in bulk" using + * `stream_to`, and you may find that it goes many times faster. Sometimes + * you gain orders of magnitude in speed. + * + * Here's how it works: you create a `stream_to` stream to start writing to + * your table. You will probably want to specify the columns. Then, you + * feed your data into the stream one row at a time. And finally, you call the + * stream's @ref complete function to tell it to finalise the operation, wait + * for completion, and check for errors. + * + * (You _must_ complete the stream before committing or aborting the + * transaction. The connection is in a special state while the stream is + * active, where it can't process commands, and can't commit or abort a + * transaction.) + * + * So how do you feed a row of data into the stream? There's several ways, but + * the preferred one is to call its @ref write_values. Pass the field values + * as arguments. Doesn't matter what type they are, as long as libpqxx knows + * how to convert them to PostgreSQL's text format: `int`, `std::string` or + * `std:string_view`, `float` and `double`, `bool`... lots of basic types + * are supported. If some of the values are null, feel free to use + * `std::optional`, `std::shared_ptr`, or `std::unique_ptr`. + * + * The arguments' types don't even have to match the fields' SQL types. If you + * want to insert an `int` into a `DECIMAL` column, that's your choice -- it + * will produce a `DECIMAL` value which happens to be integral. Insert a + * `float` into a `VARCHAR` column? That's fine, you'll get a string whose + * contents happen to read like a number. And so on. You can even insert + * different types of value in the same column on different rows. If you have + * a code path where a particular field is always null, just insert `nullptr`. + * + * There is another way to insert rows: the `<<` ("shift-left") operator. + * It's not as fast and it doesn't support variable arguments: each row must be + * either a `std::tuple` or something iterable, such as a `std::vector`, or + * anything else with a `begin()` and `end()`. + * + * @warning While a stream is active, you cannot execute queries, open a + * pipeline, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT stream_to : transaction_focus +{ +public: + /// Stream data to a pre-quoted table and columns. + /** This factory can be useful when it's not convenient to provide the + * columns list in the form of a `std::initializer_list`, or when the list + * of columns is simply not known at compile time. + * + * Also use this if you need to create multiple streams using the same table + * path and/or columns list, and you want to save a bit of work on composing + * the internal SQL statement for starting the stream. It lets you compose + * the string representations for the table path and the columns list, so you + * can compute these once and then re-use them later. + * + * @param tx The transaction within which the stream will operate. + * @param path Name or path for the table upon which the stream will + * operate. If any part of the table path may contain special + * characters or be case-sensitive, quote the path using + * pqxx::connection::quote_table(). + * @param columns Columns to which the stream will write. They should be + * comma-separated and, if needed, quoted. You can produce the string + * using pqxx::connection::quote_columns(). If you omit this argument, + * the stream will write all columns in the table, in schema order. + */ + static stream_to raw_table( + transaction_base &tx, std::string_view path, std::string_view columns = "") + { + return {tx, path, columns}; + } + + /// Create a `stream_to` writing to a named table and columns. + /** Use this to stream data to a table, where the list of columns is known at + * compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns Optionally, the columns to which the stream should write. + * If you do not pass this, the stream will write to all columns in the + * table, in schema order. + */ + static stream_to table( + transaction_base &tx, table_path path, + std::initializer_list columns = {}) + { + auto const &conn{tx.conn()}; + return raw_table(tx, conn.quote_table(path), conn.quote_columns(columns)); + } + +#if defined(PQXX_HAVE_CONCEPTS) + /// Create a `stream_to` writing to a named table and columns. + /** Use this version to stream data to a table, when the list of columns is + * not known at compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns The columns to which the stream should write. + */ + template + static stream_to + table(transaction_base &tx, table_path path, COLUMNS const &columns) + { + auto const &conn{tx.conn()}; + return stream_to::raw_table( + tx, conn.quote_table(path), tx.conn().quote_columns(columns)); + } + + /// Create a `stream_to` writing to a named table and columns. + /** Use this version to stream data to a table, when the list of columns is + * not known at compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns The columns to which the stream should write. + */ + template + static stream_to + table(transaction_base &tx, std::string_view path, COLUMNS const &columns) + { + return stream_to::raw_table(tx, path, tx.conn().quote_columns(columns)); + } +#endif // PQXX_HAVE_CONCEPTS + + /// Create a stream, without specifying columns. + /** @deprecated Use @ref table or @ref raw_table as a factory. + * + * Fields will be inserted in whatever order the columns have in the + * database. + * + * You'll probably want to specify the columns, so that the mapping between + * your data fields and the table is explicit in your code, and not hidden + * in an "implicit contract" between your code and your schema. + */ + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &tx, std::string_view table_name) : + stream_to{tx, table_name, ""sv} + {} + + /// Create a stream, specifying column names as a container of strings. + /** @deprecated Use @ref table or @ref raw_table as a factory. + */ + template + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &, std::string_view table_name, Columns const &columns); + + /// Create a stream, specifying column names as a sequence of strings. + /** @deprecated Use @ref table or @ref raw_table as a factory. + */ + template + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &, std::string_view table_name, Iter columns_begin, + Iter columns_end); + + ~stream_to() noexcept; + + /// Does this stream still need to @ref complete()? + [[nodiscard]] constexpr operator bool() const noexcept + { + return not m_finished; + } + /// Has this stream been through its concluding @c complete()? + [[nodiscard]] constexpr bool operator!() const noexcept + { + return m_finished; + } + + /// Complete the operation, and check for errors. + /** Always call this to close the stream in an orderly fashion, even after + * an error. (In the case of an error, abort the transaction afterwards.) + * + * The only circumstance where it's safe to skip this is after an error, if + * you're discarding the entire connection. + */ + void complete(); + + /// Insert a row of data. + /** Returns a reference to the stream, so you can chain the calls. + * + * The @c row can be a tuple, or any type that can be iterated. Each + * item becomes a field in the row, in the same order as the columns you + * specified when creating the stream. + * + * If you don't already happen to have your fields in the form of a tuple or + * container, prefer @c write_values. It's faster and more convenient. + */ + template stream_to &operator<<(Row const &row) + { + write_row(row); + return *this; + } + + /// Stream a `stream_from` straight into a `stream_to`. + /** This can be useful when copying between different databases. If the + * source and the destination are on the same database, you'll get better + * performance doing it all in a regular query. + */ + stream_to &operator<<(stream_from &); + + /// Insert a row of data, given in the form of a @c std::tuple or container. + /** The @c row can be a tuple, or any type that can be iterated. Each + * item becomes a field in the row, in the same order as the columns you + * specified when creating the stream. + * + * The preferred way to insert a row is @c write_values. + */ + template void write_row(Row const &row) + { + fill_buffer(row); + write_buffer(); + } + + /// Insert values as a row. + /** This is the recommended way of inserting data. Pass your field values, + * of any convertible type. + */ + template void write_values(Ts const &...fields) + { + fill_buffer(fields...); + write_buffer(); + } + +private: + /// Stream a pre-quoted table name and columns list. + stream_to( + transaction_base &tx, std::string_view path, std::string_view columns); + + bool m_finished = false; + + /// Reusable buffer for a row. Saves doing an allocation for each row. + std::string m_buffer; + + /// Reusable buffer for converting/escaping a field. + std::string m_field_buf; + + /// Glyph scanner, for parsing the client encoding. + internal::glyph_scanner_func *m_scanner; + + /// Write a row of raw text-format data into the destination table. + void write_raw_line(std::string_view); + + /// Write a row of data from @c m_buffer into the destination table. + /** Resets the buffer for the next row. + */ + void write_buffer(); + + /// COPY encoding for a null field, plus subsequent separator. + static constexpr std::string_view null_field{"\\N\t"}; + + /// Estimate buffer space needed for a field which is always null. + template + static std::enable_if_t::always_null, std::size_t> + estimate_buffer(T const &) + { + return std::size(null_field); + } + + /// Estimate buffer space needed for field f. + /** The estimate is not very precise. We don't actually know how much space + * we'll need once the escaping comes in. + */ + template + static std::enable_if_t::always_null, std::size_t> + estimate_buffer(T const &field) + { + return is_null(field) ? std::size(null_field) : size_buffer(field); + } + + /// Append escaped version of @c data to @c m_buffer, plus a tab. + void escape_field_to_buffer(std::string_view data); + + /// Append string representation for @c f to @c m_buffer. + /** This is for the general case, where the field may contain a value. + * + * Also appends a tab. The tab is meant to be a separator, not a terminator, + * so if you write any fields at all, you'll end up with one tab too many + * at the end of the buffer. + */ + template + std::enable_if_t::always_null> + append_to_buffer(Field const &f) + { + // We append each field, terminated by a tab. That will leave us with + // one tab too many, assuming we write any fields at all; we remove that + // at the end. + if (is_null(f)) + { + // Easy. Append null and tab in one go. + m_buffer.append(null_field); + } + else + { + // Convert f into m_buffer. + + using traits = string_traits; + auto const budget{estimate_buffer(f)}; + auto const offset{std::size(m_buffer)}; + + if constexpr (std::is_arithmetic_v) + { + // Specially optimised for "safe" types, which never need any + // escaping. Convert straight into m_buffer. + + // The budget we get from size_buffer() includes room for the trailing + // zero, which we must remove. But we're also inserting tabs between + // fields, so we re-purpose the extra byte for that. + auto const total{offset + budget}; + m_buffer.resize(total); + auto const data{m_buffer.data()}; + char *const end{traits::into_buf(data + offset, data + total, f)}; + *(end - 1) = '\t'; + // Shrink to fit. Keep the tab though. + m_buffer.resize(static_cast(end - data)); + } + else if constexpr ( + std::is_same_v or + std::is_same_v or + std::is_same_v) + { + // This string may need escaping. + m_field_buf.resize(budget); + escape_field_to_buffer(f); + } + else + { + // This field needs to be converted to a string, and after that, + // escaped as well. + m_field_buf.resize(budget); + auto const data{m_field_buf.data()}; + escape_field_to_buffer( + traits::to_buf(data, data + std::size(m_field_buf), f)); + } + } + } + + /// Append string representation for a null field to @c m_buffer. + /** This special case is for types which are always null. + * + * Also appends a tab. The tab is meant to be a separator, not a terminator, + * so if you write any fields at all, you'll end up with one tab too many + * at the end of the buffer. + */ + template + std::enable_if_t::always_null> + append_to_buffer(Field const &) + { + m_buffer.append(null_field); + } + + /// Write raw COPY line into @c m_buffer, based on a container of fields. + template + std::enable_if_t> + fill_buffer(Container const &c) + { + // To avoid unnecessary allocations and deallocations, we run through c + // twice: once to determine how much buffer space we may need, and once to + // actually write it into the buffer. + std::size_t budget{0}; + for (auto const &f : c) budget += estimate_buffer(f); + m_buffer.reserve(budget); + for (auto const &f : c) append_to_buffer(f); + } + + /// Estimate how many buffer bytes we need to write tuple. + template + static std::size_t + budget_tuple(Tuple const &t, std::index_sequence) + { + return (estimate_buffer(std::get(t)) + ...); + } + + /// Write tuple of fields to @c m_buffer. + template + void append_tuple(Tuple const &t, std::index_sequence) + { + (append_to_buffer(std::get(t)), ...); + } + + /// Write raw COPY line into @c m_buffer, based on a tuple of fields. + template void fill_buffer(std::tuple const &t) + { + using indexes = std::make_index_sequence; + + m_buffer.reserve(budget_tuple(t, indexes{})); + append_tuple(t, indexes{}); + } + + /// Write raw COPY line into @c m_buffer, based on varargs fields. + template void fill_buffer(const Ts &...fields) + { + (..., append_to_buffer(fields)); + } + + constexpr static std::string_view s_classname{"stream_to"}; +}; + + +template +inline stream_to::stream_to( + transaction_base &tx, std::string_view table_name, Columns const &columns) : + stream_to{tx, table_name, std::begin(columns), std::end(columns)} +{} + + +template +inline stream_to::stream_to( + transaction_base &tx, std::string_view table_name, Iter columns_begin, + Iter columns_end) : + stream_to{ + tx, + tx.quote_name( + table_name, + separated_list(",", columns_begin, columns_end, [&tx](auto col) { + return tx.quote_name(*col); + }))} +{} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/subtransaction b/ext/libpqxx-7.7.3/include/pqxx/subtransaction new file mode 100644 index 000000000..e0d154903 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/subtransaction @@ -0,0 +1,8 @@ +/** pqxx::subtransaction class. + * + * pqxx::subtransaction is a nested transaction, i.e. one inside a transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/subtransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/subtransaction.hxx b/ext/libpqxx-7.7.3/include/pqxx/subtransaction.hxx new file mode 100644 index 000000000..e66b7a7a8 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/subtransaction.hxx @@ -0,0 +1,96 @@ +/* Definition of the pqxx::subtransaction class. + * + * pqxx::subtransaction is a nested transaction, i.e. one within a transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/subtransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SUBTRANSACTION +#define PQXX_H_SUBTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx +{ +/** + * @ingroup transactions + */ +/// "Transaction" nested within another transaction +/** A subtransaction can be executed inside a backend transaction, or inside + * another subtransaction. This can be useful when, for example, statements in + * a transaction may harmlessly fail and you don't want them to abort the + * entire transaction. Here's an example of how a temporary table may be + * dropped before re-creating it, without failing if the table did not exist: + * + * ```cxx + * void do_job(connection &C) + * { + * string const temptable = "fleetingtable"; + * + * work W(C, "do_job"); + * do_firstpart(W); + * + * // Attempt to delete our temporary table if it already existed. + * try + * { + * subtransaction S(W, "droptemp"); + * S.exec0("DROP TABLE " + temptable); + * S.commit(); + * } + * catch (undefined_table const &) + * { + * // Table did not exist. Which is what we were hoping to achieve anyway. + * // Carry on without regrets. + * } + * + * // S may have gone into a failed state and been destroyed, but the + * // upper-level transaction W is still fine. We can continue to use it. + * W.exec0("CREATE TEMP TABLE " + temptable + "(bar integer, splat + * varchar)"); + * + * do_lastpart(W); + * } + * ``` + * + * (This is just an example. If you really wanted to do drop a table without + * an error if it doesn't exist, you'd use DROP TABLE IF EXISTS.) + * + * There are no isolation levels inside a transaction. They are not needed + * because all actions within the same backend transaction are always performed + * sequentially anyway. + * + * @warning While the subtransaction is "live," you cannot execute queries or + * open streams etc. on its parent transaction. A transaction can have at most + * one object of a type derived from @ref pqxx::transaction_focus active on it + * at a time. + */ +class PQXX_LIBEXPORT subtransaction : public transaction_focus, + public dbtransaction +{ +public: + /// Nest a subtransaction nested in another transaction. + explicit subtransaction(dbtransaction &t, std::string_view tname = ""sv); + + /// Nest a subtransaction in another subtransaction. + explicit subtransaction(subtransaction &t, std::string_view name = ""sv); + + virtual ~subtransaction() noexcept override; + +private: + std::string quoted_name() const + { + return quote_name(transaction_focus::name()); + } + virtual void do_commit() override; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/time b/ext/libpqxx-7.7.3/include/pqxx/time new file mode 100644 index 000000000..85df05744 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/time @@ -0,0 +1,6 @@ +/** Date/time string conversions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/time.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/time.hxx b/ext/libpqxx-7.7.3/include/pqxx/time.hxx new file mode 100644 index 000000000..effed05e0 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/time.hxx @@ -0,0 +1,88 @@ +/** Support for date/time values. + * + * At the moment this supports dates, but not times. + */ +#ifndef PQXX_H_TIME +#define PQXX_H_TIME + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/internal/concat.hxx" +#include "pqxx/strconv.hxx" + + +#if defined(PQXX_HAVE_YEAR_MONTH_DAY) + +namespace pqxx +{ +using namespace std::literals; + +template<> +struct nullness + : no_null +{}; + + +/// String representation for a Gregorian date in ISO-8601 format. +/** @warning Experimental. There may still be design problems, particularly + * when it comes to BC years. + * + * PostgreSQL supports a choice of date formats, but libpqxx does not. The + * other formats in turn support a choice of "month before day" versus "day + * before month," meaning that it's not necessarily known which format a given + * date is supposed to be. So I repeat: ISO-8601-style format only! + * + * Invalid dates will not convert. This includes February 29 on non-leap + * years, which is why it matters that `year_month_day` represents a + * _Gregorian_ date. + * + * The range of years is limited. At the time of writing, PostgreSQL 14 + * supports years from 4713 BC to 294276 AD inclusive, and C++20 supports + * a range of 32767 BC to 32767 AD inclusive. So in practice, years must fall + * between 4713 BC and 32767 AD, inclusive. + * + * @warning Support for BC (or BCE) years is still experimental. I still need + * confirmation on this issue: it looks as if C++ years are astronomical years, + * which means they have a Year Zero. Regular BC/AD years do not have a year + * zero, so the year 1 AD follows directly after 1 BC. + * + * So, what to our calendars (and to PostgreSQL) is the year "0001 BC" seems to + * count as year "0" in a `std::chrono::year_month_day`. The year 0001 AD is + * still equal to 1 as you'd expect, and all AD years work normally, but all + * years before then are shifted by one. For instance, the year 543 BC would + * be -542 in C++. + */ +template<> struct PQXX_LIBEXPORT string_traits +{ + [[nodiscard]] static zview + to_buf(char *begin, char *end, std::chrono::year_month_day const &value) + { + return generic_to_buf(begin, end, value); + } + + static char * + into_buf(char *begin, char *end, std::chrono::year_month_day const &value); + + [[nodiscard]] static std::chrono::year_month_day + from_string(std::string_view text); + + [[nodiscard]] static std::size_t + size_buffer(std::chrono::year_month_day const &) noexcept + { + static_assert(int{(std::chrono::year::min)()} >= -99999); + static_assert(int{(std::chrono::year::max)()} <= 99999); + return 5 + 1 + 2 + 1 + 2 + std::size(s_bc) + 1; + } + +private: + /// The "BC" suffix for years before 1 AD. + static constexpr std::string_view s_bc{" BC"sv}; +}; +} // namespace pqxx +#endif // PQXX_HAVE_YEAR_MONTH_DAY +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/transaction b/ext/libpqxx-7.7.3/include/pqxx/transaction new file mode 100644 index 000000000..a7ae39d43 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transaction @@ -0,0 +1,8 @@ +/** pqxx::transaction class. + * + * pqxx::transaction represents a standard database transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/transaction.hxx b/ext/libpqxx-7.7.3/include/pqxx/transaction.hxx new file mode 100644 index 000000000..e90917e38 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transaction.hxx @@ -0,0 +1,108 @@ +/* Definition of the pqxx::transaction class. + * pqxx::transaction represents a standard database transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION +#define PQXX_H_TRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx::internal +{ +/// Helper base class for the @ref transaction class template. +class PQXX_LIBEXPORT basic_transaction : public dbtransaction +{ +protected: + basic_transaction( + connection &c, zview begin_command, std::string_view tname); + basic_transaction(connection &c, zview begin_command, std::string &&tname); + basic_transaction(connection &c, zview begin_command); + + virtual ~basic_transaction() noexcept override = 0; + +private: + virtual void do_commit() override; +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @ingroup transactions + */ +//@{ + +/// Standard back-end transaction, templatised on isolation level. +/** This is the type you'll normally want to use to represent a transaction on + * the database. + * + * Usage example: double all wages. + * + * ```cxx + * extern connection C; + * work T(C); + * try + * { + * T.exec0("UPDATE employees SET wage=wage*2"); + * T.commit(); // NOTE: do this inside try block + * } + * catch (exception const &e) + * { + * cerr << e.what() << endl; + * T.abort(); // Usually not needed; same happens when T's life ends. + * } + * ``` + */ +template< + isolation_level ISOLATION = isolation_level::read_committed, + write_policy READWRITE = write_policy::read_write> +class transaction final : public internal::basic_transaction +{ +public: + /// Begin a transaction. + /** + * @param c Connection for this transaction to operate on. + * @param tname Optional name for transaction. Must begin with a letter and + * may contain letters and digits only. + */ + transaction(connection &c, std::string_view tname) : + internal::basic_transaction{ + c, internal::begin_cmd, tname} + {} + + /// Begin a transaction. + /** + * @param c Connection for this transaction to operate on. + * may contain letters and digits only. + */ + explicit transaction(connection &c) : + internal::basic_transaction{ + c, internal::begin_cmd} + {} + + virtual ~transaction() noexcept override { close(); } +}; + + +/// The default transaction type. +using work = transaction<>; + +/// Read-only transaction. +using read_transaction = + transaction; + +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/transaction_base b/ext/libpqxx-7.7.3/include/pqxx/transaction_base new file mode 100644 index 000000000..c39219aac --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transaction_base @@ -0,0 +1,9 @@ +/** Base for the transaction classes. + * + * pqxx::transaction_base defines the interface for any abstract class that + * represents a database transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transaction_base.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/transaction_base.hxx b/ext/libpqxx-7.7.3/include/pqxx/transaction_base.hxx new file mode 100644 index 000000000..4363cc56a --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transaction_base.hxx @@ -0,0 +1,810 @@ +/* Common code and definitions for the transaction classes. + * + * pqxx::transaction_base defines the interface for any abstract class that + * represents a database transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction_base instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION_BASE +#define PQXX_H_TRANSACTION_BASE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +/* End-user programs need not include this file, unless they define their own + * transaction classes. This is not something the typical program should want + * to do. + * + * However, reading this file is worthwhile because it defines the public + * interface for the available transaction classes such as transaction and + * nontransaction. + */ + +#include "pqxx/connection.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/isolation.hxx" +#include "pqxx/result.hxx" +#include "pqxx/row.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/util.hxx" + +namespace pqxx::internal::gate +{ +class transaction_subtransaction; +class transaction_sql_cursor; +class transaction_stream_to; +class transaction_transaction_focus; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +using namespace std::literals; + + +class transaction_focus; + + +/** + * @defgroup transactions Transaction classes + * + * All database access goes through instances of these classes. + * However, not all implementations of this interface need to provide full + * transactional integrity. + * + * Several implementations of this interface are shipped with libpqxx, + * including the plain transaction class, the entirely unprotected + * nontransaction, and the more cautious robusttransaction. + */ + +/// Interface definition (and common code) for "transaction" classes. +/** + * @ingroup transactions + * + * Abstract base class for all transaction types. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base +{ +public: + transaction_base() = delete; + transaction_base(transaction_base const &) = delete; + transaction_base(transaction_base &&) = delete; + transaction_base &operator=(transaction_base const &) = delete; + transaction_base &operator=(transaction_base &&) = delete; + + virtual ~transaction_base() = 0; + + /// Commit the transaction. + /** Make the effects of this transaction definite. If you destroy a + * transaction without invoking its @ref commit() first, that will implicitly + * abort it. (For the @ref nontransaction class though, "commit" and "abort" + * really don't do anything, hence its name.) + * + * There is, however, a minute risk that you might lose your connection to + * the database at just the wrong moment here. In that case, libpqxx may be + * unable to determine whether the database was able to complete the + * transaction, or had to roll it back. In that scenario, @ref commit() will + * throw an in_doubt_error. There is a different transaction class called + * @ref robusttransaction which takes some special precautions to reduce this + * risk. + */ + void commit(); + + /// Abort the transaction. + /** No special effort is required to call this function; it will be called + * implicitly when the transaction is destructed. + */ + void abort(); + + /** + * @ingroup escaping-functions + * + * Use these when writing SQL queries that incorporate C++ values as SQL + * constants. + * + * The functions you see here are just convenience shortcuts to the same + * functions on the connection object. + */ + //@{ + /// Escape string for use as SQL string literal in this transaction. + template [[nodiscard]] auto esc(ARGS &&...args) const + { + return conn().esc(std::forward(args)...); + } + + /// Escape binary data for use as SQL string literal in this transaction. + /** Raw, binary data is treated differently from regular strings. Binary + * strings are never interpreted as text, so they may safely include byte + * values or byte sequences that don't happen to represent valid characters + * in the character encoding being used. + * + * The binary string does not stop at the first zero byte, as is the case + * with textual strings. Instead, it may contain zero bytes anywhere. If + * it happens to contain bytes that look like quote characters, or other + * things that can disrupt their use in SQL queries, they will be replaced + * with special escape sequences. + */ + template [[nodiscard]] auto esc_raw(ARGS &&...args) const + { + return conn().esc_raw(std::forward(args)...); + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(zview text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return conn().unesc_raw(text); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard]] std::basic_string unesc_bin(zview text) + { + return conn().unesc_bin(text); + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(char const *text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return conn().unesc_raw(text); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard]] std::basic_string unesc_bin(char const text[]) + { + return conn().unesc_bin(text); + } + + /// Represent object as SQL string, including quoting & escaping. + /** Nulls are recognized and represented as SQL nulls. */ + template [[nodiscard]] std::string quote(T const &t) const + { + return conn().quote(t); + } + + [[deprecated( + "Use std::basic_string instead of binarystring.")]] std::string + quote(binarystring const &t) const + { + return conn().quote(t.bytes_view()); + } + + /// Binary-escape and quote a binary string for use as an SQL constant. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(unsigned char const bin[], std::size_t len) const + { + return quote(binary_cast(bin, len)); + } + + /// Binary-escape and quote a binary string for use as an SQL constant. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(zview bin) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Binary-escape and quote a binary string for use as an SQL constant. + /** For binary data you can also just use @ref quote(data). */ + template + [[nodiscard]] std::string quote_raw(DATA const &data) const + { + return conn().quote_raw(data); + } +#endif + + /// Escape an SQL identifier for use in a query. + [[nodiscard]] std::string quote_name(std::string_view identifier) const + { + return conn().quote_name(identifier); + } + + /// Escape string for literal LIKE match. + [[nodiscard]] std::string + esc_like(std::string_view bin, char escape_char = '\\') const + { + return conn().esc_like(bin, escape_char); + } + //@} + + /** + * @name Command execution + * + * There are many functions for executing (or "performing") a command (or + * "query"). This is the most fundamental thing you can do with the library, + * and you always do it from a transaction class. + * + * Command execution can throw many types of exception, including sql_error, + * broken_connection, and many sql_error subtypes such as + * feature_not_supported or insufficient_privilege. But any exception thrown + * by the C++ standard library may also occur here. All exceptions you will + * see libpqxx throw are derived from std::exception. + * + * One unusual feature in libpqxx is that you can give your query a name or + * description. This does not mean anything to the database, but sometimes + * it can help libpqxx produce more helpful error messages, making problems + * in your code easier to debug. + * + * Many of the execution functions used to accept a `desc` argument, a + * human-readable description of the statement for use in error messages. + * This could make failures easier to debug. Future versions will use + * C++20's `std::source_location` to identify the failing statement. + */ + //@{ + + /// Execute a command. + /** + * @param query Query or command to execute. + * @param desc Optional identifier for query, to help pinpoint SQL errors. + * @return A result set describing the query's or command's result. + */ + [[deprecated("The desc parameter is going away.")]] result + exec(std::string_view query, std::string_view desc); + + /// Execute a command. + /** + * @param query Query or command to execute. + * @return A result set describing the query's or command's result. + */ + result exec(std::string_view query) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec(query, std::string_view{}); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute a command. + /** + * @param query Query or command to execute. + * @param desc Optional identifier for query, to help pinpoint SQL errors. + * @return A result set describing the query's or command's result. + */ + [[deprecated( + "Pass your query as a std::string_view, not stringstream.")]] result + exec(std::stringstream const &query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec(query.str(), desc); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command, which should return zero rows of data. + /** Works like @ref exec, but fails if the result contains data. It still + * returns a result, however, which may contain useful metadata. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] result + exec0(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(0, query, desc); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command, which should return zero rows of data. + /** Works like @ref exec, but fails if the result contains data. It still + * returns a result, however, which may contain useful metadata. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + result exec0(zview query) { return exec_n(0, query); } + + /// Execute command returning a single row of data. + /** Works like @ref exec, but requires the result to contain exactly one row. + * The row can be addressed directly, without the need to find the first row + * in a result set. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] row + exec1(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(1, query, desc).front(); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command returning a single row of data. + /** Works like @ref exec, but requires the result to contain exactly one row. + * The row can be addressed directly, without the need to find the first row + * in a result set. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + row exec1(zview query) { return exec_n(1, query).front(); } + + /// Execute command, expect given number of rows. + /** Works like @ref exec, but checks that the result has exactly the expected + * number of rows. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] result + exec_n(result::size_type rows, zview query, std::string_view desc); + + /// Execute command, expect given number of rows. + /** Works like @ref exec, but checks that the result has exactly the expected + * number of rows. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + result exec_n(result::size_type rows, zview query) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(rows, query, std::string_view{}); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Perform query, expecting exactly 1 row with 1 field, and convert it. + /** This is convenience shorthand for querying exactly one value from the + * database. It returns that value, converted to the type you specify. + */ + template + [[deprecated("The desc parameter is going away.")]] TYPE + query_value(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row const r{exec1(query, desc)}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + if (std::size(r) != 1) + throw usage_error{internal::concat( + "Queried single value from result with ", std::size(r), " columns.")}; + return r[0].as(); + } + + /// Perform query, expecting exactly 1 row with 1 field, and convert it. + /** This is convenience shorthand for querying exactly one value from the + * database. It returns that value, converted to the type you specify. + */ + template TYPE query_value(zview query) + { + row const r{exec1(query)}; + if (std::size(r) != 1) + throw usage_error{internal::concat( + "Queried single value from result with ", std::size(r), " columns.")}; + return r[0].as(); + } + + /// Execute a query, and loop over the results row by row. + /** Converts the rows to `std::tuple`, of the column types you specify. + * + * Use this with a range-based "for" loop. It executes the query, and + * directly maps the resulting rows onto a `std::tuple` of the types you + * specify. It starts before all the data from the server is in, so if your + * network connection to the server breaks while you're iterating, you'll get + * an exception partway through. + * + * The stream lives entirely within the lifetime of the transaction. Make + * sure you destroy the stream before you destroy the transaction. Either + * iterate the stream all the way to the end, or destroy first the stream + * and then the transaction without touching either in any other way. Until + * the stream has finished, the transaction is in a special state where it + * cannot execute queries. + * + * As a special case, tuple may contain `std::string_view` fields, but the + * strings to which they point will only remain valid until you extract the + * next row. After that, the memory holding the string may be overwritten or + * deallocated. + * + * If any of the columns can be null, and the C++ type to which it translates + * does not have a null value, wrap the type in `std::optional` (or if + * you prefer, `std::shared_ptr` or `std::unique_ptr)`. These templates + * do recognise null values, and libpqxx will know how to convert to them. + * + * The connection is in a special state until the iteration finishes. So if + * it does not finish due to a `break` or a `return` or an exception, then + * the entire connection becomes effectively unusable. + * + * Querying in this way is faster than the `exec()` methods for larger + * results (but slower for small ones). You can start processing rows before + * the full result is in. Also, `stream()` scales better in terms of memory + * usage. Where @ref exec() reads the entire result into memory at once, + * `stream()` will read and process one row at at a time. + * + * Your query executes as part of a COPY command, not as a stand-alone query, + * so there are limitations to what you can do in the query. It can be + * either a SELECT or VALUES query; or an INSERT, UPDATE, or DELETE with a + * RETURNING clause. See the documentation for PostgreSQL's COPY command for + * the details: + * + * https://www.postgresql.org/docs/current/sql-copy.html + * + * Iterating in this way does require each of the field types you pass to be + * default-constructible, copy-constructible, and assignable. These + * requirements may be loosened once libpqxx moves on to C++20. + */ + template + [[nodiscard]] auto stream(std::string_view query) & + { + // Tricky: std::make_unique() supports constructors but not RVO functions. + return pqxx::internal::owning_stream_input_iteration{ + std::unique_ptr{ + new stream_from{stream_from::query(*this, query)}}}; + } + + // C++20: Concept like std::invocable, but without specifying param types. + /// Perform a streaming query, and for each result row, call `func`. + /** Here, `func` can be a function, a `std::function`, a lambda, or an + * object that supports the function call operator. Of course `func` must + * have an unambiguous signature; it can't be overloaded or generic. + * + * The `for_each` function executes `query` in a stream using + * @ref pqxx::stream_from. Every time a row of data comes in from the + * server, it converts the row's fields to the types of `func`'s respective + * parameters, and calls `func` with those values. + * + * This will not work for all queries, but straightforward `SELECT` and + * `UPDATE ... RETURNING` queries should work. Consult the documentation for + * @ref pqxx::stream_from and PostgreSQL's underlying `COPY` command for the + * full details. + * + * Streaming a query like this is likely to be slower than the @ref exec() + * functions for small result sets, but faster for large result sets. So if + * performance matters, you'll want to use `for_each` if you query large + * amounts of data, but not if you do lots of queries with small outputs. + */ + template + inline auto for_each(std::string_view query, CALLABLE &&func) + { + using param_types = + pqxx::internal::strip_types_t>; + param_types const *const sample{nullptr}; + auto data_stream{stream_like(query, sample)}; + for (auto const &fields : data_stream) std::apply(func, fields); + } + + /** + * @name Parameterized statements + * + * You'll often need parameters in the queries you execute: "select the + * car with this licence plate." If the parameter is a string, you need to + * quote it and escape any special characters inside it, or it may become a + * target for an SQL injection attack. If it's an integer (for example), + * you need to convert it to a string, but in the database's format, without + * locale-specific niceties like "," separators between the thousands. + * + * Parameterised statements are an easier and safer way to do this. They're + * like prepared statements, but for a single use. You don't need to name + * them, and you don't need to prepare them first. + * + * Your query will include placeholders like `$1` and `$2` etc. in the places + * where you want the arguments to go. Then, you pass the argument values + * and the actual query is constructed for you. + * + * Pass the exact right number of parameters, and in the right order. The + * parameters in the query don't have to be neatly ordered from `$1` to + * `$2` to `$3` - but you must pass the argument for `$1` first, the one + * for `$2` second, etc. + * + * @warning Beware of "nul" bytes. Any string you pass as a parameter will + * end at the first char with value zero. If you pass a string that contains + * a zero byte, the last byte in the value will be the one just before the + * zero. + */ + //@{ + /// Execute an SQL statement with parameters. + template result exec_params(zview query, Args &&...args) + { + params pp(args...); + return internal_exec_params(query, pp.make_c_params()); + } + + // Execute parameterised statement, expect a single-row result. + /** @throw unexpected_rows if the result does not consist of exactly one row. + */ + template row exec_params1(zview query, Args &&...args) + { + return exec_params_n(1, query, std::forward(args)...).front(); + } + + // Execute parameterised statement, expect a result with zero rows. + /** @throw unexpected_rows if the result contains rows. + */ + template result exec_params0(zview query, Args &&...args) + { + return exec_params_n(0, query, std::forward(args)...); + } + + // Execute parameterised statement, expect exactly a given number of rows. + /** @throw unexpected_rows if the result contains the wrong number of rows. + */ + template + result exec_params_n(std::size_t rows, zview query, Args &&...args) + { + auto const r{exec_params(query, std::forward(args)...)}; + check_rowcount_params(rows, std::size(r)); + return r; + } + //@} + + /** + * @name Prepared statements + * + * These are very similar to parameterised statements. The difference is + * that you prepare them in advance, giving them identifying names. You can + * then call them by these names, passing in the argument values appropriate + * for that call. + * + * You prepare a statement on the connection, using + * @ref pqxx::connection::prepare(). But you then call the statement in a + * transaction, using the functions you see here. + * + * Never try to prepare, execute, or unprepare a prepared statement manually + * using direct SQL queries when you also use the libpqxx equivalents. For + * any given statement, either prepare, manage, and execute it through the + * dedicated libpqxx functions; or do it all directly in SQL. Don't mix the + * two, or the code may get confused. + * + * See \ref prepared for a full discussion. + * + * @warning Beware of "nul" bytes. Any string you pass as a parameter will + * end at the first char with value zero. If you pass a string that contains + * a zero byte, the last byte in the value will be the one just before the + * zero. If you need a zero byte, you're dealing with binary strings, not + * regular strings. Represent binary strings on the SQL side as `BYTEA` + * (or as large objects). On the C++ side, use types like + * `std::basic_string` or `std::basic_string_view` + * or (in C++20) `std::vector`. Also, consider large objects on + * the SQL side and @ref blob on the C++ side. + */ + //@{ + + /// Execute a prepared statement, with optional arguments. + template + result exec_prepared(zview statement, Args &&...args) + { + params pp(args...); + return internal_exec_prepared(statement, pp.make_c_params()); + } + + /// Execute a prepared statement, and expect a single-row result. + /** @throw pqxx::unexpected_rows if the result was not exactly 1 row. + */ + template + row exec_prepared1(zview statement, Args &&...args) + { + return exec_prepared_n(1, statement, std::forward(args)...).front(); + } + + /// Execute a prepared statement, and expect a result with zero rows. + /** @throw pqxx::unexpected_rows if the result contained rows. + */ + template + result exec_prepared0(zview statement, Args &&...args) + { + return exec_prepared_n(0, statement, std::forward(args)...); + } + + /// Execute a prepared statement, expect a result with given number of rows. + /** @throw pqxx::unexpected_rows if the result did not contain exactly the + * given number of rows. + */ + template + result + exec_prepared_n(result::size_type rows, zview statement, Args &&...args) + { + auto const r{exec_prepared(statement, std::forward(args)...)}; + check_rowcount_prepared(statement, rows, std::size(r)); + return r; + } + + //@} + + /** + * @name Error/warning output + */ + //@{ + /// Have connection process a warning message. + void process_notice(char const msg[]) const { m_conn.process_notice(msg); } + /// Have connection process a warning message. + void process_notice(zview msg) const { m_conn.process_notice(msg); } + //@} + + /// The connection in which this transaction lives. + [[nodiscard]] constexpr connection &conn() const noexcept { return m_conn; } + + /// Set session variable using SQL "SET" command. + /** @deprecated To set a transaction-local variable, execute an SQL `SET` + * command. To set a session variable, use the connection's + * @ref set_session_var function. + * + * @warning When setting a string value, you must make sure that the string + * is "safe." If you call @ref quote() on the string, it will return a + * safely escaped and quoted version for use as an SQL literal. + * + * @warning This function executes SQL. Do not try to set or get variables + * while a pipeline or table stream is active. + * + * @param var The variable to set. + * @param value The new value to store in the variable. This can be any SQL + * expression. + */ + [[deprecated( + "Set transaction-local variables using SQL SET statements.")]] void + set_variable(std::string_view var, std::string_view value); + + /// Read session variable using SQL "SHOW" command. + /** @warning This executes SQL. Do not try to set or get variables while a + * pipeline or table stream is active. + */ + [[deprecated("Read variables using SQL SHOW statements.")]] std::string + get_variable(std::string_view); + + // C++20: constexpr. + /// Transaction name, if you passed one to the constructor; or empty string. + [[nodiscard]] std::string_view name() const &noexcept { return m_name; } + +protected: + /// Create a transaction (to be called by implementation classes only). + /** The name, if nonempty, must begin with a letter and may contain letters + * and digits only. + */ + transaction_base( + connection &c, std::string_view tname, + std::shared_ptr rollback_cmd) : + m_conn{c}, m_name{tname}, m_rollback_cmd{rollback_cmd} + {} + + /// Create a transaction (to be called by implementation classes only). + /** Its rollback command will be "ROLLBACK". + * + * The name, if nonempty, must begin with a letter and may contain letters + * and digits only. + */ + transaction_base(connection &c, std::string_view tname); + + /// Create a transaction (to be called by implementation classes only). + explicit transaction_base(connection &c); + + /// Register this transaction with the connection. + void register_transaction(); + + /// End transaction. To be called by implementing class' destructor. + void close() noexcept; + + /// To be implemented by derived implementation class: commit transaction. + virtual void do_commit() = 0; + + /// Transaction type-specific way of aborting a transaction. + /** @warning This will become "final", since this function can be called + * from the implementing class destructor. + */ + virtual void do_abort(); + + /// Set the rollback command. + void set_rollback_cmd(std::shared_ptr cmd) + { + m_rollback_cmd = cmd; + } + + /// Execute query on connection directly. + result direct_exec(std::string_view, std::string_view desc = ""sv); + result + direct_exec(std::shared_ptr, std::string_view desc = ""sv); + +private: + enum class status + { + active, + aborted, + committed, + in_doubt + }; + + PQXX_PRIVATE void check_pending_error(); + + result + internal_exec_prepared(zview statement, internal::c_params const &args); + + result internal_exec_params(zview query, internal::c_params const &args); + + /// Throw unexpected_rows if prepared statement returned wrong no. of rows. + void check_rowcount_prepared( + zview statement, result::size_type expected_rows, + result::size_type actual_rows); + + /// Throw unexpected_rows if wrong row count from parameterised statement. + void + check_rowcount_params(std::size_t expected_rows, std::size_t actual_rows); + + /// Describe this transaction to humans, e.g. "transaction 'foo'". + [[nodiscard]] std::string description() const; + + friend class pqxx::internal::gate::transaction_transaction_focus; + PQXX_PRIVATE void register_focus(transaction_focus *); + PQXX_PRIVATE void unregister_focus(transaction_focus *) noexcept; + PQXX_PRIVATE void register_pending_error(zview) noexcept; + PQXX_PRIVATE void register_pending_error(std::string &&) noexcept; + + /// Like @ref stream(), but takes a tuple rather than a parameter pack. + template + auto stream_like(std::string_view query, std::tuple const *) + { + return stream(query); + } + + connection &m_conn; + + /// Current "focus": a pipeline, a nested transaction, a stream... + /** This pointer is used for only one purpose: sanity checks against mistakes + * such as opening one while another is still active. + */ + transaction_focus const *m_focus = nullptr; + + status m_status = status::active; + bool m_registered = false; + std::string m_name; + std::string m_pending_error; + + /// SQL command for aborting this type of transaction. + std::shared_ptr m_rollback_cmd; + + static constexpr std::string_view s_type_name{"transaction"sv}; +}; + + +// C++20: Can borrowed_range help? +/// Forbidden specialisation: underlying buffer immediately goes out of scope. +template<> +std::string_view transaction_base::query_value( + zview query, std::string_view desc) = delete; +/// Forbidden specialisation: underlying buffer immediately goes out of scope. +template<> +zview transaction_base::query_value( + zview query, std::string_view desc) = delete; + +} // namespace pqxx + + +namespace pqxx::internal +{ +/// The SQL command for starting a given type of transaction. +template +extern const zview begin_cmd; + +// These are not static members, so "constexpr" does not imply "inline". +template<> +inline constexpr zview begin_cmd{ + "BEGIN"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN READ ONLY"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL REPEATABLE READ"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL SERIALIZABLE"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY"_zv}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/transaction_focus b/ext/libpqxx-7.7.3/include/pqxx/transaction_focus new file mode 100644 index 000000000..fe78a9bcc --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transaction_focus @@ -0,0 +1,7 @@ +/** + * Transaction focus: types which monopolise a transaction's attention. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/types.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/transaction_focus.hxx b/ext/libpqxx-7.7.3/include/pqxx/transaction_focus.hxx new file mode 100644 index 000000000..0707e3cc4 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transaction_focus.hxx @@ -0,0 +1,89 @@ +/** Transaction focus: types which monopolise a transaction's attention. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION_FOCUS +#define PQXX_H_TRANSACTION_FOCUS + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Base class for things that monopolise a transaction's attention. +/** You probably won't need to use this class. But it can be useful to _know_ + * that a given libpqxx class is derived from it. + * + * Pipelines, SQL statements, and data streams are examples of classes derived + * from `transaction_focus`. For any given transaction, only one object of + * such a class can be active at any given time. + */ +class PQXX_LIBEXPORT transaction_focus +{ +public: + transaction_focus( + transaction_base &t, std::string_view cname, std::string_view oname) : + m_trans{t}, m_classname{cname}, m_name{oname} + {} + + transaction_focus( + transaction_base &t, std::string_view cname, std::string &&oname) : + m_trans{t}, m_classname{cname}, m_name{std::move(oname)} + {} + + transaction_focus(transaction_base &t, std::string_view cname) : + m_trans{t}, m_classname{cname} + {} + + transaction_focus() = delete; + transaction_focus(transaction_focus const &) = delete; + transaction_focus &operator=(transaction_focus const &) = delete; + + /// Class name, for human consumption. + [[nodiscard]] constexpr std::string_view classname() const noexcept + { + return m_classname; + } + + /// Name for this object, if the caller passed one; empty string otherwise. + [[nodiscard]] std::string_view name() const &noexcept { return m_name; } + + [[nodiscard]] std::string description() const + { + return pqxx::internal::describe_object(m_classname, m_name); + } + + /// Can't move a transaction_focus. + /** Moving the transaction_focus would break the transaction's reference back + * to the object. + */ + transaction_focus(transaction_focus &&) = delete; + + /// Can't move a transaction_focus. + /** Moving the transaction_focus would break the transaction's reference back + * to the object. + */ + transaction_focus &operator=(transaction_focus &&) = delete; + +protected: + void register_me(); + void unregister_me() noexcept; + void reg_pending_error(std::string const &) noexcept; + bool registered() const noexcept { return m_registered; } + + transaction_base &m_trans; + +private: + bool m_registered = false; + std::string_view m_classname; + std::string m_name; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/transactor b/ext/libpqxx-7.7.3/include/pqxx/transactor new file mode 100644 index 000000000..29d1b9640 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transactor @@ -0,0 +1,8 @@ +/** pqxx::transactor class. + * + * pqxx::transactor is a framework-style wrapper for safe transactions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transactor.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/transactor.hxx b/ext/libpqxx-7.7.3/include/pqxx/transactor.hxx new file mode 100644 index 000000000..eefd04ba1 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transactor.hxx @@ -0,0 +1,147 @@ +/* Transactor framework, a wrapper for safely retryable transactions. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transactor instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTOR +#define PQXX_H_TRANSACTOR + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/connection.hxx" +#include "pqxx/transaction.hxx" + +namespace pqxx +{ +/** + * @defgroup transactor Transactor framework + * + * Sometimes a transaction can fail for completely transient reasons, such as a + * conflict with another transaction in SERIALIZABLE isolation. The right way + * to handle those failures is often just to re-run the transaction from + * scratch. + * + * For example, your REST API might be handling each HTTP request in its own + * database transaction, and if this kind of transient failure happens, you + * simply want to "replay" the whole request, in a fresh transaction. + * + * You won't necessarily want to execute the exact same SQL commands with the + * exact same data. Some of your SQL statements may depend on state that can + * vary between retries. Data in the database may already have changed, for + * instance. So instead of dumbly replaying the SQL, you re-run the same + * application code that produced those SQL commands, from the start. + * + * The transactor framework makes it a little easier for you to do this safely, + * and avoid typical pitfalls. You encapsulate the work that you want to do + * into a callable that you pass to the @ref perform function. + * + * Here's how it works. You write your transaction code as a lambda or + * function, which creates its own transaction object, does its work, and + * commits at the end. You pass that callback to @ref pqxx::perform, which + * runs it for you. + * + * If there's a failure inside your callback, there will be an exception. Your + * transaction object goes out of scope and gets destroyed, so that it aborts + * implicitly. Seeing this, @ref perform tries running your callback again. It + * stops doing that when the callback succeeds, or when it has failed too many + * times, or when there's an error that leaves the database in an unknown + * state, such as a lost connection just while we're waiting for the database + * to confirm a commit. It all depends on the type of exception. + * + * The callback takes no arguments. If you're using lambdas, the easy way to + * pass arguments is for the lambda to "capture" them from your variables. Or, + * if you're using functions, you may want to use `std::bind`. + * + * Once your callback succeeds, it can return a result, and @ref perform will + * return that result back to you. + */ +//@{ + +/// Simple way to execute a transaction with automatic retry. +/** + * Executes your transaction code as a callback. Repeats it until it completes + * normally, or it throws an error other than the few libpqxx-generated + * exceptions that the framework understands, or after a given number of failed + * attempts, or if the transaction ends in an "in-doubt" state. + * + * (An in-doubt state is one where libpqxx cannot determine whether the server + * finally committed a transaction or not. This can happen if the network + * connection to the server is lost just while we're waiting for its reply to + * a "commit" statement. The server may have completed the commit, or not, but + * it can't tell you because there's no longer a connection. + * + * Using this still takes a bit of care. If your callback makes use of data + * from the database, you'll probably have to query that data within your + * callback. If the attempt to perform your callback fails, and the framework + * tries again, you'll be in a new transaction and the data in the database may + * have changed under your feet. + * + * Also be careful about changing variables or data structures from within + * your callback. The run may still fail, and perhaps get run again. The + * ideal way to do it (in most cases) is to return your result from your + * callback, and change your program's data state only after @ref perform + * completes successfully. + * + * @param callback Transaction code that can be called with no arguments. + * @param attempts Maximum number of times to attempt performing callback. + * Must be greater than zero. + * @return Whatever your callback returns. + */ +template +inline auto perform(TRANSACTION_CALLBACK &&callback, int attempts = 3) + -> std::invoke_result_t +{ + if (attempts <= 0) + throw std::invalid_argument{ + "Zero or negative number of attempts passed to pqxx::perform()."}; + + for (; attempts > 0; --attempts) + { + try + { + return std::invoke(callback); + } + catch (in_doubt_error const &) + { + // Not sure whether transaction went through or not. The last thing in + // the world that we should do now is try again! + throw; + } + catch (statement_completion_unknown const &) + { + // Not sure whether our last statement succeeded. Don't risk running it + // again. + throw; + } + catch (broken_connection const &) + { + // Connection failed. May be worth retrying, if the transactor opens its + // own connection. + if (attempts <= 1) + throw; + continue; + } + catch (transaction_rollback const &) + { + // Some error that may well be transient, such as serialization failure + // or deadlock. Worth retrying. + if (attempts <= 1) + throw; + continue; + } + } + throw pqxx::internal_error{"No outcome reached on perform()."}; +} +} // namespace pqxx +//@} +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/types b/ext/libpqxx-7.7.3/include/pqxx/types new file mode 100644 index 000000000..23a5caae1 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/types @@ -0,0 +1,7 @@ +/** + * Basic typedefs and forward declarations. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/types.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/types.hxx b/ext/libpqxx-7.7.3/include/pqxx/types.hxx new file mode 100644 index 000000000..f95b598f8 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/types.hxx @@ -0,0 +1,173 @@ +/* Basic type aliases and forward declarations. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TYPES +#define PQXX_H_TYPES + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#if defined(PQXX_HAVE_CONCEPTS) && __has_include() +# include +#endif + + +namespace pqxx +{ +/// Number of rows in a result set. +using result_size_type = int; + +/// Difference between result sizes. +using result_difference_type = int; + +/// Number of fields in a row of database data. +using row_size_type = int; + +/// Difference between row sizes. +using row_difference_type = int; + +/// Number of bytes in a field of database data. +using field_size_type = std::size_t; + +/// Number of bytes in a large object. +using large_object_size_type = int64_t; + + +// Forward declarations, to help break compilation dependencies. +// These won't necessarily include all classes in libpqxx. +class binarystring; +class connection; +class const_result_iterator; +class const_reverse_result_iterator; +class const_reverse_row_iterator; +class const_row_iterator; +class dbtransaction; +class field; +class largeobjectaccess; +class notification_receiver; +struct range_error; +class result; +class row; +class stream_from; +class transaction_base; + +/// Marker for @ref stream_from constructors: "stream from table." +/** @deprecated Use @ref stream_from::table() instead. + */ +struct from_table_t +{}; + +/// Marker for @ref stream_from constructors: "stream from query." +/** @deprecated Use @ref stream_from::query() instead. + */ +struct from_query_t +{}; + + +/// Format code: is data text or binary? +/** Binary-compatible with libpq's format codes. + */ +enum class format : int +{ + text = 0, + binary = 1, +}; + + +/// Remove any constness, volatile, and reference-ness from a type. +/** @deprecated In C++20 we'll replace this with std::remove_cvref. + */ +template +using strip_t = std::remove_cv_t>; + + +#if defined(PQXX_HAVE_CONCEPTS) +/// The type of a container's elements. +/** At the time of writing there's a similar thing in `std::experimental`, + * which we may or may not end up using for this. + */ +template +using value_type = strip_t()))>; +#else // PQXX_HAVE_CONCEPTS +/// The type of a container's elements. +/** At the time of writing there's a similar thing in `std::experimental`, + * which we may or may not end up using for this. + */ +template +using value_type = strip_t()))>; +#endif // PQXX_HAVE_CONCEPTS + + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: Any type that we can read as a string of `char`. +template +concept char_string = std::ranges::contiguous_range and + std::same_as < strip_t>, +char > ; + +/// Concept: Anything we can iterate to get things we can read as strings. +template +concept char_strings = + std::ranges::range and char_string>>; + +/// Concept: Anything we might want to treat as binary data. +template +concept potential_binary = std::ranges::contiguous_range and + (sizeof(value_type) == 1); +#endif // PQXX_HAVE_CONCEPTS + + +// C++20: Retire these compatibility definitions. +#if defined(PQXX_HAVE_CONCEPTS) + +/// Template argument type for a range. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_RANGE_ARG std::ranges::range + +/// Template argument type for @ref char_string. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRING_ARG pqxx::char_string + +/// Template argument type for @ref char_strings +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRINGS_ARG pqxx::char_strings + +#else // PQXX_HAVE_CONCEPTS + +/// Template argument type for a range. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_RANGE_ARG typename + +/// Template argument type for @ref char_string. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRING_ARG typename + +/// Template argument type for @ref char_strings +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRINGS_ARG typename + +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/util b/ext/libpqxx-7.7.3/include/pqxx/util new file mode 100644 index 000000000..6d85ab611 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/util @@ -0,0 +1,6 @@ +/** Various utility definitions for libpqxx. + */ +// Actual definitions in .hxx file so editors and such recognize file type +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/util.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/util.hxx b/ext/libpqxx-7.7.3/include/pqxx/util.hxx new file mode 100644 index 000000000..4aa5ecf57 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/util.hxx @@ -0,0 +1,521 @@ +/* Various utility definitions for libpqxx. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/util instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_UTIL +#define PQXX_H_UTIL + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if __has_include() +# include +#endif + +#include "pqxx/except.hxx" +#include "pqxx/internal/encodings.hxx" +#include "pqxx/types.hxx" +#include "pqxx/version.hxx" + + +/// The home of all libpqxx classes, functions, templates, etc. +namespace pqxx +{} + +#include + + +/// Internal items for libpqxx' own use. Do not use these yourself. +namespace pqxx::internal +{ + +// C++20: Retire wrapper. +/// Same as `std::cmp_less`, or a workaround where that's not available. +template +inline constexpr bool cmp_less(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_less(lhs, rhs); +#else + // We need a variable just because lgtm.com gives off a false positive + // warning when we compare the values directly. It considers that a + // "self-comparison." + constexpr bool left_signed{std::is_signed_v}; + if constexpr (left_signed == std::is_signed_v) + return lhs < rhs; + else if constexpr (std::is_signed_v) + return (lhs <= 0) ? true : (std::make_unsigned_t(lhs) < rhs); + else + return (rhs <= 0) ? false : (lhs < std::make_unsigned_t(rhs)); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_greater, or workaround if not available. +template +inline constexpr bool cmp_greater(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_greater(lhs, rhs); +#else + return cmp_less(rhs, lhs); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_less_equal, or workaround if not available. +template +inline constexpr bool cmp_less_equal(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_less_equal(lhs, rhs); +#else + return not cmp_less(rhs, lhs); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_greater_equal, or workaround if not available. +template +inline constexpr bool cmp_greater_equal(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_greater_equal(lhs, rhs); +#else + return not cmp_less(lhs, rhs); +#endif +} + + +/// Efficiently concatenate two strings. +/** This is a special case of concatenate(), needed because dependency + * management does not let us use that function here. + */ +[[nodiscard]] inline std::string cat2(std::string_view x, std::string_view y) +{ + std::string buf; + auto const xs{std::size(x)}, ys{std::size(y)}; + buf.resize(xs + ys); + x.copy(std::data(buf), xs); + y.copy(std::data(buf) + xs, ys); + return buf; +} +} // namespace pqxx::internal + + +namespace pqxx +{ +using namespace std::literals; + +/// Suppress compiler warning about an unused item. +template inline constexpr void ignore_unused(T &&...) noexcept +{} + + +/// Cast a numeric value to another type, or throw if it underflows/overflows. +/** Both types must be arithmetic types, and they must either be both integral + * or both floating-point types. + */ +template +inline TO check_cast(FROM value, std::string_view description) +{ + static_assert(std::is_arithmetic_v); + static_assert(std::is_arithmetic_v); + static_assert(std::is_integral_v == std::is_integral_v); + + // The rest of this code won't quite work for bool, but bool is trivially + // convertible to other arithmetic types as far as I can see. + if constexpr (std::is_same_v) + return static_cast(value); + + // Depending on our "if constexpr" conditions, this parameter may not be + // needed. Some compilers will warn. + ignore_unused(description); + + using from_limits = std::numeric_limits; + using to_limits = std::numeric_limits; + if constexpr (std::is_signed_v) + { + if constexpr (std::is_signed_v) + { + if (value < to_limits::lowest()) + throw range_error{internal::cat2("Cast underflow: "sv, description)}; + } + else + { + // FROM is signed, but TO is not. Treat this as a special case, because + // there may not be a good broader type in which the compiler can even + // perform our check. + if (value < 0) + throw range_error{internal::cat2( + "Casting negative value to unsigned type: "sv, description)}; + } + } + else + { + // No need to check: the value is unsigned so can't fall below the range + // of the TO type. + } + + if constexpr (std::is_integral_v) + { + using unsigned_from = std::make_unsigned_t; + using unsigned_to = std::make_unsigned_t; + constexpr auto from_max{static_cast((from_limits::max)())}; + constexpr auto to_max{static_cast((to_limits::max)())}; + if constexpr (from_max > to_max) + { + if (internal::cmp_greater(value, to_max)) + throw range_error{internal::cat2("Cast overflow: "sv, description)}; + } + } + else if constexpr ((from_limits::max)() > (to_limits::max)()) + { + if (value > (to_limits::max)()) + throw range_error{internal::cat2("Cast overflow: ", description)}; + } + + return static_cast(value); +} + + +/** Check library version at link time. + * + * Ensures a failure when linking an application against a radically + * different libpqxx version than the one against which it was compiled. + * + * Sometimes application builds fail in unclear ways because they compile + * using headers from libpqxx version X, but then link against libpqxx + * binary version Y. A typical scenario would be one where you're building + * against a libpqxx which you have built yourself, but a different version + * is installed on the system. + * + * The check_library_version template is declared for any library version, + * but only actually defined for the version of the libpqxx binary against + * which the code is linked. + * + * If the library binary is a different version than the one declared in + * these headers, then this call will fail to link: there will be no + * definition for the function with these exact template parameter values. + * There will be a definition, but the version in the parameter values will + * be different. + */ +inline PQXX_PRIVATE void check_version() noexcept +{ + // There is no particular reason to do this here in @ref connection, except + // to ensure that every meaningful libpqxx client will execute it. The call + // must be in the execution path somewhere or the compiler won't try to link + // it. We can't use it to initialise a global or class-static variable, + // because a smart compiler might resolve it at compile time. + // + // On the other hand, we don't want to make a useless function call too + // often for performance reasons. A local static variable is initialised + // only on the definition's first execution. Compilers will be well + // optimised for this behaviour, so there's a minimal one-time cost. + static auto const version_ok{internal::PQXX_VERSION_CHECK()}; + ignore_unused(version_ok); +} + + +/// Descriptor of library's thread-safety model. +/** This describes what the library knows about various risks to thread-safety. + */ +struct PQXX_LIBEXPORT thread_safety_model +{ + /// Is the underlying libpq build thread-safe? + bool safe_libpq = false; + + /// Is Kerberos thread-safe? + /** @warning Is currently always `false`. + * + * If your application uses Kerberos, all accesses to libpqxx or Kerberos + * must be serialized. Confine their use to a single thread, or protect it + * with a global lock. + */ + bool safe_kerberos = false; + + /// A human-readable description of any thread-safety issues. + std::string description; +}; + + +/// Describe thread safety available in this build. +[[nodiscard]] PQXX_LIBEXPORT thread_safety_model describe_thread_safety(); + + +#if defined(PQXX_HAVE_CONCEPTS) +# define PQXX_POTENTIAL_BINARY_ARG pqxx::potential_binary +#else +# define PQXX_POTENTIAL_BINARY_ARG typename +#endif + + +/// Cast binary data to a type that libpqxx will recognise as binary. +/** There are many different formats for storing binary data in memory. You + * may have yours as a `std::string`, or a `std::vector`, or one of + * many other types. + * + * But for libpqxx to recognise your data as binary, it needs to be a + * `std::basic_string`, or a `std::basic_string_view`; + * or in C++20 or better, any contiguous block of `std::byte`. + * + * Use `binary_cast` as a convenience helper to cast your data as a + * `std::basic_string_view`. + * + * @warning There are two things you should be aware of! First, the data must + * be contiguous in memory. In C++20 the compiler will enforce this, but in + * C++17 it's your own problem. Second, you must keep the object where you + * store the actual data alive for as long as you might use this function's + * return value. + */ +template +std::basic_string_view binary_cast(TYPE const &data) +{ + static_assert(sizeof(value_type) == 1); + return { + reinterpret_cast( + const_cast const *>( + std::data(data))), + std::size(data)}; +} + + +#if defined(PQXX_HAVE_CONCEPTS) +template +concept char_sized = (sizeof(CHAR) == 1); +# define PQXX_CHAR_SIZED_ARG char_sized +#else +# define PQXX_CHAR_SIZED_ARG typename +#endif + +/// Construct a type that libpqxx will recognise as binary. +/** Takes a data pointer and a size, without being too strict about their + * types, and constructs a `std::basic_string_view` pointing to + * the same data. + * + * This makes it a little easier to turn binary data, in whatever form you + * happen to have it, into binary data as libpqxx understands it. + */ +template +std::basic_string_view binary_cast(CHAR const *data, SIZE size) +{ + static_assert(sizeof(CHAR) == 1); + return { + reinterpret_cast(data), + check_cast(size, "binary data size")}; +} + + +/// The "null" oid. +constexpr oid oid_none{0}; +} // namespace pqxx + + +/// Private namespace for libpqxx's internal use; do not access. +/** This namespace hides definitions internal to libpqxx. These are not + * supposed to be used by client programs, and they may change at any time + * without notice. + * + * Conversely, if you find something in this namespace tremendously useful, by + * all means do lodge a request for its publication. + * + * @warning Here be dragons! + */ +namespace pqxx::internal +{ +using namespace std::literals; + + +/// A safer and more generic replacement for `std::isdigit`. +/** Turns out `std::isdigit` isn't as easy to use as it sounds. It takes an + * `int`, but requires it to be nonnegative. Which means it's an outright + * liability on systems where `char` is signed. + */ +template inline constexpr bool is_digit(CHAR c) noexcept +{ + return (c >= '0') and (c <= '9'); +} + + +/// Describe an object for humans, based on class name and optional name. +/** Interprets an empty name as "no name given." + */ +[[nodiscard]] std::string +describe_object(std::string_view class_name, std::string_view name); + + +/// Check validity of registering a new "guest" in a "host." +/** The host might be e.g. a connection, and the guest a transaction. The + * host can only have one guest at a time, so it is an error to register a new + * guest while the host already has a guest. + * + * If the new registration is an error, this function throws a descriptive + * exception. + * + * Pass the old guest (if any) and the new guest (if any), for both, a type + * name (at least if the guest is not null), and optionally an object name + * (but which may be omitted if the caller did not assign one). + */ +void check_unique_register( + void const *old_guest, std::string_view old_class, std::string_view old_name, + void const *new_guest, std::string_view new_class, + std::string_view new_name); + + +/// Like @ref check_unique_register, but for un-registering a guest. +/** Pass the guest which was registered, as well as the guest which is being + * unregistered, so that the function can check that they are the same one. + */ +void check_unique_unregister( + void const *old_guest, std::string_view old_class, std::string_view old_name, + void const *new_guest, std::string_view new_class, + std::string_view new_name); + + +/// Compute buffer size needed to escape binary data for use as a BYTEA. +/** This uses the hex-escaping format. The return value includes room for the + * "\x" prefix. + */ +inline constexpr std::size_t size_esc_bin(std::size_t binary_bytes) noexcept +{ + return 2 + (2 * binary_bytes) + 1; +} + + +/// Compute binary size from the size of its escaped version. +/** Do not include a terminating zero in `escaped_bytes`. + */ +inline constexpr std::size_t size_unesc_bin(std::size_t escaped_bytes) noexcept +{ + return (escaped_bytes - 2) / 2; +} + + +// TODO: Use actual binary type for "data". +/// Hex-escape binary data into a buffer. +/** The buffer must be able to accommodate + * `size_esc_bin(std::size(binary_data))` bytes, and the function will write + * exactly that number of bytes into the buffer. This includes a trailing + * zero. + */ +void PQXX_LIBEXPORT +esc_bin(std::basic_string_view binary_data, char buffer[]) noexcept; + + +/// Hex-escape binary data into a std::string. +std::string PQXX_LIBEXPORT +esc_bin(std::basic_string_view binary_data); + + +/// Reconstitute binary data from its escaped version. +void PQXX_LIBEXPORT +unesc_bin(std::string_view escaped_data, std::byte buffer[]); + + +/// Reconstitute binary data from its escaped version. +std::basic_string + PQXX_LIBEXPORT unesc_bin(std::string_view escaped_data); + + +/// Transitional: std::ssize(), or custom implementation if not available. +template auto ssize(T const &c) +{ +#if defined(__cpp_lib_ssize) && __cplusplus >= __cpp_lib_ssize + return std::ssize(c); +#else + using signed_t = std::make_signed_t; + return static_cast(std::size(c)); +#endif // __cpp_lib_ssize +} + + +/// Helper for determining a function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple args_f(RETURN (&func)(ARGS...)); + + +/// Helper for determining a `std::function`'s parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple args_f(std::function const &); + + +/// Helper for determining a member function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple member_args_f(RETURN (CLASS::*)(ARGS...)); + + +/// Helper for determining a const member function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple member_args_f(RETURN (CLASS::*)(ARGS...) const); + + +/// Helper for determining a callable type's parameter types. +/** This specialisation should work for lambdas. + * + * This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +auto args_f(CALLABLE const &f) + -> decltype(member_args_f(&CALLABLE::operator())); + + +/// A callable's parameter types, as a tuple. +template +using args_t = decltype(args_f(std::declval())); + + +/// Helper: Apply `strip_t` to each of a tuple type's component types. +/** This function has no definition. It is not meant to be called, only to be + * used to deduce the right types. + */ +template +std::tuple...> strip_types(std::tuple const &); + + +/// Take a tuple type and apply @ref strip_t to its component types. +template +using strip_types_t = decltype(strip_types(std::declval())); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/version b/ext/libpqxx-7.7.3/include/pqxx/version new file mode 100644 index 000000000..8dd5e48d4 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/version @@ -0,0 +1,7 @@ +/** libpqxx version info. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/version.hxx" +#include "pqxx/internal/header-post.hxx" + diff --git a/ext/libpqxx-7.7.3/include/pqxx/version.hxx b/ext/libpqxx-7.7.3/include/pqxx/version.hxx new file mode 100644 index 000000000..a159f1bed --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/version.hxx @@ -0,0 +1,55 @@ +/* Version info for libpqxx. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/version instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_VERSION + +# if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +# endif + +/// Full libpqxx version string. +# define PQXX_VERSION "7.7.3" +/// Library ABI version. +# define PQXX_ABI "7.7" + +/// Major version number. +# define PQXX_VERSION_MAJOR 7 +/// Minor version number. +# define PQXX_VERSION_MINOR 7 + +# define PQXX_VERSION_CHECK check_pqxx_version_7_7 + +namespace pqxx::internal +{ +/// Library version check stub. +/** Helps detect version mismatches between libpqxx headers and the libpqxx + * library binary. + * + * Sometimes users run into trouble linking their code against libpqxx because + * they build their own libpqxx, but the system also has a different version + * installed. The declarations in the headers against which they compile their + * code will differ from the ones used to build the libpqxx version they're + * using, leading to confusing link errors. The solution is to generate a link + * error when the libpqxx binary is not the same version as the libpqxx headers + * used to compile the code. + * + * This function's definition is in the libpqxx binary, so it's based on the + * version as found in the binary. The headers contain a call to the function, + * whose name contains the libpqxx version as found in the headers. (The + * library build process will use its own local headers even if another version + * of the headers is installed on the system.) + * + * If the libpqxx binary was compiled for a different version than the user's + * code, linking will fail with an error: `check_pqxx_version_*_*` will not + * exist for the given version number. + */ +PQXX_LIBEXPORT int PQXX_VERSION_CHECK() noexcept; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/version.hxx.template b/ext/libpqxx-7.7.3/include/pqxx/version.hxx.template new file mode 100644 index 000000000..40837f16a --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/version.hxx.template @@ -0,0 +1,55 @@ +/* Version info for libpqxx. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/version instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_VERSION + +#if !defined(PQXX_HEADER_PRE) +#error "Include libpqxx headers as , not ." +#endif + +/// Full libpqxx version string. +# define PQXX_VERSION "@PQXXVERSION@" +/// Library ABI version. +# define PQXX_ABI "@PQXX_ABI@" + +/// Major version number. +# define PQXX_VERSION_MAJOR @PQXX_MAJOR@ +/// Minor version number. +# define PQXX_VERSION_MINOR @PQXX_MINOR@ + +# define PQXX_VERSION_CHECK check_pqxx_version_@PQXX_MAJOR@_@PQXX_MINOR@ + +namespace pqxx::internal +{ +/// Library version check stub. +/** Helps detect version mismatches between libpqxx headers and the libpqxx + * library binary. + * + * Sometimes users run into trouble linking their code against libpqxx because + * they build their own libpqxx, but the system also has a different version + * installed. The declarations in the headers against which they compile their + * code will differ from the ones used to build the libpqxx version they're + * using, leading to confusing link errors. The solution is to generate a link + * error when the libpqxx binary is not the same version as the libpqxx headers + * used to compile the code. + * + * This function's definition is in the libpqxx binary, so it's based on the + * version as found in the binary. The headers contain a call to the function, + * whose name contains the libpqxx version as found in the headers. (The + * library build process will use its own local headers even if another version + * of the headers is installed on the system.) + * + * If the libpqxx binary was compiled for a different version than the user's + * code, linking will fail with an error: `check_pqxx_version_*_*` will not + * exist for the given version number. + */ +PQXX_LIBEXPORT int PQXX_VERSION_CHECK() noexcept; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/zview b/ext/libpqxx-7.7.3/include/pqxx/zview new file mode 100644 index 000000000..66ea2a625 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/zview @@ -0,0 +1,6 @@ +/** Zero-terminated string view class. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/zview.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/zview.hxx b/ext/libpqxx-7.7.3/include/pqxx/zview.hxx new file mode 100644 index 000000000..36a779f51 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/zview.hxx @@ -0,0 +1,163 @@ +/* Zero-terminated string view. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/zview instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ZVIEW +#define PQXX_H_ZVIEW + +#include +#include +#include + +#include "pqxx/types.hxx" + + +namespace pqxx +{ +/// Marker-type wrapper: zero-terminated `std::string_view`. +/** @warning Use this only if the underlying string is zero-terminated. + * + * When you construct a zview, you are promising that if the data pointer is + * non-null, the underlying string is zero-terminated. It otherwise behaves + * exactly like a std::string_view. + * + * The terminating zero is not "in" the string, so it does not count as part of + * the view's length. + * + * The added guarantee lets the view be used as a C-style string, which often + * matters since libpqxx builds on top of a C library. For this reason, zview + * also adds a @ref c_str method. + */ +class zview : public std::string_view +{ +public: + constexpr zview() noexcept = default; + + /// Convenience overload: construct using pointer and signed length. + constexpr zview(char const text[], std::ptrdiff_t len) : + std::string_view{text, static_cast(len)} + {} + + /// Convenience overload: construct using pointer and signed length. + constexpr zview(char text[], std::ptrdiff_t len) : + std::string_view{text, static_cast(len)} + {} + + /// Explicitly promote a `string_view` to a `zview`. + explicit constexpr zview(std::string_view other) noexcept : + std::string_view{other} + {} + + /// Construct from any initialiser you might use for `std::string_view`. + /** @warning Only do this if you are sure that the string is zero-terminated. + */ + template + explicit constexpr zview(Args &&...args) : + std::string_view(std::forward(args)...) + {} + + // C++20: constexpr. + /// @warning There's an implicit conversion from `std::string`. + zview(std::string const &str) noexcept : + std::string_view{str.c_str(), str.size()} + {} + + /// Construct a `zview` from a C-style string. + /** @warning This scans the string to discover its length. So if you need to + * do it many times, it's probably better to create the `zview` once and + * re-use it. + */ + constexpr zview(char const str[]) : std::string_view{str} {} + + /// Construct a `zview` from a string literal. + /** A C++ string literal ("foo") normally looks a lot like a pointer to + * char const, but that's not really true. It's actually an array of char, + * which _devolves_ to a pointer when you pass it. + * + * For the purpose of creating a `zview` there is one big difference: if we + * know the array's size, we don't need to scan through the string in order + * to find out its length. + */ + template + constexpr zview(char const (&literal)[size]) : zview(literal, size - 1) + {} + + /// Either a null pointer, or a zero-terminated text buffer. + [[nodiscard]] constexpr char const *c_str() const &noexcept + { + return data(); + } +}; + + +/// Support @ref zview literals. +/** You can "import" this selectively into your namespace, without pulling in + * all of the @ref pqxx namespace: + * + * ```cxx + * using pqxx::operator"" _zv; + * ``` + */ +constexpr zview operator"" _zv(char const str[], std::size_t len) noexcept +{ + return zview{str, len}; +} +} // namespace pqxx + + +#if defined(PQXX_HAVE_CONCEPTS) +/// A zview is a view. +template<> inline constexpr bool std::ranges::enable_view{true}; + + +/// A zview is a borrowed range. +template<> +inline constexpr bool std::ranges::enable_borrowed_range{true}; + +namespace pqxx::internal +{ +/// Concept: T is a known zero-terminated string type. +/** There's no unified API for these string types. It's just a check for some + * known types. Any code that makes use of the concept will still have to + * support each of these individually. + */ +template +concept ZString = std::is_convertible_v < strip_t, +char const * > or std::is_convertible_v, zview> or + std::is_convertible_v; +} // namespace pqxx::internal +#endif // PQXX_HAVE_CONCEPTS + + +namespace pqxx::internal +{ +/// Get a raw C string pointer. +inline constexpr char const *as_c_string(char const str[]) noexcept +{ + return str; +} +/// Get a raw C string pointer. +template +inline constexpr char const *as_c_string(char (&str)[N]) noexcept +{ + return str; +} +/// Get a raw C string pointer. +inline constexpr char const *as_c_string(pqxx::zview str) noexcept +{ + return str.c_str(); +} +// C++20: Make this constexpr. +/// Get a raw C string pointer. +inline char const *as_c_string(std::string const &str) noexcept +{ + return str.c_str(); +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/array b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/array new file mode 100644 index 000000000..689f5b27b --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/array @@ -0,0 +1,6 @@ +/** Handling of SQL arrays. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/array.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/array.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/array.hxx new file mode 100644 index 000000000..8440a244f --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/array.hxx @@ -0,0 +1,103 @@ +/* Handling of SQL arrays. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ARRAY +#define PQXX_H_ARRAY + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/internal/encodings.hxx" + + +namespace pqxx +{ +/// Low-level array parser. +/** Use this to read an array field retrieved from the database. + * + * This parser will only work reliably if your client encoding is UTF-8, ASCII, + * or a single-byte encoding which is a superset of ASCII (such as Latin-1). + * + * Also, the parser only supports array element types which use either a comma + * or a semicolon ("," or ";") as the separator between array elements. All + * built-in types use comma, except for one which uses semicolon, but some + * custom types may not work. + * + * The input is a C-style string containing the textual representation of an + * array, as returned by the database. The parser reads this representation + * on the fly. The string must remain in memory until parsing is done. + * + * Parse the array by making calls to @ref get_next until it returns a + * @ref juncture of "done". The @ref juncture tells you what the parser found + * in that step: did the array "nest" to a deeper level, or "un-nest" back up? + */ +class PQXX_LIBEXPORT array_parser +{ +public: + /// What's the latest thing found in the array? + enum class juncture + { + /// Starting a new row. + row_start, + /// Ending the current row. + row_end, + /// Found a NULL value. + null_value, + /// Found a string value. + string_value, + /// Parsing has completed. + done, + }; + + // TODO: constexpr noexcept. Breaks ABI. + /// Constructor. You don't need this; use @ref field::as_array instead. + /** The parser only remains valid while the data underlying the @ref result + * remains valid. Once all `result` objects referring to that data have been + * destroyed, the parser will no longer refer to valid memory. + */ + explicit array_parser( + std::string_view input, + internal::encoding_group = internal::encoding_group::MONOBYTE); + + /// Parse the next step in the array. + /** Returns what it found. If the juncture is @ref juncture::string_value, + * the string will contain the value. Otherwise, it will be empty. + * + * Call this until the @ref array_parser::juncture it returns is + * @ref juncture::done. + */ + std::pair get_next(); + +private: + std::string_view m_input; + internal::glyph_scanner_func *const m_scan; + + /// Current parsing position in the input. + std::string::size_type m_pos = 0u; + + std::string::size_type scan_single_quoted_string() const; + std::string parse_single_quoted_string(std::string::size_type end) const; + std::string::size_type scan_double_quoted_string() const; + std::string parse_double_quoted_string(std::string::size_type end) const; + std::string::size_type scan_unquoted_string() const; + std::string parse_unquoted_string(std::string::size_type end) const; + + std::string::size_type scan_glyph(std::string::size_type pos) const; + std::string::size_type + scan_glyph(std::string::size_type pos, std::string::size_type end) const; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/binarystring b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/binarystring new file mode 100644 index 000000000..77551d9f7 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/binarystring @@ -0,0 +1,6 @@ +/** BYTEA (binary string) conversions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/binarystring.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/binarystring.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/binarystring.hxx new file mode 100644 index 000000000..47c82a035 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/binarystring.hxx @@ -0,0 +1,236 @@ +/* Deprecated representation for raw, binary data. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/binarystring instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_BINARYSTRING +#define PQXX_H_BINARYSTRING + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/result.hxx" +#include "pqxx/strconv.hxx" + +namespace pqxx +{ +class binarystring; +template<> struct string_traits; + + +/// Binary data corresponding to PostgreSQL's "BYTEA" binary-string type. +/** @ingroup escaping-functions + * @deprecated Use @c std::basic_string and + * @c std::basic_string_view for binary data. In C++20 or better, + * any @c contiguous_range of @c std::byte will do. + * + * This class represents a binary string as stored in a field of type @c bytea. + * + * Internally a binarystring is zero-terminated, but it may also contain null + * bytes, they're just like any other byte value. So don't assume that it's + * safe to treat the contents as a C-style string. + * + * The binarystring retains its value even if the result it was obtained from + * is destroyed, but it cannot be copied or assigned. + * + * \relatesalso transaction_base::quote_raw + * + * To include a @c binarystring value in an SQL query, escape and quote it + * using the transaction's @c quote_raw function. + * + * @warning This class is implemented as a reference-counting smart pointer. + * Copying, swapping, and destroying binarystring objects that refer to the + * same underlying data block is not thread-safe. If you wish to pass + * binarystrings around between threads, make sure that each of these + * operations is protected against concurrency with similar operations on the + * same object, or other objects pointing to the same data block. + */ +class PQXX_LIBEXPORT binarystring +{ +public: + using char_type = unsigned char; + using value_type = std::char_traits::char_type; + using size_type = std::size_t; + using difference_type = long; + using const_reference = value_type const &; + using const_pointer = value_type const *; + using const_iterator = const_pointer; + using const_reverse_iterator = std::reverse_iterator; + + [[deprecated("Use std::byte for binary data.")]] binarystring( + binarystring const &) = default; + + /// Read and unescape bytea field. + /** The field will be zero-terminated, even if the original bytea field + * isn't. + * @param F the field to read; must be a bytea field + */ + [[deprecated("Use std::byte for binary data.")]] explicit binarystring( + field const &); + + /// Copy binary data from std::string_view on binary data. + /** This is inefficient in that it copies the data to a buffer allocated on + * the heap. + */ + [[deprecated("Use std::byte for binary data.")]] explicit binarystring( + std::string_view); + + /// Copy binary data of given length straight out of memory. + [[deprecated("Use std::byte for binary data.")]] binarystring( + void const *, std::size_t); + + /// Efficiently wrap a buffer of binary data in a @c binarystring. + [[deprecated("Use std::byte for binary data.")]] binarystring( + std::shared_ptr ptr, size_type size) : + m_buf{std::move(ptr)}, m_size{size} + {} + + /// Size of converted string in bytes. + [[nodiscard]] size_type size() const noexcept { return m_size; } + /// Size of converted string in bytes. + [[nodiscard]] size_type length() const noexcept { return size(); } + [[nodiscard]] bool empty() const noexcept { return size() == 0; } + + [[nodiscard]] const_iterator begin() const noexcept { return data(); } + [[nodiscard]] const_iterator cbegin() const noexcept { return begin(); } + [[nodiscard]] const_iterator end() const noexcept { return data() + m_size; } + [[nodiscard]] const_iterator cend() const noexcept { return end(); } + + [[nodiscard]] const_reference front() const noexcept { return *begin(); } + [[nodiscard]] const_reference back() const noexcept + { + return *(data() + m_size - 1); + } + + [[nodiscard]] const_reverse_iterator rbegin() const + { + return const_reverse_iterator{end()}; + } + [[nodiscard]] const_reverse_iterator crbegin() const { return rbegin(); } + [[nodiscard]] const_reverse_iterator rend() const + { + return const_reverse_iterator{begin()}; + } + [[nodiscard]] const_reverse_iterator crend() const { return rend(); } + + /// Unescaped field contents. + [[nodiscard]] value_type const *data() const noexcept { return m_buf.get(); } + + [[nodiscard]] const_reference operator[](size_type i) const noexcept + { + return data()[i]; + } + + [[nodiscard]] PQXX_PURE bool operator==(binarystring const &) const noexcept; + [[nodiscard]] bool operator!=(binarystring const &rhs) const noexcept + { + return not operator==(rhs); + } + + binarystring &operator=(binarystring const &); + + /// Index contained string, checking for valid index. + const_reference at(size_type) const; + + /// Swap contents with other binarystring. + void swap(binarystring &); + + /// Raw character buffer (no terminating zero is added). + /** @warning No terminating zero is added! If the binary data did not end in + * a null character, you will not find one here. + */ + [[nodiscard]] char const *get() const noexcept + { + return reinterpret_cast(m_buf.get()); + } + + /// Read contents as a std::string_view. + [[nodiscard]] std::string_view view() const noexcept + { + return std::string_view(get(), size()); + } + + /// Read as regular C++ string (may include null characters). + /** This creates and returns a new string object. Don't call this + * repeatedly; retrieve your string once and keep it in a local variable. + * Also, do not expect to be able to compare the string's address to that of + * an earlier invocation. + */ + [[nodiscard]] std::string str() const; + + /// Access data as a pointer to @c std::byte. + [[nodiscard]] std::byte const *bytes() const + { + return reinterpret_cast(get()); + } + + /// Read data as a @c std::basic_string_view. + [[nodiscard]] std::basic_string_view bytes_view() const + { + return std::basic_string_view{bytes(), size()}; + } + +private: + std::shared_ptr m_buf; + size_type m_size{0}; +}; + + +template<> struct nullness : no_null +{}; + + +/// String conversion traits for @c binarystring. +/** Defines the conversions between a @c binarystring and its PostgreSQL + * textual format, for communication with the database. + * + * These conversions rely on the "hex" format which was introduced in + * PostgreSQL 9.0. Both your libpq and the server must be recent enough to + * speak this format. + */ +template<> struct string_traits +{ + static std::size_t size_buffer(binarystring const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf(char *begin, char *end, binarystring const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, binarystring const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + std::string_view text{value.view()}; + internal::esc_bin(binary_cast(text), begin); + return begin + budget; + } + + static binarystring from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::shared_ptr buf{ + new unsigned char[size], [](unsigned char const *x) { delete[] x; }}; + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.get())); +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return binarystring{std::move(buf), size}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + } +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/blob b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/blob new file mode 100644 index 000000000..3fd0afac9 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/blob @@ -0,0 +1,6 @@ +/** Binary Large Objects interface. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/blob.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/blob.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/blob.hxx new file mode 100644 index 000000000..6d77be724 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/blob.hxx @@ -0,0 +1,351 @@ +/* Binary Large Objects interface. + * + * Read or write large objects, stored in their own storage on the server. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_BLOB +#define PQXX_H_BLOB + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#if defined(PQXX_HAVE_PATH) +# include +#endif + +#if defined(PQXX_HAVE_RANGES) && __has_include() +# include +#endif + +#if defined(PQXX_HAVE_SPAN) && __has_include() +# include +#endif + +#include "pqxx/dbtransaction.hxx" + + +namespace pqxx +{ +/** Binary large object. + * + * This is how you store data that may be too large for the `BYTEA` type. + * Access operations are similar to those for a file: you can read, write, + * query or set the current reading/writing position, and so on. + * + * These large objects live in their own storage on the server, indexed by an + * integer object identifier ("oid"). + * + * Two `blob` objects may refer to the same actual large object in the + * database at the same time. Each will have its own reading/writing position, + * but writes to the one will of course affect what the other sees. + */ +class PQXX_LIBEXPORT blob +{ +public: + /// Create a new, empty large object. + /** You may optionally specify an oid for the new blob. If you do, then + * the new object will have that oid -- or creation will fail if there + * already is an object with that oid. + */ + [[nodiscard]] static oid create(dbtransaction &, oid = 0); + + /// Delete a large object, or fail if it does not exist. + static void remove(dbtransaction &, oid); + + /// Open blob for reading. Any attempt to write to it will fail. + [[nodiscard]] static blob open_r(dbtransaction &, oid); + // Open blob for writing. Any attempt to read from it will fail. + [[nodiscard]] static blob open_w(dbtransaction &, oid); + // Open blob for reading and/or writing. + [[nodiscard]] static blob open_rw(dbtransaction &, oid); + + /// You can default-construct a blob, but it won't do anything useful. + /** Most operations on a default-constructed blob will throw @ref + * usage_error. + */ + blob() = default; + + /// You can move a blob, but not copy it. The original becomes unusable. + blob(blob &&); + /// You can move a blob, but not copy it. The original becomes unusable. + blob &operator=(blob &&); + + blob(blob const &) = delete; + blob &operator=(blob const &) = delete; + ~blob(); + + /// Maximum number of bytes that can be read or written at a time. + /** The underlying protocol only supports reads and writes up to 2 GB + * exclusive. + * + * If you need to read or write more data to or from a binary large object, + * you'll have to break it up into chunks. + */ + static constexpr std::size_t chunk_limit = 0x7fffffff; + + /// Read up to `size` bytes of the object into `buf`. + /** Uses a buffer that you provide, resizing it as needed. If it suits you, + * this lets you allocate the buffer once and then re-use it multiple times. + * + * Resizes `buf` as needed. + * + * @warning The underlying protocol only supports reads up to 2GB at a time. + * If you need to read more, try making repeated calls to @ref append_to_buf. + */ + std::size_t read(std::basic_string &buf, std::size_t size); + +#if defined(PQXX_HAVE_SPAN) + /// Read up to `std::size(buf)` bytes from the object. + /** Retrieves bytes from the blob, at the current position, until `buf` is + * full or there are no more bytes to read, whichever comes first. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template + std::span read(std::span buf) + { + return buf.subspan(0, raw_read(std::data(buf), std::size(buf))); + } +#endif // PQXX_HAVE_SPAN + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Read up to `std::size(buf)` bytes from the object. + /** Retrieves bytes from the blob, at the current position, until `buf` is + * full or there are no more bytes to read, whichever comes first. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template std::span read(DATA &buf) + { + return {std::data(buf), raw_read(std::data(buf), std::size(buf))}; + } +#else // PQXX_HAVE_CONCEPTS && PQXX_HAVE_SPAN + /// Read up to `std::size(buf)` bytes from the object. + /** @deprecated As libpqxx moves to C++20 as its baseline language version, + * this will take and return `std::span`. + * + * Retrieves bytes from the blob, at the current position, until `buf` is + * full (i.e. its current size is reached), or there are no more bytes to + * read, whichever comes first. + * + * This function will not change either the size or the capacity of `buf`, + * only its contents. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template + std::basic_string_view read(std::vector &buf) + { + return {std::data(buf), raw_read(std::data(buf), std::size(buf))}; + } +#endif // PQXX_HAVE_CONCEPTS && PQXX_HAVE_SPAN + +#if defined(PQXX_HAVE_CONCEPTS) + /// Write `data` to large object, at the current position. + /** If the writing position is at the end of the object, this will append + * `data` to the object's contents and move the writing position so that + * it's still at the end. + * + * If the writing position was not at the end, writing will overwrite the + * prior data, but it will not remove data that follows the part where you + * wrote your new data. + * + * @warning This is a big difference from writing to a file. You can + * overwrite some data in a large object, but this does not truncate the + * data that was already there. For example, if the object contained binary + * data "abc", and you write "12" at the starting position, the object will + * contain "12c". + * + * @warning The underlying protocol only supports writes up to 2 GB at a + * time. If you need to write more, try making repeated calls to + * @ref append_from_buf. + */ + template void write(DATA const &data) + { + raw_write(std::data(data), std::size(data)); + } +#else + /// Write `data` large object, at the current position. + /** If the writing position is at the end of the object, this will append + * `data` to the object's contents and move the writing position so that + * it's still at the end. + * + * If the writing position was not at the end, writing will overwrite the + * prior data, but it will not remove data that follows the part where you + * wrote your new data. + * + * @warning This is a big difference from writing to a file. You can + * overwrite some data in a large object, but this does not truncate the + * data that was already there. For example, if the object contained binary + * data "abc", and you write "12" at the starting position, the object will + * contain "12c". + * + * @warning The underlying protocol only supports writes up to 2 GB at a + * time. If you need to write more, try making repeated calls to + * @ref append_from_buf. + */ + template void write(DATA const &data) + { + raw_write(std::data(data), std::size(data)); + } +#endif + + /// Resize large object to `size` bytes. + /** If the blob is more than `size` bytes long, this removes the end so as + * to make the blob the desired length. + * + * If the blob is less than `size` bytes long, it adds enough zero bytes to + * make it the desired length. + */ + void resize(std::int64_t size); + + /// Return the current reading/writing position in the large object. + [[nodiscard]] std::int64_t tell() const; + + /// Set the current reading/writing position to an absolute offset. + /** Returns the new file offset. */ + std::int64_t seek_abs(std::int64_t offset = 0); + /// Move the current reading/writing position forwards by an offset. + /** To move backwards, pass a negative offset. + * + * Returns the new file offset. + */ + std::int64_t seek_rel(std::int64_t offset = 0); + /// Set the current position to an offset relative to the end of the blob. + /** You'll probably want an offset of zero or less. + * + * Returns the new file offset. + */ + std::int64_t seek_end(std::int64_t offset = 0); + + /// Create a binary large object containing given `data`. + /** You may optionally specify an oid for the new object. If you do, and an + * object with that oid already exists, creation will fail. + */ + static oid from_buf( + dbtransaction &tx, std::basic_string_view data, oid id = 0); + + /// Append `data` to binary large object. + /** The underlying protocol only supports appending blocks up to 2 GB. + */ + static void append_from_buf( + dbtransaction &tx, std::basic_string_view data, oid id); + + /// Read client-side file and store it server-side as a binary large object. + [[nodiscard]] static oid from_file(dbtransaction &, char const path[]); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Read client-side file and store it server-side as a binary large object. + /** This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + [[nodiscard]] static oid + from_file(dbtransaction &tx, std::filesystem::path const &path) + { + return from_file(tx, path.c_str()); + } +#endif + + /// Read client-side file and store it server-side as a binary large object. + /** In this version, you specify the binary large object's oid. If that oid + * is already in use, the operation will fail. + */ + static oid from_file(dbtransaction &, char const path[], oid); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Read client-side file and store it server-side as a binary large object. + /** In this version, you specify the binary large object's oid. If that oid + * is already in use, the operation will fail. + * + * This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + static oid + from_file(dbtransaction &tx, std::filesystem::path const &path, oid id) + { + return from_file(tx, path.c_str(), id); + } +#endif + + /// Convenience function: Read up to `max_size` bytes from blob with `id`. + /** You could easily do this yourself using the @ref open_r and @ref read + * functions, but it can save you a bit of code to do it this way. + */ + static void to_buf( + dbtransaction &, oid, std::basic_string &, + std::size_t max_size); + + /// Read part of the binary large object with `id`, and append it to `buf`. + /** Use this to break up a large read from one binary large object into one + * massive buffer. Just keep calling this function until it returns zero. + * + * The `offset` is how far into the large object your desired chunk is, and + * `append_max` says how much to try and read in one go. + */ + static std::size_t append_to_buf( + dbtransaction &tx, oid id, std::int64_t offset, + std::basic_string &buf, std::size_t append_max); + + /// Write a binary large object's contents to a client-side file. + static void to_file(dbtransaction &, oid, char const path[]); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Write a binary large object's contents to a client-side file. + /** This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + static void + to_file(dbtransaction &tx, oid id, std::filesystem::path const &path) + { + to_file(tx, id, path.c_str()); + } +#endif + + /// Close this blob. + /** This does not delete the blob from the database; it only terminates your + * local object for accessing the blob. + * + * Resets the blob to a useless state similar to one that was + * default-constructed. + * + * The destructor will do this for you automatically. Still, there is a + * reason to `close()` objects explicitly where possible: if an error should + * occur while closing, `close()` can throw an exception. A destructor + * cannot. + */ + void close(); + +private: + PQXX_PRIVATE blob(connection &conn, int fd) noexcept : + m_conn{&conn}, m_fd{fd} + {} + static PQXX_PRIVATE blob open_internal(dbtransaction &, oid, int); + static PQXX_PRIVATE pqxx::internal::pq::PGconn * + raw_conn(pqxx::connection *) noexcept; + static PQXX_PRIVATE pqxx::internal::pq::PGconn * + raw_conn(pqxx::dbtransaction const &) noexcept; + static PQXX_PRIVATE std::string errmsg(connection const *); + static PQXX_PRIVATE std::string errmsg(dbtransaction const &tx) + { + return errmsg(&tx.conn()); + } + PQXX_PRIVATE std::string errmsg() const { return errmsg(m_conn); } + PQXX_PRIVATE std::int64_t seek(std::int64_t offset, int whence); + std::size_t raw_read(std::byte buf[], std::size_t size); + void raw_write(std::byte const buf[], std::size_t size); + + connection *m_conn = nullptr; + int m_fd = -1; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/composite b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/composite new file mode 100644 index 000000000..2bfa7ade9 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/composite @@ -0,0 +1,6 @@ +/** Handling of SQL "composite types." + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/composite.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/composite.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/composite.hxx new file mode 100644 index 000000000..439b133a8 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/composite.hxx @@ -0,0 +1,149 @@ +#ifndef PQXX_H_COMPOSITE +#define PQXX_H_COMPOSITE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/internal/array-composite.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Parse a string representation of a value of a composite type. +/** @warning This code is still experimental. Use with care. + * + * You may use this as a helper while implementing your own @ref string_traits + * for a composite type. + * + * This function interprets `text` as the string representation of a value of + * some composite type, and sets each of `fields` to the respective values of + * its fields. The field types must be copy-assignable. + * + * The number of fields must match the number of fields in the composite type, + * and there must not be any other text in the input. The function is meant to + * handle any value string that the backend can produce, but not necessarily + * every valid alternative spelling. + * + * Fields in composite types can be null. When this happens, the C++ type of + * the corresponding field reference must be of a type that can handle nulls. + * If you are working with a type that does not have an inherent null value, + * such as e.g. `int`, consider using `std::optional`. + */ +template +inline void parse_composite( + pqxx::internal::encoding_group enc, std::string_view text, T &...fields) +{ + static_assert(sizeof...(fields) > 0); + + auto const scan{pqxx::internal::get_glyph_scanner(enc)}; + auto const data{std::data(text)}; + auto const size{std::size(text)}; + if (size == 0) + throw conversion_error{"Cannot parse composite value from empty string."}; + + std::size_t here{0}, next{scan(data, size, here)}; + if (next != 1 or data[here] != '(') + throw conversion_error{ + internal::concat("Invalid composite value string: ", text)}; + + here = next; + + constexpr auto num_fields{sizeof...(fields)}; + std::size_t index{0}; + (pqxx::internal::parse_composite_field( + index, text, here, fields, scan, num_fields - 1), + ...); + if (here != std::size(text)) + throw conversion_error{internal::concat( + "Composite value did not end at the closing parenthesis: '", text, + "'.")}; + if (text[here - 1] != ')') + throw conversion_error{internal::concat( + "Composive value did not end in parenthesis: '", text, "'")}; +} + + +/// Parse a string representation of a value of a composite type. +/** @warning This version only works for UTF-8 and single-byte encodings. + * + * For proper encoding support, use the composite-type support in the + * `field` class. + */ +template +inline void parse_composite(std::string_view text, T &...fields) +{ + parse_composite(pqxx::internal::encoding_group::MONOBYTE, text, fields...); +} +} // namespace pqxx + + +namespace pqxx::internal +{ +constexpr char empty_composite_str[]{"()"}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// Estimate the buffer size needed to represent a value of a composite type. +/** Returns a conservative estimate. + */ +template +[[nodiscard]] inline std::size_t +composite_size_buffer(T const &...fields) noexcept +{ + constexpr auto num{sizeof...(fields)}; + + // Size for a multi-field composite includes room for... + // + opening parenthesis + // + field budgets + // + separating comma per field + // - comma after final field + // + closing parenthesis + // + terminating zero + + if constexpr (num == 0) + return std::size(pqxx::internal::empty_composite_str); + else + return 1 + (pqxx::internal::size_composite_field_buffer(fields) + ...) + + num + 1; +} + + +/// Render a series of values as a single composite SQL value. +/** @warning This code is still experimental. Use with care. + * + * You may use this as a helper while implementing your own `string_traits` + * for a composite type. + */ +template +inline char *composite_into_buf(char *begin, char *end, T const &...fields) +{ + if (std::size_t(end - begin) < composite_size_buffer(fields...)) + throw conversion_error{ + "Buffer space may not be enough to represent composite value."}; + + constexpr auto num_fields{sizeof...(fields)}; + if constexpr (num_fields == 0) + { + constexpr char empty[]{"()"}; + std::memcpy(begin, empty, std::size(empty)); + return begin + std::size(empty); + } + + char *pos{begin}; + *pos++ = '('; + + (pqxx::internal::write_composite_field(pos, end, fields), ...); + + // If we've got multiple fields, "backspace" that last comma. + if constexpr (num_fields > 1) + --pos; + *pos++ = ')'; + *pos++ = '\0'; + return pos; +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/config-public-compiler.h b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/config-public-compiler.h new file mode 100644 index 000000000..3668a10f8 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/config-public-compiler.h @@ -0,0 +1,81 @@ +/* include/pqxx/config.h.in. Generated from configure.ac by autoheader. */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLFCN_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTTYPES_H */ +/* Define to 1 if you have the `pq' library (-lpq). */ +/* #undef HAVE_LIBPQ */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MEMORY_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDINT_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDLIB_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRINGS_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRING_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_STAT_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TYPES_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UNISTD_H */ +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +/* #undef LT_OBJDIR */ +/* Name of package */ +/* #undef PACKAGE */ +/* Define to the address where bug reports for this package should be sent. */ +/* #undef PACKAGE_BUGREPORT */ +/* Define to the full name of this package. */ +/* #undef PACKAGE_NAME */ +/* Define to the full name and version of this package. */ +/* #undef PACKAGE_STRING */ +/* Define to the one symbol short name of this package. */ +/* #undef PACKAGE_TARNAME */ +/* Define to the home page for this package. */ +/* #undef PACKAGE_URL */ +/* Define to the version of this package. */ +/* #undef PACKAGE_VERSION */ +/* Define if supports floating-point conversion. */ +#define PQXX_HAVE_CHARCONV_FLOAT +/* Define if supports integer conversion. */ +#define PQXX_HAVE_CHARCONV_INT +/* Define if compiler has C++20 std::cmp_greater etc. */ +/* #undef PQXX_HAVE_CMP */ +/* Define if compiler supports Concepts and header. */ +/* #undef PQXX_HAVE_CONCEPTS */ +/* Define if compiler supports __cxa_demangle */ +#define PQXX_HAVE_CXA_DEMANGLE +/* Define if g++ supports pure attribute */ +#define PQXX_HAVE_GCC_PURE +/* Define if g++ supports visibility attribute. */ +#define PQXX_HAVE_GCC_VISIBILITY +/* Define if likely & unlikely work. */ +/* #undef PQXX_HAVE_LIKELY */ +/* Define if operator[] can take multiple arguments. */ +/* #undef PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT */ +/* Define if compiler has usable std::filesystem::path. */ +#define PQXX_HAVE_PATH +/* Define if poll() is available. */ +#define PQXX_HAVE_POLL +/* Define if libpq has PQencryptPasswordConn (since pg 10). */ +#define PQXX_HAVE_PQENCRYPTPASSWORDCONN +/* Define if libpq has pipeline mode (since pg 14). */ +#define PQXX_HAVE_PQ_PIPELINE +/* Define if std::this_thread::sleep_for works. */ +#define PQXX_HAVE_SLEEP_FOR +/* Define if compiler has std::span. */ +/* #undef PQXX_HAVE_SPAN */ +/* Define if strerror_r() is available. */ +#define PQXX_HAVE_STRERROR_R +/* Define if strerror_s() is available. */ +/* #undef PQXX_HAVE_STRERROR_S */ +/* Define if thread_local is fully supported. */ +#define PQXX_HAVE_THREAD_LOCAL +/* Define if std::chrono has year_month_day etc. */ +/* #undef PQXX_HAVE_YEAR_MONTH_DAY */ +/* Define to 1 if you have the ANSI C header files. */ +/* #undef STDC_HEADERS */ +/* Version number of package */ +/* #undef VERSION */ diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/connection b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/connection new file mode 100644 index 000000000..82ff43aa5 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/connection @@ -0,0 +1,8 @@ +/** pqxx::connection class. + * + * pqxx::connection encapsulates a connection to a database. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/connection.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/connection.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/connection.hxx new file mode 100644 index 000000000..92454bb47 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/connection.hxx @@ -0,0 +1,1261 @@ +/* Definition of the connection class. + * + * pqxx::connection encapsulates a connection to a database. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/connection instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_CONNECTION +#define PQXX_H_CONNECTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Double-check in order to suppress an overzealous Visual C++ warning (#418). +#if defined(PQXX_HAVE_CONCEPTS) && __has_include() +# include +#endif + +#include "pqxx/errorhandler.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/params.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + + +/** + * @addtogroup connections + * + * Use of the libpqxx library starts here. + * + * Everything that can be done with a database through libpqxx must go through + * a @ref pqxx::connection object. It connects to a database when you create + * it, and it terminates that communication during destruction. + * + * Many things come together in this class. Handling of error and warning + * messages, for example, is defined by @ref pqxx::errorhandler objects in the + * context of a connection. Prepared statements are also defined here. + * + * When you connect to a database, you pass a connection string containing any + * parameters and options, such as the server address and the database name. + * + * These are identical to the ones in libpq, the C language binding upon which + * libpqxx itself is built: + * + * https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING + * + * There are also environment variables you can set to provide defaults, again + * as defined by libpq: + * + * https://www.postgresql.org/docs/current/libpq-envars.html + * + * You can also create a database connection _asynchronously_ using an + * intermediate @ref pqxx::connecting object. + */ + +namespace pqxx::internal +{ +class sql_cursor; + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: T is a range of pairs of zero-terminated strings. +template +concept ZKey_ZValues = std::ranges::input_range and requires(T t) +{ + {std::cbegin(t)}; + { + std::get<0>(*std::cbegin(t)) + } -> ZString; + { + std::get<1>(*std::cbegin(t)) + } -> ZString; +} and std::tuple_size_v::value_type> +== 2; +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx::internal + + +namespace pqxx::internal::gate +{ +class connection_dbtransaction; +class connection_errorhandler; +class connection_largeobject; +class connection_notification_receiver; +class connection_pipeline; +class connection_sql_cursor; +class connection_stream_from; +class connection_stream_to; +class connection_transaction; +class const_connection_largeobject; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Representation of a PostgreSQL table path. +/** A "table path" consists of a table name, optionally prefixed by a schema + * name, which in turn is optionally prefixed by a database name. + * + * A minimal example of a table path would be `{mytable}`. But a table path + * may also take the forms `{myschema,mytable}` or + * `{mydb,myschema,mytable}`. + */ +using table_path = std::initializer_list; + + +/// Encrypt a password. @deprecated Use connection::encrypt_password instead. +[[nodiscard, + deprecated("Use connection::encrypt_password instead.")]] std::string + PQXX_LIBEXPORT + encrypt_password(char const user[], char const password[]); + +/// Encrypt password. @deprecated Use connection::encrypt_password instead. +[[nodiscard, + deprecated("Use connection::encrypt_password instead.")]] inline std::string +encrypt_password(zview user, zview password) +{ +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return encrypt_password(user.c_str(), password.c_str()); +#include "pqxx/internal/ignore-deprecated-post.hxx" +} + + +/// Error verbosity levels. +enum class error_verbosity : int +{ + // These values must match those in libpq's PGVerbosity enum. + terse = 0, + normal = 1, + verbose = 2 +}; + + +/// Connection to a database. +/** This is the first class to look at when you wish to work with a database + * through libpqxx. The connection opens during construction, and closes upon + * destruction. + * + * When creating a connection, you can pass a connection URI or a postgres + * connection string, to specify the database server's address, a login + * username, and so on. If you don't, the connection will try to obtain them + * from certain environment variables. If those are not set either, the + * default is to try and connect to the local system's port 5432. + * + * Find more about connection strings here: + * + * https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING + * + * The variables are documented here: + * + * https://www.postgresql.org/docs/current/libpq-envars.html + * + * To query or manipulate the database once connected, use one of the + * transaction classes (see pqxx/transaction_base.hxx) and perhaps also the + * transactor framework (see pqxx/transactor.hxx). + * + * When a connection breaks, you will typically get a @ref broken_connection + * exception. This can happen at almost any point. + * + * @warning On Unix-like systems, including GNU and BSD systems, your program + * may receive the SIGPIPE signal when the connection to the backend breaks. By + * default this signal will abort your program. Use "signal(SIGPIPE, SIG_IGN)" + * if you want your program to continue running after a connection fails. + */ +class PQXX_LIBEXPORT connection +{ +public: + connection() : connection{""} {} + + /// Connect to a database, using `options` string. + explicit connection(char const options[]) + { + check_version(); + init(options); + } + + /// Connect to a database, using `options` string. + explicit connection(zview options) : connection{options.c_str()} + { + // (Delegates to other constructor which calls check_version for us.) + } + + /// Move constructor. + /** Moving a connection is not allowed if it has an open transaction, or has + * error handlers or notification receivers registered on it. In those + * situations, other objects may hold references to the old object which + * would become invalid and might produce hard-to-diagnose bugs. + */ + connection(connection &&rhs); + +#if defined(PQXX_HAVE_CONCEPTS) + /// Connect to a database, passing options as a range of key/value pairs. + /** @warning Experimental. Requires C++20 "concepts" support. Define + * `PQXX_HAVE_CONCEPTS` to enable it. + * + * There's no need to escape the parameter values. + * + * See the PostgreSQL libpq documentation for the full list of possible + * options: + * + * https://postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS + * + * The options can be anything that can be iterated as a series of pairs of + * zero-terminated strings: `std::pair`, or + * `std::tuple`, or + * `std::map`, and so on. + */ + template + inline connection(MAPPING const ¶ms); +#endif // PQXX_HAVE_CONCEPTS + + ~connection() + { + try + { + close(); + } + catch (std::exception const &) + {} + } + + /// Move assignment. + /** Neither connection can have an open transaction, registered error + * handlers, or registered notification receivers. + */ + connection &operator=(connection &&rhs); + + connection(connection const &) = delete; + connection &operator=(connection const &) = delete; + + /// Is this connection open at the moment? + /** @warning This function is **not** needed in most code. Resist the + * temptation to check it after opening a connection. The `connection` + * constructor will throw a @ref broken_connection exception if can't connect + * to the database. + */ + [[nodiscard]] bool PQXX_PURE is_open() const noexcept; + + /// Invoke notice processor function. The message should end in newline. + void process_notice(char const[]) noexcept; + /// Invoke notice processor function. Newline at end is recommended. + /** The zview variant, with a message ending in newline, is the most + * efficient way to call process_notice. + */ + void process_notice(zview) noexcept; + + /// Enable tracing to a given output stream, or nullptr to disable. + void trace(std::FILE *) noexcept; + + /** + * @name Connection properties + * + * These are probably not of great interest, since most are derived from + * information supplied by the client program itself, but they are included + * for completeness. + * + * The connection needs to be currently active for these to work. + */ + //@{ + /// Name of database we're connected to, if any. + [[nodiscard]] char const *dbname() const; + + /// Database user ID we're connected under, if any. + [[nodiscard]] char const *username() const; + + /// Address of server, or nullptr if none specified (i.e. default or local) + [[nodiscard]] char const *hostname() const; + + /// Server port number we're connected to. + [[nodiscard]] char const *port() const; + + /// Process ID for backend process, or 0 if inactive. + [[nodiscard]] int PQXX_PURE backendpid() const &noexcept; + + /// Socket currently used for connection, or -1 for none. Use with care! + /** Query the current socket number. This is intended for event loops based + * on functions such as select() or poll(), where you're waiting for any of + * multiple file descriptors to become ready for communication. + * + * Please try to stay away from this function. It is really only meant for + * event loops that need to wait on more than one file descriptor. If all + * you need is to block until a notification arrives, for instance, use + * await_notification(). If you want to issue queries and retrieve results + * in nonblocking fashion, check out the pipeline class. + */ + [[nodiscard]] int PQXX_PURE sock() const &noexcept; + + /// What version of the PostgreSQL protocol is this connection using? + /** The answer can be 0 (when there is no connection); 3 for protocol 3.0; or + * possibly higher values as newer protocol versions come into use. + */ + [[nodiscard]] int PQXX_PURE protocol_version() const noexcept; + + /// What version of the PostgreSQL server are we connected to? + /** The result is a bit complicated: each of the major, medium, and minor + * release numbers is written as a two-digit decimal number, and the three + * are then concatenated. Thus server version 9.4.2 will be returned as the + * decimal number 90402. If there is no connection to the server, this + * returns zero. + * + * @warning When writing version numbers in your code, don't add zero at the + * beginning! Numbers beginning with zero are interpreted as octal (base-8) + * in C++. Thus, 070402 is not the same as 70402, and 080000 is not a number + * at all because there is no digit "8" in octal notation. Use strictly + * decimal notation when it comes to these version numbers. + */ + [[nodiscard]] int PQXX_PURE server_version() const noexcept; + //@} + + /// @name Text encoding + /** + * Each connection is governed by a "client encoding," which dictates how + * strings and other text is represented in bytes. The database server will + * send text data to you in this encoding, and you should use it for the + * queries and data which you send to the server. + * + * Search the PostgreSQL documentation for "character set encodings" to find + * out more about the available encodings, how to extend them, and how to use + * them. Not all server-side encodings are compatible with all client-side + * encodings or vice versa. + * + * Encoding names are case-insensitive, so e.g. "UTF8" is equivalent to + * "utf8". + * + * You can change the client encoding, but this may not work when the + * connection is in a special state, such as when streaming a table. It's + * not clear what happens if you change the encoding during a transaction, + * and then abort the transaction. + */ + //@{ + /// Get client-side character encoding, by name. + [[nodiscard]] std::string get_client_encoding() const; + + /// Set client-side character encoding, by name. + /** + * @param encoding Name of the character set encoding to use. + */ + void set_client_encoding(zview encoding) & + { + set_client_encoding(encoding.c_str()); + } + + /// Set client-side character encoding, by name. + /** + * @param encoding Name of the character set encoding to use. + */ + void set_client_encoding(char const encoding[]) &; + + /// Get the connection's encoding, as a PostgreSQL-defined code. + [[nodiscard]] int PQXX_PRIVATE encoding_id() const; + + //@} + + /// Set session variable, using SQL's `SET` command. + /** @deprecated To set a session variable, use @ref set_session_var. To set + * a transaction-local variable, execute an SQL `SET` command. + * + * @warning When setting a string value, you must escape and quote it first. + * Use the @ref quote() function to do that. + * + * @warning This executes an SQL query, so do not get or set variables while + * a table stream or pipeline is active on the same connection. + * + * @param var Variable to set. + * @param value New value for Var. This can be any SQL expression. If it's + * a string, be sure that it's properly escaped and quoted. + */ + [[deprecated("To set session variables, use set_session_var.")]] void + set_variable(std::string_view var, std::string_view value) &; + + /// Set one of the session variables to a new value. + /** This executes SQL, so do not do it while a pipeline or stream is active + * on the connection. + * + * The value you set here will last for the rest of the connection's + * duration, or until you set a new value. + * + * If you set the value while in a @ref dbtransaction (i.e. any transaction + * that is not a @ref nontransaction), then rolling back the transaction will + * undo the change. + * + * All applies to setting _session_ variables. You can also set the same + * variables as _local_ variables, in which case they will always revert to + * their previous value when the transaction ends (or when you overwrite them + * of course). To set a local variable, simply execute an SQL statement + * along the lines of "`SET LOCAL var = 'value'`" inside your transaction. + * + * @param var The variable to set. + * @param value The new value for the variable. + * @throw @ref variable_set_to_null if the value is null; this is not + * allowed. + */ + template + void set_session_var(std::string_view var, TYPE const &value) & + { + if constexpr (nullness::has_null) + { + if (nullness::is_null(value)) + throw variable_set_to_null{ + internal::concat("Attempted to set variable ", var, " to null.")}; + } + exec(internal::concat("SET ", quote_name(var), "=", quote(value))); + } + + /// Read session variable, using SQL's `SHOW` command. + /** @warning This executes an SQL query, so do not get or set variables while + * a table stream or pipeline is active on the same connection. + */ + [[deprecated("Use get_var instead.")]] std::string + get_variable(std::string_view); + + /// Read currently applicable value of a variable. + /** This function executes an SQL statement, so it won't work while a + * @ref pipeline or query stream is active on the connection. + * + * @return a blank `std::optional` if the variable's value is null, or its + * string value otherwise. + */ + std::string get_var(std::string_view var); + + /// Read currently applicable value of a variable. + /** This function executes an SQL statement, so it won't work while a + * @ref pipeline or query stream is active on the connection. + * + * If there is any possibility that the variable is null, ensure that `TYPE` + * can represent null values. + */ + template TYPE get_var_as(std::string_view var) + { + return from_string(get_var(var)); + } + + /** + * @name Notifications and Receivers + */ + //@{ + /// Check for pending notifications and take appropriate action. + /** This does not block. To wait for incoming notifications, either call + * await_notification() (it calls this function); or wait for incoming data + * on the connection's socket (i.e. wait to read), and then call this + * function repeatedly until it returns zero. After that, there are no more + * pending notifications so you may want to wait again. + * + * If any notifications are pending when you call this function, it + * processes them by finding any receivers that match the notification string + * and invoking those. If no receivers match, there is nothing to invoke but + * we do consider the notification processed. + * + * If any of the client-registered receivers throws an exception, the + * function will report it using the connection's errorhandlers. It does not + * re-throw the exceptions. + * + * @return Number of notifications processed. + */ + int get_notifs(); + + /// Wait for a notification to come in. + /** There are other events that will also terminate the wait, such as the + * backend failing. It will also wake up periodically. + * + * If a notification comes in, the call will process it, along with any other + * notifications that may have been pending. + * + * To wait for notifications into your own event loop instead, wait until + * there is incoming data on the connection's socket to be read, then call + * @ref get_notifs() repeatedly until it returns zero. + * + * @return Number of notifications processed. + */ + int await_notification(); + + /// Wait for a notification to come in, or for given timeout to pass. + /** There are other events that will also terminate the wait, such as the + * backend failing, or timeout expiring. + * + * If a notification comes in, the call will process it, along with any other + * notifications that may have been pending. + * + * To wait for notifications into your own event loop instead, wait until + * there is incoming data on the connection's socket to be read, then call + * @ref get_notifs repeatedly until it returns zero. + * + * @return Number of notifications processed + */ + int await_notification(std::time_t seconds, long microseconds); + //@} + + /** + * @name Password encryption + * + * Use this when setting a new password for the user if password encryption + * is enabled. Inputs are the SQL name for the user for whom you with to + * encrypt a password; the plaintext password; and the hash algorithm. + * + * The algorithm must be one of "md5", "scram-sha-256" (introduced in + * PostgreSQL 10), or `nullptr`. If the pointer is null, this will query + * the `password_encryption setting` from the server, and use the default + * algorithm as defined there. + * + * @return encrypted version of the password, suitable for encrypted + * PostgreSQL authentication. + * + * Thus you can change a user's password with: + * ```cxx + * void setpw(transaction_base &t, string const &user, string const &pw) + * { + * t.exec0("ALTER USER " + user + " " + * "PASSWORD '" + t.conn().encrypt_password(user,pw) + "'"); + * } + * ``` + * + * When building this against a libpq older than version 10, this will use + * an older function which only supports md5. In that case, requesting a + * different algorithm than md5 will result in a @ref feature_not_supported + * exception. + */ + //@{ + /// Encrypt a password for a given user. + [[nodiscard]] std::string + encrypt_password(zview user, zview password, zview algorithm) + { + return encrypt_password(user.c_str(), password.c_str(), algorithm.c_str()); + } + /// Encrypt a password for a given user. + [[nodiscard]] std::string encrypt_password( + char const user[], char const password[], char const *algorithm = nullptr); + //@} + + /** + * @name Prepared statements + * + * PostgreSQL supports prepared SQL statements, i.e. statements that you can + * register under a name you choose, optimized once by the backend, and + * executed any number of times under the given name. + * + * Prepared statement definitions are not sensitive to transaction + * boundaries. A statement defined inside a transaction will remain defined + * outside that transaction, even if the transaction itself is subsequently + * aborted. Once a statement has been prepared, it will only go away if you + * close the connection or explicitly "unprepare" the statement. + * + * Use the `pqxx::transaction_base::exec_prepared` functions to execute a + * prepared statement. See @ref prepared for a full discussion. + * + * @warning Using prepared statements can save time, but if your statement + * takes parameters, it may also make your application significantly slower! + * The reason is that the server works out a plan for executing the query + * when you prepare it. At that time, of course it does not know the values + * for the parameters that you will pass. If you execute a query without + * preparing it, then the server works out the plan on the spot, with full + * knowledge of the parameter values. + * + * A statement's definition can refer to its parameters as `$1`, `$2`, etc. + * The first parameter you pass to the call provides a value for `$1`, and + * so on. + * + * Here's an example of how to use prepared statements. + * + * ```cxx + * using namespace pqxx; + * void foo(connection &c) + * { + * c.prepare("findtable", "select * from pg_tables where name=$1"); + * work tx{c}; + * result r = tx.exec_prepared("findtable", "mytable"); + * if (std::empty(r)) throw runtime_error{"mytable not found!"}; + * } + * ``` + */ + //@{ + + /// Define a prepared statement. + /** + * @param name unique name for the new prepared statement. + * @param definition SQL statement to prepare. + */ + void prepare(zview name, zview definition) & + { + prepare(name.c_str(), definition.c_str()); + } + + /** + * @param name unique name for the new prepared statement. + * @param definition SQL statement to prepare. + */ + void prepare(char const name[], char const definition[]) &; + + /// Define a nameless prepared statement. + /** + * This can be useful if you merely want to pass large binary parameters to a + * statement without otherwise wishing to prepare it. If you use this + * feature, always keep the definition and the use close together to avoid + * the nameless statement being redefined unexpectedly by code somewhere + * else. + */ + void prepare(char const definition[]) &; + void prepare(zview definition) & { return prepare(definition.c_str()); } + + /// Drop prepared statement. + void unprepare(std::string_view name); + + //@} + + // C++20: constexpr. Breaks ABI. + /// Suffix unique number to name to make it unique within session context. + /** Used internally to generate identifiers for SQL objects (such as cursors + * and nested transactions) based on a given human-readable base name. + */ + [[nodiscard]] std::string adorn_name(std::string_view); + + /** + * @defgroup escaping-functions String-escaping functions + */ + //@{ + + /// Escape string for use as SQL string literal on this connection. + /** @warning This accepts a length, and it does not require a terminating + * zero byte. But if there is a zero byte, escaping stops there even if + * it's not at the end of the string! + */ + [[deprecated("Use std::string_view or pqxx:zview.")]] std::string + esc(char const text[], std::size_t maxlen) const + { + return esc(std::string_view{text, maxlen}); + } + + /// Escape string for use as SQL string literal on this connection. + [[nodiscard]] std::string esc(char const text[]) const + { + return esc(std::string_view{text}); + } + +#if defined(PQXX_HAVE_SPAN) + /// Escape string for use as SQL string literal, into `buffer`. + /** Use this variant when you want to re-use the same buffer across multiple + * calls. If that's not the case, or convenience and simplicity are more + * important, use the single-argument variant. + * + * For every byte in `text`, there must be at least 2 bytes of space in + * `buffer`; plus there must be one byte of space for a trailing zero. + * Throws @ref range_error if this space is not available. + * + * Returns a reference to the escaped string, which is actually stored in + * `buffer`. + */ + [[nodiscard]] std::string_view + esc(std::string_view text, std::span buffer) + { + auto const size{std::size(text)}, space{std::size(buffer)}; + auto const needed{2 * size + 1}; + if (space < needed) + throw range_error{internal::concat( + "Not enough room to escape string of ", size, " byte(s): need ", + needed, " bytes of buffer space, but buffer size is ", space, ".")}; + auto const data{buffer.data()}; + return {data, esc_to_buf(text, data)}; + } +#endif + + /// Escape string for use as SQL string literal on this connection. + /** @warning This is meant for text strings only. It cannot contain bytes + * whose value is zero ("nul bytes"). + */ + [[nodiscard]] std::string esc(std::string_view text) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape binary string for use as SQL string literal on this connection. + /** This is identical to `esc_raw(data)`. */ + template [[nodiscard]] std::string esc(DATA const &data) const + { + return esc_raw(data); + } +#endif + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + /** Use this variant when you want to re-use the same buffer across multiple + * calls. If that's not the case, or convenience and simplicity are more + * important, use the single-argument variant. + * + * For every byte in `data`, there must be at least two bytes of space in + * `buffer`; plus there must be two bytes of space for a header and one for + * a trailing zero. Throws @ref range_error if this space is not available. + * + * Returns a reference to the escaped string, which is actually stored in + * `buffer`. + */ + template + [[nodiscard]] zview esc(DATA const &data, std::span buffer) const + { + auto const size{std::size(data)}, space{std::size(buffer)}; + auto const needed{internal::size_esc_bin(std::size(data))}; + if (space < needed) + throw range_error{internal::concat( + "Not enough room to escape binary string of ", size, " byte(s): need ", + needed, " bytes of buffer space, but buffer size is ", space, ".")}; + + std::basic_string_view view{std::data(data), std::size(data)}; + auto const out{std::data(buffer)}; + // Actually, in the modern format, we know beforehand exactly how many + // bytes we're going to fill. Just leave out the trailing zero. + internal::esc_bin(view, out); + return zview{out, needed - 1}; + } +#endif + + /// Escape binary string for use as SQL string literal on this connection. + [[deprecated("Use std::byte for binary data.")]] std::string + esc_raw(unsigned char const bin[], std::size_t len) const; + + /// Escape binary string for use as SQL string literal on this connection. + /** You can also just use @ref esc with a binary string. */ + [[nodiscard]] std::string esc_raw(std::basic_string_view) const; + +#if defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + /** You can also just use @ref esc with a binary string. */ + [[nodiscard]] std::string + esc_raw(std::basic_string_view, std::span buffer) const; +#endif + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape binary string for use as SQL string literal on this connection. + /** You can also just use @ref esc with a binary string. */ + template + [[nodiscard]] std::string esc_raw(DATA const &data) const + { + return esc_raw( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + template + [[nodiscard]] zview esc_raw(DATA const &data, std::span buffer) const + { + return this->esc(binary_cast(data), buffer); + } +#endif + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(zview text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return unesc_raw(text.c_str()); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(char const text[]) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + * + * (The data must be encoded in PostgreSQL's "hex" format. The legacy + * "bytea" escape format, used prior to PostgreSQL 9.0, is no longer + * supported.) + */ + [[nodiscard]] std::basic_string + unesc_bin(std::string_view text) const + { + std::basic_string buf; + buf.resize(pqxx::internal::size_unesc_bin(std::size(text))); + pqxx::internal::unesc_bin(text, buf.data()); + return buf; + } + + /// Escape and quote a string of binary data. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(unsigned char const bin[], std::size_t len) const; + + /// Escape and quote a string of binary data. + std::string quote_raw(std::basic_string_view) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape and quote a string of binary data. + /** You can also just use @ref quote with binary data. */ + template + [[nodiscard]] std::string quote_raw(DATA const &data) const + { + return quote_raw( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote an SQL identifier for use in a query. + [[nodiscard]] std::string quote_name(std::string_view identifier) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote a table name. + /** When passing just a table name, this is just another name for + * @ref quote_name. + */ + [[nodiscard]] std::string quote_table(std::string_view name) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote a table path. + /** A table path consists of a table name, optionally prefixed by a schema + * name; and if both are given, they are in turn optionally prefixed by a + * database name. + * + * Each portion of the path (database name, schema name, table name) will be + * quoted separately, and they will be joined together by dots. So for + * example, `myschema.mytable` will become `"myschema"."mytable"`. + */ + [[nodiscard]] std::string quote_table(table_path) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Quote and comma-separate a series of column names. + /** Use this to save a bit of work in cases where you repeatedly need to pass + * the same list of column names, e.g. with @ref stream_to and @ref + * stream_from. Some functions that need to quote the columns list + * internally, will have a "raw" alternative which let you do the quoting + * yourself. It's a bit of extra work, but it can in rare cases let you + * eliminate some duplicate work in quoting them repeatedly. + */ + template + inline std::string quote_columns(STRINGS const &columns) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Represent object as SQL string, including quoting & escaping. + /** + * Recognises nulls and represents them as SQL nulls. They get no quotes. + */ + template + [[nodiscard]] inline std::string quote(T const &t) const; + + [[deprecated("Use std::byte for binary data.")]] std::string + quote(binarystring const &) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote binary data for use as a BYTEA value in SQL statement. + [[nodiscard]] std::string + quote(std::basic_string_view bytes) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape string for literal LIKE match. + /** Use this when part of an SQL "LIKE" pattern should match only as a + * literal string, not as a pattern, even if it contains "%" or "_" + * characters that would normally act as wildcards. + * + * The string does not get string-escaped or quoted. You do that later. + * + * For instance, let's say you have a string `name` entered by the user, + * and you're searching a `file` column for items that match `name` + * followed by a dot and three letters. Even if `name` contains wildcard + * characters "%" or "_", you only want those to match literally, so "_" + * only matches "_" and "%" only matches a single "%". + * + * You do that by "like-escaping" `name`, appending the wildcard pattern + * `".___"`, and finally, escaping and quoting the result for inclusion in + * your query: + * + * ```cxx + * tx.exec( + * "SELECT file FROM item WHERE file LIKE " + + * tx.quote(tx.esc_like(name) + ".___")); + * ``` + * + * The SQL "LIKE" operator also lets you choose your own escape character. + * This is supported, but must be a single-byte character. + */ + [[nodiscard]] std::string + esc_like(std::string_view text, char escape_char = '\\') const; + //@} + + /// Attempt to cancel the ongoing query, if any. + /** You can use this from another thread, and/or while a query is executing + * in a pipeline, but it's up to you to ensure that you're not canceling the + * wrong query. This may involve locking. + */ + void cancel_query(); + +#if defined(_WIN32) || __has_include() + /// Set socket to blocking (true) or nonblocking (false). + /** @warning Do not use this unless you _really_ know what you're doing. + * @warning This function is available on most systems, but not necessarily + * all. + */ + void set_blocking(bool block) &; +#endif // defined(_WIN32) || __has_include() + + /// Set session verbosity. + /** Set the verbosity of error messages to "terse", "normal" (the default), + * or "verbose." + * + * If "terse", returned messages include severity, primary text, and + * position only; this will normally fit on a single line. "normal" produces + * messages that include the above plus any detail, hint, or context fields + * (these might span multiple lines). "verbose" includes all available + * fields. + */ + void set_verbosity(error_verbosity verbosity) &noexcept; + + /// Return pointers to the active errorhandlers. + /** The entries are ordered from oldest to newest handler. + * + * You may use this to find errorhandlers that your application wants to + * delete when destroying the connection. Be aware, however, that libpqxx + * may also add errorhandlers of its own, and those will be included in the + * list. If this is a problem for you, derive your errorhandlers from a + * custom base class derived from pqxx::errorhandler. Then use dynamic_cast + * to find which of the error handlers are yours. + * + * The pointers point to the real errorhandlers. The container it returns + * however is a copy of the one internal to the connection, not a reference. + */ + [[nodiscard]] std::vector get_errorhandlers() const; + + /// Return a connection string encapsulating this connection's options. + /** The connection must be currently open for this to work. + * + * Returns a reconstruction of this connection's connection string. It may + * not exactly match the connection string you passed in when creating this + * connection. + */ + [[nodiscard]] std::string connection_string() const; + + /// Explicitly close the connection. + /** The destructor will do this for you automatically. Still, there is a + * reason to `close()` objects explicitly where possible: if an error should + * occur while closing, `close()` can throw an exception. A destructor + * cannot. + * + * Closing a connection is idempotent. Closing a connection that's already + * closed does nothing. + */ + void close(); + + /// Seize control of a raw libpq connection. + /** @warning Do not do this. Please. It's for very rare, very specific + * use-cases. The mechanism may change (or break) in unexpected ways in + * future versions. + * + * @param raw_conn a raw libpq `PQconn` pointer. + */ + static connection seize_raw_connection(internal::pq::PGconn *raw_conn) + { + return connection{raw_conn}; + } + + /// Release the raw connection without closing it. + /** @warning Do not do this. It's for very rare, very specific use-cases. + * The mechanism may change (or break) in unexpected ways in future versions. + * + * The `connection` object becomes unusable after this. + */ + internal::pq::PGconn *release_raw_connection() && + { + return std::exchange(m_conn, nullptr); + } + +private: + friend class connecting; + enum connect_mode + { + connect_nonblocking + }; + connection(connect_mode, zview connection_string); + + /// For use by @ref seize_raw_connection. + explicit connection(internal::pq::PGconn *raw_conn) : m_conn{raw_conn} {} + + /// Poll for ongoing connection, try to progress towards completion. + /** Returns a pair of "now please wait to read data from socket" and "now + * please wait to write data to socket." Both will be false when done. + * + * Throws an exception if polling indicates that the connection has failed. + */ + std::pair poll_connect(); + + // Initialise based on connection string. + void init(char const options[]); + // Initialise based on parameter names and values. + void init(char const *params[], char const *values[]); + void complete_init(); + + result make_result( + internal::pq::PGresult *pgr, std::shared_ptr const &query, + std::string_view desc = ""sv); + + void PQXX_PRIVATE set_up_state(); + + int PQXX_PRIVATE PQXX_PURE status() const noexcept; + + /// Escape a string, into a buffer allocated by the caller. + /** The buffer must have room for at least `2*std::size(text) + 1` bytes. + * + * Returns the number of bytes written, including the trailing zero. + */ + std::size_t esc_to_buf(std::string_view text, char *buf) const; + + friend class internal::gate::const_connection_largeobject; + char const *PQXX_PURE err_msg() const noexcept; + + void PQXX_PRIVATE process_notice_raw(char const msg[]) noexcept; + + result exec_prepared(std::string_view statement, internal::c_params const &); + + /// Throw @ref usage_error if this connection is not in a movable state. + void check_movable() const; + /// Throw @ref usage_error if not in a state where it can be move-assigned. + void check_overwritable() const; + + friend class internal::gate::connection_errorhandler; + void PQXX_PRIVATE register_errorhandler(errorhandler *); + void PQXX_PRIVATE unregister_errorhandler(errorhandler *) noexcept; + + friend class internal::gate::connection_transaction; + result exec(std::string_view, std::string_view = ""sv); + result + PQXX_PRIVATE exec(std::shared_ptr, std::string_view = ""sv); + void PQXX_PRIVATE register_transaction(transaction_base *); + void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept; + + friend class internal::gate::connection_stream_from; + std::pair>, std::size_t> + PQXX_PRIVATE read_copy_line(); + + friend class internal::gate::connection_stream_to; + void PQXX_PRIVATE write_copy_line(std::string_view); + void PQXX_PRIVATE end_copy_write(); + + friend class internal::gate::connection_largeobject; + internal::pq::PGconn *raw_connection() const { return m_conn; } + + friend class internal::gate::connection_notification_receiver; + void add_receiver(notification_receiver *); + void remove_receiver(notification_receiver *) noexcept; + + friend class internal::gate::connection_pipeline; + void PQXX_PRIVATE start_exec(char const query[]); + bool PQXX_PRIVATE consume_input() noexcept; + bool PQXX_PRIVATE is_busy() const noexcept; + internal::pq::PGresult *get_result(); + + friend class internal::gate::connection_dbtransaction; + friend class internal::gate::connection_sql_cursor; + + result exec_params(std::string_view query, internal::c_params const &args); + + /// Connection handle. + internal::pq::PGconn *m_conn = nullptr; + + /// Active transaction on connection, if any. + /** We don't use this for anything, except to check for open transactions + * when we close the connection or start a new transaction. + * + * We also don't allow move construction or move assignment while there's a + * transaction, since moving the connection in that case would leave one or + * more pointers back from the transaction to the connection dangling. + */ + transaction_base const *m_trans = nullptr; + + std::list m_errorhandlers; + + using receiver_list = + std::multimap; + /// Notification receivers. + receiver_list m_receivers; + + /// Unique number to use as suffix for identifiers (see adorn_name()). + int m_unique_id = 0; +}; + + +/// @deprecated Old base class for connection. They are now the same class. +using connection_base = connection; + + +/// An ongoing, non-blocking stepping stone to a connection. +/** Use this when you want to create a connection to the database, but without + * blocking your whole thread. It is only available on systems that have + * the `` header, and Windows. + * + * Connecting in this way is probably not "faster" (it's more complicated and + * has some extra overhead), but in some situations you can use it to make your + * application as a whole faster. It all depends on having other useful work + * to do in the same thread, and being able to wait on a socket. If you have + * other I/O going on at the same time, your event loop can wait for both the + * libpqxx socket and your own sockets, and wake up whenever any of them is + * ready to do work. + * + * Connecting in this way is not properly "asynchronous;" it's merely + * "nonblocking." This means it's not a super-high-performance mechanism like + * you might get with e.g. `io_uring`. In particular, if we need to look up + * the database hostname in DNS, that will happen synchronously. + * + * To use this, create the `connecting` object, passing a connection string. + * Then loop: If @ref wait_to_read returns true, wait for the socket to have + * incoming data on it. If @ref wait_to_write returns true, wait for the + * socket to be ready for writing. Then call @ref process to process any + * incoming or outgoing data. Do all of this until @ref done returns true (or + * there is an exception). Finally, call @ref produce to get the completed + * connection. + * + * For example: + * + * ```cxx + * pqxx::connecting cg{}; + * + * // Loop until we're done connecting. + * while (!cg.done()) + * { + * wait_for_fd(cg.sock(), cg.wait_to_read(), cg.wait_to_write()); + * cg.process(); + * } + * + * pqxx::connection conn = std::move(cg).produce(); + * + * // At this point, conn is a working connection. You can no longer use + * // cg at all. + * ``` + */ +class PQXX_LIBEXPORT connecting +{ +public: + /// Start connecting. + connecting(zview connection_string = ""_zv); + + connecting(connecting const &) = delete; + connecting(connecting &&) = default; + connecting &operator=(connecting const &) = delete; + connecting &operator=(connecting &&) = default; + + /// Get the socket. The socket may change during the connection process. + [[nodiscard]] int sock() const &noexcept { return m_conn.sock(); } + + /// Should we currently wait to be able to _read_ from the socket? + [[nodiscard]] constexpr bool wait_to_read() const &noexcept + { + return m_reading; + } + + /// Should we currently wait to be able to _write_ to the socket? + [[nodiscard]] constexpr bool wait_to_write() const &noexcept + { + return m_writing; + } + + /// Progress towards completion (but don't block). + void process() &; + + /// Is our connection finished? + [[nodiscard]] constexpr bool done() const &noexcept + { + return not m_reading and not m_writing; + } + + /// Produce the completed connection object. + /** Use this only once, after @ref done returned `true`. Once you have + * called this, the `connecting` instance has no more use or meaning. You + * can't call any of its member functions afterwards. + * + * This member function is rvalue-qualified, meaning that you can only call + * it on an rvalue instance of the class. If what you have is not an rvalue, + * turn it into one by wrapping it in `std::move()`. + */ + [[nodiscard]] connection produce() &&; + +private: + connection m_conn; + bool m_reading{false}; + bool m_writing{true}; +}; + + +template inline std::string connection::quote(T const &t) const +{ + if constexpr (nullness::always_null) + { + return "NULL"; + } + else + { + if (is_null(t)) + return "NULL"; + auto const text{to_string(t)}; + + // Okay, there's an easy way to do this and there's a hard way. The easy + // way was "quote, esc(to_string(t)), quote". I'm going with the hard way + // because it's going to save some string manipulation that will probably + // incur some unnecessary memory allocations and deallocations. + std::string buf{'\''}; + buf.resize(2 + 2 * std::size(text) + 1); + auto const content_bytes{esc_to_buf(text, buf.data() + 1)}; + auto const closing_quote{1 + content_bytes}; + buf[closing_quote] = '\''; + auto const end{closing_quote + 1}; + buf.resize(end); + return buf; + } +} + + +template +inline std::string connection::quote_columns(STRINGS const &columns) const +{ + return separated_list( + ","sv, std::cbegin(columns), std::cend(columns), + [this](auto col) { return this->quote_name(*col); }); +} + + +#if defined(PQXX_HAVE_CONCEPTS) +template +inline connection::connection(MAPPING const ¶ms) +{ + check_version(); + + std::vector keys, values; + if constexpr (std::ranges::sized_range) + { + auto const size{std::ranges::size(params) + 1}; + keys.reserve(size); + values.reserve(size); + } + for (auto const &[key, value] : params) + { + keys.push_back(internal::as_c_string(key)); + values.push_back(internal::as_c_string(value)); + } + keys.push_back(nullptr); + values.push_back(nullptr); + init(std::data(keys), std::data(values)); +} +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/cursor b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/cursor new file mode 100644 index 000000000..e20b3a4fa --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/cursor @@ -0,0 +1,8 @@ +/** Definition of the iterator/container-style cursor classes. + * + * C++-style wrappers for SQL cursors + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/cursor.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/cursor.hxx new file mode 100644 index 000000000..b392e2407 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/cursor.hxx @@ -0,0 +1,483 @@ +/* Definition of the iterator/container-style cursor classes. + * + * C++-style wrappers for SQL cursors. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/cursor instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_CURSOR +#define PQXX_H_CURSOR + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/result.hxx" +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +/// Common definitions for cursor types +/** In C++ terms, fetches are always done in pre-increment or pre-decrement + * fashion--i.e. the result does not include the row the cursor is on at the + * beginning of the fetch, and the cursor ends up being positioned on the last + * row in the result. + * + * There are singular positions akin to `end()` at both the beginning and the + * end of the cursor's range of movement, although these fit in so naturally + * with the semantics that one rarely notices them. The cursor begins at the + * first of these, but any fetch in the forward direction will move the cursor + * off this position and onto the first row before returning anything. + */ +class PQXX_LIBEXPORT cursor_base +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + + /// Cursor access-pattern policy + /** Allowing a cursor to move forward only can result in better performance, + * so use this access policy whenever possible. + */ + enum access_policy + { + /// Cursor can move forward only + forward_only, + /// Cursor can move back and forth + random_access + }; + + /// Cursor update policy + /** + * @warning Not all PostgreSQL versions support updatable cursors. + */ + enum update_policy + { + /// Cursor can be used to read data but not to write + read_only, + /// Cursor can be used to update data as well as read it + update + }; + + /// Cursor destruction policy + /** The normal thing to do is to make a cursor object the owner of the SQL + * cursor it represents. There may be cases, however, where a cursor needs + * to persist beyond the end of the current transaction (and thus also beyond + * the lifetime of the cursor object that created it!), where it can be + * "adopted" into a new cursor object. See the basic_cursor documentation + * for an explanation of cursor adoption. + * + * If a cursor is created with "loose" ownership policy, the object + * representing the underlying SQL cursor will not take the latter with it + * when its own lifetime ends, nor will its originating transaction. + * + * @warning Use this feature with care and moderation. Only one cursor + * object should be responsible for any one underlying SQL cursor at any + * given time. + */ + enum ownership_policy + { + /// Destroy SQL cursor when cursor object is closed at end of transaction + owned, + /// Leave SQL cursor in existence after close of object and transaction + loose + }; + + cursor_base() = delete; + cursor_base(cursor_base const &) = delete; + cursor_base &operator=(cursor_base const &) = delete; + + /** + * @name Special movement distances. + */ + //@{ + + // TODO: Make constexpr inline (but breaks ABI). + /// Special value: read until end. + /** @return Maximum value for result::difference_type, so the cursor will + * attempt to read the largest possible result set. + */ + [[nodiscard]] static difference_type all() noexcept; + + /// Special value: read one row only. + /** @return Unsurprisingly, 1. + */ + [[nodiscard]] static constexpr difference_type next() noexcept { return 1; } + + /// Special value: read backwards, one row only. + /** @return Unsurprisingly, -1. + */ + [[nodiscard]] static constexpr difference_type prior() noexcept + { + return -1; + } + + // TODO: Make constexpr inline (but breaks ABI). + /// Special value: read backwards from current position back to origin. + /** @return Minimum value for result::difference_type. + */ + [[nodiscard]] static difference_type backward_all() noexcept; + + //@} + + /// Name of underlying SQL cursor + /** + * @returns Name of SQL cursor, which may differ from original given name. + * @warning Don't use this to access the SQL cursor directly without going + * through the provided wrapper classes! + */ + [[nodiscard]] constexpr std::string const &name() const noexcept + { + return m_name; + } + +protected: + cursor_base(connection &, std::string_view Name, bool embellish_name = true); + + std::string const m_name; +}; +} // namespace pqxx + + +#include + + +namespace pqxx +{ +/// "Stateless cursor" class: easy API for retrieving parts of result sets +/** This is a front-end for SQL cursors, but with a more C++-like API. + * + * Actually, stateless_cursor feels entirely different from SQL cursors. You + * don't keep track of positions, fetches, and moves; you just say which rows + * you want. See the retrieve() member function. + */ +template +class stateless_cursor +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + + /// Create cursor. + /** + * @param tx The transaction within which you want to create the cursor. + * @param query The SQL query whose results the cursor should traverse. + * @param cname A hint for the cursor's name. The actual SQL cursor's name + * will be based on this (though not necessarily identical). + * @param hold Create a `WITH HOLD` cursor? Such cursors stay alive after + * the transaction has ended, so you can continue to use it. + */ + stateless_cursor( + transaction_base &tx, std::string_view query, std::string_view cname, + bool hold) : + m_cur{tx, query, cname, cursor_base::random_access, up, op, hold} + {} + + /// Adopt an existing scrolling SQL cursor. + /** This lets you define a cursor yourself, and then wrap it in a + * libpqxx-managed `stateless_cursor` object. + * + * @param tx The transaction within which you want to manage the cursor. + * @param adopted_cursor Your cursor's SQL name. + */ + stateless_cursor(transaction_base &tx, std::string_view adopted_cursor) : + m_cur{tx, adopted_cursor, op} + { + // Put cursor in known position + m_cur.move(cursor_base::backward_all()); + } + + /// Close this cursor. + /** The destructor will do this for you automatically. + * + * Closing a cursor is idempotent. Closing a cursor that's already closed + * does nothing. + */ + void close() noexcept { m_cur.close(); } + + /// Number of rows in cursor's result set + /** @note This function is not const; it may need to scroll to find the size + * of the result set. + */ + [[nodiscard]] size_type size() + { + return internal::obtain_stateless_cursor_size(m_cur); + } + + /// Retrieve rows from begin_pos (inclusive) to end_pos (exclusive) + /** Rows are numbered starting from 0 to size()-1. + * + * @param begin_pos First row to retrieve. May be one row beyond the end of + * the result set, to avoid errors for empty result sets. Otherwise, must be + * a valid row number in the result set. + * @param end_pos Row up to which to fetch. Rows are returned ordered from + * begin_pos to end_pos, i.e. in ascending order if begin_pos < end_pos but + * in descending order if begin_pos > end_pos. The end_pos may be + * arbitrarily inside or outside the result set; only existing rows are + * included in the result. + */ + result retrieve(difference_type begin_pos, difference_type end_pos) + { + return internal::stateless_cursor_retrieve( + m_cur, result::difference_type(size()), begin_pos, end_pos); + } + + /// Return this cursor's name. + [[nodiscard]] constexpr std::string const &name() const noexcept + { + return m_cur.name(); + } + +private: + internal::sql_cursor m_cur; +}; + + +class icursor_iterator; +} // namespace pqxx + + +namespace pqxx::internal::gate +{ +class icursor_iterator_icursorstream; +class icursorstream_icursor_iterator; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Simple read-only cursor represented as a stream of results +/** SQL cursors can be tricky, especially in C++ since the two languages seem + * to have been designed on different planets. An SQL cursor has two singular + * positions akin to `end()` on either side of the underlying result set. + * + * These cultural differences are hidden from view somewhat by libpqxx, which + * tries to make SQL cursors behave more like familiar C++ entities such as + * iterators, sequences, streams, and containers. + * + * Data is fetched from the cursor as a sequence of result objects. Each of + * these will contain the number of rows defined as the stream's stride, except + * of course the last block of data which may contain fewer rows. + * + * This class can create or adopt cursors that live outside any backend + * transaction, which your backend version may not support. + */ +class PQXX_LIBEXPORT icursorstream +{ +public: + using size_type = cursor_base::size_type; + using difference_type = cursor_base::difference_type; + + /// Set up a read-only, forward-only cursor. + /** Roughly equivalent to a C++ Standard Library istream, this cursor type + * supports only two operations: reading a block of rows while moving + * forward, and moving forward without reading any data. + * + * @param context Transaction context in which this cursor will be active. + * @param query SQL query whose results this cursor shall iterate. + * @param basename Suggested name for the SQL cursor; the library will append + * a unique code to ensure its uniqueness. + * @param sstride Number of rows to fetch per read operation; must be a + * positive number. + */ + icursorstream( + transaction_base &context, std::string_view query, + std::string_view basename, difference_type sstride = 1); + + /// Adopt existing SQL cursor. Use with care. + /** Forms a cursor stream around an existing SQL cursor, as returned by e.g. + * a server-side function. The SQL cursor will be cleaned up by the stream's + * destructor as if it had been created by the stream; cleaning it up by hand + * or adopting the same cursor twice is an error. + * + * Passing the name of the cursor as a string is not allowed, both to avoid + * confusion with the other constructor and to discourage unnecessary use of + * adopted cursors. + * + * @warning It is technically possible to adopt a "WITH HOLD" cursor, i.e. a + * cursor that stays alive outside its creating transaction. However, any + * cursor stream (including the underlying SQL cursor, naturally) must be + * destroyed before its transaction context object is destroyed. Therefore + * the only way to use SQL's WITH HOLD feature is to adopt the cursor, but + * defer doing so until after entering the transaction context that will + * eventually destroy it. + * + * @param context Transaction context in which this cursor will be active. + * @param cname Result field containing the name of the SQL cursor to adopt. + * @param sstride Number of rows to fetch per read operation; must be a + * positive number. + * @param op Ownership policy. Determines whether the cursor underlying this + * stream will be destroyed when the stream is closed. + */ + icursorstream( + transaction_base &context, field const &cname, difference_type sstride = 1, + cursor_base::ownership_policy op = cursor_base::owned); + + /// Return `true` if this stream may still return more data. + constexpr operator bool() const &noexcept { return not m_done; } + + /// Read new value into given result object; same as operator `>>`. + /** The result set may continue any number of rows from zero to the chosen + * stride, inclusive. An empty result will only be returned if there are no + * more rows to retrieve. + * + * @param res Write the retrieved data into this result object. + * @return Reference to this very stream, to facilitate "chained" invocations + * ("C.get(r1).get(r2);") + */ + icursorstream &get(result &res) + { + res = fetchblock(); + return *this; + } + /// Read new value into given result object; same as `get(result&)`. + /** The result set may continue any number of rows from zero to the chosen + * stride, inclusive. An empty result will only be returned if there are no + * more rows to retrieve. + * + * @param res Write the retrieved data into this result object. + * @return Reference to this very stream, to facilitate "chained" invocations + * ("C >> r1 >> r2;") + */ + icursorstream &operator>>(result &res) { return get(res); } + + /// Move given number of rows forward without reading data. + /** Ignores any stride that you may have set. It moves by a given number of + * rows, not a number of strides. + * + * @return Reference to this stream itself, to facilitate "chained" + * invocations. + */ + icursorstream &ignore(std::streamsize n = 1) &; + + /// Change stride, i.e. the number of rows to fetch per read operation. + /** + * @param stride Must be a positive number. + */ + void set_stride(difference_type stride) &; + [[nodiscard]] constexpr difference_type stride() const noexcept + { + return m_stride; + } + +private: + result fetchblock(); + + friend class internal::gate::icursorstream_icursor_iterator; + size_type forward(size_type n = 1); + void insert_iterator(icursor_iterator *) noexcept; + void remove_iterator(icursor_iterator *) const noexcept; + + void service_iterators(difference_type); + + internal::sql_cursor m_cur; + + difference_type m_stride; + difference_type m_realpos, m_reqpos; + + mutable icursor_iterator *m_iterators; + + bool m_done; +}; + + +/// Approximate istream_iterator for icursorstream. +/** Intended as an implementation of an input_iterator (as defined by the C++ + * Standard Library), this class supports only two basic operations: reading + * the current element, and moving forward. In addition to the minimal + * guarantees for istream_iterators, this class supports multiple successive + * reads of the same position (the current result set is cached in the + * iterator) even after copying and even after new data have been read from the + * stream. This appears to be a requirement for input_iterators. Comparisons + * are also supported in the general case. + * + * The iterator does not care about its own position, however. Moving an + * iterator forward moves the underlying stream forward and reads the data from + * the new stream position, regardless of the iterator's old position in the + * stream. + * + * The stream's stride defines the granularity for all iterator movement or + * access operations, i.e. "ici += 1" advances the stream by one stride's worth + * of rows, and "*ici++" reads one stride's worth of rows from the stream. + * + * @warning Do not read from the underlying stream or its cursor, move its read + * position, or change its stride, between the time the first icursor_iterator + * on it is created and the time its last icursor_iterator is destroyed. + * + * @warning Manipulating these iterators within the context of a single cursor + * stream is not thread-safe. Creating a new iterator, copying one, + * or destroying one affects the stream as a whole. + */ +class PQXX_LIBEXPORT icursor_iterator +{ +public: + using iterator_category = std::input_iterator_tag; + using value_type = result; + using pointer = result const *; + using reference = result const &; + using istream_type = icursorstream; + using size_type = istream_type::size_type; + using difference_type = istream_type::difference_type; + + icursor_iterator() noexcept; + explicit icursor_iterator(istream_type &) noexcept; + icursor_iterator(icursor_iterator const &) noexcept; + ~icursor_iterator() noexcept; + + result const &operator*() const + { + refresh(); + return m_here; + } + result const *operator->() const + { + refresh(); + return &m_here; + } + icursor_iterator &operator++(); + icursor_iterator operator++(int); + icursor_iterator &operator+=(difference_type); + icursor_iterator &operator=(icursor_iterator const &) noexcept; + + [[nodiscard]] bool operator==(icursor_iterator const &rhs) const; + [[nodiscard]] bool operator!=(icursor_iterator const &rhs) const noexcept + { + return not operator==(rhs); + } + [[nodiscard]] bool operator<(icursor_iterator const &rhs) const; + [[nodiscard]] bool operator>(icursor_iterator const &rhs) const + { + return rhs < *this; + } + [[nodiscard]] bool operator<=(icursor_iterator const &rhs) const + { + return not(*this > rhs); + } + [[nodiscard]] bool operator>=(icursor_iterator const &rhs) const + { + return not(*this < rhs); + } + +private: + void refresh() const; + + friend class internal::gate::icursor_iterator_icursorstream; + difference_type pos() const noexcept { return m_pos; } + void fill(result const &); + + icursorstream *m_stream{nullptr}; + result m_here; + difference_type m_pos; + icursor_iterator *m_prev{nullptr}, *m_next{nullptr}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/dbtransaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/dbtransaction new file mode 100644 index 000000000..fa8d26476 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/dbtransaction @@ -0,0 +1,8 @@ +/** pqxx::dbtransaction abstract base class. + * + * pqxx::dbransaction defines a real transaction on the database. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/dbtransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/dbtransaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/dbtransaction.hxx new file mode 100644 index 000000000..d85cb170f --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/dbtransaction.hxx @@ -0,0 +1,70 @@ +/* Definition of the pqxx::dbtransaction abstract base class. + * + * pqxx::dbransaction defines a real transaction on the database. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/dbtransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_DBTRANSACTION +#define PQXX_H_DBTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/transaction_base.hxx" + +namespace pqxx +{ +/// Abstract transaction base class: bracket transactions on the database. +/** + * @ingroup transactions + * + * Use a dbtransaction-derived object such as "work" (transaction<>) to enclose + * operations on a database in a single "unit of work." This ensures that the + * whole series of operations either succeeds as a whole or fails completely. + * In no case will it leave half-finished work behind in the database. + * + * Once processing on a transaction has succeeded and any changes should be + * allowed to become permanent in the database, call commit(). If something + * has gone wrong and the changes should be forgotten, call abort() instead. + * If you do neither, an implicit abort() is executed at destruction time. + * + * It is an error to abort a transaction that has already been committed, or to + * commit a transaction that has already been aborted. Aborting an already + * aborted transaction or committing an already committed one is allowed, to + * make error handling easier. Repeated aborts or commits have no effect after + * the first one. + * + * Database transactions are not suitable for guarding long-running processes. + * If your transaction code becomes too long or too complex, consider ways to + * break it up into smaller ones. Unfortunately there is no universal recipe + * for this. + * + * The actual operations for committing/aborting the backend transaction are + * implemented by a derived class. The implementing concrete class must also + * call @ref close from its destructor. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE dbtransaction : public transaction_base +{ +protected: + /// Begin transaction. + explicit dbtransaction(connection &c) : transaction_base{c} {} + /// Begin transaction. + dbtransaction(connection &c, std::string_view tname) : + transaction_base{c, tname} + {} + /// Begin transaction. + dbtransaction( + connection &c, std::string_view tname, + std::shared_ptr rollback_cmd) : + transaction_base{c, tname, rollback_cmd} + {} +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/errorhandler b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/errorhandler new file mode 100644 index 000000000..ea572ee79 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/errorhandler @@ -0,0 +1,8 @@ +/** pqxx::errorhandler class. + * + * Callbacks for handling errors and warnings. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/errorhandler.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/errorhandler.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/errorhandler.hxx new file mode 100644 index 000000000..2ffb5703c --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/errorhandler.hxx @@ -0,0 +1,92 @@ +/* Definition of the pqxx::errorhandler class. + * + * pqxx::errorhandler handlers errors and warnings in a database session. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/errorhandler instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ERRORHANDLER +#define PQXX_H_ERRORHANDLER + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/types.hxx" + + +namespace pqxx::internal::gate +{ +class errorhandler_connection; +} + + +namespace pqxx +{ +/** + * @addtogroup errorhandler + */ +//@{ + +/// Base class for error-handler callbacks. +/** To receive errors and warnings from a connection, subclass this with your + * own error-handler functor, and instantiate it for the connection. Destroying + * the handler un-registers it. + * + * A connection can have multiple error handlers at the same time. When the + * database connection emits an error or warning message, it passes the message + * to each error handler, starting with the most recently registered one and + * progressing towards the oldest one. However an error handler may also + * instruct the connection not to pass the message to further handlers by + * returning "false." + * + * @warning Strange things happen when a result object outlives its parent + * connection. If you register an error handler on a connection, then you must + * not access the result after destroying the connection. This applies even if + * you destroy the error handler first! + */ +class PQXX_LIBEXPORT errorhandler +{ +public: + explicit errorhandler(connection &); + virtual ~errorhandler(); + + /// Define in subclass: receive an error or warning message from the + /// database. + /** + * @return Whether the same error message should also be passed to the + * remaining, older errorhandlers. + */ + virtual bool operator()(char const msg[]) noexcept = 0; + + errorhandler() = delete; + errorhandler(errorhandler const &) = delete; + errorhandler &operator=(errorhandler const &) = delete; + +private: + connection *m_home; + + friend class internal::gate::errorhandler_connection; + void unregister() noexcept; +}; + + +/// An error handler that suppresses any previously registered error handlers. +class quiet_errorhandler : public errorhandler +{ +public: + /// Suppress error notices. + quiet_errorhandler(connection &conn) : errorhandler{conn} {} + + /// Revert to previous handling of error notices. + virtual bool operator()(char const[]) noexcept override { return false; } +}; + +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/except b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/except new file mode 100644 index 000000000..e5dd508bf --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/except @@ -0,0 +1,8 @@ +/** libpqxx exception classes. + * + * pqxx::sql_error, pqxx::broken_connection, pqxx::in_doubt_error, ... + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/except.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/except.hxx new file mode 100644 index 000000000..24f959437 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/except.hxx @@ -0,0 +1,447 @@ +/* Definition of libpqxx exception classes. + * + * pqxx::sql_error, pqxx::broken_connection, pqxx::in_doubt_error, ... + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/except instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_EXCEPT +#define PQXX_H_EXCEPT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + + +namespace pqxx +{ +/** + * @addtogroup exception Exception classes + * + * These exception classes follow, roughly, the two-level hierarchy defined by + * the PostgreSQL SQLSTATE error codes (see Appendix A of the PostgreSQL + * documentation corresponding to your server version). This is not a complete + * mapping though. There are other differences as well, e.g. the error code + * for `statement_completion_unknown` has a separate status in libpqxx as + * @ref in_doubt_error, and `too_many_connections` is classified as a + * `broken_connection` rather than a subtype of `insufficient_resources`. + * + * @see http://www.postgresql.org/docs/9.4/interactive/errcodes-appendix.html + * + * @{ + */ + +/// Run-time failure encountered by libpqxx, similar to std::runtime_error. +struct PQXX_LIBEXPORT failure : std::runtime_error +{ + explicit failure(std::string const &); +}; + + +/// Exception class for lost or failed backend connection. +/** + * @warning When this happens on Unix-like systems, you may also get a SIGPIPE + * signal. That signal aborts the program by default, so if you wish to be + * able to continue after a connection breaks, be sure to disarm this signal. + * + * If you're working on a Unix-like system, see the manual page for + * `signal` (2) on how to deal with SIGPIPE. The easiest way to make this + * signal harmless is to make your program ignore it: + * + * ```cxx + * #include + * + * int main() + * { + * signal(SIGPIPE, SIG_IGN); + * // ... + * ``` + */ +struct PQXX_LIBEXPORT broken_connection : failure +{ + broken_connection(); + explicit broken_connection(std::string const &); +}; + + +/// The caller attempted to set a variable to null, which is not allowed. +struct PQXX_LIBEXPORT variable_set_to_null : failure +{ + variable_set_to_null(); + explicit variable_set_to_null(std::string const &); +}; + + +/// Exception class for failed queries. +/** Carries, in addition to a regular error message, a copy of the failed query + * and (if available) the SQLSTATE value accompanying the error. + */ +class PQXX_LIBEXPORT sql_error : public failure +{ + /// Query string. Empty if unknown. + std::string const m_query; + /// SQLSTATE string describing the error type, if known; or empty string. + std::string const m_sqlstate; + +public: + explicit sql_error( + std::string const &whatarg = "", std::string const &Q = "", + char const sqlstate[] = nullptr); + virtual ~sql_error() noexcept override; + + /// The query whose execution triggered the exception + [[nodiscard]] PQXX_PURE std::string const &query() const noexcept; + + /// SQLSTATE error code if known, or empty string otherwise. + [[nodiscard]] PQXX_PURE std::string const &sqlstate() const noexcept; +}; + + +/// "Help, I don't know whether transaction was committed successfully!" +/** Exception that might be thrown in rare cases where the connection to the + * database is lost while finishing a database transaction, and there's no way + * of telling whether it was actually executed by the backend. In this case + * the database is left in an indeterminate (but consistent) state, and only + * manual inspection will tell which is the case. + */ +struct PQXX_LIBEXPORT in_doubt_error : failure +{ + explicit in_doubt_error(std::string const &); +}; + + +/// The backend saw itself forced to roll back the ongoing transaction. +struct PQXX_LIBEXPORT transaction_rollback : sql_error +{ + explicit transaction_rollback( + std::string const &whatarg, std::string const &q = "", + char const sqlstate[] = nullptr); +}; + + +/// Transaction failed to serialize. Please retry it. +/** Can only happen at transaction isolation levels REPEATABLE READ and + * SERIALIZABLE. + * + * The current transaction cannot be committed without violating the guarantees + * made by its isolation level. This is the effect of a conflict with another + * ongoing transaction. The transaction may still succeed if you try to + * perform it again. + */ +struct PQXX_LIBEXPORT serialization_failure : transaction_rollback +{ + explicit serialization_failure( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// We can't tell whether our last statement succeeded. +struct PQXX_LIBEXPORT statement_completion_unknown : transaction_rollback +{ + explicit statement_completion_unknown( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// The ongoing transaction has deadlocked. Retrying it may help. +struct PQXX_LIBEXPORT deadlock_detected : transaction_rollback +{ + explicit deadlock_detected( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// Internal error in libpqxx library +struct PQXX_LIBEXPORT internal_error : std::logic_error +{ + explicit internal_error(std::string const &); +}; + + +/// Error in usage of libpqxx library, similar to std::logic_error +struct PQXX_LIBEXPORT usage_error : std::logic_error +{ + explicit usage_error(std::string const &); +}; + + +/// Invalid argument passed to libpqxx, similar to std::invalid_argument +struct PQXX_LIBEXPORT argument_error : std::invalid_argument +{ + explicit argument_error(std::string const &); +}; + + +/// Value conversion failed, e.g. when converting "Hello" to int. +struct PQXX_LIBEXPORT conversion_error : std::domain_error +{ + explicit conversion_error(std::string const &); +}; + + +/// Could not convert value to string: not enough buffer space. +struct PQXX_LIBEXPORT conversion_overrun : conversion_error +{ + explicit conversion_overrun(std::string const &); +}; + + +/// Something is out of range, similar to std::out_of_range +struct PQXX_LIBEXPORT range_error : std::out_of_range +{ + explicit range_error(std::string const &); +}; + + +/// Query returned an unexpected number of rows. +struct PQXX_LIBEXPORT unexpected_rows : public range_error +{ + explicit unexpected_rows(std::string const &msg) : range_error{msg} {} +}; + + +/// Database feature not supported in current setup. +struct PQXX_LIBEXPORT feature_not_supported : sql_error +{ + explicit feature_not_supported( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Error in data provided to SQL statement. +struct PQXX_LIBEXPORT data_exception : sql_error +{ + explicit data_exception( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT integrity_constraint_violation : sql_error +{ + explicit integrity_constraint_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT restrict_violation : integrity_constraint_violation +{ + explicit restrict_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT not_null_violation : integrity_constraint_violation +{ + explicit not_null_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT foreign_key_violation : integrity_constraint_violation +{ + explicit foreign_key_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT unique_violation : integrity_constraint_violation +{ + explicit unique_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT check_violation : integrity_constraint_violation +{ + explicit check_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_cursor_state : sql_error +{ + explicit invalid_cursor_state( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_sql_statement_name : sql_error +{ + explicit invalid_sql_statement_name( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_cursor_name : sql_error +{ + explicit invalid_cursor_name( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT syntax_error : sql_error +{ + /// Approximate position in string where error occurred, or -1 if unknown. + int const error_position; + + explicit syntax_error( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr, int pos = -1) : + sql_error{err, Q, sqlstate}, error_position{pos} + {} +}; + +struct PQXX_LIBEXPORT undefined_column : syntax_error +{ + explicit undefined_column( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT undefined_function : syntax_error +{ + explicit undefined_function( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT undefined_table : syntax_error +{ + explicit undefined_table( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT insufficient_privilege : sql_error +{ + explicit insufficient_privilege( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Resource shortage on the server +struct PQXX_LIBEXPORT insufficient_resources : sql_error +{ + explicit insufficient_resources( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT disk_full : insufficient_resources +{ + explicit disk_full( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + insufficient_resources{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT out_of_memory : insufficient_resources +{ + explicit out_of_memory( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + insufficient_resources{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT too_many_connections : broken_connection +{ + explicit too_many_connections(std::string const &err) : + broken_connection{err} + {} +}; + +/// PL/pgSQL error +/** Exceptions derived from this class are errors from PL/pgSQL procedures. + */ +struct PQXX_LIBEXPORT plpgsql_error : sql_error +{ + explicit plpgsql_error( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Exception raised in PL/pgSQL procedure +struct PQXX_LIBEXPORT plpgsql_raise : plpgsql_error +{ + explicit plpgsql_raise( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT plpgsql_no_data_found : plpgsql_error +{ + explicit plpgsql_no_data_found( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT plpgsql_too_many_rows : plpgsql_error +{ + explicit plpgsql_too_many_rows( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT blob_already_exists : failure +{ + explicit blob_already_exists(std::string const &); +}; + +/** + * @} + */ +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/field b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/field new file mode 100644 index 000000000..37cb69e84 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/field @@ -0,0 +1,8 @@ +/** pqxx::field class. + * + * pqxx::field refers to a field in a query result. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/field.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/field.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/field.hxx new file mode 100644 index 000000000..b8b869fe4 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/field.hxx @@ -0,0 +1,542 @@ +/* Definitions for the pqxx::field class. + * + * pqxx::field refers to a field in a query result. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_FIELD +#define PQXX_H_FIELD + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/array.hxx" +#include "pqxx/composite.hxx" +#include "pqxx/result.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/types.hxx" + +namespace pqxx +{ +/// Reference to a field in a result set. +/** A field represents one entry in a row. It represents an actual value + * in the result set, and can be converted to various types. + */ +class PQXX_LIBEXPORT field +{ +public: + using size_type = field_size_type; + + /// Constructor. Do not call this yourself; libpqxx will do it for you. + /** Create field as reference to a field in a result set. + * @param r Row that this field is part of. + * @param c Column number of this field. + */ + [[deprecated( + "Do not construct fields yourself. Get them from the row.")]] field(row const &r, row_size_type c) noexcept; + + /// Constructor. Do not call this yourself; libpqxx will do it for you. + [[deprecated( + "Do not construct fields yourself. Get them from the " + "row.")]] field() noexcept = default; + + /** + * @name Comparison + */ + //@{ + // TODO: noexcept. Breaks ABI. + /// Byte-by-byte comparison of two fields (all nulls are considered equal) + /** @warning null handling is still open to discussion and change! + * + * Handling of null values differs from that in SQL where a comparison + * involving a null value yields null, so nulls are never considered equal + * to one another or even to themselves. + * + * Null handling also probably differs from the closest equivalent in C++, + * which is the NaN (Not-a-Number) value, a singularity comparable to + * SQL's null. This is because the builtin == operator demands that a == a. + * + * The usefulness of this operator is questionable. No interpretation + * whatsoever is imposed on the data; 0 and 0.0 are considered different, + * as are null vs. the empty string, or even different (but possibly + * equivalent and equally valid) encodings of the same Unicode character + * etc. + */ + [[nodiscard]] PQXX_PURE bool operator==(field const &) const; + + /// Byte-by-byte comparison (all nulls are considered equal) + /** @warning See operator==() for important information about this operator + */ + [[nodiscard]] PQXX_PURE bool operator!=(field const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + /** + * @name Column information + */ + //@{ + /// Column name. + [[nodiscard]] PQXX_PURE char const *name() const &; + + /// Column type. + [[nodiscard]] oid PQXX_PURE type() const; + + /// What table did this column come from? + [[nodiscard]] PQXX_PURE oid table() const; + + /// Return row number. The first row is row 0, the second is row 1, etc. + PQXX_PURE constexpr row_size_type num() const noexcept { return col(); } + + /// What column number in its originating table did this column come from? + [[nodiscard]] PQXX_PURE row_size_type table_column() const; + //@} + + /** + * @name Content access + */ + //@{ + /// Read as `string_view`, or an empty one if null. + /** The result only remains usable while the data for the underlying + * @ref result exists. Once all `result` objects referring to that data have + * been destroyed, the `string_view` will no longer point to valid memory. + */ + [[nodiscard]] PQXX_PURE std::string_view view() const & + { + return std::string_view(c_str(), size()); + } + + /// Read as plain C string. + /** Since the field's data is stored internally in the form of a + * zero-terminated C string, this is the fastest way to read it. Use the + * to() or as() functions to convert the string to other types such as + * `int`, or to C++ strings. + * + * Do not use this for BYTEA values, or other binary values. To read those, + * convert the value to your desired type using `to()` or `as()`. For + * example: `f.as>()`. + */ + [[nodiscard]] PQXX_PURE char const *c_str() const &; + + /// Is this field's value null? + [[nodiscard]] PQXX_PURE bool is_null() const noexcept; + + /// Return number of bytes taken up by the field's value. + [[nodiscard]] PQXX_PURE size_type size() const noexcept; + + /// Read value into obj; or if null, leave obj untouched and return `false`. + /** This can be used with optional types (except pointers other than C-style + * strings). + */ + template + auto to(T &obj) const -> typename std::enable_if_t< + (not std::is_pointer::value or std::is_same::value), + bool> + { + if (is_null()) + { + return false; + } + else + { + auto const bytes{c_str()}; + from_string(bytes, obj); + return true; + } + } + + /// Read field as a composite value, write its components into `fields`. + /** @warning This is still experimental. It may change or be replaced. + * + * Returns whether the field was null. If it was, it will not touch the + * values in `fields`. + */ + template bool composite_to(T &...fields) const + { + if (is_null()) + { + return false; + } + else + { + parse_composite(m_home.m_encoding, view(), fields...); + return true; + } + } + + /// Read value into obj; or leave obj untouched and return `false` if null. + template bool operator>>(T &obj) const { return to(obj); } + + /// Read value into obj; or if null, use default value and return `false`. + /** This can be used with `std::optional`, as well as with standard smart + * pointer types, but not with raw pointers. If the conversion from a + * PostgreSQL string representation allocates a pointer (e.g. using `new`), + * then the object's later deallocation should be baked in as well, right + * from the point where the object is created. So if you want a pointer, use + * a smart pointer, not a raw pointer. + * + * There is one exception, of course: C-style strings. Those are just + * pointers to the field's internal text data. + */ + template + auto to(T &obj, T const &default_value) const -> typename std::enable_if_t< + (not std::is_pointer::value or std::is_same::value), + bool> + { + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = from_string(this->view()); + return not null; + } + + /// Return value as object of given type, or default value if null. + /** Note that unless the function is instantiated with an explicit template + * argument, the Default value's type also determines the result type. + */ + template T as(T const &default_value) const + { + if (is_null()) + return default_value; + else + return from_string(this->view()); + } + + /// Return value as object of given type, or throw exception if null. + /** Use as `as>()` or `as()` as + * an alternative to `get()`; this is disabled for use with raw pointers + * (other than C-strings) because storage for the value can't safely be + * allocated here + */ + template T as() const + { + if (is_null()) + { + if constexpr (not nullness::has_null) + internal::throw_null_conversion(type_name); + else + return nullness::null(); + } + else + { + return from_string(this->view()); + } + } + + /// Return value wrapped in some optional type (empty for nulls). + /** Use as `get()` as before to obtain previous behavior, or specify + * container type with `get()` + */ + template class O = std::optional> + constexpr O get() const + { + return as>(); + } + + // TODO: constexpr noexcept, once array_parser constructor gets those. + /// Parse the field as an SQL array. + /** Call the parser to retrieve values (and structure) from the array. + * + * Make sure the @ref result object stays alive until parsing is finished. If + * you keep the @ref row of `field` object alive, it will keep the @ref + * result object alive as well. + */ + array_parser as_array() const & + { + return array_parser{c_str(), m_home.m_encoding}; + } + //@} + + +protected: + constexpr result const &home() const noexcept { return m_home; } + constexpr result::size_type idx() const noexcept { return m_row; } + constexpr row_size_type col() const noexcept { return m_col; } + + // TODO: Create gates. + friend class pqxx::result; + friend class pqxx::row; + field( + result const &r, result_size_type row_num, row_size_type col_num) noexcept + : + m_col{col_num}, m_home{r}, m_row{row_num} + {} + + /** + * You'd expect this to be unsigned, but due to the way reverse iterators + * are related to regular iterators, it must be allowed to underflow to -1. + */ + row_size_type m_col; + +private: + result m_home; + result::size_type m_row; +}; + + +template<> inline bool field::to(std::string &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = std::string{view()}; + return not null; +} + + +template<> +inline bool field::to( + std::string &obj, std::string const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = std::string{view()}; + return not null; +} + + +/// Specialization: `to(char const *&)`. +/** The buffer has the same lifetime as the data in this result (i.e. of this + * result object, or the last remaining one copied from it etc.), so take care + * not to use it after the last result object referring to this query result is + * destroyed. + */ +template<> inline bool field::to(char const *&obj) const +{ + bool const null{is_null()}; + if (not null) + obj = c_str(); + return not null; +} + + +template<> inline bool field::to(std::string_view &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = view(); + return not null; +} + + +template<> +inline bool field::to( + std::string_view &obj, std::string_view const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = view(); + return not null; +} + + +template<> inline std::string_view field::as() const +{ + if (is_null()) + PQXX_UNLIKELY + internal::throw_null_conversion(type_name); + return view(); +} + + +template<> +inline std::string_view +field::as(std::string_view const &default_value) const +{ + return is_null() ? default_value : view(); +} + + +template<> inline bool field::to(zview &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = zview{c_str(), size()}; + return not null; +} + + +template<> +inline bool field::to(zview &obj, zview const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = zview{c_str(), size()}; + return not null; +} + + +template<> inline zview field::as() const +{ + if (is_null()) + PQXX_UNLIKELY + internal::throw_null_conversion(type_name); + return zview{c_str(), size()}; +} + + +template<> inline zview field::as(zview const &default_value) const +{ + return is_null() ? default_value : zview{c_str(), size()}; +} + + +template> +class field_streambuf : public std::basic_streambuf +{ +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + using openmode = std::ios::openmode; + using seekdir = std::ios::seekdir; + + explicit field_streambuf(field const &f) : m_field{f} { initialize(); } + +protected: + virtual int sync() override { return traits_type::eof(); } + + virtual pos_type seekoff(off_type, seekdir, openmode) override + { + return traits_type::eof(); + } + virtual pos_type seekpos(pos_type, openmode) override + { + return traits_type::eof(); + } + virtual int_type overflow(int_type) override { return traits_type::eof(); } + virtual int_type underflow() override { return traits_type::eof(); } + +private: + field const &m_field; + + int_type initialize() + { + auto g{static_cast(const_cast(m_field.c_str()))}; + this->setg(g, g, g + std::size(m_field)); + return int_type(std::size(m_field)); + } +}; + + +/// Input stream that gets its data from a result field +/** Use this class exactly as you would any other istream to read data from a + * field. All formatting and streaming operations of `std::istream` are + * supported. What you'll typically want to use, however, is the fieldstream + * alias (which defines a @ref basic_fieldstream for `char`). This is similar + * to how e.g. `std::ifstream` relates to `std::basic_ifstream`. + * + * This class has only been tested for the char type (and its default traits). + */ +template> +class basic_fieldstream : public std::basic_istream +{ + using super = std::basic_istream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + + basic_fieldstream(field const &f) : super{nullptr}, m_buf{f} + { + super::init(&m_buf); + } + +private: + field_streambuf m_buf; +}; + +using fieldstream = basic_fieldstream; + +/// Write a result field to any type of stream +/** This can be convenient when writing a field to an output stream. More + * importantly, it lets you write a field to e.g. a `stringstream` which you + * can then use to read, format and convert the field in ways that to() does + * not support. + * + * Example: parse a field into a variable of the nonstandard + * "long long" type. + * + * ```cxx + * extern result R; + * long long L; + * stringstream S; + * + * // Write field's string into S + * S << R[0][0]; + * + * // Parse contents of S into L + * S >> L; + * ``` + */ +template +inline std::basic_ostream & +operator<<(std::basic_ostream &s, field const &value) +{ + s.write(value.c_str(), std::streamsize(std::size(value))); + return s; +} + + +/// Convert a field's value to type `T`. +/** Unlike the "regular" `from_string`, this knows how to deal with null + * values. + */ +template inline T from_string(field const &value) +{ + if (value.is_null()) + { + if constexpr (nullness::has_null) + return nullness::null(); + else + internal::throw_null_conversion(type_name); + } + else + { + return from_string(value.view()); + } +} + + +/// Convert a field's value to `nullptr_t`. +/** Yes, you read that right. This conversion does nothing useful. It always + * returns `nullptr`. + * + * Except... what if the field is not null? In that case, this throws + * @ref conversion_error. + */ +template<> +inline std::nullptr_t from_string(field const &value) +{ + if (not value.is_null()) + throw conversion_error{ + "Extracting non-null field into nullptr_t variable."}; + return nullptr; +} + + +/// Convert a field to a string. +template<> PQXX_LIBEXPORT std::string to_string(field const &value); +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/array-composite.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/array-composite.hxx new file mode 100644 index 000000000..d2b6603e5 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/array-composite.hxx @@ -0,0 +1,305 @@ +#if !defined(PQXX_ARRAY_COMPOSITE_HXX) +# define PQXX_ARRAY_COMPOSITE_HXX + +# include + +# include "pqxx/strconv.hxx" + +namespace pqxx::internal +{ +// Find the end of a double-quoted string. +/** `input[pos]` must be the opening double quote. + * + * Returns the offset of the first position after the closing quote. + */ +inline std::size_t scan_double_quoted_string( + char const input[], std::size_t size, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + // XXX: find_char<'"', '\\'>(). + auto next{scan(input, size, pos)}; + bool at_quote{false}; + for (pos = next, next = scan(input, size, pos); pos < size; + pos = next, next = scan(input, size, pos)) + { + if (at_quote) + { + if (next - pos == 1 and input[pos] == '"') + { + // We just read a pair of double quotes. Carry on. + at_quote = false; + } + else + { + // We just read one double quote, and now we're at a character that's + // not a second double quote. Ergo, that last character was the + // closing double quote and this is the position right after it. + return pos; + } + } + else if (next - pos == 1) + { + switch (input[pos]) + { + case '\\': + // Backslash escape. Skip ahead by one more character. + pos = next; + next = scan(input, size, pos); + break; + + case '"': + // This is either the closing double quote, or the first of a pair of + // double quotes. + at_quote = true; + break; + } + } + else + { + // Multibyte character. Carry on. + } + } + if (not at_quote) + throw argument_error{ + "Missing closing double-quote: " + std::string{input}}; + return pos; +} + + +/// Un-quote and un-escape a double-quoted SQL string. +inline std::string parse_double_quoted_string( + char const input[], std::size_t end, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + std::string output; + // Maximum output size is same as the input size, minus the opening and + // closing quotes. Or in the extreme opposite case, the real number could be + // half that. Usually it'll be a pretty close estimate. + output.reserve(std::size_t(end - pos - 2)); + + for (auto here{scan(input, end, pos)}, next{scan(input, end, here)}; + here < end - 1; here = next, next = scan(input, end, here)) + { + // A backslash here is always an escape. So is a double-quote, since we're + // inside the double-quoted string. In either case, we can just ignore the + // escape character and use the next character. This is the one redeeming + // feature of SQL's escaping system. + if ((next - here == 1) and (input[here] == '\\' or input[here] == '"')) + { + // Skip escape. + here = next; + next = scan(input, end, here); + } + output.append(input + here, input + next); + } + return output; +} + + +/// Find the end of an unquoted string in an array or composite-type value. +/** Stops when it gets to the end of the input; or when it sees any of the + * characters in STOP which has not been escaped. + * + * For array values, STOP is a comma, a semicolon, or a closing brace. For + * a value of a composite type, STOP is a comma or a closing parenthesis. + */ +template +inline std::size_t scan_unquoted_string( + char const input[], std::size_t size, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + bool at_backslash{false}; + auto next{scan(input, size, pos)}; + while ((pos < size) and + ((next - pos) > 1 or at_backslash or ((input[pos] != STOP) and ...))) + { + pos = next; + next = scan(input, size, pos); + at_backslash = + ((not at_backslash) and ((next - pos) == 1) and (input[pos] == '\\')); + } + return pos; +} + + +/// Parse an unquoted array entry or cfield of a composite-type field. +inline std::string parse_unquoted_string( + char const input[], std::size_t end, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + std::string output; + bool at_backslash{false}; + output.reserve(end - pos); + for (auto next{scan(input, end, pos)}; pos < end; + pos = next, next = scan(input, end, pos)) + { + at_backslash = + ((not at_backslash) and ((next - pos) == 1) and (input[pos] == '\\')); + if (not at_backslash) + output.append(input + pos, next - pos); + } + return output; +} + + +/// Parse a field of a composite-type value. +/** `T` is the C++ type of the field we're parsing, and `index` is its + * zero-based number. + * + * Strip off the leading parenthesis or bracket yourself before parsing. + * However, this function will parse the lcosing parenthesis or bracket. + * + * After a successful parse, `pos` will point at `std::end(text)`. + * + * For the purposes of parsing, ranges and arrays count as compositve values, + * so this function supports parsing those. If you specifically need a closing + * parenthesis, check afterwards that `text` did not end in a bracket instead. + * + * @param index Index of the current field, zero-based. It will increment for + * the next field. + * @param input Full input text for the entire composite-type value. + * @param pos Starting position (in `input`) of the field that we're parsing. + * After parsing, this will point at the beginning of the next field if + * there is one, or one position past the last character otherwise. + * @param field Destination for the parsed value. + * @param scan Glyph scanning function for the relevant encoding type. + * @param last_field Number of the last field in the value (zero-based). When + * parsing the last field, this will equal `index`. + */ +template +inline void parse_composite_field( + std::size_t &index, std::string_view input, std::size_t &pos, T &field, + glyph_scanner_func *scan, std::size_t last_field) +{ + assert(index <= last_field); + auto next{scan(std::data(input), std::size(input), pos)}; + if ((next - pos) != 1) + throw conversion_error{"Non-ASCII character in composite-type syntax."}; + + // Expect a field. + switch (input[pos]) + { + case ',': + case ')': + case ']': + // The field is empty, i.e, null. + if constexpr (nullness::has_null) + field = nullness::null(); + else + throw conversion_error{ + "Can't read composite field " + to_string(index) + ": C++ type " + + type_name + " does not support nulls."}; + break; + + case '"': { + auto const stop{scan_double_quoted_string( + std::data(input), std::size(input), pos, scan)}; + auto const text{ + parse_double_quoted_string(std::data(input), stop, pos, scan)}; + field = from_string(text); + pos = stop; + } + break; + + default: { + auto const stop{scan_unquoted_string<',', ')', ']'>( + std::data(input), std::size(input), pos, scan)}; + auto const text{parse_unquoted_string(std::data(input), stop, pos, scan)}; + field = from_string(text); + pos = stop; + } + break; + } + + // Expect a comma or a closing parenthesis. + next = scan(std::data(input), std::size(input), pos); + + if ((next - pos) != 1) + throw conversion_error{ + "Unexpected non-ASCII character after composite field: " + + std::string{input}}; + + if (index < last_field) + { + if (input[pos] != ',') + throw conversion_error{ + "Found '" + std::string{input[pos]} + + "' in composite value where comma was expected: " + std::data(input)}; + } + else + { + if (input[pos] == ',') + throw conversion_error{ + "Composite value contained more fields than the expected " + + to_string(last_field) + ": " + std::data(input)}; + if (input[pos] != ')' and input[pos] != ']') + throw conversion_error{ + "Composite value has unexpected characters where closing parenthesis " + "was expected: " + + std::string{input}}; + if (next != std::size(input)) + throw conversion_error{ + "Composite value has unexpected text after closing parenthesis: " + + std::string{input}}; + } + + pos = next; + ++index; +} + + +/// Conservatively estimate buffer size needed for a composite field. +template +inline std::size_t size_composite_field_buffer(T const &field) +{ + if constexpr (is_unquoted_safe) + { + // Safe to copy, without quotes or escaping. Drop the terminating zero. + return size_buffer(field) - 1; + } + else + { + // + Opening quote. + // + Field budget. + // - Terminating zero. + // + Escaping for each byte in the field's string representation. + // - Escaping for terminating zero. + // + Closing quote. + return 1 + 2 * (size_buffer(field) - 1) + 1; + } +} + + +template +inline void write_composite_field(char *&pos, char *end, T const &field) +{ + if constexpr (is_unquoted_safe) + { + // No need for quoting or escaping. Convert it straight into its final + // place in the buffer, and "backspace" the trailing zero. + pos = string_traits::into_buf(pos, end, field) - 1; + } + else + { + // The field may need escaping, which means we need an intermediate buffer. + // To avoid allocating that at run time, we use the end of the buffer that + // we have. + auto const budget{size_buffer(field)}; + *pos++ = '"'; + + // Now escape buf into its final position. + for (char const c : string_traits::to_buf(end - budget, end, field)) + { + if ((c == '"') or (c == '\\')) + *pos++ = '\\'; + + *pos++ = c; + } + + *pos++ = '"'; + } + + *pos++ = ','; +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/callgate.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/callgate.hxx new file mode 100644 index 000000000..42f7703e3 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/callgate.hxx @@ -0,0 +1,70 @@ +#ifndef PQXX_H_CALLGATE +#define PQXX_H_CALLGATE + +/* +Here's what a typical gate class definition looks like: + +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE @gateclass@ : callgate<@host@> +{ + friend class @client@; + + @gateclass@(reference x) : super(x) {} + + // Methods here. Use home() to access the host-class object. +}; +} // namespace pqxx::internal::gate +*/ + +namespace pqxx::internal +{ +/// Base class for call gates. +/** + * A call gate defines a limited, private interface on the host class that + * specified client classes can access. + * + * The metaphor works as follows: the gate stands in front of a "home," which + * is really a class, and only lets specific friends in. + * + * To implement a call gate that gives client C access to host H, + * * derive a gate class from callgate; + * * make the gate class a friend of H; + * * make C a friend of the gate class; and + * * implement "stuff C can do with H" as private members in the gate class. + * + * This special kind of "gated" friendship gives C private access to H, but + * only through an expressly limited interface. The gate class can access its + * host object as home(). + * + * Keep gate classes entirely stateless. They should be ultra-lightweight + * wrappers for their host classes, and be optimized away as much as possible + * by the compiler. Once you start adding state, you're on a slippery slope + * away from the pure, clean, limited interface pattern that gate classes are + * meant to implement. + * + * Ideally, all member functions of the gate class should be one-liners passing + * calls straight on to the host class. It can be useful however to break this + * rule temporarily during inter-class refactoring. + */ +template class PQXX_PRIVATE callgate +{ +protected: + /// This class, to keep constructors easy. + using super = callgate; + /// A reference to the host class. Helps keep constructors easy. + using reference = HOME &; + + callgate(reference x) : m_home(x) {} + + /// The home object. The gate class has full "private" access. + reference home() const noexcept { return m_home; } + +private: + reference m_home; +}; +} // namespace pqxx::internal + +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/concat.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/concat.hxx new file mode 100644 index 000000000..cd28bde7c --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/concat.hxx @@ -0,0 +1,45 @@ +#if !defined(PQXX_CONCAT_HXX) +# define PQXX_CONCAT_HXX + +# include +# include + +# include "pqxx/strconv.hxx" + +namespace pqxx::internal +{ +/// Convert item to a string, write it into [here, end). +template +void render_item(TYPE const &item, char *&here, char *end) +{ + here = string_traits::into_buf(here, end, item) - 1; +} + + +// C++20: Support non-random_access_range ranges. +/// Efficiently combine a bunch of items into one big string. +/** Use this as an optimised version of string concatentation. It takes just + * about any type; it will represent each item as a string according to its + * @ref string_traits. + * + * This is a simpler, more specialised version of @ref separated_list for a + * statically known series of items, possibly of different types. + */ +template +[[nodiscard]] inline std::string concat(TYPE... item) +{ + std::string buf; + // Size to accommodate string representations of all inputs, minus their + // terminating zero bytes. + buf.resize(size_buffer(item...)); + + char *const data{buf.data()}; + char *here = data; + char *end = data + std::size(buf); + (render_item(item, here, end), ...); + + buf.resize(static_cast(here - data)); + return buf; +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/conversions.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/conversions.hxx new file mode 100644 index 000000000..1df4fdead --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/conversions.hxx @@ -0,0 +1,1188 @@ +#include +#include +#include +#include +#include +#include + +#if defined(PQXX_HAVE_SPAN) && __has_include() +# include +#endif + +#include +#include +#include + +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" + + +/* Internal helpers for string conversion, and conversion implementations. + * + * Do not include this header directly. The libpqxx headers do it for you. + */ +namespace pqxx::internal +{ +/// Convert a number in [0, 9] to its ASCII digit. +inline constexpr char number_to_digit(int i) noexcept +{ + return static_cast(i + '0'); +} + + +/// Compute numeric value of given textual digit (assuming that it is a digit). +constexpr int digit_to_number(char c) noexcept +{ + return c - '0'; +} + + +/// Summarize buffer overrun. +/** Don't worry about the exact parameter types: the sizes will be reasonably + * small, and nonnegative. + */ +std::string PQXX_LIBEXPORT +state_buffer_overrun(int have_bytes, int need_bytes); + + +template +inline std::string state_buffer_overrun(HAVE have_bytes, NEED need_bytes) +{ + return state_buffer_overrun( + static_cast(have_bytes), static_cast(need_bytes)); +} + + +/// Throw exception for attempt to convert null to given type. +[[noreturn]] PQXX_LIBEXPORT void +throw_null_conversion(std::string const &type); + + +/// Deliberately nonfunctional conversion traits for `char` types. +/** There are no string conversions for `char` and its signed and unsigned + * variants. Such a conversion would be dangerously ambiguous: should we treat + * it as text, or as a small integer? It'd be an open invitation for bugs. + * + * But the error message when you get this wrong is very cryptic. So, we + * derive dummy @ref string_traits implementations from this dummy type, and + * ensure that the compiler disallows their use. The compiler error message + * will at least contain a hint of the root of the problem. + */ +template struct disallowed_ambiguous_char_conversion +{ + static char *into_buf(char *, char *, CHAR_TYPE) = delete; + static constexpr zview + to_buf(char *, char *, CHAR_TYPE const &) noexcept = delete; + + static constexpr std::size_t + size_buffer(CHAR_TYPE const &) noexcept = delete; + static CHAR_TYPE from_string(std::string_view) = delete; +}; + + +template PQXX_LIBEXPORT extern std::string to_string_float(T); + + +/// Generic implementation for into_buf, on top of to_buf. +template +inline char *generic_into_buf(char *begin, char *end, T const &value) +{ + zview const text{string_traits::to_buf(begin, end, value)}; + auto const space{end - begin}; + // Include the trailing zero. + auto const len = std::size(text) + 1; + if (internal::cmp_greater(len, space)) + throw conversion_overrun{ + "Not enough buffer space to insert " + type_name + ". " + + state_buffer_overrun(space, len)}; + std::memmove(begin, text.data(), len); + return begin + len; +} + + +/// String traits for builtin integral types (though not bool). +template struct integral_traits +{ + static PQXX_LIBEXPORT T from_string(std::string_view text); + static PQXX_LIBEXPORT zview to_buf(char *begin, char *end, T const &value); + static PQXX_LIBEXPORT char *into_buf(char *begin, char *end, T const &value); + + static constexpr std::size_t size_buffer(T const &) noexcept + { + /** Includes a sign if needed; the number of base-10 digits which the type + * can reliably represent; the one extra base-10 digit which the type can + * only partially represent; and the terminating zero. + */ + return std::is_signed_v + std::numeric_limits::digits10 + 1 + 1; + } +}; + + +/// String traits for builtin floating-point types. +template struct float_traits +{ + static PQXX_LIBEXPORT T from_string(std::string_view text); + static PQXX_LIBEXPORT zview to_buf(char *begin, char *end, T const &value); + static PQXX_LIBEXPORT char *into_buf(char *begin, char *end, T const &value); + + // Return a nonnegative integral value's number of decimal digits. + static constexpr std::size_t digits10(std::size_t value) noexcept + { + if (value < 10) + return 1; + else + return 1 + digits10(value / 10); + } + + static constexpr std::size_t size_buffer(T const &) noexcept + { + using lims = std::numeric_limits; + // See #328 for a detailed discussion on the maximum number of digits. + // + // In a nutshell: for the big cases, the scientific notation is always + // the shortest one, and therefore the one that to_chars will pick. + // + // So... How long can the scientific notation get? 1 (for sign) + 1 (for + // decimal point) + 1 (for 'e') + 1 (for exponent sign) + max_digits10 + + // max number of digits in the exponent + 1 (terminating zero). + // + // What's the max number of digits in the exponent? It's the max number of + // digits out of the most negative exponent and the most positive one. + // + // The longest positive exponent is easy: 1 + ceil(log10(max_exponent10)). + // (The extra 1 is because 10^n takes up 1 + n digits, not n.) + // + // The longest negative exponent is a bit harder: min_exponent10 gives us + // the smallest power of 10 which a normalised version of T can represent. + // But the smallest denormalised power of 10 that T can represent is + // another max_digits10 powers of 10 below that. + // needs a minus sign. + // + // All this stuff messes with my head a bit because it's on the order of + // log10(log10(n)). It's easy to get the number of logs wrong. + auto const max_pos_exp{digits10(lims::max_exponent10)}; + // Really want std::abs(lims::min_exponent10), but MSVC 2017 apparently has + // problems with std::abs. So we use -lims::min_exponent10 instead. + auto const max_neg_exp{ + digits10(lims::max_digits10 - lims::min_exponent10)}; + return 1 + // Sign. + 1 + // Decimal point. + std::numeric_limits::max_digits10 + // Mantissa digits. + 1 + // Exponent "e". + 1 + // Exponent sign. + // Spell this weirdly to stop Windows compilers from reading this as + // a call to their "max" macro when NOMINMAX is not defined. + (std::max)(max_pos_exp, max_neg_exp) + // Exponent digits. + 1; // Terminating zero. + } +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// The built-in arithmetic types do not have inherent null values. +template +struct nullness>> : no_null +{}; + + +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits + : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits + : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; + + +template<> struct string_traits +{ + static PQXX_LIBEXPORT bool from_string(std::string_view text); + + static constexpr zview to_buf(char *, char *, bool const &value) noexcept + { + return value ? "true"_zv : "false"_zv; + } + + static char *into_buf(char *begin, char *end, bool const &value) + { + return pqxx::internal::generic_into_buf(begin, end, value); + } + + static constexpr std::size_t size_buffer(bool const &) noexcept { return 6; } +}; + + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + + +template<> inline constexpr bool is_unquoted_safe{true}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + /// Technically, you could have an optional of an always-null type. + static constexpr bool always_null = nullness::always_null; + static constexpr bool is_null(std::optional const &v) noexcept + { + return ((not v.has_value()) or pqxx::is_null(*v)); + } + static constexpr std::optional null() { return {}; } +}; + + +template +inline constexpr format param_format(std::optional const &value) +{ + return param_format(*value); +} + + +template struct string_traits> +{ + static char *into_buf(char *begin, char *end, std::optional const &value) + { + return string_traits::into_buf(begin, end, *value); + } + + static zview to_buf(char *begin, char *end, std::optional const &value) + { + if (value.has_value()) + return string_traits::to_buf(begin, end, *value); + else + return {}; + } + + static std::optional from_string(std::string_view text) + { + return std::optional{ + std::in_place, string_traits::from_string(text)}; + } + + static std::size_t size_buffer(std::optional const &value) noexcept + { + return pqxx::size_buffer(value.value()); + } +}; + + +template +inline constexpr bool is_unquoted_safe>{is_unquoted_safe}; + + +template struct nullness> +{ + static constexpr bool has_null = (nullness::has_null or ...); + static constexpr bool always_null = (nullness::always_null and ...); + static constexpr bool is_null(std::variant const &value) noexcept + { + return std::visit( + [](auto const &i) noexcept { + return nullness>::is_null(i); + }, + value); + } + + // We don't support `null()` for `std::variant`. + /** It would be technically possible to have a `null` in the case where just + * one of the types has a null, but it gets complicated and arbitrary. + */ + static constexpr std::variant null() = delete; +}; + + +template struct string_traits> +{ + static char * + into_buf(char *begin, char *end, std::variant const &value) + { + return std::visit( + [begin, end](auto const &i) { + return string_traits>::into_buf(begin, end, i); + }, + value); + } + static zview to_buf(char *begin, char *end, std::variant const &value) + { + return std::visit( + [begin, end](auto const &i) { + return string_traits>::to_buf(begin, end, i); + }, + value); + } + static std::size_t size_buffer(std::variant const &value) noexcept + { + return std::visit( + [](auto const &i) noexcept { return pqxx::size_buffer(i); }, value); + } + + /** There's no from_string for std::variant. We could have one with a rule + * like "pick the first type which fits the value," but we'd have to look + * into how natural that API feels to users. + */ + static std::variant from_string(std::string_view) = delete; +}; + + +template +inline constexpr format param_format(std::variant const &value) +{ + return std::visit([](auto &v) { return param_format(v); }, value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + (is_unquoted_safe and ...)}; + + +template inline T from_string(std::stringstream const &text) +{ + return from_string(text.str()); +} + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::nullptr_t) = delete; + + static constexpr zview + to_buf(char *, char *, std::nullptr_t const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::nullptr_t = nullptr) noexcept + { + return 0; + } + static std::nullptr_t from_string(std::string_view) = delete; +}; + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::nullopt_t) = delete; + + static constexpr zview + to_buf(char *, char *, std::nullopt_t const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::nullopt_t) noexcept + { + return 0; + } + static std::nullopt_t from_string(std::string_view) = delete; +}; + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::monostate) = delete; + + static constexpr zview + to_buf(char *, char *, std::monostate const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::monostate) noexcept + { + return 0; + } + static std::monostate from_string(std::string_view) = delete; +}; + + +template<> inline constexpr bool is_unquoted_safe{true}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(char const *t) noexcept + { + return t == nullptr; + } + static constexpr char const *null() noexcept { return nullptr; } +}; + + +/// String traits for C-style string ("pointer to char const"). +template<> struct string_traits +{ + static char const *from_string(std::string_view text) { return text.data(); } + + static zview to_buf(char *begin, char *end, char const *const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, char const *const &value) + { + auto const space{end - begin}; + // Count the trailing zero, even though std::strlen() and friends don't. + auto const len{std::strlen(value) + 1}; + if (space < ptrdiff_t(len)) + throw conversion_overrun{ + "Could not copy string: buffer too small. " + + pqxx::internal::state_buffer_overrun(space, len)}; + std::memmove(begin, value, len); + return begin + len; + } + + static std::size_t size_buffer(char const *const &value) noexcept + { + return std::strlen(value) + 1; + } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(char const *t) noexcept + { + return t == nullptr; + } + static constexpr char const *null() { return nullptr; } +}; + + +/// String traits for non-const C-style string ("pointer to char"). +template<> struct string_traits +{ + static char *into_buf(char *begin, char *end, char *const &value) + { + return string_traits::into_buf(begin, end, value); + } + static zview to_buf(char *begin, char *end, char *const &value) + { + return string_traits::to_buf(begin, end, value); + } + static std::size_t size_buffer(char *const &value) noexcept + { + return string_traits::size_buffer(value); + } + + /// Don't allow conversion to this type since it breaks const-safety. + static char *from_string(std::string_view) = delete; +}; + + +template struct nullness : no_null +{}; + + +/// String traits for C-style string constant ("array of char"). +/** @warning This assumes that every array-of-char is a C-style string literal. + * So, it must include a trailing zero. and it must have static duration. + */ +template struct string_traits +{ + static constexpr zview + to_buf(char *, char *, char const (&value)[N]) noexcept + { + return zview{value, N - 1}; + } + + static char *into_buf(char *begin, char *end, char const (&value)[N]) + { + if (internal::cmp_less(end - begin, size_buffer(value))) + throw conversion_overrun{ + "Could not convert char[] to string: too long for buffer."}; + std::memcpy(begin, value, N); + return begin + N; + } + static constexpr std::size_t size_buffer(char const (&)[N]) noexcept + { + return N; + } + + /// Don't allow conversion to this type. + static void from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +template<> struct string_traits +{ + static std::string from_string(std::string_view text) + { + return std::string{text}; + } + + static char *into_buf(char *begin, char *end, std::string const &value) + { + if (internal::cmp_greater_equal(std::size(value), end - begin)) + throw conversion_overrun{ + "Could not convert string to string: too long for buffer."}; + // Include the trailing zero. + value.copy(begin, std::size(value)); + begin[std::size(value)] = '\0'; + return begin + std::size(value) + 1; + } + + static zview to_buf(char *begin, char *end, std::string const &value) + { + return generic_to_buf(begin, end, value); + } + + static std::size_t size_buffer(std::string const &value) noexcept + { + return std::size(value) + 1; + } +}; + + +/// There's no real null for `std::string_view`. +/** I'm not sure how clear-cut this is: a `string_view` may have a null + * data pointer, which is analogous to a null `char` pointer. + */ +template<> struct nullness : no_null +{}; + + +/// String traits for `string_view`. +template<> struct string_traits +{ + static constexpr std::size_t + size_buffer(std::string_view const &value) noexcept + { + return std::size(value) + 1; + } + + static char *into_buf(char *begin, char *end, std::string_view const &value) + { + if (internal::cmp_greater_equal(std::size(value), end - begin)) + throw conversion_overrun{ + "Could not store string_view: too long for buffer."}; + value.copy(begin, std::size(value)); + begin[std::size(value)] = '\0'; + return begin + std::size(value) + 1; + } + + /// Don't convert to this type; it has nowhere to store its contents. + static std::string_view from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +/// String traits for `zview`. +template<> struct string_traits +{ + static constexpr std::size_t + size_buffer(std::string_view const &value) noexcept + { + return std::size(value) + 1; + } + + static char *into_buf(char *begin, char *end, zview const &value) + { + auto const size{std::size(value)}; + if (internal::cmp_less_equal(end - begin, std::size(value))) + throw conversion_overrun{"Not enough buffer space to store this zview."}; + value.copy(begin, size); + begin[size] = '\0'; + return begin + size + 1; + } + + static std::string_view to_buf(char *begin, char *end, zview const &value) + { + return {into_buf(begin, end, value), std::size(value)}; + } + + /// Don't convert to this type; it has nowhere to store its contents. + static zview from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +template<> struct string_traits +{ + static std::size_t size_buffer(std::stringstream const &) = delete; + + static std::stringstream from_string(std::string_view text) + { + std::stringstream stream; + stream.write(text.data(), std::streamsize(std::size(text))); + return stream; + } + + static char *into_buf(char *, char *, std::stringstream const &) = delete; + static std::string_view + to_buf(char *, char *, std::stringstream const &) = delete; +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::nullptr_t const &) noexcept + { + return true; + } + static constexpr std::nullptr_t null() noexcept { return nullptr; } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::nullopt_t const &) noexcept + { + return true; + } + static constexpr std::nullopt_t null() noexcept { return std::nullopt; } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::monostate const &) noexcept + { + return true; + } + static constexpr std::monostate null() noexcept { return {}; } +}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(std::unique_ptr const &t) noexcept + { + return not t or pqxx::is_null(*t); + } + static constexpr std::unique_ptr null() { return {}; } +}; + + +template +struct string_traits> +{ + static std::unique_ptr from_string(std::string_view text) + { + return std::make_unique(string_traits::from_string(text)); + } + + static char * + into_buf(char *begin, char *end, std::unique_ptr const &value) + { + return string_traits::into_buf(begin, end, *value); + } + + static zview + to_buf(char *begin, char *end, std::unique_ptr const &value) + { + if (value) + return string_traits::to_buf(begin, end, *value); + else + return {}; + } + + static std::size_t + size_buffer(std::unique_ptr const &value) noexcept + { + return pqxx::size_buffer(*value.get()); + } +}; + + +template +inline format param_format(std::unique_ptr const &value) +{ + return param_format(*value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + is_unquoted_safe}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(std::shared_ptr const &t) noexcept + { + return not t or pqxx::is_null(*t); + } + static constexpr std::shared_ptr null() { return {}; } +}; + + +template struct string_traits> +{ + static std::shared_ptr from_string(std::string_view text) + { + return std::make_shared(string_traits::from_string(text)); + } + + static zview to_buf(char *begin, char *end, std::shared_ptr const &value) + { + return string_traits::to_buf(begin, end, *value); + } + static char * + into_buf(char *begin, char *end, std::shared_ptr const &value) + { + return string_traits::into_buf(begin, end, *value); + } + static std::size_t size_buffer(std::shared_ptr const &value) noexcept + { + return pqxx::size_buffer(*value); + } +}; + + +template format param_format(std::shared_ptr const &value) +{ + return param_format(*value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + is_unquoted_safe}; + + +template<> +struct nullness> + : no_null> +{}; + + +#if defined(PQXX_HAVE_CONCEPTS) +template struct nullness : no_null +{}; + + +template inline constexpr format param_format(DATA const &) +{ + return format::binary; +} + + +template struct string_traits +{ + static std::size_t size_buffer(DATA const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf(char *begin, char *end, DATA const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, DATA const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + static DATA from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::basic_string buf; + buf.resize(size); + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.data())); + return buf; + } +}; +#endif // PQXX_HAVE_CONCEPTS + + +template<> struct string_traits> +{ + static std::size_t + size_buffer(std::basic_string const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview + to_buf(char *begin, char *end, std::basic_string const &value) + { + return generic_to_buf(begin, end, value); + } + + static char * + into_buf(char *begin, char *end, std::basic_string const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + static std::basic_string from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::basic_string buf; + buf.resize(size); + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.data())); + return buf; + } +}; + + +template<> +inline constexpr format param_format(std::basic_string const &) +{ + return format::binary; +} + + +template<> +struct nullness> + : no_null> +{}; + + +template<> struct string_traits> +{ + static std::size_t + size_buffer(std::basic_string_view const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf( + char *begin, char *end, std::basic_string_view const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf( + char *begin, char *end, std::basic_string_view const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + // There's no from_string, because there's nobody to hold the data. +}; + +template<> +inline constexpr format param_format(std::basic_string_view const &) +{ + return format::binary; +} +} // namespace pqxx + + +namespace pqxx::internal +{ +/// String traits for SQL arrays. +template struct array_string_traits +{ +private: + using elt_type = strip_t>; + using elt_traits = string_traits; + static constexpr zview s_null{"NULL"}; + +public: + static zview to_buf(char *begin, char *end, Container const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, Container const &value) + { + std::size_t const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to convert array to string."}; + + char *here = begin; + *here++ = '{'; + + bool nonempty{false}; + for (auto const &elt : value) + { + if (is_null(elt)) + { + s_null.copy(here, std::size(s_null)); + here += std::size(s_null); + } + else if constexpr (is_sql_array) + { + // Render nested array in-place. Then erase the trailing zero. + here = elt_traits::into_buf(here, end, elt) - 1; + } + else if constexpr (is_unquoted_safe) + { + // No need to quote or escape. Just convert the value straight into + // its place in the array, and "backspace" the trailing zero. + here = elt_traits::into_buf(here, end, elt) - 1; + } + else + { + *here++ = '"'; + + // Use the tail end of the destination buffer as an intermediate + // buffer. + auto const elt_budget{pqxx::size_buffer(elt)}; + for (char const c : elt_traits::to_buf(end - elt_budget, end, elt)) + { + if (c == '\\' or c == '"') + *here++ = '\\'; + *here++ = c; + } + *here++ = '"'; + } + *here++ = array_separator; + nonempty = true; + } + + // Erase that last comma, if present. + if (nonempty) + here--; + + *here++ = '}'; + *here++ = '\0'; + + return here; + } + + static std::size_t size_buffer(Container const &value) noexcept + { + if constexpr (is_unquoted_safe) + return 3 + std::accumulate( + std::begin(value), std::end(value), std::size_t{}, + [](std::size_t acc, elt_type const &elt) { + return acc + + (pqxx::is_null(elt) ? + std::size(s_null) : + elt_traits::size_buffer(elt)) - + 1; + }); + else + return 3 + std::accumulate( + std::begin(value), std::end(value), std::size_t{}, + [](std::size_t acc, elt_type const &elt) { + // Opening and closing quotes, plus worst-case escaping, + // but don't count the trailing zeroes. + std::size_t const elt_size{ + pqxx::is_null(elt) ? std::size(s_null) : + elt_traits::size_buffer(elt) - 1}; + return acc + 2 * elt_size + 2; + }); + } + + // We don't yet support parsing of array types using from_string. Doing so + // would require a reference to the connection. +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +template +struct nullness> : no_null> +{}; + + +template +struct string_traits> + : internal::array_string_traits> +{}; + + +/// We don't know how to pass array params in binary format, so pass as text. +template +inline constexpr format param_format(std::vector const &) +{ + return format::text; +} + + +/// A `std::vector` is a binary string. Other vectors are not. +template +inline constexpr format param_format(std::vector const &) +{ + return format::binary; +} + + +template inline constexpr bool is_sql_array>{true}; + + +template +struct nullness> : no_null> +{}; + + +template +struct string_traits> + : internal::array_string_traits> +{}; + + +/// We don't know how to pass array params in binary format, so pass as text. +template +inline constexpr format param_format(std::array const &) +{ + return format::text; +} + + +/// An array of `std::byte` is a binary string. +template +inline constexpr format param_format(std::array const &) +{ + return format::binary; +} + + +template +inline constexpr bool is_sql_array>{true}; +} // namespace pqxx + + +namespace pqxx +{ +template inline std::string to_string(T const &value) +{ + if (is_null(value)) + throw conversion_error{ + "Attempt to convert null " + type_name + " to a string."}; + + std::string buf; + // We can't just reserve() space; modifying the terminating zero leads to + // undefined behaviour. + buf.resize(size_buffer(value)); + auto const data{buf.data()}; + auto const end{ + string_traits::into_buf(data, data + std::size(buf), value)}; + buf.resize(static_cast(end - data - 1)); + return buf; +} + + +template<> inline std::string to_string(float const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(double const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(long double const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(std::stringstream const &value) +{ + return value.str(); +} + + +template inline void into_string(T const &value, std::string &out) +{ + if (is_null(value)) + throw conversion_error{ + "Attempt to convert null " + type_name + " to a string."}; + + // We can't just reserve() data; modifying the terminating zero leads to + // undefined behaviour. + out.resize(size_buffer(value) + 1); + auto const data{out.data()}; + auto const end{ + string_traits::into_buf(data, data + std::size(out), value)}; + out.resize(static_cast(end - data - 1)); +} +} // namespace pqxx diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/encoding_group.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/encoding_group.hxx new file mode 100644 index 000000000..e17736e5b --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/encoding_group.hxx @@ -0,0 +1,60 @@ +/** Enum type for supporting encodings in libpqxx + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ENCODING_GROUP +#define PQXX_H_ENCODING_GROUP + +#include + +namespace pqxx::internal +{ +// Types of encodings supported by PostgreSQL, see +// https://www.postgresql.org/docs/current/static/multibyte.html#CHARSET-TABLE +enum class encoding_group +{ + // Handles all single-byte fixed-width encodings + MONOBYTE, + + // Multibyte encodings. + // Many of these can embed ASCII-like bytes inside multibyte characters, + // notably Big5, SJIS, SHIFT_JIS_2004, GP18030, GBK, JOHAB, UHC. + BIG5, + EUC_CN, + // TODO: Merge EUC_JP and EUC_JIS_2004? + EUC_JP, + EUC_JIS_2004, + EUC_KR, + EUC_TW, + GB18030, + GBK, + JOHAB, + MULE_INTERNAL, + // TODO: Merge SJIS and SHIFT_JIS_2004? + SJIS, + SHIFT_JIS_2004, + UHC, + UTF8, +}; + + +// TODO:: Can we just use string_view now? +/// Function type: "find the end of the current glyph." +/** This type of function takes a text buffer, and a location in that buffer, + * and returns the location one byte past the end of the current glyph. + * + * The start offset marks the beginning of the current glyph. It must fall + * within the buffer. + * + * There are multiple different glyph scanner implementations, for different + * kinds of encodings. + */ +using glyph_scanner_func = + std::size_t(char const buffer[], std::size_t buffer_len, std::size_t start); +} // namespace pqxx::internal + +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/encodings.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/encodings.hxx new file mode 100644 index 000000000..ba7fecc70 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/encodings.hxx @@ -0,0 +1,90 @@ +/** Internal string encodings support for libpqxx + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ENCODINGS +#define PQXX_H_ENCODINGS + +#include "pqxx/internal/encoding_group.hxx" + +#include +#include + + +namespace pqxx::internal +{ +char const *name_encoding(int encoding_id); + +/// Convert libpq encoding enum or encoding name to its libpqxx group. +encoding_group enc_group(int /* libpq encoding ID */); +encoding_group enc_group(std::string_view); + + +/// Look up the glyph scanner function for a given encoding group. +/** To identify the glyph boundaries in a buffer, call this to obtain the + * scanner function appropriate for the buffer's encoding. Then, repeatedly + * call the scanner function to find the glyphs. + */ +PQXX_LIBEXPORT glyph_scanner_func *get_glyph_scanner(encoding_group); + + +// TODO: For ASCII search, treat UTF8/EUC_*/MULE_INTERNAL as MONOBYTE. + +/// Find any of the ASCII characters `NEEDLE` in `haystack`. +/** Scans through `haystack` until it finds a single-byte character that + * matches any value in `NEEDLE`. + * + * If it finds one, returns its offset. If not, returns the end of the + * haystack. + */ +template +inline std::size_t find_char( + glyph_scanner_func *scanner, std::string_view haystack, + std::size_t here = 0u) +{ + auto const sz{std::size(haystack)}; + auto const data{std::data(haystack)}; + while (here < sz) + { + auto next{scanner(data, sz, here)}; + // (For some reason gcc had a problem with a right-fold here. But clang + // was fine.) + if ((... or (data[here] == NEEDLE))) + { + // Also check against a multibyte character starting with a bytes which + // just happens to match one of the ASCII bytes we're looking for. It'd + // be cleaner to check that first, but either works. So, let's apply the + // most selective filter first and skip this check in almost all cases. + if (next == here + 1) + return here; + } + + // Nope, no hit. Move on. + here = next; + } + return sz; +} + + +/// Iterate over the glyphs in a buffer. +/** Scans the glyphs in the buffer, and for each, passes its begin and its + * one-past-end pointers to `callback`. + */ +template +inline void for_glyphs( + encoding_group enc, CALLABLE callback, char const buffer[], + std::size_t buffer_len, std::size_t start = 0) +{ + auto const scan{get_glyph_scanner(enc)}; + for (std::size_t here = start, next; here < buffer_len; here = next) + { + next = scan(buffer, buffer_len, here); + callback(buffer + here, buffer + next); + } +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-errorhandler.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-errorhandler.hxx new file mode 100644 index 000000000..ffc12a6cf --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-errorhandler.hxx @@ -0,0 +1,26 @@ +#include + +namespace pqxx +{ +class connection; +class errorhandler; +} // namespace pqxx + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_errorhandler : callgate +{ + friend class pqxx::errorhandler; + + connection_errorhandler(reference x) : super(x) {} + + void register_errorhandler(errorhandler *h) + { + home().register_errorhandler(h); + } + void unregister_errorhandler(errorhandler *h) + { + home().unregister_errorhandler(h); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-largeobject.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-largeobject.hxx new file mode 100644 index 000000000..49feaf9e6 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-largeobject.hxx @@ -0,0 +1,35 @@ +#include + +#include +#include + +namespace pqxx +{ +class blob; +class largeobject; +} // namespace pqxx + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_largeobject : callgate +{ + friend class pqxx::blob; + friend class pqxx::largeobject; + + connection_largeobject(reference x) : super(x) {} + + pq::PGconn *raw_connection() const { return home().raw_connection(); } +}; + + +class PQXX_PRIVATE const_connection_largeobject : callgate +{ + friend class pqxx::blob; + friend class pqxx::largeobject; + + const_connection_largeobject(reference x) : super(x) {} + + std::string error_message() const { return home().err_msg(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-notification_receiver.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-notification_receiver.hxx new file mode 100644 index 000000000..0bcb2db17 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-notification_receiver.hxx @@ -0,0 +1,29 @@ +#include + +#include "pqxx/connection.hxx" + + +namespace pqxx +{ +class notification_receiver; +} + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_notification_receiver : callgate +{ + friend class pqxx::notification_receiver; + + connection_notification_receiver(reference x) : super(x) {} + + void add_receiver(notification_receiver *receiver) + { + home().add_receiver(receiver); + } + void remove_receiver(notification_receiver *receiver) noexcept + { + home().remove_receiver(receiver); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-pipeline.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-pipeline.hxx new file mode 100644 index 000000000..c6ae6e17a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-pipeline.hxx @@ -0,0 +1,23 @@ +#include "pqxx/internal/libpq-forward.hxx" +#include + +#include "pqxx/pipeline.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_pipeline : callgate +{ + friend class pqxx::pipeline; + + connection_pipeline(reference x) : super(x) {} + + void start_exec(char const query[]) { home().start_exec(query); } + pqxx::internal::pq::PGresult *get_result() { return home().get_result(); } + void cancel_query() { home().cancel_query(); } + + bool consume_input() noexcept { return home().consume_input(); } + bool is_busy() const noexcept { return home().is_busy(); } + + int encoding_id() { return home().encoding_id(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-sql_cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-sql_cursor.hxx new file mode 100644 index 000000000..51a889844 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-sql_cursor.hxx @@ -0,0 +1,19 @@ +#include + +namespace pqxx::internal +{ +class sql_cursor; +} + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + + connection_sql_cursor(reference x) : super(x) {} + + result exec(char const query[]) { return home().exec(query); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-stream_from.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-stream_from.hxx new file mode 100644 index 000000000..8961e7146 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-stream_from.hxx @@ -0,0 +1,15 @@ +#include + +#include "pqxx/connection.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_stream_from : callgate +{ + friend class pqxx::stream_from; + + connection_stream_from(reference x) : super{x} {} + + auto read_copy_line() { return home().read_copy_line(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-stream_to.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-stream_to.hxx new file mode 100644 index 000000000..a6974fb21 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-stream_to.hxx @@ -0,0 +1,17 @@ +#include + +#include "pqxx/stream_to.hxx" + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_stream_to : callgate +{ + friend class pqxx::stream_to; + + connection_stream_to(reference x) : super(x) {} + + void write_copy_line(std::string_view line) { home().write_copy_line(line); } + void end_copy_write() { home().end_copy_write(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-transaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-transaction.hxx new file mode 100644 index 000000000..74d659253 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/connection-transaction.hxx @@ -0,0 +1,44 @@ +#include + +namespace pqxx +{ +class connection; +} + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_transaction : callgate +{ + friend class pqxx::transaction_base; + + connection_transaction(reference x) : super(x) {} + + template result exec(STRING query, std::string_view desc) + { + return home().exec(query, desc); + } + + void register_transaction(transaction_base *t) + { + home().register_transaction(t); + } + void unregister_transaction(transaction_base *t) noexcept + { + home().unregister_transaction(t); + } + + auto read_copy_line() { return home().read_copy_line(); } + void write_copy_line(std::string_view line) { home().write_copy_line(line); } + void end_copy_write() { home().end_copy_write(); } + + result exec_prepared(zview statement, internal::c_params const &args) + { + return home().exec_prepared(statement, args); + } + + result exec_params(zview query, internal::c_params const &args) + { + return home().exec_params(query, args); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/errorhandler-connection.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/errorhandler-connection.hxx new file mode 100644 index 000000000..5560cedec --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/errorhandler-connection.hxx @@ -0,0 +1,13 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE errorhandler_connection : callgate +{ + friend class pqxx::connection; + + errorhandler_connection(reference x) : super(x) {} + + void unregister() noexcept { home().unregister(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx new file mode 100644 index 000000000..296d22145 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx @@ -0,0 +1,24 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE icursor_iterator_icursorstream : callgate +{ + friend class pqxx::icursorstream; + + icursor_iterator_icursorstream(reference x) : super(x) {} + + icursor_iterator::difference_type pos() const noexcept + { + return home().pos(); + } + + icursor_iterator *get_prev() { return home().m_prev; } + void set_prev(icursor_iterator *i) { home().m_prev = i; } + + icursor_iterator *get_next() { return home().m_next; } + void set_next(icursor_iterator *i) { home().m_next = i; } + + void fill(result const &r) { home().fill(r); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx new file mode 100644 index 000000000..56056d5ef --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx @@ -0,0 +1,32 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE icursorstream_icursor_iterator : callgate +{ + friend class pqxx::icursor_iterator; + + icursorstream_icursor_iterator(reference x) : super(x) {} + + void insert_iterator(icursor_iterator *i) noexcept + { + home().insert_iterator(i); + } + + void remove_iterator(icursor_iterator *i) const noexcept + { + home().remove_iterator(i); + } + + icursorstream::size_type forward() { return home().forward(); } + icursorstream::size_type forward(icursorstream::size_type n) + { + return home().forward(n); + } + + void service_iterators(icursorstream::difference_type p) + { + home().service_iterators(p); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-connection.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-connection.hxx new file mode 100644 index 000000000..daa0808c0 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-connection.hxx @@ -0,0 +1,14 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_connection : callgate +{ + friend class pqxx::connection; + + result_connection(reference x) : super(x) {} + + operator bool() const { return bool(home()); } + bool operator!() const { return not home(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-creation.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-creation.hxx new file mode 100644 index 000000000..3d9205f2c --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-creation.hxx @@ -0,0 +1,24 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_creation : callgate +{ + friend class pqxx::connection; + friend class pqxx::pipeline; + + result_creation(reference x) : super(x) {} + + static result create( + internal::pq::PGresult *rhs, std::shared_ptr const &query, + encoding_group enc) + { + return result(rhs, query, enc); + } + + void check_status(std::string_view desc = ""sv) const + { + return home().check_status(desc); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-pipeline.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-pipeline.hxx new file mode 100644 index 000000000..3ebe436d2 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-pipeline.hxx @@ -0,0 +1,16 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_pipeline : callgate +{ + friend class pqxx::pipeline; + + result_pipeline(reference x) : super(x) {} + + std::shared_ptr query_ptr() const + { + return home().query_ptr(); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-sql_cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-sql_cursor.hxx new file mode 100644 index 000000000..78b450739 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/result-sql_cursor.hxx @@ -0,0 +1,13 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + + result_sql_cursor(reference x) : super(x) {} + + char const *cmd_status() const noexcept { return home().cmd_status(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/transaction-sql_cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/transaction-sql_cursor.hxx new file mode 100644 index 000000000..4ed78dc93 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/transaction-sql_cursor.hxx @@ -0,0 +1,10 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE transaction_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + transaction_sql_cursor(reference x) : super(x) {} +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/transaction-transaction_focus.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/transaction-transaction_focus.hxx new file mode 100644 index 000000000..ca7939a99 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/gates/transaction-transaction_focus.hxx @@ -0,0 +1,30 @@ +#include + +#include "pqxx/transaction_base.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE transaction_transaction_focus : callgate +{ + friend class pqxx::transaction_focus; + + transaction_transaction_focus(reference x) : super(x) {} + + void register_focus(transaction_focus *focus) + { + home().register_focus(focus); + } + void unregister_focus(transaction_focus *focus) noexcept + { + home().unregister_focus(focus); + } + void register_pending_error(zview error) + { + home().register_pending_error(error); + } + void register_pending_error(std::string &&error) + { + home().register_pending_error(std::move(error)); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/header-post.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/header-post.hxx new file mode 100644 index 000000000..ff6bf8986 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/header-post.hxx @@ -0,0 +1,22 @@ +/* Compiler deficiency workarounds for compiling libpqxx headers. + * + * To be included at the end of each libpqxx header, in order to restore the + * client program's settings. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +// NO GUARDS HERE! This code should be executed every time! + +#if defined(_MSC_VER) +# pragma warning(pop) // Restore compiler's warning state +#endif + +#if !defined(PQXX_HEADER_PRE) +# error "Include pqxx/internal/header-post.hxx AFTER its 'pre' counterpart." +#endif + +#undef PQXX_HEADER_PRE diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/header-pre.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/header-pre.hxx new file mode 100644 index 000000000..abc1a398d --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/header-pre.hxx @@ -0,0 +1,169 @@ +/* Compiler settings for compiling libpqxx headers, and workarounds for all. + * + * Include this before including any other libpqxx headers from within libpqxx. + * And to balance it out, also include header-post.hxx at the end of the batch + * of headers. + * + * The public libpqxx headers (e.g. ``) include this already; + * there's no need to do this from within an application. + * + * Include this file at the highest aggregation level possible to avoid nesting + * and to keep things simple. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ + +// NO GUARD HERE! This part should be included every time this file is. +#if defined(_MSC_VER) + +// Save compiler's warning state, and set warning level 4 for maximum +// sensitivity to warnings. +# pragma warning(push, 4) + +// Visual C++ generates some entirely unreasonable warnings. Disable them. +// Copy constructor could not be generated. +# pragma warning(disable : 4511) +// Assignment operator could not be generated. +# pragma warning(disable : 4512) +// Can't expose outside classes without exporting them. Except the MSVC docs +// say please ignore the warning if it's a standard library class. +# pragma warning(disable : 4251) +// Can't derive library classes from outside classes without exporting them. +// Except the MSVC docs say please ignore the warning if the parent class is +// in the standard library. +# pragma warning(disable : 4275) +// Can't inherit from non-exported class. +# pragma warning(disable : 4275) + +#endif // _MSC_VER + + +#if defined(PQXX_HEADER_PRE) +# error "Avoid nesting #include of pqxx/internal/header-pre.hxx." +#endif + +#define PQXX_HEADER_PRE + + +// Workarounds & definitions that need to be included even in library's headers +#include "pqxx/config-public-compiler.h" + +// Enable ISO-646 alternative operaotr representations: "and" instead of "&&" +// etc. on older compilers. C++20 removes this header. +#if __has_include() +# include +#endif + + +#if defined(PQXX_HAVE_GCC_PURE) +/// Declare function "pure": no side effects, only reads globals and its args. +# define PQXX_PURE __attribute__((pure)) +#else +# define PQXX_PURE /* pure */ +#endif + + +#if defined(__GNUC__) +/// Tell the compiler to optimise a function for size, not speed. +# define PQXX_COLD __attribute__((cold)) +#else +# define PQXX_COLD /* cold */ +#endif + + +// Workarounds for Windows +#ifdef _WIN32 + +/* For now, export DLL symbols if _DLL is defined. This is done automatically + * by the compiler when linking to the dynamic version of the runtime library, + * according to "gzh" + */ +# if defined(PQXX_SHARED) && !defined(PQXX_LIBEXPORT) +# define PQXX_LIBEXPORT __declspec(dllimport) +# endif // PQXX_SHARED && !PQXX_LIBEXPORT + + +// Workarounds for Microsoft Visual C++ +# ifdef _MSC_VER + +// Suppress vtables on abstract classes. +# define PQXX_NOVTABLE __declspec(novtable) + +// Automatically link with the appropriate libpq (static or dynamic, debug or +// release). The default is to use the release DLL. Define PQXX_PQ_STATIC to +// link to a static version of libpq, and _DEBUG to link to a debug version. +// The two may be combined. +# if defined(PQXX_AUTOLINK) +# if defined(PQXX_PQ_STATIC) +# ifdef _DEBUG +# pragma comment(lib, "libpqd") +# else +# pragma comment(lib, "libpq") +# endif +# else +# ifdef _DEBUG +# pragma comment(lib, "libpqddll") +# else +# pragma comment(lib, "libpqdll") +# endif +# endif +# endif + +// If we're not compiling libpqxx itself, automatically link with the +// appropriate libpqxx library. To link with the libpqxx DLL, define +// PQXX_SHARED; the default is to link with the static library. A static link +// is the recommended practice. +// +// The preprocessor macro PQXX_INTERNAL is used to detect whether we +// are compiling the libpqxx library itself. When you compile the library +// yourself using your own project file, make sure to include this macro. +# if defined(PQXX_AUTOLINK) && !defined(PQXX_INTERNAL) +# ifdef PQXX_SHARED +# ifdef _DEBUG +# pragma comment(lib, "libpqxxD") +# else +# pragma comment(lib, "libpqxx") +# endif +# else // !PQXX_SHARED +# ifdef _DEBUG +# pragma comment(lib, "libpqxx_staticD") +# else +# pragma comment(lib, "libpqxx_static") +# endif +# endif +# endif + +# endif // _MSC_VER + +#elif defined(PQXX_HAVE_GCC_VISIBILITY) // !_WIN32 + +# define PQXX_LIBEXPORT __attribute__((visibility("default"))) +# define PQXX_PRIVATE __attribute__((visibility("hidden"))) + +#endif // PQXX_HAVE_GCC_VISIBILITY + + +#ifndef PQXX_LIBEXPORT +# define PQXX_LIBEXPORT /* libexport */ +#endif + +#ifndef PQXX_PRIVATE +# define PQXX_PRIVATE /* private */ +#endif + +#ifndef PQXX_NOVTABLE +# define PQXX_NOVTABLE /* novtable */ +#endif + +// C++20: Assume support. +#if defined(PQXX_HAVE_LIKELY) +# define PQXX_LIKELY [[likely]] +# define PQXX_UNLIKELY [[unlikely]] +#else +# define PQXX_LIKELY /* [[likely]] */ +# define PQXX_UNLIKELY /* [[unlikely]] */ +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/ignore-deprecated-post.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/ignore-deprecated-post.hxx new file mode 100644 index 000000000..cebcf0594 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/ignore-deprecated-post.hxx @@ -0,0 +1,15 @@ +/// End a code block started by "ignore-deprecated-pre.hxx". + +#if !defined(PQXX_IGNORING_DEPRECATED) +# error "Ended an 'ignore-deprecated' block while none was active." +#endif + +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif // __GNUC__ + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#undef PQXX_IGNORING_DEPRECATED diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/ignore-deprecated-pre.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/ignore-deprecated-pre.hxx new file mode 100644 index 000000000..8ac57afaa --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/ignore-deprecated-pre.hxx @@ -0,0 +1,28 @@ +/** Start a block of deprecated code which may call other deprecated code. + * + * Most compilers will emit warnings when deprecated code is invoked from + * non-deprecated code. But some compilers (notably gcc) will always emit the + * warning even when the calling code is also deprecated. + * + * This header starts a block where those warnings are suppressed. It can be + * included inside a code block. + * + * Always match the #include with a closing #include of + * "ignore-deprecated-post.hxx". To avoid mistakes, keep the enclosed area as + * small as possible. + */ +#if defined(PQXX_IGNORING_DEPRECATED) +# error "Started an 'ignore-deprecated' block inside another." +#endif + +#define PQXX_IGNORING_DEPRECATED + +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // __GNUC__ + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4996) +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/libpq-forward.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/libpq-forward.hxx new file mode 100644 index 000000000..9e74f79ec --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/libpq-forward.hxx @@ -0,0 +1,31 @@ +/** Minimal forward declarations of libpq types needed in libpqxx headers. + * + * DO NOT INCLUDE THIS FILE when building client programs. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +extern "C" +{ + struct pg_conn; + struct pg_result; + struct pgNotify; +} + +/// Forward declarations of libpq types as needed in libpqxx headers. +namespace pqxx::internal::pq +{ +using PGconn = pg_conn; +using PGresult = pg_result; +using PGnotify = pgNotify; +using PQnoticeProcessor = void (*)(void *, char const *); +} // namespace pqxx::internal::pq + +namespace pqxx +{ +/// PostgreSQL database row identifier. +using oid = unsigned int; +} // namespace pqxx diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/result_iter.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/result_iter.hxx new file mode 100644 index 000000000..1fa1f7d8a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/result_iter.hxx @@ -0,0 +1,124 @@ +/** Result loops. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT_ITER +#define PQXX_H_RESULT_ITER + +#include + +#include "pqxx/strconv.hxx" + +namespace pqxx +{ +class result; +} // namespace pqxx + + +namespace pqxx::internal +{ +// C++20: Replace with generator? +/// Iterator for looped unpacking of a result. +template class result_iter +{ +public: + using value_type = std::tuple; + + /// Construct an "end" iterator. + result_iter() = default; + + explicit result_iter(result const &home) : + m_home{&home}, m_size{std::size(home)} + { + if (not std::empty(home)) + read(); + } + result_iter(result_iter const &) = default; + + result_iter &operator++() + { + m_index++; + if (m_index >= m_size) + m_home = nullptr; + else + read(); + return *this; + } + + /// Comparison only works for comparing to end(). + bool operator==(result_iter const &rhs) const + { + return m_home == rhs.m_home; + } + bool operator!=(result_iter const &rhs) const { return not(*this == rhs); } + + value_type const &operator*() const { return m_value; } + +private: + void read() { (*m_home)[m_index].convert(m_value); } + + result const *m_home{nullptr}; + result::size_type m_index{0}; + result::size_type m_size; + value_type m_value; +}; + + +template class result_iteration +{ +public: + using iterator = result_iter; + explicit result_iteration(result const &home) : m_home{home} + { + constexpr auto tup_size{sizeof...(TYPE)}; + if (home.columns() != tup_size) + throw usage_error{internal::concat( + "Tried to extract ", to_string(tup_size), + " field(s) from a result with ", to_string(home.columns()), + " column(s).")}; + } + iterator begin() const + { + if (std::size(m_home) == 0) + return end(); + else + return iterator{m_home}; + } + iterator end() const { return {}; } + +private: + pqxx::result const &m_home; +}; +} // namespace pqxx::internal + + +template inline auto pqxx::result::iter() const +{ + return pqxx::internal::result_iteration{*this}; +} + + +template +inline void pqxx::result::for_each(CALLABLE &&func) const +{ + using args_tuple = internal::args_t; + constexpr auto sz{std::tuple_size_v}; + static_assert( + sz > 0, + "Callback for for_each must take parameters, one for each column in the " + "result."); + + auto const cols{this->columns()}; + if (sz != cols) + throw usage_error{internal::concat( + "Callback to for_each takes ", sz, "parameter", (sz == 1) ? "" : "s", + ", but result set has ", cols, "field", (cols == 1) ? "" : "s", ".")}; + + using pass_tuple = pqxx::internal::strip_types_t; + for (auto const r : *this) std::apply(func, r.as_tuple()); +} +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/result_iterator.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/result_iterator.hxx new file mode 100644 index 000000000..3f27a1d3f --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/result_iterator.hxx @@ -0,0 +1,389 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT_ITERATOR +#define PQXX_H_RESULT_ITERATOR + +#include "pqxx/row.hxx" + + +/* Result iterator. + * + * Don't include this header from your own application; it is included for you + * by other libpqxx headers. + */ + +namespace pqxx +{ +/// Iterator for rows in a result. Use as result::const_iterator. +/** A result, once obtained, cannot be modified. Therefore there is no + * plain iterator type for result. However its const_iterator type can be + * used to inspect its rows without changing them. + */ +class PQXX_LIBEXPORT const_result_iterator : public row +{ +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = row const; + using pointer = row const *; + using reference = row; + using size_type = result_size_type; + using difference_type = result_difference_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create an iterator, but in an unusable state. + const_result_iterator() noexcept = default; + /// Copy an iterator. + const_result_iterator(const_result_iterator const &) noexcept = default; + /// Move an iterator. + const_result_iterator(const_result_iterator &&) noexcept = default; + + /// Begin iterating a @ref row. + const_result_iterator(row const &t) noexcept : row{t} {} +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /** + * @name Dereferencing operators + * + * An iterator "points to" its own row, which is also itself. This makes it + * easy to address a @ref result as a two-dimensional container, without + * going through the intermediate step of dereferencing the iterator. It + * makes the interface similar to C pointer/array semantics. + * + * IIRC Alex Stepanov, the inventor of the STL, once remarked that having + * this as standard behaviour for pointers would be useful in some + * algorithms. So even if this makes me look foolish, I would seem to be in + * distinguished company. + */ + //@{ + /// Dereference the iterator. + [[nodiscard]] pointer operator->() const { return this; } + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Dereference the iterator. + [[nodiscard]] reference operator*() const { return *this; } +#include "pqxx/internal/ignore-deprecated-post.hxx" + //@} + + /** + * @name Field access + */ + //@{ + using row::back; + using row::front; + using row::operator[]; + using row::at; + using row::rownumber; + //@} + + /** + * @name Manipulations + */ + //@{ + const_result_iterator &operator=(const_result_iterator const &rhs) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::operator=(rhs); +#include "pqxx/internal/ignore-deprecated-post.hxx" + return *this; + } + + const_result_iterator &operator=(const_result_iterator &&rhs) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::operator=(std::move(rhs)); +#include "pqxx/internal/ignore-deprecated-post.hxx" + return *this; + } + + const_result_iterator operator++(int); + const_result_iterator &operator++() + { + ++m_index; + return *this; + } + const_result_iterator operator--(int); + const_result_iterator &operator--() + { + --m_index; + return *this; + } + + const_result_iterator &operator+=(difference_type i) + { + m_index += i; + return *this; + } + const_result_iterator &operator-=(difference_type i) + { + m_index -= i; + return *this; + } + + /// Interchange two iterators in an exception-safe manner. + void swap(const_result_iterator &other) noexcept + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::swap(other); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool operator==(const_result_iterator const &i) const + { + return m_index == i.m_index; + } + [[nodiscard]] bool operator!=(const_result_iterator const &i) const + { + return m_index != i.m_index; + } + [[nodiscard]] bool operator<(const_result_iterator const &i) const + { + return m_index < i.m_index; + } + [[nodiscard]] bool operator<=(const_result_iterator const &i) const + { + return m_index <= i.m_index; + } + [[nodiscard]] bool operator>(const_result_iterator const &i) const + { + return m_index > i.m_index; + } + [[nodiscard]] bool operator>=(const_result_iterator const &i) const + { + return m_index >= i.m_index; + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] inline const_result_iterator operator+(difference_type) const; + friend const_result_iterator + operator+(difference_type, const_result_iterator const &); + [[nodiscard]] inline const_result_iterator operator-(difference_type) const; + [[nodiscard]] inline difference_type + operator-(const_result_iterator const &) const; + //@} + +private: + friend class pqxx::result; + const_result_iterator(pqxx::result const *r, result_size_type i) noexcept : + row{*r, i, r->columns()} + {} +}; + + +/// Reverse iterator for result. Use as result::const_reverse_iterator. +class PQXX_LIBEXPORT const_reverse_result_iterator + : private const_result_iterator +{ +public: + using super = const_result_iterator; + using iterator_type = const_result_iterator; + using iterator_type::difference_type; + using iterator_type::iterator_category; + using iterator_type::pointer; + using value_type = iterator_type::value_type; + using reference = iterator_type::reference; + + /// Create an iterator, but in an unusable state. + const_reverse_result_iterator() = default; + /// Copy an iterator. + const_reverse_result_iterator(const_reverse_result_iterator const &rhs) = + default; + /// Copy a reverse iterator from a regular iterator. + explicit const_reverse_result_iterator(const_result_iterator const &rhs) : + const_result_iterator{rhs} + { + super::operator--(); + } + + /// Move a regular iterator into a reverse iterator. + explicit const_reverse_result_iterator(const_result_iterator const &&rhs) : + const_result_iterator{std::move(rhs)} + { + super::operator--(); + } + + /// Return the underlying "regular" iterator (as per standard library). + [[nodiscard]] PQXX_PURE const_result_iterator base() const noexcept; + + /** + * @name Dereferencing operators + */ + //@{ + /// Dereference iterator. + using const_result_iterator::operator->; + /// Dereference iterator. + using const_result_iterator::operator*; + //@} + + /** + * @name Field access + */ + //@{ + using const_result_iterator::back; + using const_result_iterator::front; + using const_result_iterator::operator[]; + using const_result_iterator::at; + using const_result_iterator::rownumber; + //@} + + /** + * @name Manipulations + */ + //@{ + const_reverse_result_iterator & + operator=(const_reverse_result_iterator const &r) + { + iterator_type::operator=(r); + return *this; + } + const_reverse_result_iterator &operator=(const_reverse_result_iterator &&r) + { + iterator_type::operator=(std::move(r)); + return *this; + } + const_reverse_result_iterator &operator++() + { + iterator_type::operator--(); + return *this; + } + const_reverse_result_iterator operator++(int); + const_reverse_result_iterator &operator--() + { + iterator_type::operator++(); + return *this; + } + const_reverse_result_iterator operator--(int); + const_reverse_result_iterator &operator+=(difference_type i) + { + iterator_type::operator-=(i); + return *this; + } + const_reverse_result_iterator &operator-=(difference_type i) + { + iterator_type::operator+=(i); + return *this; + } + + void swap(const_reverse_result_iterator &other) noexcept + { + const_result_iterator::swap(other); + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] const_reverse_result_iterator + operator+(difference_type i) const + { + return const_reverse_result_iterator(base() - i); + } + [[nodiscard]] const_reverse_result_iterator operator-(difference_type i) + { + return const_reverse_result_iterator(base() + i); + } + [[nodiscard]] difference_type + operator-(const_reverse_result_iterator const &rhs) const + { + return rhs.const_result_iterator::operator-(*this); + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool + operator==(const_reverse_result_iterator const &rhs) const noexcept + { + return iterator_type::operator==(rhs); + } + [[nodiscard]] bool + operator!=(const_reverse_result_iterator const &rhs) const noexcept + { + return not operator==(rhs); + } + + [[nodiscard]] bool operator<(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator>(rhs); + } + [[nodiscard]] bool operator<=(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator>=(rhs); + } + [[nodiscard]] bool operator>(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator<(rhs); + } + [[nodiscard]] bool operator>=(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator<=(rhs); + } + //@} +}; + + +inline const_result_iterator +const_result_iterator::operator+(result::difference_type o) const +{ + return {&m_result, size_type(result::difference_type(m_index) + o)}; +} + +inline const_result_iterator +operator+(result::difference_type o, const_result_iterator const &i) +{ + return i + o; +} + +inline const_result_iterator +const_result_iterator::operator-(result::difference_type o) const +{ + return {&m_result, result_size_type(result::difference_type(m_index) - o)}; +} + +inline result::difference_type +const_result_iterator::operator-(const const_result_iterator &i) const +{ + return result::difference_type(num() - i.num()); +} + +inline const_result_iterator result::end() const noexcept +{ + return {this, size()}; +} + + +inline const_result_iterator result::cend() const noexcept +{ + return end(); +} + + +inline const_reverse_result_iterator +operator+(result::difference_type n, const_reverse_result_iterator const &i) +{ + return const_reverse_result_iterator{i.base() - n}; +} + +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/sql_cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/sql_cursor.hxx new file mode 100644 index 000000000..a26d06306 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/sql_cursor.hxx @@ -0,0 +1,118 @@ +/** Internal wrapper for SQL cursors. Supports higher-level cursor classes. + * + * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SQL_CURSOR +#define PQXX_H_SQL_CURSOR + +namespace pqxx::internal +{ +/// Cursor with SQL positioning semantics. +/** Thin wrapper around an SQL cursor, with SQL's ideas of positioning. + * + * SQL cursors have pre-increment/pre-decrement semantics, with on either end + * of the result set a special position that does not repesent a row. This + * class models SQL cursors for the purpose of implementing more C++-like + * semantics on top. + * + * Positions of actual rows are numbered starting at 1. Position 0 exists but + * does not refer to a row. There is a similar non-row position at the end of + * the result set. + * + * Don't use this at home. You deserve better. Use the stateles_cursor + * instead. + */ +class PQXX_LIBEXPORT sql_cursor : public cursor_base +{ +public: + sql_cursor( + transaction_base &t, std::string_view query, std::string_view cname, + cursor_base::access_policy ap, cursor_base::update_policy up, + cursor_base::ownership_policy op, bool hold); + + sql_cursor( + transaction_base &t, std::string_view cname, + cursor_base::ownership_policy op); + + ~sql_cursor() noexcept { close(); } + + result fetch(difference_type rows, difference_type &displacement); + result fetch(difference_type rows) + { + difference_type d = 0; + return fetch(rows, d); + } + difference_type move(difference_type rows, difference_type &displacement); + difference_type move(difference_type rows) + { + difference_type d = 0; + return move(rows, d); + } + + /// Current position, or -1 for unknown + /** + * The starting position, just before the first row, counts as position zero. + * + * Position may be unknown if (and only if) this cursor was adopted, and has + * never hit its starting position (position zero). + */ + difference_type pos() const noexcept { return m_pos; } + + /// End position, or -1 for unknown + /** + * Returns the final position, just after the last row in the result set. The + * starting position, just before the first row, counts as position zero. + * + * End position is unknown until it is encountered during use. + */ + difference_type endpos() const noexcept { return m_endpos; } + + /// Return zero-row result for this cursor. + result const &empty_result() const noexcept { return m_empty_result; } + + void close() noexcept; + +private: + difference_type adjust(difference_type hoped, difference_type actual); + static std::string stridestring(difference_type); + /// Initialize cached empty result. Call only at beginning or end! + void init_empty_result(transaction_base &); + + /// Connection in which this cursor lives. + connection &m_home; + + /// Zero-row result from this cursor (or plain empty one if cursor is + /// adopted) + result m_empty_result; + + result m_cached_current_row; + + /// Is this cursor adopted (as opposed to created by this cursor object)? + bool m_adopted; + + /// Will this cursor object destroy its SQL cursor when it dies? + cursor_base::ownership_policy m_ownership; + + /// At starting position (-1), somewhere in the middle (0), or past end (1) + int m_at_end; + + /// Position, or -1 for unknown + difference_type m_pos; + + /// End position, or -1 for unknown + difference_type m_endpos = -1; +}; + + +PQXX_LIBEXPORT result_size_type obtain_stateless_cursor_size(sql_cursor &); +PQXX_LIBEXPORT result stateless_cursor_retrieve( + sql_cursor &, result::difference_type size, + result::difference_type begin_pos, result::difference_type end_pos); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/statement_parameters.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/statement_parameters.hxx new file mode 100644 index 000000000..b078bf6e0 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/statement_parameters.hxx @@ -0,0 +1,131 @@ +/** Common implementation for statement parameter lists. + * + * These are used for both prepared statements and parameterized statements. + * + * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STATEMENT_PARAMETER +#define PQXX_H_STATEMENT_PARAMETER + +#include +#include +#include +#include +#include + +#include "pqxx/binarystring.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/util.hxx" + + +namespace pqxx::internal +{ +template +constexpr inline auto const iterator_identity{ + [](decltype(*std::declval()) x) { return x; }}; + + +/// Marker type: pass a dynamically-determined number of statement parameters. +/** @deprecated Use @ref params instead. + * + * Normally when invoking a prepared or parameterised statement, the number + * of parameters is known at compile time. For instance, + * `t.exec_prepared("foo", 1, "x");` executes statement `foo` with two + * parameters, an `int` and a C string. + * + * But sometimes you may want to pass a number of parameters known only at run + * time. In those cases, a @ref dynamic_params encodes a dynamically + * determined number of parameters. You can mix these with regular, static + * parameter lists, and you can re-use them for multiple statement invocations. + * + * A dynamic_params object does not store copies of its parameters, so make + * sure they remain accessible until you've executed the statement. + * + * The ACCESSOR is an optional callable (such as a lambda). If you pass an + * accessor `a`, then each parameter `p` goes into your statement as `a(p)`. + */ +template)> +class dynamic_params +{ +public: + /// Wrap a sequence of pointers or iterators. + constexpr dynamic_params(IT begin, IT end) : + m_begin(begin), m_end(end), m_accessor(iterator_identity) + {} + + /// Wrap a sequence of pointers or iterators. + /** This version takes an accessor callable. If you pass an accessor `acc`, + * then any parameter `p` will go into the statement's parameter list as + * `acc(p)`. + */ + constexpr dynamic_params(IT begin, IT end, ACCESSOR &acc) : + m_begin(begin), m_end(end), m_accessor(acc) + {} + + /// Wrap a container. + template + explicit constexpr dynamic_params(C &container) : + dynamic_params(std::begin(container), std::end(container)) + {} + + /// Wrap a container. + /** This version takes an accessor callable. If you pass an accessor `acc`, + * then any parameter `p` will go into the statement's parameter list as + * `acc(p)`. + */ + template + explicit constexpr dynamic_params(C &container, ACCESSOR &acc) : + dynamic_params(std::begin(container), std::end(container), acc) + {} + + constexpr IT begin() const noexcept { return m_begin; } + constexpr IT end() const noexcept { return m_end; } + + constexpr auto access(decltype(*std::declval()) value) const + -> decltype(std::declval()(value)) + { + return m_accessor(value); + } + +private: + IT const m_begin, m_end; + ACCESSOR m_accessor = iterator_identity; +}; + + +/// Internal type: encode statement parameters. +/** Compiles arguments for prepared statements and parameterised queries into + * a format that can be passed into libpq. + * + * Objects of this type are meant to be short-lived: a `c_params` lives and + * dies entirely within the call to execute. So, for example, if you pass in a + * non-null pointer as a parameter, @ref params may simply use that pointer as + * a parameter value, without arranging longer-term storage for the data to + * which it points. All values referenced by parameters must remain "live" + * until the parameterised or prepared statement has been executed. + */ +struct PQXX_LIBEXPORT c_params +{ + c_params() = default; + /// Copying these objects is pointless and expensive. Don't do it. + c_params(c_params const &) = delete; + c_params(c_params &&) = default; + + /// Pre-allocate storage for `n` parameters. + void reserve(std::size_t n) &; + + /// As used by libpq: pointers to parameter values. + std::vector values; + /// As used by libpq: lengths of non-null arguments, in bytes. + std::vector lengths; + /// As used by libpq: effectively boolean "is this a binary parameter?" + std::vector formats; +}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/stream_iterator.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/stream_iterator.hxx new file mode 100644 index 000000000..f240dcfa7 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/stream_iterator.hxx @@ -0,0 +1,105 @@ +/** Stream iterators. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_ITERATOR +#define PQXX_H_STREAM_ITERATOR + +#include + +namespace pqxx +{ +class stream_from; +} + + +namespace pqxx::internal +{ +// C++20: Replace with generator? +/// Input iterator for stream_from. +/** Just barely enough to support range-based "for" loops. Don't assume that + * any of the usual behaviour works beyond that. + */ +template class stream_input_iterator +{ +public: + using value_type = std::tuple; + + /// Construct an "end" iterator. + stream_input_iterator() = default; + + explicit stream_input_iterator(stream_from &home) : m_home(&home) + { + advance(); + } + stream_input_iterator(stream_input_iterator const &) = default; + + stream_input_iterator &operator++() + { + advance(); + return *this; + } + + value_type const &operator*() const { return m_value; } + + /// Comparison only works for comparing to end(). + bool operator==(stream_input_iterator const &rhs) const + { + return m_home == rhs.m_home; + } + /// Comparison only works for comparing to end(). + bool operator!=(stream_input_iterator const &rhs) const + { + return not(*this == rhs); + } + +private: + void advance() + { + if (m_home == nullptr) + throw usage_error{"Moving stream_from iterator beyond end()."}; + if (not((*m_home) >> m_value)) + m_home = nullptr; + } + + stream_from *m_home{nullptr}; + value_type m_value; +}; + + +// C++20: Replace with generator? +/// Iteration over a @ref stream_from. +template class stream_input_iteration +{ +public: + using iterator = stream_input_iterator; + explicit stream_input_iteration(stream_from &home) : m_home{home} {} + iterator begin() const { return iterator{m_home}; } + iterator end() const { return {}; } + +private: + stream_from &m_home; +}; + + +// C++20: Replace with generator? +/// Iteration over a @ref stream_from, deleting it once done. +template class owning_stream_input_iteration +{ +public: + using iterator = stream_input_iterator; + explicit owning_stream_input_iteration(std::unique_ptr &&home) : + m_home{std::move(home)} + {} + iterator begin() const { return iterator{*m_home.get()}; } + iterator end() const { return {}; } + +private: + std::unique_ptr m_home; +}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/wait.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/wait.hxx new file mode 100644 index 000000000..7a82e6553 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/internal/wait.hxx @@ -0,0 +1,18 @@ +#if !defined(PQXX_WAIT_HXX) +# define PQXX_WAIT_HXX + +namespace pqxx::internal +{ +/// Wait. +/** This is normally `std::this_thread::sleep_for()`. But MinGW's `thread` + * header doesn't work, so we must be careful about including it. + */ +void PQXX_LIBEXPORT wait_for(unsigned int microseconds); + + +/// Wait for a socket to be ready for reading/writing, or timeout. +PQXX_LIBEXPORT void wait_fd( + int fd, bool for_read, bool for_write, unsigned seconds = 1, + unsigned microseconds = 0); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/isolation b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/isolation new file mode 100644 index 000000000..1b801329b --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/isolation @@ -0,0 +1,8 @@ +/** Transaction isolation levels. + * + * Policies and traits describing SQL transaction isolation levels + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/isolation.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/isolation.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/isolation.hxx new file mode 100644 index 000000000..0698c6ab4 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/isolation.hxx @@ -0,0 +1,75 @@ +/* Definitions for transaction isolation levels, and such. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/isolation instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ISOLATION +#define PQXX_H_ISOLATION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Should a transaction be read-only, or read-write? +/** No, this is not an isolation level. So it really doesn't belong here. + * But it's not really worth a separate header. + */ +enum class write_policy +{ + read_only, + read_write +}; + + +/// Transaction isolation levels. +/** These are as defined in the SQL standard. But there are a few notes + * specific to PostgreSQL. + * + * First, postgres does not support "read uncommitted." The lowest level you + * can get is "read committed," which is better. PostgreSQL is built on the + * MVCC paradigm, which guarantees "read committed" isolation without any + * additional performance overhead, so there was no point in providing the + * lower level. + * + * Second, "repeatable read" also makes more isolation guarantees than the + * standard requires. According to the standard, this level prevents "dirty + * reads" and "nonrepeatable reads," but not "phantom reads." In postgres, + * it actually prevents all three. + * + * Third, "serializable" is only properly supported starting at postgres 9.1. + * If you request "serializable" isolation on an older backend, you will get + * the same isolation as in "repeatable read." It's better than the + * "repeatable read" defined in the SQL standard, but not a complete + * implementation of the standard's "serializable" isolation level. + * + * In general, a lower isolation level will allow more surprising interactions + * between ongoing transactions, but improve performance. A higher level + * gives you more protection from subtle concurrency bugs, but sometimes it + * may not be possible to complete your transaction without avoiding paradoxes + * in the data. In that case a transaction may fail, and the application will + * have to re-do the whole thing based on the latest state of the database. + * (If you want to retry your code in that situation, have a look at the + * transactor framework.) + * + * Study the levels and design your application with the right level in mind. + */ +enum isolation_level +{ + // PostgreSQL only has the better isolation levels. + // read_uncommitted, + + read_committed, + repeatable_read, + serializable, +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/largeobject b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/largeobject new file mode 100644 index 000000000..1f2f94790 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/largeobject @@ -0,0 +1,8 @@ +/** Large Objects interface. + * + * Supports direct access to large objects, as well as through I/O streams + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/largeobject.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/largeobject.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/largeobject.hxx new file mode 100644 index 000000000..ebafc51d8 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/largeobject.hxx @@ -0,0 +1,735 @@ +/* Large Objects interface. Deprecated; use blob instead. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_LARGEOBJECT +#define PQXX_H_LARGEOBJECT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/dbtransaction.hxx" + + +namespace pqxx +{ +/// Identity of a large object. +/** @deprecated Use the @ref blob class instead. + * + * Encapsulates the identity of a large object. + * + * A largeobject must be accessed only from within a backend transaction, but + * the object's identity remains valid as long as the object exists. + */ +class PQXX_LIBEXPORT largeobject +{ +public: + using size_type = large_object_size_type; + + /// Refer to a nonexistent large object (similar to what a null pointer + /// does). + [[deprecated("Use blob instead.")]] largeobject() noexcept = default; + + /// Create new large object. + /** @param t Backend transaction in which the object is to be created. + */ + [[deprecated("Use blob instead.")]] explicit largeobject(dbtransaction &t); + + /// Wrap object with given oid. + /** Convert combination of a transaction and object identifier into a + * large object identity. Does not affect the database. + * @param o Object identifier for the given object. + */ + [[deprecated("Use blob instead.")]] explicit largeobject(oid o) noexcept : + m_id{o} + {} + + /// Import large object from a local file. + /** Creates a large object containing the data found in the given file. + * @param t Backend transaction in which the large object is to be created. + * @param file A filename on the client program's filesystem. + */ + [[deprecated("Use blob instead.")]] largeobject( + dbtransaction &t, std::string_view file); + + /// Take identity of an opened large object. + /** Copy identity of already opened large object. Note that this may be done + * as an implicit conversion. + * @param o Already opened large object to copy identity from. + */ + [[deprecated("Use blob instead.")]] largeobject( + largeobjectaccess const &o) noexcept; + + /// Object identifier. + /** The number returned by this function identifies the large object in the + * database we're connected to (or oid_none is returned if we refer to the + * null object). + */ + [[nodiscard]] oid id() const noexcept { return m_id; } + + /** + * @name Identity comparisons + * + * These operators compare the object identifiers of large objects. This has + * nothing to do with the objects' actual contents; use them only for keeping + * track of containers of references to large objects and such. + */ + //@{ + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator==(largeobject const &other) const + { + return m_id == other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator!=(largeobject const &other) const + { + return m_id != other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator<=(largeobject const &other) const + { + return m_id <= other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator>=(largeobject const &other) const + { + return m_id >= other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator<(largeobject const &other) const + { + return m_id < other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator>(largeobject const &other) const + { + return m_id > other.m_id; + } + //@} + + /// Export large object's contents to a local file + /** Writes the data stored in the large object to the given file. + * @param t Transaction in which the object is to be accessed + * @param file A filename on the client's filesystem + */ + void to_file(dbtransaction &t, std::string_view file) const; + + /// Delete large object from database + /** Unlike its low-level equivalent cunlink, this will throw an exception if + * deletion fails. + * @param t Transaction in which the object is to be deleted + */ + void remove(dbtransaction &t) const; + +protected: + PQXX_PURE static internal::pq::PGconn * + raw_connection(dbtransaction const &T); + + PQXX_PRIVATE std::string reason(connection const &, int err) const; + +private: + oid m_id = oid_none; +}; + + +/// Accessor for large object's contents. +/** @deprecated Use the `blob` class instead. + */ +class PQXX_LIBEXPORT largeobjectaccess : private largeobject +{ +public: + using largeobject::size_type; + using off_type = size_type; + using pos_type = size_type; + + /// Open mode: `in`, `out` (can be combined using "bitwise or"). + /** According to the C++ standard, these should be in `std::ios_base`. We + * take them from derived class `std::ios` instead, which is easier on the + * eyes. + * + * Historical note: taking it from std::ios was originally a workaround for a + * problem with gcc 2.95. + */ + using openmode = std::ios::openmode; + + /// Default open mode: in, out, binary. + static constexpr auto default_mode{ + std::ios::in | std::ios::out | std::ios::binary}; + + /// Seek direction: `beg`, `cur`, `end`. + using seekdir = std::ios::seekdir; + + /// Create new large object and open it. + /** + * @param t Backend transaction in which the object is to be created. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] explicit largeobjectaccess( + dbtransaction &t, openmode mode = default_mode); + + /// Open large object with given oid. + /** Convert combination of a transaction and object identifier into a + * large object identity. Does not affect the database. + * @param t Transaction in which the object is to be accessed. + * @param o Object identifier for the given object. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, oid o, openmode mode = default_mode); + + /// Open given large object. + /** Open a large object with the given identity for reading and/or writing. + * @param t Transaction in which the object is to be accessed. + * @param o Identity for the large object to be accessed. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, largeobject o, openmode mode = default_mode); + + /// Import large object from a local file and open it. + /** Creates a large object containing the data found in the given file. + * @param t Backend transaction in which the large object is to be created. + * @param file A filename on the client program's filesystem. + * @param mode Access mode, defaults to ios_base::in | ios_base::out. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, std::string_view file, openmode mode = default_mode); + + ~largeobjectaccess() noexcept { close(); } + + /// Object identifier. + /** The number returned by this function uniquely identifies the large object + * in the context of the database we're connected to. + */ + using largeobject::id; + + /// Export large object's contents to a local file. + /** Writes the data stored in the large object to the given file. + * @param file A filename on the client's filesystem. + */ + void to_file(std::string_view file) const + { + largeobject::to_file(m_trans, file); + } + + using largeobject::to_file; + + /** + * @name High-level access to object contents. + */ + //@{ + /// Write data to large object. + /** @warning The size of a write is currently limited to 2GB. + * + * @param buf Data to write. + * @param len Number of bytes from Buf to write. + */ + void write(char const buf[], std::size_t len); + + /// Write string to large object. + /** If not all bytes could be written, an exception is thrown. + * @param buf Data to write; no terminating zero is written. + */ + void write(std::string_view buf) { write(std::data(buf), std::size(buf)); } + + /// Read data from large object. + /** Throws an exception if an error occurs while reading. + * @param buf Location to store the read data in. + * @param len Number of bytes to try and read. + * @return Number of bytes read, which may be less than the number requested + * if the end of the large object is reached. + */ + size_type read(char buf[], std::size_t len); + + /// Seek in large object's data stream. + /** Throws an exception if an error occurs. + * @return The new position in the large object + */ + size_type seek(size_type dest, seekdir dir); + + /// Report current position in large object's data stream. + /** Throws an exception if an error occurs. + * @return The current position in the large object. + */ + [[nodiscard]] size_type tell() const; + //@} + + /** + * @name Low-level access to object contents. + * + * These functions provide a more "C-like" access interface, returning + * special values instead of throwing exceptions on error. These functions + * are generally best avoided in favour of the high-level access functions, + * which behave more like C++ functions should. + * + * Due to libpq's underlying API, some operations are limited to "int" + * sizes, typically 2 GB, even though a large object can grow much larger. + */ + //@{ + /// Seek in large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param dest Offset to go to. + * @param dir Origin to which dest is relative: ios_base::beg (from beginning + * of the object), ios_base::cur (from current access position), or + * ios_base;:end (from end of object). + * @return New position in large object, or -1 if an error occurred. + */ + pos_type cseek(off_type dest, seekdir dir) noexcept; + + /// Write to large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param buf Data to write. + * @param len Number of bytes to write. + * @return Number of bytes actually written, or -1 if an error occurred. + */ + off_type cwrite(char const buf[], std::size_t len) noexcept; + + /// Read from large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param buf Area where incoming bytes should be stored. + * @param len Number of bytes to read. + * @return Number of bytes actually read, or -1 if an error occurred.. + */ + off_type cread(char buf[], std::size_t len) noexcept; + + /// Report current position in large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @return Current position in large object, of -1 if an error occurred. + */ + [[nodiscard]] pos_type ctell() const noexcept; + //@} + + /** + * @name Error/warning output + */ + //@{ + /// Issue message to transaction's notice processor. + void process_notice(zview) noexcept; + //@} + + using largeobject::remove; + + using largeobject::operator==; + using largeobject::operator!=; + using largeobject::operator<; + using largeobject::operator<=; + using largeobject::operator>; + using largeobject::operator>=; + + largeobjectaccess() = delete; + largeobjectaccess(largeobjectaccess const &) = delete; + largeobjectaccess operator=(largeobjectaccess const &) = delete; + +private: + PQXX_PRIVATE std::string reason(int err) const; + internal::pq::PGconn *raw_connection() const + { + return largeobject::raw_connection(m_trans); + } + + PQXX_PRIVATE void open(openmode mode); + void close() noexcept; + + dbtransaction &m_trans; + int m_fd = -1; +}; + + +/// Streambuf to use large objects in standard I/O streams. +/** @deprecated Access large objects directly using the @ref blob class. + * + * The standard streambuf classes provide uniform access to data storage such + * as files or string buffers, so they can be accessed using standard input or + * output streams. This streambuf implementation provided similar access to + * large objects, so they could be read and written using the same stream + * classes. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class largeobject_streambuf : public std::basic_streambuf +{ + using size_type = largeobject::size_type; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + using openmode = largeobjectaccess::openmode; + using seekdir = largeobjectaccess::seekdir; + + /// Default open mode: in, out, binary. + static constexpr auto default_mode{ + std::ios::in | std::ios::out | std::ios::binary}; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + [[deprecated("Use blob instead.")]] largeobject_streambuf( + dbtransaction &t, largeobject o, openmode mode = default_mode, + size_type buf_size = 512) : + m_bufsize{buf_size}, m_obj{t, o, mode}, m_g{nullptr}, m_p{nullptr} + { + initialize(mode); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + [[deprecated("Use blob instead.")]] largeobject_streambuf( + dbtransaction &t, oid o, openmode mode = default_mode, + size_type buf_size = 512) : + m_bufsize{buf_size}, m_obj{t, o, mode}, m_g{nullptr}, m_p{nullptr} + { + initialize(mode); + } + + virtual ~largeobject_streambuf() noexcept + { + delete[] m_p; + delete[] m_g; + } + + /// For use by large object stream classes. + void process_notice(zview const &s) { m_obj.process_notice(s); } + +protected: + virtual int sync() override + { + // setg() sets eback, gptr, egptr. + this->setg(this->eback(), this->eback(), this->egptr()); + return overflow(eof()); + } + + virtual pos_type seekoff(off_type offset, seekdir dir, openmode) override + { + return adjust_eof(m_obj.cseek(largeobjectaccess::off_type(offset), dir)); + } + + virtual pos_type seekpos(pos_type pos, openmode) override + { + largeobjectaccess::pos_type const newpos{ + m_obj.cseek(largeobjectaccess::off_type(pos), std::ios::beg)}; + return adjust_eof(newpos); + } + + virtual int_type overflow(int_type ch) override + { + auto *const pp{this->pptr()}; + if (pp == nullptr) + return eof(); + auto *const pb{this->pbase()}; + int_type res{0}; + + if (pp > pb) + { + auto const write_sz{pp - pb}; + auto const written_sz{ + m_obj.cwrite(pb, static_cast(pp - pb))}; + if (internal::cmp_less_equal(written_sz, 0)) + throw internal_error{ + "pqxx::largeobject: write failed " + "(is transaction still valid on write or flush?), " + "libpq reports error"}; + else if (write_sz != written_sz) + throw internal_error{ + "pqxx::largeobject: write failed " + "(is transaction still valid on write or flush?), " + + std::to_string(written_sz) + "/" + std::to_string(write_sz) + + " bytes written"}; + auto const out{adjust_eof(written_sz)}; + + if constexpr (std::is_arithmetic_v) + res = check_cast(out, "largeobject position"sv); + else + res = int_type(out); + } + this->setp(m_p, m_p + m_bufsize); + + // Write that one more character, if it's there. + if (ch != eof()) + { + *this->pptr() = static_cast(ch); + this->pbump(1); + } + return res; + } + + virtual int_type overflow() { return overflow(eof()); } + + virtual int_type underflow() override + { + if (this->gptr() == nullptr) + return eof(); + auto *const eb{this->eback()}; + auto const res{adjust_eof( + m_obj.cread(this->eback(), static_cast(m_bufsize)))}; + this->setg( + eb, eb, eb + (res == eof() ? 0 : static_cast(res))); + return (res == eof() or res == 0) ? eof() : traits_type::to_int_type(*eb); + } + +private: + /// Shortcut for traits_type::eof(). + static int_type eof() { return traits_type::eof(); } + + /// Helper: change error position of -1 to EOF (probably a no-op). + template static std::streampos adjust_eof(INTYPE pos) + { + bool const at_eof{pos == -1}; + if constexpr (std::is_arithmetic_v) + { + return check_cast( + (at_eof ? eof() : pos), "large object seek"sv); + } + else + { + return std::streampos(at_eof ? eof() : pos); + } + } + + void initialize(openmode mode) + { + if ((mode & std::ios::in) != 0) + { + m_g = new char_type[unsigned(m_bufsize)]; + this->setg(m_g, m_g, m_g); + } + if ((mode & std::ios::out) != 0) + { + m_p = new char_type[unsigned(m_bufsize)]; + this->setp(m_p, m_p + m_bufsize); + } + } + + size_type const m_bufsize; + largeobjectaccess m_obj; + + /// Get & put buffers. + char_type *m_g, *m_p; +}; + + +/// Input stream that gets its data from a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This class worked like any other istream, but to read data from a large + * object. It supported all formatting and streaming operations of + * `std::istream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_ilostream : public std::basic_istream +{ + using super = std::basic_istream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create a basic_ilostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_ilostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::in | std::ios::binary, buf_size} + { + super::init(&m_buf); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// Create a basic_ilostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Identifier of a large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_ilostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::in | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + +private: + largeobject_streambuf m_buf; +}; + +using ilostream = basic_ilostream; + + +/// Output stream that writes data back to a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This worked like any other ostream, but to write data to a large object. + * It supported all formatting and streaming operations of `std::ostream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_olostream : public std::basic_ostream +{ + using super = std::basic_ostream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create a basic_olostream. + /** + * @param t transaction in which this stream is to exist. + * @param o a large object to access. + * @param buf_size size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_olostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// Create a basic_olostream. + /** + * @param t transaction in which this stream is to exist. + * @param o a large object to access. + * @param buf_size size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_olostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + ~basic_olostream() + { + try + { + m_buf.pubsync(); + m_buf.pubsync(); + } + catch (std::exception const &e) + { + m_buf.process_notice(e.what()); + } + } + +private: + largeobject_streambuf m_buf; +}; + +using olostream = basic_olostream; + + +/// Stream that reads and writes a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This worked like a std::iostream, but to read data from, or write data to, a + * large object. It supported all formatting and streaming operations of + * `std::iostream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_lostream : public std::basic_iostream +{ + using super = std::basic_iostream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + + /// Create a basic_lostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_lostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{ + t, o, std::ios::in | std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + /// Create a basic_lostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_lostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{ + t, o, std::ios::in | std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + ~basic_lostream() + { + try + { + m_buf.pubsync(); + m_buf.pubsync(); + } + catch (std::exception const &e) + { + m_buf.process_notice(e.what()); + } + } + +private: + largeobject_streambuf m_buf; +}; + +using lostream = basic_lostream; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/nontransaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/nontransaction new file mode 100644 index 000000000..bb5b79724 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/nontransaction @@ -0,0 +1,8 @@ +/** pqxx::nontransaction class. + * + * pqxx::nontransaction provides nontransactional database access. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/nontransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/nontransaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/nontransaction.hxx new file mode 100644 index 000000000..c50715594 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/nontransaction.hxx @@ -0,0 +1,76 @@ +/* Definition of the pqxx::nontransaction class. + * + * pqxx::nontransaction provides nontransactional database access + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/nontransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_NONTRANSACTION +#define PQXX_H_NONTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/connection.hxx" +#include "pqxx/result.hxx" +#include "pqxx/transaction.hxx" + +namespace pqxx +{ +using namespace std::literals; + +/// Simple "transaction" class offering no transactional integrity. +/** + * @ingroup transactions + * + * nontransaction, like transaction or any other transaction_base-derived + * class, provides access to a database through a connection. Unlike its + * siblings, however, nontransaction does not maintain any kind of + * transactional integrity. This may be useful eg. for read-only access to the + * database that does not require a consistent, atomic view on its data; or for + * operations that are not allowed within a backend transaction, such as + * creating tables. + * + * For queries that update the database, however, a real transaction is likely + * to be faster unless the transaction consists of only a single record update. + * + * Also, you can keep a nontransaction open for as long as you like. Actual + * back-end transactions are limited in lifespan, and will sometimes fail just + * because they took too long to execute or were left idle for too long. This + * will not happen with a nontransaction (although the connection may still + * time out, e.g. when the network is unavailable for a very long time). + * + * Any query executed in a nontransaction is committed immediately, and neither + * commit() nor abort() has any effect. + * + * Database features that require a backend transaction, such as cursors or + * large objects, will not work in a nontransaction. + */ +class PQXX_LIBEXPORT nontransaction final : public transaction_base +{ +public: + /// Constructor. + /** Create a "dummy" transaction. + * @param c Connection in which this "transaction" will operate. + * @param tname Optional tname for the transaction, beginning with a letter + * and containing only letters and digits. + */ + nontransaction(connection &c, std::string_view tname = ""sv) : + transaction_base{c, tname, std::shared_ptr{}} + { + register_transaction(); + } + + virtual ~nontransaction() override { close(); } + +private: + virtual void do_commit() override {} +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/notification b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/notification new file mode 100644 index 000000000..a0bd1c73e --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/notification @@ -0,0 +1,8 @@ +/** pqxx::notification_receiver functor interface. + * + * pqxx::notification_receiver handles incoming notifications. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/notification.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/notification.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/notification.hxx new file mode 100644 index 000000000..b59b8567a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/notification.hxx @@ -0,0 +1,94 @@ +/* Definition of the pqxx::notification_receiver functor interface. + * + * pqxx::notification_receiver handles incoming notifications. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/notification instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_NOTIFICATION +#define PQXX_H_NOTIFICATION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/types.hxx" + + +namespace pqxx +{ +/// "Observer" base class for notifications. +/** @addtogroup notification Notifications and Receivers + * + * To listen on a notification issued using the NOTIFY command, derive your own + * class from notification_receiver and define its function-call operator to + * perform whatever action you wish to take when the given notification + * arrives. Then create an object of that class and pass it to your connection. + * DO NOT use raw SQL to listen for notifications, or your attempts to listen + * won't be resumed when a connection fails--and you'll have no way to notice. + * + * Notifications never arrive inside a transaction, not even in a + * nontransaction. Therefore, you are free to open a transaction of your own + * inside your receiver's function invocation operator. + * + * Notifications you are listening for may arrive anywhere within libpqxx code, + * but be aware that **PostgreSQL defers notifications occurring inside + * transactions.** (This was done for excellent reasons; just think about what + * happens if the transaction where you happen to handle an incoming + * notification is later rolled back for other reasons). So if you're keeping + * a transaction open, don't expect any of your receivers on the same + * connection to be notified. + * + * (For very similar reasons, outgoing notifications are also not sent until + * the transaction that sends them commits.) + * + * Multiple receivers on the same connection may listen on a notification of + * the same name. An incoming notification is processed by invoking all + * receivers (zero or more) of the same name. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE notification_receiver +{ +public: + /// Register the receiver with a connection. + /** + * @param c Connnection to operate on. + * @param channel Name of the notification to listen for. + */ + notification_receiver(connection &c, std::string_view channel); + /// Register the receiver with a connection. + notification_receiver(notification_receiver const &) = delete; + /// Register the receiver with a connection. + notification_receiver &operator=(notification_receiver const &) = delete; + /// Deregister the receiver. + virtual ~notification_receiver(); + + /// The channel that this receiver listens on. + [[nodiscard]] std::string const &channel() const & { return m_channel; } + + // TODO: Change API to take payload as zview instead of string ref. + /// Overridable: action to invoke when notification arrives. + /** + * @param payload An optional string that may have been passed to the NOTIFY + * command. + * @param backend_pid Process ID of the database backend process that served + * our connection when the notification arrived. The actual process ID + * behind the connection may have changed by the time this method is called. + */ + virtual void operator()(std::string const &payload, int backend_pid) = 0; + +protected: + connection &conn() const noexcept { return m_conn; } + +private: + connection &m_conn; + std::string m_channel; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/params b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/params new file mode 100644 index 000000000..4098782aa --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/params @@ -0,0 +1,8 @@ +/** Helper classes for passing statement parameters. + * + * Use these for prepared statements and parameterised statements. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/params.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/params.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/params.hxx new file mode 100644 index 000000000..2d29cdfed --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/params.hxx @@ -0,0 +1,383 @@ +/* Helpers for prepared statements and parameterised statements. + * + * See the connection class for more about such statements. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_PARAMS +#define PQXX_H_PARAMS + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/statement_parameters.hxx" +#include "pqxx/types.hxx" + + +/// @deprecated The new @ref params class replaces all of this. +namespace pqxx::prepare +{ +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * sequence ranging from `begin` to `end` exclusively. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic sequences. + * + * @param begin A pointer or iterator for iterating parameters. + * @param end A pointer or iterator for iterating parameters. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(IT begin, IT end) +{ + return pqxx::internal::dynamic_params(begin, end); +} + + +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * container of parameter values. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic containers. + * + * @param container A container of parameter values. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(C const &container) +{ + using IT = typename C::const_iterator; +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return pqxx::internal::dynamic_params{container}; +#include "pqxx/internal/ignore-deprecated-post.hxx" +} + + +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * container of parameter values. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic containers. + * + * @param container A container of parameter values. + * @param accessor For each parameter `p`, pass `accessor(p)`. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(C &container, ACCESSOR accessor) +{ + using IT = decltype(std::begin(container)); +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return pqxx::internal::dynamic_params{container, accessor}; +#include "pqxx/internal/ignore-deprecated-post.hxx" +} +} // namespace pqxx::prepare + + +namespace pqxx +{ +/// Generate parameter placeholders for use in an SQL statement. +/** When you want to pass parameters to a prepared statement or a parameterised + * statement, you insert placeholders into the SQL. During invocation, the + * database replaces those with the respective parameter values you passed. + * + * The placeholders look like `$1` (for the first parameter value), `$2` (for + * the second), and so on. You can just write those directly in your + * statement. But for those rare cases where it becomes difficult to track + * which number a placeholder should have, you can use a `placeholders` object + * to count and generate them in order. + */ +template class placeholders +{ +public: + /// Maximum number of parameters we support. + static inline constexpr unsigned int max_params{ + (std::numeric_limits::max)()}; + + placeholders() + { + static constexpr auto initial{"$1\0"sv}; + initial.copy(std::data(m_buf), std::size(initial)); + } + + /// Read an ephemeral version of the current placeholder text. + /** @warning Changing the current placeholder number will overwrite this. + * Use the view immediately, or lose it. + */ + constexpr zview view() const &noexcept + { + return zview{std::data(m_buf), m_len}; + } + + /// Read the current placeholder text, as a `std::string`. + /** This will be slightly slower than converting to a `zview`. With most + * C++ implementations however, until you get into ridiculous numbers of + * parameters, the string will benefit from the Short String Optimization, or + * SSO. + */ + std::string get() const { return std::string(std::data(m_buf), m_len); } + + /// Move on to the next parameter. + void next() & + { + if (m_current >= max_params) + throw range_error{pqxx::internal::concat( + "Too many parameters in one statement: limit is ", max_params, ".")}; + ++m_current; + if (m_current % 10 == 0) + { + // Carry the 1. Don't get too clever for this relatively rare + // case, just rewrite the entire number. Leave the $ in place + // though. + char *const data{std::data(m_buf)}; + char *const end{string_traits::into_buf( + data + 1, data + std::size(m_buf), m_current)}; + // (Subtract because we don't include the trailing zero.) + m_len = check_cast(end - data, "placeholders counter") - 1; + } + else + { + PQXX_LIKELY + // Shortcut for the common case: just increment that last digit. + ++m_buf[m_len - 1]; + } + } + + /// Return the current placeholder number. The initial placeholder is 1. + COUNTER count() const noexcept { return m_current; } + +private: + /// Current placeholder number. Starts at 1. + COUNTER m_current = 1; + + /// Length of the current placeholder string, not including trailing zero. + COUNTER m_len = 2; + + /// Text buffer where we render the placeholders, with a trailing zero. + /** We keep reusing this for every subsequent placeholder, just because we + * don't like string allocations. + * + * Maximum length is the maximum base-10 digits that COUNTER can fully + * represent, plus 1 more for the extra digit that it can only partially + * fill up, plus room for the dollar sign and the trailing zero. + */ + std::array::digits10 + 3> m_buf; +}; + + +/// Build a parameter list for a parameterised or prepared statement. +/** When calling a parameterised statement or a prepared statement, you can + * pass parameters into the statement directly in the invocation, as + * additional arguments to `exec_prepared` or `exec_params`. But in + * complex cases, sometimes that's just not convenient. + * + * In those situations, you can create a `params` and append your parameters + * into that, one by one. Then you pass the `params` to `exec_prepared` or + * `exec_params`. + * + * Combinations also work: if you have a `params` containing a string + * parameter, and you call `exec_params` with an `int` argument followed by + * your `params`, you'll be passing the `int` as the first parameter and + * the string as the second. You can even insert a `params` in a `params`, + * or pass two `params` objects to a statement. + */ +class PQXX_LIBEXPORT params +{ +public: + params() = default; + + /// Pre-populate a `params` with `args`. Feel free to add more later. + template constexpr params(Args &&...args) + { + reserve(sizeof...(args)); + append_pack(std::forward(args)...); + } + + /// Pre-allocate room for at least `n` parameters. + /** This is not needed, but it may improve efficiency. + * + * Reserve space if you're going to add parameters individually, and you've + * got some idea of how many there are going to be. It may save some + * memory re-allocations. + */ + void reserve(std::size_t n) &; + + // C++20: constexpr. + /// Get the number of parameters currently in this `params`. + [[nodiscard]] auto size() const noexcept { return m_params.size(); } + + // C++20: Use the vector's ssize() directly and go noexcept+constexpr. + /// Get the number of parameters (signed). + /** Unlike `size()`, this is not yet `noexcept`. That's because C++17's + * `std::vector` does not have a `ssize()` member function. These member + * functions are `noexcept`, but `std::size()` and `std::ssize()` are + * not. + */ + [[nodiscard]] auto ssize() const { return pqxx::internal::ssize(m_params); } + + /// Append a null value. + void append() &; + + /// Append a non-null zview parameter. + /** The underlying data must stay valid for as long as the `params` + * remains active. + */ + void append(zview) &; + + /// Append a non-null string parameter. + /** Copies the underlying data into internal storage. For best efficiency, + * use the @ref zview variant if you can, or `std::move()` + */ + void append(std::string const &) &; + + /// Append a non-null string parameter. + void append(std::string &&) &; + + /// Append a non-null binary parameter. + /** The underlying data must stay valid for as long as the `params` + * remains active. + */ + void append(std::basic_string_view) &; + + /// Append a non-null binary parameter. + /** Copies the underlying data into internal storage. For best efficiency, + * use the `std::basic_string_view` variant if you can, or + * `std::move()`. + */ + void append(std::basic_string const &) &; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Append a non-null binary parameter. + /** The `data` object must stay in place and unchanged, for as long as the + * `params` remains active. + */ + template void append(DATA const &data) & + { + append( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif // PQXX_HAVE_CONCEPTS + + /// Append a non-null binary parameter. + void append(std::basic_string &&) &; + + /// @deprecated Append binarystring parameter. + /** The binarystring must stay valid for as long as the `params` remains + * active. + */ + void append(binarystring const &value) &; + + /// Append all parameters from value. + template + void append(pqxx::internal::dynamic_params const &value) & + { + for (auto ¶m : value) append(value.access(param)); + } + + void append(params const &value) &; + + void append(params &&value) &; + + /// Append a non-null parameter, converting it to its string + /// representation. + template void append(TYPE const &value) & + { + // TODO: Pool storage for multiple string conversions in one buffer? + if constexpr (nullness>::always_null) + { + ignore_unused(value); + m_params.emplace_back(); + } + else if (is_null(value)) + { + m_params.emplace_back(); + } + else + { + m_params.emplace_back(entry{to_string(value)}); + } + } + + /// Append all elements of `range` as parameters. + template void append_multi(RANGE const &range) & + { +#if defined(PQXX_HAVE_CONCEPTS) + if constexpr (std::ranges::sized_range) + reserve(std::size(*this) + std::size(range)); +#endif + for (auto &value : range) append(value); + } + + /// For internal use: Generate a `params` object for use in calls. + /** The params object encapsulates the pointers which we will need to pass + * to libpq when calling a parameterised or prepared statement. + * + * The pointers in the params will refer to storage owned by either the + * params object, or the caller. This is not a problem because a + * `c_params` object is guaranteed to live only while the call is going on. + * As soon as we climb back out of that call tree, we're done with that + * data. + */ + pqxx::internal::c_params make_c_params() const; + +private: + /// Recursively append a pack of params. + template + void append_pack(Arg &&arg, More &&...args) + { + this->append(std::forward(arg)); + // Recurse for remaining args. + append_pack(std::forward(args)...); + } + + /// Terminating case: append an empty parameter pack. It's not hard BTW. + constexpr void append_pack() noexcept {} + + // The way we store a parameter depends on whether it's binary or text + // (most types are text), and whether we're responsible for storing the + // contents. + using entry = std::variant< + std::nullptr_t, zview, std::string, std::basic_string_view, + std::basic_string>; + std::vector m_params; + + static constexpr std::string_view s_overflow{ + "Statement parameter length overflow."sv}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/pipeline b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/pipeline new file mode 100644 index 000000000..bf828843a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/pipeline @@ -0,0 +1,8 @@ +/** pqxx::pipeline class. + * + * Throughput-optimized query interface. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/pipeline.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/pipeline.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/pipeline.hxx new file mode 100644 index 000000000..049dcdd58 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/pipeline.hxx @@ -0,0 +1,237 @@ +/* Definition of the pqxx::pipeline class. + * + * Throughput-optimized mechanism for executing queries. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/pipeline instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_PIPELINE +#define PQXX_H_PIPELINE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +// TODO: libpq 14 introduced a similar "pipeline mode." Can we use that? + +/// Processes several queries in FIFO manner, optimized for high throughput. +/** Use a pipeline if you want to keep doing useful work while your queries are + * executing. Result retrieval is decoupled from execution request; queries + * "go in at the front" and results "come out the back." + * + * Actually, you can retrieve the results in any order if you want, but it may + * lead to surprising "time travel" effects if any of the queries fails. In + * particular, syntax errors in the queries can confuse things and show up too + * early in the stream of results. + * + * Generally, if any of the queries fails, it will throw an exception at the + * point where you request its result. But it may happen earlier, especially + * if you request results out of chronological order. + * + * @warning While a pipeline is active, you cannot execute queries, open + * streams, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT pipeline : public transaction_focus +{ +public: + /// Identifying numbers for queries. + using query_id = long; + + pipeline(pipeline const &) = delete; + pipeline &operator=(pipeline const &) = delete; + + /// Start a pipeline. + explicit pipeline(transaction_base &t) : transaction_focus{t, s_classname} + { + init(); + } + /// Start a pipeline. Assign it a name, for more helpful error messages. + pipeline(transaction_base &t, std::string_view tname) : + transaction_focus{t, s_classname, tname} + { + init(); + } + + /// Close the pipeline. + ~pipeline() noexcept; + + /// Add query to the pipeline. + /** Queries accumulate in the pipeline, which sends them to the backend in a + * batch separated by semicolons. The queries you insert must not use this + * trick themselves, or the pipeline will get hopelessly confused! + * + * @return Identifier for this query, unique only within this pipeline. + */ + query_id insert(std::string_view) &; + + /// Wait for all ongoing or pending operations to complete, and detach. + /** Detaches from the transaction when done. + * + * This does not produce the queries' results, so it may not report any + * errors which may have occurred in their execution. To be sure that your + * statements succeeded, call @ref retrieve until the pipeline is empty. + */ + void complete(); + + /// Forget all ongoing or pending operations and retrieved results. + /** Queries already sent to the backend may still be completed, depending + * on implementation and timing. + * + * Any error state (unless caused by an internal error) will also be cleared. + * This is mostly useful in a nontransaction, since a backend transaction is + * aborted automatically when an error occurs. + * + * Detaches from the transaction when done. + */ + void flush(); + + /// Cancel ongoing query, if any. + /** May cancel any or all of the queries that have been inserted at this + * point whose results have not yet been retrieved. If the pipeline lives in + * a backend transaction, that transaction may be left in a nonfunctional + * state in which it can only be aborted. + * + * Therefore, either use this function in a nontransaction, or abort the + * transaction after calling it. + */ + void cancel(); + + /// Is result for given query available? + [[nodiscard]] bool is_finished(query_id) const; + + /// Retrieve result for given query. + /** If the query failed for whatever reason, this will throw an exception. + * The function will block if the query has not finished yet. + * @warning If results are retrieved out-of-order, i.e. in a different order + * than the one in which their queries were inserted, errors may "propagate" + * to subsequent queries. + */ + result retrieve(query_id qid) + { + return retrieve(m_queries.find(qid)).second; + } + + /// Retrieve oldest unretrieved result (possibly wait for one). + /** @return The query's identifier and its result set. */ + std::pair retrieve(); + + [[nodiscard]] bool empty() const noexcept { return std::empty(m_queries); } + + /// Set maximum number of queries to retain before issuing them to the + /// backend. + /** The pipeline will perform better if multiple queries are issued at once, + * but retaining queries until the results are needed (as opposed to issuing + * them to the backend immediately) may negate any performance benefits the + * pipeline can offer. + * + * Recommended practice is to set this value no higher than the number of + * queries you intend to insert at a time. + * @param retain_max A nonnegative "retention capacity;" passing zero will + * cause queries to be issued immediately + * @return Old retention capacity + */ + int retain(int retain_max = 2) &; + + + /// Resume retained query emission. Harmless when not needed. + void resume() &; + +private: + struct PQXX_PRIVATE Query + { + explicit Query(std::string_view q) : + query{std::make_shared(q)} + {} + + std::shared_ptr query; + result res; + }; + + using QueryMap = std::map; + + void init(); + void attach(); + void detach(); + + /// Upper bound to query id's. + static constexpr query_id qid_limit() noexcept + { + // Parenthesise this to work around an eternal Visual C++ problem: + // Without the extra parentheses, unless NOMINMAX is defined, the + // preprocessor will mistake this "max" for its annoying built-in macro + // of the same name. + return (std::numeric_limits::max)(); + } + + /// Create new query_id. + PQXX_PRIVATE query_id generate_id(); + + bool have_pending() const noexcept + { + return m_issuedrange.second != m_issuedrange.first; + } + + PQXX_PRIVATE void issue(); + + /// The given query failed; never issue anything beyond that. + void set_error_at(query_id qid) noexcept + { + PQXX_UNLIKELY + if (qid < m_error) + m_error = qid; + } + + /// Throw pqxx::internal_error. + [[noreturn]] PQXX_PRIVATE void internal_error(std::string const &err); + + PQXX_PRIVATE bool obtain_result(bool expect_none = false); + + PQXX_PRIVATE void obtain_dummy(); + PQXX_PRIVATE void get_further_available_results(); + PQXX_PRIVATE void check_end_results(); + + /// Receive any results that happen to be available; it's not urgent. + PQXX_PRIVATE void receive_if_available(); + + /// Receive results, up to stop if possible. + PQXX_PRIVATE void receive(pipeline::QueryMap::const_iterator stop); + std::pair retrieve(pipeline::QueryMap::iterator); + + QueryMap m_queries; + std::pair m_issuedrange; + int m_retain = 0; + int m_num_waiting = 0; + query_id m_q_id = 0; + + /// Is there a "dummy query" pending? + bool m_dummy_pending = false; + + /// Point at which an error occurred; no results beyond it will be available + query_id m_error = qid_limit(); + + /// Encoding. + /** We store this in the object to avoid the risk of exceptions at awkward + * moments. + */ + internal::encoding_group m_encoding; + + static constexpr std::string_view s_classname{"pipeline"}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/pqxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/pqxx new file mode 100644 index 000000000..17a8eaa9c --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/pqxx @@ -0,0 +1,28 @@ +/// Convenience header: include all libpqxx definitions. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/array.hxx" +#include "pqxx/binarystring.hxx" +#include "pqxx/blob.hxx" +#include "pqxx/connection.hxx" +#include "pqxx/cursor.hxx" +#include "pqxx/errorhandler.hxx" +#include "pqxx/except.hxx" +#include "pqxx/largeobject.hxx" +#include "pqxx/nontransaction.hxx" +#include "pqxx/notification.hxx" +#include "pqxx/params.hxx" +#include "pqxx/pipeline.hxx" +#include "pqxx/prepared_statement.hxx" +#include "pqxx/result.hxx" +#include "pqxx/internal/result_iterator.hxx" +#include "pqxx/internal/result_iter.hxx" +#include "pqxx/robusttransaction.hxx" +#include "pqxx/row.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/stream_to.hxx" +#include "pqxx/subtransaction.hxx" +#include "pqxx/transaction.hxx" +#include "pqxx/transactor.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/prepared_statement b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/prepared_statement new file mode 100644 index 000000000..674be7090 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/prepared_statement @@ -0,0 +1,3 @@ +/// @deprecated Include @c instead. + +#include "params.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/prepared_statement.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/prepared_statement.hxx new file mode 100644 index 000000000..674be7090 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/prepared_statement.hxx @@ -0,0 +1,3 @@ +/// @deprecated Include @c instead. + +#include "params.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/range b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/range new file mode 100644 index 000000000..11985eca4 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/range @@ -0,0 +1,6 @@ +/** Client-side support for SQL range types. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/range.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/range.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/range.hxx new file mode 100644 index 000000000..dc480e4b7 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/range.hxx @@ -0,0 +1,515 @@ +#ifndef PQXX_H_RANGE +#define PQXX_H_RANGE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/internal/array-composite.hxx" +#include "pqxx/internal/concat.hxx" + +namespace pqxx +{ +/// An _unlimited_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should extend + * to infinity on that side. + * + * An unlimited boundary is always inclusive of "infinity" values, if the + * range's value type supports them. + */ +struct no_bound +{ + template constexpr bool extends_down_to(TYPE const &) const + { + return true; + } + template constexpr bool extends_up_to(TYPE const &) const + { + return true; + } +}; + + +/// An _inclusive_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should include + * the value. + */ +template class inclusive_bound +{ +public: + inclusive_bound() = delete; + explicit inclusive_bound(TYPE const &value) : m_value{value} + { + if (is_null(value)) + throw argument_error{"Got null value as an inclusive range bound."}; + } + + [[nodiscard]] constexpr TYPE const &get() const &noexcept { return m_value; } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as a lower bound, include value? + [[nodiscard]] bool extends_down_to(TYPE const &value) const + { + return not(value < m_value); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as an upper bound, include value? + [[nodiscard]] bool extends_up_to(TYPE const &value) const + { + return not(m_value < value); + } + +private: + TYPE m_value; +}; + + +/// An _exclusive_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should _not_ + * include the value. + */ +template class exclusive_bound +{ +public: + exclusive_bound() = delete; + explicit exclusive_bound(TYPE const &value) : m_value{value} + { + if (is_null(value)) + throw argument_error{"Got null value as an exclusive range bound."}; + } + + [[nodiscard]] constexpr TYPE const &get() const &noexcept { return m_value; } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as a lower bound, include value? + [[nodiscard]] bool extends_down_to(TYPE const &value) const + { + return m_value < value; + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as an upper bound, include value? + [[nodiscard]] bool extends_up_to(TYPE const &value) const + { + return value < m_value; + } + +private: + TYPE m_value; +}; + + +/// A range boundary value. +/** A range bound is either no bound at all; or an inclusive bound; or an + * exclusive bound. Pass one of the three to the constructor. + */ +template class range_bound +{ +public: + range_bound() = delete; + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(no_bound) : m_bound{} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(inclusive_bound const &bound) : m_bound{bound} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(exclusive_bound const &bound) : m_bound{bound} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(range_bound const &) = default; + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(range_bound &&) = default; + + // TODO: constexpr and/or noexcept if underlying operators support it. + bool operator==(range_bound const &rhs) const + { + if (this->is_limited()) + return ( + rhs.is_limited() and (this->is_inclusive() == rhs.is_inclusive()) and + (*this->value() == *rhs.value())); + else + return not rhs.is_limited(); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + bool operator!=(range_bound const &rhs) const { return not(*this == rhs); } + range_bound &operator=(range_bound const &) = default; + range_bound &operator=(range_bound &&) = default; + + /// Is this a finite bound? + constexpr bool is_limited() const noexcept + { + return not std::holds_alternative(m_bound); + } + + /// Is this boundary an inclusive one? + constexpr bool is_inclusive() const noexcept + { + return std::holds_alternative>(m_bound); + } + + /// Is this boundary an exclusive one? + constexpr bool is_exclusive() const noexcept + { + return std::holds_alternative>(m_bound); + } + + // TODO: constexpr/noexcept if underlying function supports it. + /// Would this bound, as a lower bound, include `value`? + bool extends_down_to(TYPE const &value) const + { + return std::visit( + [&value](auto const &bound) { return bound.extends_down_to(value); }, + m_bound); + } + + // TODO: constexpr/noexcept if underlying function supports it. + /// Would this bound, as an upper bound, include `value`? + bool extends_up_to(TYPE const &value) const + { + return std::visit( + [&value](auto const &bound) { return bound.extends_up_to(value); }, + m_bound); + } + + /// Return bound value, or `nullptr` if it's not limited. + [[nodiscard]] constexpr TYPE const *value() const &noexcept + { + return std::visit( + [](auto const &bound) noexcept { + using bound_t = std::decay_t; + if constexpr (std::is_same_v) + return static_cast(nullptr); + else + return &bound.get(); + }, + m_bound); + } + +private: + std::variant, exclusive_bound> m_bound; +}; + + +// C++20: Concepts for comparisons, construction, etc. +/// A C++ equivalent to PostgreSQL's range types. +/** You can use this as a client-side representation of a "range" in SQL. + * + * PostgreSQL defines several range types, differing in the data type over + * which they range. You can also define your own range types. + * + * Usually you'll want the server to deal with ranges. But on occasions where + * you need to work with them client-side, you may want to use @ref + * pqxx::range. (In cases where all you do is pass them along to the server + * though, it's not worth the complexity. In that case you might as well treat + * ranges as just strings.) + * + * For documentation on PostgreSQL's range types, see: + * https://www.postgresql.org/docs/current/rangetypes.html + * + * The value type must be copyable and default-constructible, and support the + * less-than (`<`) and equals (`==`) comparisons. Value initialisation must + * produce a consistent value. + */ +template class range +{ +public: + /// Create a range. + /** For each of the two bounds, pass a @ref no_bound, @ref inclusive_bound, + * or + * @ref exclusive_bound. + */ + range(range_bound lower, range_bound upper) : + m_lower{lower}, m_upper{upper} + { + if ( + lower.is_limited() and upper.is_limited() and + (*upper.value() < *lower.value())) + throw range_error{internal::concat( + "Range's lower bound (", *lower.value(), + ") is greater than its upper bound (", *upper.value(), ").")}; + } + + // TODO: constexpr and/or noexcept if underlying constructor supports it. + /// Create an empty range. + /** SQL has a separate literal to denote an empty range, but any range which + * encompasses no values is an empty range. + */ + range() : + m_lower{exclusive_bound{TYPE{}}}, + m_upper{exclusive_bound{TYPE{}}} + {} + + // TODO: constexpr and/or noexcept if underlying operators support it. + bool operator==(range const &rhs) const + { + return (this->lower_bound() == rhs.lower_bound() and + this->upper_bound() == rhs.upper_bound()) or + (this->empty() and rhs.empty()); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + bool operator!=(range const &rhs) const { return !(*this == rhs); } + + range(range const &) = default; + range(range &&) = default; + range &operator=(range const &) = default; + range &operator=(range &&) = default; + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Is this range clearly empty? + /** An empty range encompasses no values. + * + * It is possible to "fool" this. For example, if your range is of an + * integer type and has exclusive bounds of 0 and 1, it encompasses no values + * but its `empty()` will return false. The PostgreSQL implementation, by + * contrast, will notice that it is empty. Similar things can happen for + * floating-point types, but with more subtleties and edge cases. + */ + bool empty() const + { + return (m_lower.is_exclusive() or m_upper.is_exclusive()) and + m_lower.is_limited() and m_upper.is_limited() and + not(*m_lower.value() < *m_upper.value()); + } + + // TODO: constexpr and/or noexcept if underlying functions support it. + /// Does this range encompass `value`? + bool contains(TYPE value) const + { + return m_lower.extends_down_to(value) and m_upper.extends_up_to(value); + } + + // TODO: constexpr and/or noexcept if underlying operators support it. + /// Does this range encompass all of `other`? + /** This function is not particularly smart. It does not know, for example, + * that integer ranges `[0,9]` and `[0,10)` contain the same values. + */ + bool contains(range const &other) const + { + return (*this & other) == other; + } + + [[nodiscard]] constexpr range_bound const & + lower_bound() const &noexcept + { + return m_lower; + } + [[nodiscard]] constexpr range_bound const & + upper_bound() const &noexcept + { + return m_upper; + } + + // TODO: constexpr and/or noexcept if underlying operators support it. + /// Intersection of two ranges. + /** Returns a range describing those values which are in both ranges. + */ + range operator&(range const &other) const + { + range_bound lower{no_bound{}}; + if (not this->lower_bound().is_limited()) + lower = other.lower_bound(); + else if (not other.lower_bound().is_limited()) + lower = this->lower_bound(); + else if (*this->lower_bound().value() < *other.lower_bound().value()) + lower = other.lower_bound(); + else if (*other.lower_bound().value() < *this->lower_bound().value()) + lower = this->lower_bound(); + else if (this->lower_bound().is_exclusive()) + lower = this->lower_bound(); + else + lower = other.lower_bound(); + + range_bound upper{no_bound{}}; + if (not this->upper_bound().is_limited()) + upper = other.upper_bound(); + else if (not other.upper_bound().is_limited()) + upper = this->upper_bound(); + else if (*other.upper_bound().value() < *this->upper_bound().value()) + upper = other.upper_bound(); + else if (*this->upper_bound().value() < *other.upper_bound().value()) + upper = this->upper_bound(); + else if (this->upper_bound().is_exclusive()) + upper = this->upper_bound(); + else + upper = other.upper_bound(); + + if ( + lower.is_limited() and upper.is_limited() and + (*upper.value() < *lower.value())) + return {}; + else + return {lower, upper}; + } + + /// Convert to another base type. + template operator range() const + { + range_bound lower{no_bound{}}, upper{no_bound{}}; + if (lower_bound().is_inclusive()) + lower = inclusive_bound{*lower_bound().value()}; + else if (lower_bound().is_exclusive()) + lower = exclusive_bound{*lower_bound().value()}; + + if (upper_bound().is_inclusive()) + upper = inclusive_bound{*upper_bound().value()}; + else if (upper_bound().is_exclusive()) + upper = exclusive_bound{*upper_bound().value()}; + + return {lower, upper}; + } + +private: + range_bound m_lower, m_upper; +}; + + +/// String conversions for a @ref range type. +/** Conversion assumes that either your client encoding is UTF-8, or the values + * are pure ASCII. + */ +template struct string_traits> +{ + [[nodiscard]] static inline zview + to_buf(char *begin, char *end, range const &value) + { + return generic_to_buf(begin, end, value); + } + + static inline char * + into_buf(char *begin, char *end, range const &value) + { + if (value.empty()) + { + if ((end - begin) <= internal::ssize(s_empty)) + throw conversion_overrun{s_overrun.c_str()}; + char *here = begin + s_empty.copy(begin, std::size(s_empty)); + *here++ = '\0'; + return here; + } + else + { + if (end - begin < 4) + throw conversion_overrun{s_overrun.c_str()}; + char *here = begin; + *here++ = + (static_cast(value.lower_bound().is_inclusive() ? '[' : '(')); + TYPE const *lower{value.lower_bound().value()}; + // Convert bound (but go back to overwrite that trailing zero). + if (lower != nullptr) + here = string_traits::into_buf(here, end, *lower) - 1; + *here++ = ','; + TYPE const *upper{value.upper_bound().value()}; + // Convert bound (but go back to overwrite that trailing zero). + if (upper != nullptr) + here = string_traits::into_buf(here, end, *upper) - 1; + if ((end - here) < 2) + throw conversion_overrun{s_overrun.c_str()}; + *here++ = + static_cast(value.upper_bound().is_inclusive() ? ']' : ')'); + *here++ = '\0'; + return here; + } + } + + [[nodiscard]] static inline range from_string(std::string_view text) + { + if (std::size(text) < 3) + throw pqxx::conversion_error{err_bad_input(text)}; + bool left_inc{false}; + switch (text[0]) + { + case '[': left_inc = true; break; + + case '(': break; + + case 'e': + case 'E': + if ( + (std::size(text) != std::size(s_empty)) or + (text[1] != 'm' and text[1] != 'M') or + (text[2] != 'p' and text[2] != 'P') or + (text[3] != 't' and text[3] != 'T') or + (text[4] != 'y' and text[4] != 'Y')) + throw pqxx::conversion_error{err_bad_input(text)}; + return {}; + break; + + default: throw pqxx::conversion_error{err_bad_input(text)}; + } + + auto scan{internal::get_glyph_scanner(internal::encoding_group::UTF8)}; + // The field parser uses this to track which field it's parsing, and + // when not to expect a field separator. + std::size_t index{0}; + // The last field we expect to see. + static constexpr std::size_t last{1}; + // Current parsing position. We skip the opening parenthesis or bracket. + std::size_t pos{1}; + // The string may leave out either bound to indicate that it's unlimited. + std::optional lower, upper; + // We reuse the same field parser we use for composite values and arrays. + internal::parse_composite_field(index, text, pos, lower, scan, last); + internal::parse_composite_field(index, text, pos, upper, scan, last); + + // We need one more character: the closing parenthesis or bracket. + if (pos != std::size(text)) + throw pqxx::conversion_error{err_bad_input(text)}; + char const closing{text[pos - 1]}; + if (closing != ')' and closing != ']') + throw pqxx::conversion_error{err_bad_input(text)}; + bool const right_inc{closing == ']'}; + + range_bound lower_bound{no_bound{}}, upper_bound{no_bound{}}; + if (lower) + { + if (left_inc) + lower_bound = inclusive_bound{*lower}; + else + lower_bound = exclusive_bound{*lower}; + } + if (upper) + { + if (right_inc) + upper_bound = inclusive_bound{*upper}; + else + upper_bound = exclusive_bound{*upper}; + } + + return {lower_bound, upper_bound}; + } + + [[nodiscard]] static inline constexpr std::size_t + size_buffer(range const &value) noexcept + { + TYPE const *lower{value.lower_bound().value()}, + *upper{value.upper_bound().value()}; + std::size_t const lsz{ + lower == nullptr ? 0 : string_traits::size_buffer(*lower) - 1}, + usz{upper == nullptr ? 0 : string_traits::size_buffer(*upper) - 1}; + + if (value.empty()) + return std::size(s_empty) + 1; + else + return 1 + lsz + 1 + usz + 2; + } + +private: + static constexpr zview s_empty{"empty"_zv}; + static constexpr auto s_overrun{"Not enough space in buffer for range."_zv}; + + /// Compose error message for invalid range input. + static std::string err_bad_input(std::string_view text) + { + return internal::concat("Invalid range input: '", text, "'"); + } +}; + + +/// A range type does not have an innate null value. +template struct nullness> : no_null> +{}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/result b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/result new file mode 100644 index 000000000..523394b72 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/result @@ -0,0 +1,16 @@ +/** pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/result.hxx" + +// Now include some types which depend on result, but which the user will +// expect to see defined after including this header. +#include "pqxx/internal/result_iterator.hxx" +#include "pqxx/field.hxx" +#include "pqxx/internal/result_iter.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/result.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/result.hxx new file mode 100644 index 000000000..6c41cc096 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/result.hxx @@ -0,0 +1,335 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT +#define PQXX_H_RESULT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include + +#include "pqxx/except.hxx" +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + +#include "pqxx/internal/encodings.hxx" + + +namespace pqxx::internal +{ +// TODO: Make noexcept (but breaks ABI). +PQXX_LIBEXPORT void clear_result(pq::PGresult const *); +} // namespace pqxx::internal + + +namespace pqxx::internal::gate +{ +class result_connection; +class result_creation; +class result_pipeline; +class result_row; +class result_sql_cursor; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Result set containing data returned by a query or command. +/** This behaves as a container (as defined by the C++ standard library) and + * provides random access const iterators to iterate over its rows. You can + * also access a row by indexing a `result R` by the row's zero-based + * number: + * + * + * for (result::size_type i=0; i < std::size(R); ++i) Process(R[i]); + * + * + * Result sets in libpqxx are lightweight, reference-counted wrapper objects + * which are relatively small and cheap to copy. Think of a result object as + * a "smart pointer" to an underlying result set. + * + * @warning The result set that a result object points to is not thread-safe. + * If you copy a result object, it still refers to the same underlying result + * set. So never copy, destroy, query, or otherwise access a result while + * another thread may be copying, destroying, querying, or otherwise accessing + * the same result set--even if it is doing so through a different result + * object! + */ +class PQXX_LIBEXPORT result +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + using reference = row; + using const_iterator = const_result_iterator; + using pointer = const_iterator; + using iterator = const_iterator; + using const_reverse_iterator = const_reverse_result_iterator; + using reverse_iterator = const_reverse_iterator; + + result() noexcept : + m_data{make_data_pointer()}, + m_query{}, + m_encoding{internal::encoding_group::MONOBYTE} + {} + + result(result const &rhs) noexcept = default; + result(result &&rhs) noexcept = default; + + /// Assign one result to another. + /** Copying results is cheap: it copies only smart pointers, but the actual + * data stays in the same place. + */ + result &operator=(result const &rhs) noexcept = default; + + /// Assign one result to another, invaliding the old one. + result &operator=(result &&rhs) noexcept = default; + + /** + * @name Comparisons + * + * You can compare results for equality. Beware: this is a very strict, + * dumb comparison. The smallest difference between two results (such as a + * string "Foo" versus a string "foo") will make them unequal. + */ + //@{ + /// Compare two results for equality. + [[nodiscard]] bool operator==(result const &) const noexcept; + /// Compare two results for inequality. + [[nodiscard]] bool operator!=(result const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + /// Iterate rows, reading them directly into a tuple of "TYPE...". + /** Converts the fields to values of the given respective types. + * + * Use this only with a ranged "for" loop. The iteration produces + * std::tuple which you can "unpack" to a series of `auto` + * variables. + */ + template auto iter() const; + + [[nodiscard]] const_reverse_iterator rbegin() const; + [[nodiscard]] const_reverse_iterator crbegin() const; + [[nodiscard]] const_reverse_iterator rend() const; + [[nodiscard]] const_reverse_iterator crend() const; + + [[nodiscard]] const_iterator begin() const noexcept; + [[nodiscard]] const_iterator cbegin() const noexcept; + [[nodiscard]] inline const_iterator end() const noexcept; + [[nodiscard]] inline const_iterator cend() const noexcept; + + [[nodiscard]] reference front() const noexcept; + [[nodiscard]] reference back() const noexcept; + + [[nodiscard]] PQXX_PURE size_type size() const noexcept; + [[nodiscard]] PQXX_PURE bool empty() const noexcept; + [[nodiscard]] size_type capacity() const noexcept { return size(); } + + /// Exchange two `result` values in an exception-safe manner. + /** If the swap fails, the two values will be exactly as they were before. + * + * The swap is not necessarily thread-safe. + */ + void swap(result &) noexcept; + + /// Index a row by number. + /** This returns a @ref row object. Generally you should not keep the row + * around as a variable, but if you do, make sure that your variable is a + * `row`, not a `row&`. + */ + [[nodiscard]] row operator[](size_type i) const noexcept; + +#if defined(PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT) + // TODO: If C++23 will let us, also accept string for the column. + [[nodiscard]] field + operator[](size_type row_num, row_size_type col_num) const noexcept; +#endif + + /// Index a row by number, but check that the row number is valid. + row at(size_type) const; + + /// Index a field by row number and column number. + field at(size_type, row_size_type) const; + + /// Let go of the result's data. + /** Use this if you need to deallocate the result data earlier than you can + * destroy the `result` object itself. + * + * Multiple `result` objects can refer to the same set of underlying data. + * The underlying data will be deallocated once all `result` objects that + * refer to it are cleared or destroyed. + */ + void clear() noexcept + { + m_data.reset(); + m_query = nullptr; + } + + /** + * @name Column information + */ + //@{ + /// Number of columns in result. + [[nodiscard]] PQXX_PURE row_size_type columns() const noexcept; + + /// Number of given column (throws exception if it doesn't exist). + [[nodiscard]] row_size_type column_number(zview name) const; + + /// Name of column with this number (throws exception if it doesn't exist) + [[nodiscard]] char const *column_name(row_size_type number) const &; + + /// Return column's type, as an OID from the system catalogue. + [[nodiscard]] oid column_type(row_size_type col_num) const; + + /// Return column's type, as an OID from the system catalogue. + [[nodiscard]] oid column_type(zview col_name) const + { + return column_type(column_number(col_name)); + } + + /// What table did this column come from? + [[nodiscard]] oid column_table(row_size_type col_num) const; + + /// What table did this column come from? + [[nodiscard]] oid column_table(zview col_name) const + { + return column_table(column_number(col_name)); + } + + /// What column in its table did this column come from? + [[nodiscard]] row_size_type table_column(row_size_type col_num) const; + + /// What column in its table did this column come from? + [[nodiscard]] row_size_type table_column(zview col_name) const + { + return table_column(column_number(col_name)); + } + //@} + + /// Query that produced this result, if available (empty string otherwise) + [[nodiscard]] PQXX_PURE std::string const &query() const &noexcept; + + /// If command was an `INSERT` of 1 row, return oid of the inserted row. + /** @return Identifier of inserted row if exactly one row was inserted, or + * @ref oid_none otherwise. + */ + [[nodiscard]] PQXX_PURE oid inserted_oid() const; + + /// If command was `INSERT`, `UPDATE`, or `DELETE`: number of affected rows. + /** @return Number of affected rows if last command was `INSERT`, `UPDATE`, + * or `DELETE`; zero for all other commands. + */ + [[nodiscard]] PQXX_PURE size_type affected_rows() const; + + // C++20: Concept like std::invocable, but without specifying param types. + /// Run `func` on each row, passing the row's fields as parameters. + /** Goes through the rows from first to last. You provide a callable `func`. + * + * For each row in the `result`, `for_each` will call `func`. It converts + * the row's fields to the types of `func`'s parameters, and pass them to + * `func`. + * + * (Therefore `func` must have a _single_ signature. It can't be a generic + * lambda, or an object of a class with multiple overloaded function call + * operators. Otherwise, `for_each` will have no way to detect a parameter + * list without ambiguity.) + * + * If any of your parameter types is `std::string_view`, it refers to the + * underlying storage of this `result`. + * + * If any of your parameter types is a reference type, its argument will + * refer to a temporary value which only lives for the duration of that + * single invocation to `func`. If the reference is an lvalue reference, it + * must be `const`. + * + * For example, this queries employee names and salaries from the database + * and prints how much each would like to earn instead: + * ```cxx + * tx.exec("SELECT name, salary FROM employee").for_each( + * [](std::string_view name, float salary){ + * std::cout << name << " would like " << salary * 2 << ".\n"; + * }) + * ``` + * + * If `func` throws an exception, processing stops at that point and + * propagates the exception. + * + * @throws usage_error if `func`'s number of parameters does not match the + * number of columns in this result. + */ + template inline void for_each(CALLABLE &&func) const; + +private: + using data_pointer = std::shared_ptr; + + /// Underlying libpq result set. + data_pointer m_data; + + /// Factory for data_pointer. + static data_pointer + make_data_pointer(internal::pq::PGresult const *res = nullptr) noexcept + { + return {res, internal::clear_result}; + } + + friend class pqxx::internal::gate::result_pipeline; + PQXX_PURE std::shared_ptr query_ptr() const noexcept + { + return m_query; + } + + /// Query string. + std::shared_ptr m_query; + + internal::encoding_group m_encoding; + + static std::string const s_empty_string; + + friend class pqxx::field; + // TODO: noexcept. Breaks ABI. + PQXX_PURE char const *get_value(size_type row, row_size_type col) const; + // TODO: noexcept. Breaks ABI. + PQXX_PURE bool get_is_null(size_type row, row_size_type col) const; + PQXX_PURE + field_size_type get_length(size_type, row_size_type) const noexcept; + + friend class pqxx::internal::gate::result_creation; + result( + internal::pq::PGresult *rhs, std::shared_ptr query, + internal::encoding_group enc); + + PQXX_PRIVATE void check_status(std::string_view desc = ""sv) const; + + friend class pqxx::internal::gate::result_connection; + friend class pqxx::internal::gate::result_row; + bool operator!() const noexcept { return m_data.get() == nullptr; } + operator bool() const noexcept { return m_data.get() != nullptr; } + + [[noreturn]] PQXX_PRIVATE void + throw_sql_error(std::string const &Err, std::string const &Query) const; + PQXX_PRIVATE PQXX_PURE int errorposition() const; + PQXX_PRIVATE std::string status_error() const; + + friend class pqxx::internal::gate::result_sql_cursor; + PQXX_PURE char const *cmd_status() const noexcept; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/robusttransaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/robusttransaction new file mode 100644 index 000000000..04b71d7cc --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/robusttransaction @@ -0,0 +1,8 @@ +/** pqxx::robusttransaction class. + * + * pqxx::robusttransaction is a slower but safer transaction class. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/robusttransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/robusttransaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/robusttransaction.hxx new file mode 100644 index 000000000..faf6dbf5e --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/robusttransaction.hxx @@ -0,0 +1,120 @@ +/* Definition of the pqxx::robusttransaction class. + * + * pqxx::robusttransaction is a slower but safer transaction class. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/robusttransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ROBUSTTRANSACTION +#define PQXX_H_ROBUSTTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx::internal +{ +/// Helper base class for the @ref robusttransaction class template. +class PQXX_LIBEXPORT PQXX_NOVTABLE basic_robusttransaction + : public dbtransaction +{ +public: + virtual ~basic_robusttransaction() override = 0; + +protected: + basic_robusttransaction( + connection &c, zview begin_command, std::string_view tname); + basic_robusttransaction(connection &c, zview begin_command); + +private: + using IDType = unsigned long; + + std::string m_conn_string; + std::string m_xid; + int m_backendpid = -1; + + void init(zview begin_command); + + // @warning This function will become `final`. + virtual void do_commit() override; +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @ingroup transactions + * + * @{ + */ + +/// Slightly slower, better-fortified version of transaction. +/** Requires PostgreSQL 10 or better. + * + * robusttransaction is similar to transaction, but spends more time and effort + * to deal with the hopefully rare case that the connection to the backend is + * lost just while it's trying to commit. In such cases, the client does not + * know whether the backend (on the other side of the broken connection) + * managed to commit the transaction. + * + * When this happens, robusttransaction tries to reconnect to the database and + * figure out what happened. + * + * This service level was made optional since you may not want to pay the + * overhead where it is not necessary. Certainly the use of this class makes + * no sense for local connections, or for transactions that read the database + * but never modify it, or for noncritical database manipulations. + * + * Besides being slower, it's also more complex. Which means that in practice + * a robusttransaction could actually fail more instead of less often than a + * normal transaction. What robusttransaction tries to achieve is to give you + * certainty, not just be more successful per se. + */ +template +class robusttransaction final : public internal::basic_robusttransaction +{ +public: + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + * @param tname optional human-readable name for this transaction. + */ + robusttransaction(connection &c, std::string_view tname) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd, + tname} + {} + + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + * @param tname optional human-readable name for this transaction. + */ + robusttransaction(connection &c, std::string &&tname) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd, + std::move(tname)} + {} + + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + */ + explicit robusttransaction(connection &c) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd} + {} + + virtual ~robusttransaction() noexcept override { close(); } +}; + +/** + * @} + */ +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/row b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/row new file mode 100644 index 000000000..62a950ac8 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/row @@ -0,0 +1,11 @@ +/** pqxx::row class. + * + * pqxx::row refers to a row in a result. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/result.hxx" +#include "pqxx/row.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/row.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/row.hxx new file mode 100644 index 000000000..5be5132e3 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/row.hxx @@ -0,0 +1,561 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ROW +#define PQXX_H_ROW + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/except.hxx" +#include "pqxx/field.hxx" +#include "pqxx/result.hxx" + +#include "pqxx/internal/concat.hxx" + +namespace pqxx::internal +{ +template class result_iter; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// Reference to one row in a result. +/** A row represents one row (also called a row) in a query result set. + * It also acts as a container mapping column numbers or names to field + * values (see below): + * + * ```cxx + * cout << row["date"].c_str() << ": " << row["name"].c_str() << endl; + * ``` + * + * The row itself acts like a (non-modifyable) container, complete with its + * own const_iterator and const_reverse_iterator. + */ +class PQXX_LIBEXPORT row +{ +public: + using size_type = row_size_type; + using difference_type = row_difference_type; + using const_iterator = const_row_iterator; + using iterator = const_iterator; + using reference = field; + using pointer = const_row_iterator; + using const_reverse_iterator = const_reverse_row_iterator; + using reverse_iterator = const_reverse_iterator; + + row() noexcept = default; + row(row &&) noexcept = default; + row(row const &) noexcept = default; + row &operator=(row const &) noexcept = default; + row &operator=(row &&) noexcept = default; + + /** + * @name Comparison + */ + //@{ + [[nodiscard]] PQXX_PURE bool operator==(row const &) const noexcept; + [[nodiscard]] bool operator!=(row const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + [[nodiscard]] const_iterator begin() const noexcept; + [[nodiscard]] const_iterator cbegin() const noexcept; + [[nodiscard]] const_iterator end() const noexcept; + [[nodiscard]] const_iterator cend() const noexcept; + + /** + * @name Field access + */ + //@{ + [[nodiscard]] reference front() const noexcept; + [[nodiscard]] reference back() const noexcept; + + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator rbegin() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator crbegin() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator rend() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator crend() const; + + [[nodiscard]] reference operator[](size_type) const noexcept; + /** Address field by name. + * @warning This is much slower than indexing by number, or iterating. + */ + [[nodiscard]] reference operator[](zview col_name) const; + + reference at(size_type) const; + /** Address field by name. + * @warning This is much slower than indexing by number, or iterating. + */ + reference at(zview col_name) const; + + [[nodiscard]] constexpr size_type size() const noexcept + { + return m_end - m_begin; + } + + [[deprecated("Swap iterators, not rows.")]] void swap(row &) noexcept; + + /// Row number, assuming this is a real row and not end()/rend(). + [[nodiscard]] constexpr result::size_type rownumber() const noexcept + { + return m_index; + } + + /** + * @name Column information + */ + //@{ + /// Number of given column (throws exception if it doesn't exist). + [[nodiscard]] size_type column_number(zview col_name) const; + + /// Return a column's type. + [[nodiscard]] oid column_type(size_type) const; + + /// Return a column's type. + [[nodiscard]] oid column_type(zview col_name) const + { + return column_type(column_number(col_name)); + } + + /// What table did this column come from? + [[nodiscard]] oid column_table(size_type col_num) const; + + /// What table did this column come from? + [[nodiscard]] oid column_table(zview col_name) const + { + return column_table(column_number(col_name)); + } + + /// What column number in its table did this result column come from? + /** A meaningful answer can be given only if the column in question comes + * directly from a column in a table. If the column is computed in any + * other way, a logic_error will be thrown. + * + * @param col_num a zero-based column number in this result set + * @return a zero-based column number in originating table + */ + [[nodiscard]] size_type table_column(size_type) const; + + /// What column number in its table did this result column come from? + [[nodiscard]] size_type table_column(zview col_name) const + { + return table_column(column_number(col_name)); + } + //@} + + [[nodiscard]] constexpr result::size_type num() const noexcept + { + return rownumber(); + } + + /** Produce a slice of this row, containing the given range of columns. + * + * @deprecated I haven't heard of anyone caring about row slicing at all in + * at least the last 15 years. Yet it adds complexity, so unless anyone + * files a bug explaining why they really need this feature, I'm going to + * remove it. Even if they do, the feature may need an update. + * + * The slice runs from the range's starting column to the range's end + * column, exclusive. It looks just like a normal result row, except + * slices can be empty. + */ + [[deprecated("Row slicing is going away. File a bug if you need it.")]] row + slice(size_type sbegin, size_type send) const; + + /// Is this a row without fields? Can only happen to a slice. + [[nodiscard, deprecated("Row slicing is going away.")]] PQXX_PURE bool + empty() const noexcept; + + /// Extract entire row's values into a tuple. + /** Converts to the types of the tuple's respective fields. + */ + template void to(Tuple &t) const + { + check_size(std::tuple_size_v); + convert(t); + } + + template std::tuple as() const + { + check_size(sizeof...(TYPE)); + using seq = std::make_index_sequence; + return get_tuple>(seq{}); + } + +protected: + friend class const_row_iterator; + friend class result; + row(result const &r, result_size_type index, size_type cols) noexcept; + + /// Throw @ref usage_error if row size is not `expected`. + void check_size(size_type expected) const + { + if (size() != expected) + throw usage_error{internal::concat( + "Tried to extract ", expected, " field(s) from a row of ", size(), + ".")}; + } + + /// Convert to a given tuple of values, don't check sizes. + /** We need this for cases where we have a full tuple of field types, but + * not a parameter pack. + */ + template TUPLE as_tuple() const + { + using seq = std::make_index_sequence>; + return get_tuple(seq{}); + } + + template friend class pqxx::internal::result_iter; + /// Convert entire row to tuple fields, without checking row size. + template void convert(Tuple &t) const + { + extract_fields(t, std::make_index_sequence>{}); + } + + friend class field; + + /// Result set of which this is one row. + result m_result; + + /// Row number. + /** + * You'd expect this to be unsigned, but due to the way reverse iterators + * are related to regular iterators, it must be allowed to underflow to -1. + */ + result::size_type m_index = 0; + + // TODO: Remove m_begin and (if possible) m_end when we remove slice(). + /// First column in slice. This row ignores lower-numbered columns. + size_type m_begin = 0; + /// End column in slice. This row only sees lower-numbered columns. + size_type m_end = 0; + +private: + template + void extract_fields(Tuple &t, std::index_sequence) const + { + (extract_value(t), ...); + } + + template + void extract_value(Tuple &t) const; + + /// Convert row's values as a new tuple. + template + auto get_tuple(std::index_sequence) const + { + return std::make_tuple(get_field()...); + } + + /// Extract and convert a field. + template auto get_field() const + { + return (*this)[index].as>(); + } +}; + + +/// Iterator for fields in a row. Use as row::const_iterator. +class PQXX_LIBEXPORT const_row_iterator : public field +{ +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = field const; + using pointer = field const *; + using size_type = row_size_type; + using difference_type = row_difference_type; + using reference = field; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + const_row_iterator() = default; +#include "pqxx/internal/ignore-deprecated-post.hxx" + const_row_iterator(row const &t, row_size_type c) noexcept : + field{t.m_result, t.m_index, c} + {} + const_row_iterator(field const &F) noexcept : field{F} {} + const_row_iterator(const_row_iterator const &) noexcept = default; + const_row_iterator(const_row_iterator &&) noexcept = default; + + /** + * @name Dereferencing operators + */ + //@{ + [[nodiscard]] constexpr pointer operator->() const noexcept { return this; } + [[nodiscard]] reference operator*() const noexcept { return {*this}; } + //@} + + /** + * @name Manipulations + */ + //@{ + const_row_iterator &operator=(const_row_iterator const &) noexcept = default; + const_row_iterator &operator=(const_row_iterator &&) noexcept = default; + + // TODO: noexcept. Breaks ABI. + const_row_iterator operator++(int); + const_row_iterator &operator++() noexcept + { + ++m_col; + return *this; + } + // TODO: noexcept. Breaks ABI. + const_row_iterator operator--(int); + const_row_iterator &operator--() noexcept + { + --m_col; + return *this; + } + + const_row_iterator &operator+=(difference_type i) noexcept + { + m_col = size_type(difference_type(m_col) + i); + return *this; + } + const_row_iterator &operator-=(difference_type i) noexcept + { + m_col = size_type(difference_type(m_col) - i); + return *this; + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] constexpr bool + operator==(const_row_iterator const &i) const noexcept + { + return col() == i.col(); + } + [[nodiscard]] constexpr bool + operator!=(const_row_iterator const &i) const noexcept + { + return col() != i.col(); + } + [[nodiscard]] constexpr bool + operator<(const_row_iterator const &i) const noexcept + { + return col() < i.col(); + } + [[nodiscard]] constexpr bool + operator<=(const_row_iterator const &i) const noexcept + { + return col() <= i.col(); + } + [[nodiscard]] constexpr bool + operator>(const_row_iterator const &i) const noexcept + { + return col() > i.col(); + } + [[nodiscard]] constexpr bool + operator>=(const_row_iterator const &i) const noexcept + { + return col() >= i.col(); + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] inline const_row_iterator + operator+(difference_type) const noexcept; + + friend const_row_iterator + operator+(difference_type, const_row_iterator const &) noexcept; + + [[nodiscard]] inline const_row_iterator + operator-(difference_type) const noexcept; + [[nodiscard]] inline difference_type + operator-(const_row_iterator const &) const noexcept; + //@} +}; + + +/// Reverse iterator for a row. Use as row::const_reverse_iterator. +class PQXX_LIBEXPORT const_reverse_row_iterator : private const_row_iterator +{ +public: + using super = const_row_iterator; + using iterator_type = const_row_iterator; + using iterator_type::difference_type; + using iterator_type::iterator_category; + using iterator_type::pointer; + using value_type = iterator_type::value_type; + using reference = iterator_type::reference; + + const_reverse_row_iterator() noexcept = default; + const_reverse_row_iterator(const_reverse_row_iterator const &) noexcept = + default; + const_reverse_row_iterator(const_reverse_row_iterator &&) noexcept = default; + + explicit const_reverse_row_iterator(super const &rhs) noexcept : + const_row_iterator{rhs} + { + super::operator--(); + } + + [[nodiscard]] PQXX_PURE iterator_type base() const noexcept; + + /** + * @name Dereferencing operators + */ + //@{ + using iterator_type::operator->; + using iterator_type::operator*; + //@} + + /** + * @name Manipulations + */ + //@{ + const_reverse_row_iterator & + operator=(const_reverse_row_iterator const &r) noexcept + { + iterator_type::operator=(r); + return *this; + } + const_reverse_row_iterator operator++() noexcept + { + iterator_type::operator--(); + return *this; + } + // TODO: noexcept. Breaks ABI. + const_reverse_row_iterator operator++(int); + const_reverse_row_iterator &operator--() noexcept + { + iterator_type::operator++(); + return *this; + } + const_reverse_row_iterator operator--(int); + // TODO: noexcept. Breaks ABI. + const_reverse_row_iterator &operator+=(difference_type i) noexcept + { + iterator_type::operator-=(i); + return *this; + } + const_reverse_row_iterator &operator-=(difference_type i) noexcept + { + iterator_type::operator+=(i); + return *this; + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] const_reverse_row_iterator + operator+(difference_type i) const noexcept + { + return const_reverse_row_iterator{base() - i}; + } + [[nodiscard]] const_reverse_row_iterator + operator-(difference_type i) noexcept + { + return const_reverse_row_iterator{base() + i}; + } + [[nodiscard]] difference_type + operator-(const_reverse_row_iterator const &rhs) const noexcept + { + return rhs.const_row_iterator::operator-(*this); + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool + operator==(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator==(rhs); + } + [[nodiscard]] bool + operator!=(const_reverse_row_iterator const &rhs) const noexcept + { + return !operator==(rhs); + } + + [[nodiscard]] constexpr bool + operator<(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator>(rhs); + } + [[nodiscard]] constexpr bool + operator<=(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator>=(rhs); + } + [[nodiscard]] constexpr bool + operator>(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator<(rhs); + } + [[nodiscard]] constexpr bool + operator>=(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator<=(rhs); + } + //@} +}; + + +const_row_iterator +const_row_iterator::operator+(difference_type o) const noexcept +{ + // TODO:: More direct route to home().columns()? + return { + row{home(), idx(), home().columns()}, + size_type(difference_type(col()) + o)}; +} + +inline const_row_iterator operator+( + const_row_iterator::difference_type o, const_row_iterator const &i) noexcept +{ + return i + o; +} + +inline const_row_iterator +const_row_iterator::operator-(difference_type o) const noexcept +{ + // TODO:: More direct route to home().columns()? + return { + row{home(), idx(), home().columns()}, + size_type(difference_type(col()) - o)}; +} + +inline const_row_iterator::difference_type +const_row_iterator::operator-(const_row_iterator const &i) const noexcept +{ + return difference_type(num() - i.num()); +} + + +template +inline void row::extract_value(Tuple &t) const +{ + using field_type = strip_t(t))>; + field const f{m_result, m_index, index}; + std::get(t) = from_string(f); +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/separated_list b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/separated_list new file mode 100644 index 000000000..1bdf51c6a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/separated_list @@ -0,0 +1,6 @@ +/** Helper similar to Python's @c str.join(). + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/separated_list.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/separated_list.hxx new file mode 100644 index 000000000..d4230ea08 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/separated_list.hxx @@ -0,0 +1,142 @@ +/* Helper similar to Python's `str.join()`. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/separated_list instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SEPARATED_LIST +#define PQXX_H_SEPARATED_LIST + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/strconv.hxx" + +// C++20: Simplify using std::ranges::range. +// C++20: Optimise buffer allocation using random_access_range/iterator. +namespace pqxx +{ +/** + * @defgroup utility Utility functions + */ +//@{ + +/// Represent sequence of values as a string, joined by a given separator. +/** + * Use this to turn e.g. the numbers 1, 2, and 3 into a string "1, 2, 3". + * + * @param sep separator string (to be placed between items) + * @param begin beginning of items sequence + * @param end end of items sequence + * @param access functor defining how to dereference sequence elements + */ +template +[[nodiscard]] inline std::string +separated_list(std::string_view sep, ITER begin, ITER end, ACCESS access) +{ + if (end == begin) + return {}; + auto next{begin}; + ++next; + if (next == end) + return to_string(access(begin)); + + // From here on, we've got at least 2 elements -- meaning that we need sep. + using elt_type = strip_t; + using traits = string_traits; + + std::size_t budget{0}; + for (ITER cnt{begin}; cnt != end; ++cnt) + budget += traits::size_buffer(access(cnt)); + budget += + static_cast(std::distance(begin, end)) * std::size(sep); + + std::string result; + result.resize(budget); + + char *const data{result.data()}; + char *here{data}; + char *stop{data + budget}; + here = traits::into_buf(here, stop, access(begin)) - 1; + for (++begin; begin != end; ++begin) + { + here += sep.copy(here, std::size(sep)); + here = traits::into_buf(here, stop, access(begin)) - 1; + } + result.resize(static_cast(here - data)); + return result; +} + + +/// Render sequence as a string, using given separator between items. +template +[[nodiscard]] inline std::string +separated_list(std::string_view sep, ITER begin, ITER end) +{ + return separated_list(sep, begin, end, [](ITER i) { return *i; }); +} + + +/// Render items in a container as a string, using given separator. +template +[[nodiscard]] inline auto +separated_list(std::string_view sep, CONTAINER const &c) + /* + Always std::string; necessary because SFINAE doesn't work with the + contents of function bodies, so the check for iterability has to be in + the signature. + */ + -> typename std::enable_if< + (not std::is_void::value and + not std::is_void::value), + std::string>::type +{ + return separated_list(sep, std::begin(c), std::end(c)); +} + + +/// Render items in a tuple as a string, using given separator. +template< + typename TUPLE, std::size_t INDEX = 0, typename ACCESS, + typename std::enable_if< + (INDEX == std::tuple_size::value - 1), int>::type = 0> +[[nodiscard]] inline std::string separated_list( + std::string_view /* sep */, TUPLE const &t, ACCESS const &access) +{ + return to_string(access(&std::get(t))); +} + +template< + typename TUPLE, std::size_t INDEX = 0, typename ACCESS, + typename std::enable_if< + (INDEX < std::tuple_size::value - 1), int>::type = 0> +[[nodiscard]] inline std::string +separated_list(std::string_view sep, TUPLE const &t, ACCESS const &access) +{ + std::string out{to_string(access(&std::get(t)))}; + out.append(sep); + out.append(separated_list(sep, t, access)); + return out; +} + +template< + typename TUPLE, std::size_t INDEX = 0, + typename std::enable_if< + (INDEX <= std::tuple_size::value), int>::type = 0> +[[nodiscard]] inline std::string +separated_list(std::string_view sep, TUPLE const &t) +{ + // TODO: Optimise allocation. + return separated_list(sep, t, [](TUPLE const &tup) { return *tup; }); +} +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/strconv b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/strconv new file mode 100644 index 000000000..aa2c40ed5 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/strconv @@ -0,0 +1,6 @@ +/** String conversion definitions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/strconv.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/strconv.hxx new file mode 100644 index 000000000..863711228 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/strconv.hxx @@ -0,0 +1,468 @@ +/* String conversion definitions. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STRCONV +#define PQXX_H_STRCONV + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include + +#if __has_include() +# include +#endif + +#if defined(PQXX_HAVE_RANGES) && __has_include() +# include +#endif + +#include "pqxx/except.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + + +namespace pqxx::internal +{ +/// Attempt to demangle @c std::type_info::name() to something human-readable. +PQXX_LIBEXPORT std::string demangle_type_name(char const[]); +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @defgroup stringconversion String conversion + * + * The PostgreSQL server accepts and represents data in string form. It has + * its own formats for various data types. The string conversions define how + * various C++ types translate to and from their respective PostgreSQL text + * representations. + * + * Each conversion is defined by a specialisations of @c string_traits. It + * gets complicated if you want top performance, but until you do, all you + * really need to care about when converting values between C++ in-memory + * representations such as @c int and the postgres string representations is + * the @c pqxx::to_string and @c pqxx::from_string functions. + * + * If you need to convert a type which is not supported out of the box, you'll + * need to define your own specialisations for these templates, similar to the + * ones defined here and in `pqxx/conversions.hxx`. Any conversion code which + * "sees" your specialisation will now support your conversion. In particular, + * you'll be able to read result fields into a variable of the new type. + * + * There is a macro to help you define conversions for individual enumeration + * types. The conversion will represent enumeration values as numeric strings. + */ +//@{ + +/// A human-readable name for a type, used in error messages and such. +/** Actually this may not always be very user-friendly. It uses + * @c std::type_info::name(). On gcc-like compilers we try to demangle its + * output. Visual Studio produces human-friendly names out of the box. + * + * This variable is not inline. Inlining it gives rise to "memory leak" + * warnings from asan, the address sanitizer, possibly from use of + * @c std::type_info::name. + */ +template +std::string const type_name{internal::demangle_type_name(typeid(TYPE).name())}; + + +/// Traits describing a type's "null value," if any. +/** Some C++ types have a special value or state which correspond directly to + * SQL's NULL. + * + * The @c nullness traits describe whether it exists, and whether a particular + * value is null. + */ +template struct nullness +{ + /// Does this type have a null value? + static bool has_null; + + /// Is this type always null? + static bool always_null; + + /// Is @c value a null? + static bool is_null(TYPE const &value); + + /// Return a null value. + /** Don't use this in generic code to compare a value and see whether it is + * null. Some types may have multiple null values which do not compare as + * equal, or may define a null value which is not equal to anything including + * itself, like in SQL. + */ + [[nodiscard]] static TYPE null(); +}; + + +/// Nullness traits describing a type which does not have a null value. +template struct no_null +{ + /// Does @c TYPE have a "built-in null value"? + /** For example, a pointer can equal @c nullptr, which makes a very natural + * representation of an SQL null value. For such types, the code sometimes + * needs to make special allowances. + * + * for most types, such as @c int or @c std::string, there is no built-in + * null. If you want to represent an SQL null value for such a type, you + * would have to wrap it in something that does have a null value. For + * example, you could use @c std::optional for "either an @c int or a + * null value." + */ + static constexpr bool has_null = false; + + /// Are all values of this type null? + /** There are a few special C++ types which are always null - mainly + * @c std::nullptr_t. + */ + static constexpr bool always_null = false; + + /// Does a given value correspond to an SQL null value? + /** Most C++ types, such as @c int or @c std::string, have no inherent null + * value. But some types such as C-style string pointers do have a natural + * equivalent to an SQL null. + */ + [[nodiscard]] static constexpr bool is_null(TYPE const &) noexcept + { + return false; + } +}; + + +/// Traits class for use in string conversions. +/** Specialize this template for a type for which you wish to add to_string + * and from_string support. + * + * String conversions are not meant to work for nulls. Check for null before + * converting a value of @c TYPE to a string, or vice versa. + */ +template struct string_traits +{ + /// Return a @c string_view representing value, plus terminating zero. + /** Produces a @c string_view containing the PostgreSQL string representation + * for @c value. + * + * Uses the space from @c begin to @c end as a buffer, if needed. The + * returned string may lie somewhere in that buffer, or it may be a + * compile-time constant, or it may be null if value was a null value. Even + * if the string is stored in the buffer, its @c begin() may or may not be + * the same as @c begin. + * + * The @c string_view is guaranteed to be valid as long as the buffer from + * @c begin to @c end remains accessible and unmodified. + * + * @throws pqxx::conversion_overrun if the provided buffer space may not be + * enough. For maximum performance, this is a conservative estimate. It may + * complain about a buffer which is actually large enough for your value, if + * an exact check gets too expensive. + */ + [[nodiscard]] static inline zview + to_buf(char *begin, char *end, TYPE const &value); + + /// Write value's string representation into buffer at @c begin. + /** Assumes that value is non-null. + * + * Writes value's string representation into the buffer, starting exactly at + * @c begin, and ensuring a trailing zero. Returns the address just beyond + * the trailing zero, so the caller could use it as the @c begin for another + * call to @c into_buf writing a next value. + */ + static inline char *into_buf(char *begin, char *end, TYPE const &value); + + /// Parse a string representation of a @c TYPE value. + /** Throws @c conversion_error if @c value does not meet the expected format + * for a value of this type. + */ + [[nodiscard]] static inline TYPE from_string(std::string_view text); + + // C++20: Can we make these all constexpr? + /// Estimate how much buffer space is needed to represent value. + /** The estimate may be a little pessimistic, if it saves time. + * + * The estimate includes the terminating zero. + */ + [[nodiscard]] static inline std::size_t + size_buffer(TYPE const &value) noexcept; +}; + + +/// Nullness: Enums do not have an inherent null value. +template +struct nullness>> : no_null +{}; +} // namespace pqxx + + +namespace pqxx::internal +{ +/// Helper class for defining enum conversions. +/** The conversion will convert enum values to numeric strings, and vice versa. + * + * To define a string conversion for an enum type, derive a @c string_traits + * specialisation for the enum from this struct. + * + * There's usually an easier way though: the @c PQXX_DECLARE_ENUM_CONVERSION + * macro. Use @c enum_traits manually only if you need to customise your + * traits type in more detail. + */ +template struct enum_traits +{ + using impl_type = std::underlying_type_t; + using impl_traits = string_traits; + + [[nodiscard]] static constexpr zview + to_buf(char *begin, char *end, ENUM const &value) + { + return impl_traits::to_buf(begin, end, to_underlying(value)); + } + + static constexpr char *into_buf(char *begin, char *end, ENUM const &value) + { + return impl_traits::into_buf(begin, end, to_underlying(value)); + } + + [[nodiscard]] static ENUM from_string(std::string_view text) + { + return static_cast(impl_traits::from_string(text)); + } + + [[nodiscard]] static std::size_t size_buffer(ENUM const &value) noexcept + { + return impl_traits::size_buffer(to_underlying(value)); + } + +private: + // C++23: Replace with std::to_underlying. + static constexpr impl_type to_underlying(ENUM const &value) noexcept + { + return static_cast(value); + } +}; +} // namespace pqxx::internal + + +/// Macro: Define a string conversion for an enum type. +/** This specialises the @c pqxx::string_traits template, so use it in the + * @c ::pqxx namespace. + * + * For example: + * + * #include + * #include + * enum X { xa, xb }; + * namespace pqxx { PQXX_DECLARE_ENUM_CONVERSION(x); } + * int main() { std::cout << pqxx::to_string(xa) << std::endl; } + */ +#define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \ + template<> struct string_traits : pqxx::internal::enum_traits \ + {}; \ + template<> inline std::string const type_name { #ENUM } + + +namespace pqxx +{ +/// Parse a value in postgres' text format as a TYPE. +/** If the form of the value found in the string does not match the expected + * type, e.g. if a decimal point is found when converting to an integer type, + * the conversion fails. Overflows (e.g. converting "9999999999" to a 16-bit + * C++ type) are also treated as errors. If in some cases this behaviour + * should be inappropriate, convert to something bigger such as @c long @c int + * first and then truncate the resulting value. + * + * Only the simplest possible conversions are supported. Fancy features like + * hexadecimal or octal, spurious signs, or exponent notation won't work. + * Whitespace is not stripped away. Only the kinds of strings that come out of + * PostgreSQL and out of to_string() can be converted. + */ +template +[[nodiscard]] inline TYPE from_string(std::string_view text) +{ + return string_traits::from_string(text); +} + + +/// "Convert" a std::string_view to a std::string_view. +/** Just returns its input. + * + * @warning Of course the result is only valid for as long as the original + * string remains valid! Never access the string referenced by the return + * value after the original has been destroyed. + */ +template<> +[[nodiscard]] inline std::string_view from_string(std::string_view text) +{ + return text; +} + + +/// Attempt to convert postgres-generated string to given built-in object. +/** This is like the single-argument form of the function, except instead of + * returning the value, it sets @c value. + * + * You may find this more convenient in that it infers the type you want from + * the argument you pass. But there are disadvantages: it requires an + * assignment operator, and it may be less efficient. + */ +template inline void from_string(std::string_view text, T &value) +{ + value = from_string(text); +} + + +/// Convert a value to a readable string that PostgreSQL will understand. +/** The conversion does no special formatting, and ignores any locale settings. + * The resulting string will be human-readable and in a format suitable for use + * in SQL queries. It won't have niceties such as "thousands separators" + * though. + */ +template inline std::string to_string(TYPE const &value); + + +/// Convert multiple values to strings inside a single buffer. +/** There must be enough room for all values, or this will throw + * @c conversion_overrun. You can obtain a conservative estimate of the buffer + * space required by calling @c size_buffer() on the values. + * + * The @c std::string_view results may point into the buffer, so don't assume + * that they will remain valid after you destruct or move the buffer. + */ +template +[[nodiscard]] inline std::vector +to_buf(char *here, char const *end, TYPE... value) +{ + return {[&here, end](auto v) { + auto begin = here; + here = string_traits::into_buf(begin, end, v); + // Exclude the trailing zero out of the string_view. + auto len{static_cast(here - begin) - 1}; + return std::string_view{begin, len}; + }(value)...}; +} + +/// Convert a value to a readable string that PostgreSQL will understand. +/** This variant of to_string can sometimes save a bit of time in loops, by + * re-using a std::string for multiple conversions. + */ +template +inline void into_string(TYPE const &value, std::string &out); + + +/// Is @c value null? +template +[[nodiscard]] inline constexpr bool is_null(TYPE const &value) noexcept +{ + return nullness>::is_null(value); +} + + +/// Estimate how much buffer space is needed to represent values as a string. +/** The estimate may be a little pessimistic, if it saves time. It also + * includes room for a terminating zero after each value. + */ +template +[[nodiscard]] inline std::size_t size_buffer(TYPE const &...value) noexcept +{ + return (string_traits>::size_buffer(value) + ...); +} + + +/// Does this type translate to an SQL array? +/** Specialisations may override this to be true for container types. + * + * This may not always be a black-and-white choice. For instance, a + * @c std::string is a container, but normally it translates to an SQL string, + * not an SQL array. + */ +template inline constexpr bool is_sql_array{false}; + + +/// Can we use this type in arrays and composite types without quoting them? +/** Define this as @c true only if values of @c TYPE can never contain any + * special characters that might need escaping or confuse the parsing of array + * or composite * types, such as commas, quotes, parentheses, braces, newlines, + * and so on. + * + * When converting a value of such a type to a string in an array or a field in + * a composite type, we do not need to add quotes, nor escape any special + * characters. + * + * This is just an optimisation, so it defaults to @c false to err on the side + * of slow correctness. + */ +template inline constexpr bool is_unquoted_safe{false}; + + +/// Element separator between SQL array elements of this type. +template inline constexpr char array_separator{','}; + + +/// What's the preferred format for passing non-null parameters of this type? +/** This affects how we pass parameters of @c TYPE when calling parameterised + * statements or prepared statements. + * + * Generally we pass parameters in text format, but binary strings are the + * exception. We also pass nulls in binary format, so this function need not + * handle null values. + */ +template inline constexpr format param_format(TYPE const &) +{ + return format::text; +} + + +/// Implement @c string_traits::to_buf by calling @c into_buf. +/** When you specialise @c string_traits for a new type, most of the time its + * @c to_buf implementation has no special optimisation tricks and just writes + * its text into the buffer it receives from the caller, starting at the + * beginning. + * + * In that common situation, you can implement @c to_buf as just a call to + * @c generic_to_buf. It will call @c into_buf and return the right result for + * @c to_buf. + */ +template +inline zview generic_to_buf(char *begin, char *end, TYPE const &value) +{ + using traits = string_traits; + // The trailing zero does not count towards the zview's size, so subtract 1 + // from the result we get from into_buf(). + if (is_null(value)) + return {}; + else + return {begin, traits::into_buf(begin, end, value) - begin - 1}; +} + + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: Binary string, akin to @c std::string for binary data. +/** Any type that satisfies this concept can represent an SQL BYTEA value. + * + * A @c binary has a @c begin(), @c end(), @c size(), and @data(). Each byte + * is a @c std::byte, and they must all be laid out contiguously in memory so + * we can reference them by a pointer. + */ +template +concept binary = std::ranges::contiguous_range and + std::is_same_v>, std::byte>; +#endif +//@} +} // namespace pqxx + + +#include "pqxx/internal/conversions.hxx" +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_from b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_from new file mode 100644 index 000000000..972762443 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_from @@ -0,0 +1,8 @@ +/** pqxx::stream_from class. + * + * pqxx::stream_from enables optimized batch reads from a database table. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_from.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_from.hxx new file mode 100644 index 000000000..ff4a93d2e --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_from.hxx @@ -0,0 +1,361 @@ +/* Definition of the pqxx::stream_from class. + * + * pqxx::stream_from enables optimized batch reads from a database table. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_from instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_FROM +#define PQXX_H_STREAM_FROM + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/connection.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/internal/stream_iterator.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/transaction_focus.hxx" + + +namespace pqxx +{ +class transaction_base; + + +/// Pass this to a `stream_from` constructor to stream table contents. +/** @deprecated Use @ref stream_from::table() instead. + */ +constexpr from_table_t from_table; +/// Pass this to a `stream_from` constructor to stream query results. +/** @deprecated Use stream_from::query() instead. + */ +constexpr from_query_t from_query; + + +/// Stream data from the database. +/** For larger data sets, retrieving data this way is likely to be faster than + * executing a query and then iterating and converting the rows fields. You + * will also be able to start processing before all of the data has come in. + * + * There are also downsides. Not all kinds of query will work in a stream. + * But straightforward `SELECT` and `UPDATE ... RETURNING` queries should work. + * This function makes use of @ref pqxx::stream_from, which in turn uses + * PostgreSQL's `COPY` command, so see the documentation for those to get the + * full details. + * + * There are other downsides. If there stream encounters an error, it may + * leave the entire connection in an unusable state, so you'll have to give the + * whole thing up. Finally, opening a stream puts the connection in a special + * state, so you won't be able to do many other things with the connection or + * the transaction while the stream is open. + * + * There are two ways of starting a stream: you stream either all rows in a + * table (using one of the factories, `table()` or `raw_table()`), or the + * results of a query (using the `query()` factory). + * + * Usually you'll want the `stream` convenience wrapper in + * @ref transaction_base, * so you don't need to deal with this class directly. + * + * @warning While a stream is active, you cannot execute queries, open a + * pipeline, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT stream_from : transaction_focus +{ +public: + using raw_line = + std::pair>, std::size_t>; + + /// Factory: Execute query, and stream the results. + /** The query can be a SELECT query or a VALUES query; or it can be an + * UPDATE, INSERT, or DELETE with a RETURNING clause. + * + * The query is executed as part of a COPY statement, so there are additional + * restrictions on what kind of query you can use here. See the PostgreSQL + * documentation for the COPY command: + * + * https://www.postgresql.org/docs/current/sql-copy.html + */ + static stream_from query(transaction_base &tx, std::string_view q) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return {tx, from_query, q}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /** + * @name Streaming data from tables + * + * You can use `stream_from` to read a table's contents. This is a quick + * and easy way to read a table, but it comes with limitations. It cannot + * stream from a view, only from a table. It does not support conditions. + * And there are no guarantees about ordering. If you need any of those + * things, consider streaming from a query instead. + */ + //@{ + + /// Factory: Stream data from a pre-quoted table and columns. + /** Use this factory if you need to create multiple streams using the same + * table path and/or columns list, and you want to save a bit of work on + * composing the internal SQL statement for starting the stream. It lets you + * compose the string representations for the table path and the columns + * list, so you can compute these once and then re-use them later. + * + * @param tx The transaction within which the stream will operate. + * @param path Name or path for the table upon which the stream will + * operate. If any part of the table path may contain special + * characters or be case-sensitive, quote the path using + * pqxx::connection::quote_table(). + * @param columns Columns which the stream will read. They should be + * comma-separated and, if needed, quoted. You can produce the string + * using pqxx::connection::quote_columns(). If you omit this argument, + * the stream will read all columns in the table, in schema order. + */ + static stream_from raw_table( + transaction_base &tx, std::string_view path, + std::string_view columns = ""sv); + + /// Factory: Stream data from a given table. + /** This is the convenient way to stream from a table. + */ + static stream_from table( + transaction_base &tx, table_path path, + std::initializer_list columns = {}); + //@} + + /// Execute query, and stream over the results. + /** @deprecated Use factory function @ref query instead. + */ + [[deprecated("Use query() factory instead.")]] stream_from( + transaction_base &, from_query_t, std::string_view query); + + /// Stream all rows in table, all columns. + /** @deprecated Use factories @ref table or @ref raw_table instead. + */ + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &, from_table_t, std::string_view table); + + /// Stream given columns from all rows in table. + /** @deprecated Use factories @ref table or @ref raw_table instead. + */ + template + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &, from_table_t, std::string_view table, + Iter columns_begin, Iter columns_end); + + /// Stream given columns from all rows in table. + /** @deprecated Use factory function @ref query instead. + */ + template + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &tx, from_table_t, std::string_view table, + Columns const &columns); + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// @deprecated Use factories @ref table or @ref raw_table instead. + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &tx, std::string_view table) : + stream_from{tx, from_table, table} + {} +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// @deprecated Use factories @ref table or @ref raw_table instead. + template + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &tx, std::string_view table, Columns const &columns) : + stream_from{tx, from_table, table, columns} + {} + + /// @deprecated Use factories @ref table or @ref raw_table instead. + template + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &, std::string_view table, Iter columns_begin, + Iter columns_end); + + ~stream_from() noexcept; + + /// May this stream still produce more data? + [[nodiscard]] constexpr operator bool() const noexcept + { + return not m_finished; + } + /// Has this stream produced all the data it is going to produce? + [[nodiscard]] constexpr bool operator!() const noexcept + { + return m_finished; + } + + /// Finish this stream. Call this before continuing to use the connection. + /** Consumes all remaining lines, and closes the stream. + * + * This may take a while if you're abandoning the stream before it's done, so + * skip it in error scenarios where you're not planning to use the connection + * again afterwards. + */ + void complete(); + + /// Read one row into a tuple. + /** Converts the row's fields into the fields making up the tuple. + * + * For a column which can contain nulls, be sure to give the corresponding + * tuple field a type which can be null. For example, to read a field as + * `int` when it may contain nulls, read it as `std::optional`. + * Using `std::shared_ptr` or `std::unique_ptr` will also work. + */ + template stream_from &operator>>(Tuple &); + + /// Doing this with a `std::variant` is going to be horrifically borked. + template + stream_from &operator>>(std::variant &) = delete; + + /// Iterate over this stream. Supports range-based "for" loops. + /** Produces an input iterator over the stream. + * + * Do not call this yourself. Use it like "for (auto data : stream.iter())". + */ + template [[nodiscard]] auto iter() & + { + return pqxx::internal::stream_input_iteration{*this}; + } + + /// Read a row. Return fields as views, valid until you read the next row. + /** Returns `nullptr` when there are no more rows to read. Do not attempt + * to read any further rows after that. + * + * Do not access the vector, or the storage referenced by the views, after + * closing or completing the stream, or after attempting to read a next row. + * + * A @ref pqxx::zview is like a `std::string_view`, but with the added + * guarantee that if its data pointer is non-null, the string is followed by + * a terminating zero (which falls just outside the view itself). + * + * If any of the views' data pointer is null, that means that the + * corresponding SQL field is null. + * + * @warning The return type may change in the future, to support C++20 + * coroutine-based usage. + */ + std::vector const *read_row() &; + + /// Read a raw line of text from the COPY command. + /** @warning Do not use this unless you really know what you're doing. */ + raw_line get_raw_line(); + +private: + // TODO: Clean up this signature once we cull the deprecated constructors. + /// @deprecated + stream_from( + transaction_base &tx, std::string_view table, std::string_view columns, + from_table_t); + + // TODO: Clean up this signature once we cull the deprecated constructors. + /// @deprecated + stream_from( + transaction_base &, std::string_view unquoted_table, + std::string_view columns, from_table_t, int); + + template + void extract_fields(Tuple &t, std::index_sequence) const + { + (extract_value(t), ...); + } + + pqxx::internal::glyph_scanner_func *m_glyph_scanner; + + /// Current row's fields' text, combined into one reusable string. + std::string m_row; + + /// The current row's fields. + std::vector m_fields; + + bool m_finished = false; + + void close(); + + template + void extract_value(Tuple &) const; + + /// Read a line of COPY data, write `m_row` and `m_fields`. + void parse_line(); +}; + + +template +inline stream_from::stream_from( + transaction_base &tx, from_table_t, std::string_view table_name, + Columns const &columns) : + stream_from{ + tx, from_table, table_name, std::begin(columns), std::end(columns)} +{} + + +template +inline stream_from::stream_from( + transaction_base &tx, from_table_t, std::string_view table, + Iter columns_begin, Iter columns_end) : + stream_from{ + tx, table, separated_list(",", columns_begin, columns_end), + from_table, 1} +{} + + +template inline stream_from &stream_from::operator>>(Tuple &t) +{ + if (m_finished) + return *this; + static constexpr auto tup_size{std::tuple_size_v}; + m_fields.reserve(tup_size); + parse_line(); + if (m_finished) + return *this; + + if (std::size(m_fields) != tup_size) + throw usage_error{internal::concat( + "Tried to extract ", tup_size, " field(s) from a stream of ", + std::size(m_fields), ".")}; + + extract_fields(t, std::make_index_sequence{}); + return *this; +} + + +template +inline void stream_from::extract_value(Tuple &t) const +{ + using field_type = strip_t(t))>; + using nullity = nullness; + assert(index < std::size(m_fields)); + if constexpr (nullity::always_null) + { + if (std::data(m_fields[index]) != nullptr) + throw conversion_error{"Streaming non-null value into null field."}; + } + else if (std::data(m_fields[index]) == nullptr) + { + if constexpr (nullity::has_null) + std::get(t) = nullity::null(); + else + internal::throw_null_conversion(type_name); + } + else + { + // Don't ever try to convert a non-null value to nullptr_t! + std::get(t) = from_string(m_fields[index]); + } +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_to b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_to new file mode 100644 index 000000000..8760cf1f4 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_to @@ -0,0 +1,8 @@ +/** pqxx::stream_to class. + * + * pqxx::stream_to enables optimized batch updates to a database table. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/stream_to.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_to.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_to.hxx new file mode 100644 index 000000000..2a49d8f85 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/stream_to.hxx @@ -0,0 +1,455 @@ +/* Definition of the pqxx::stream_to class. + * + * pqxx::stream_to enables optimized batch updates to a database table. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_to.hxx instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_TO +#define PQXX_H_STREAM_TO + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/separated_list.hxx" +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +/// Efficiently write data directly to a database table. +/** If you wish to insert rows of data into a table, you can compose INSERT + * statements and execute them. But it's slow and tedious, and you need to + * worry about quoting and escaping the data. + * + * If you're just inserting a single row, it probably won't matter much. You + * can use prepared or parameterised statements to take care of the escaping + * for you. But if you're inserting large numbers of rows you will want + * something better. + * + * Inserting rows one by one using INSERT statements involves a lot of + * pointless overhead, especially when you are working with a remote database + * server over the network. You may end up sending each row over the network + * as a separate query, and waiting for a reply. Do it "in bulk" using + * `stream_to`, and you may find that it goes many times faster. Sometimes + * you gain orders of magnitude in speed. + * + * Here's how it works: you create a `stream_to` stream to start writing to + * your table. You will probably want to specify the columns. Then, you + * feed your data into the stream one row at a time. And finally, you call the + * stream's @ref complete function to tell it to finalise the operation, wait + * for completion, and check for errors. + * + * (You _must_ complete the stream before committing or aborting the + * transaction. The connection is in a special state while the stream is + * active, where it can't process commands, and can't commit or abort a + * transaction.) + * + * So how do you feed a row of data into the stream? There's several ways, but + * the preferred one is to call its @ref write_values. Pass the field values + * as arguments. Doesn't matter what type they are, as long as libpqxx knows + * how to convert them to PostgreSQL's text format: `int`, `std::string` or + * `std:string_view`, `float` and `double`, `bool`... lots of basic types + * are supported. If some of the values are null, feel free to use + * `std::optional`, `std::shared_ptr`, or `std::unique_ptr`. + * + * The arguments' types don't even have to match the fields' SQL types. If you + * want to insert an `int` into a `DECIMAL` column, that's your choice -- it + * will produce a `DECIMAL` value which happens to be integral. Insert a + * `float` into a `VARCHAR` column? That's fine, you'll get a string whose + * contents happen to read like a number. And so on. You can even insert + * different types of value in the same column on different rows. If you have + * a code path where a particular field is always null, just insert `nullptr`. + * + * There is another way to insert rows: the `<<` ("shift-left") operator. + * It's not as fast and it doesn't support variable arguments: each row must be + * either a `std::tuple` or something iterable, such as a `std::vector`, or + * anything else with a `begin()` and `end()`. + * + * @warning While a stream is active, you cannot execute queries, open a + * pipeline, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT stream_to : transaction_focus +{ +public: + /// Stream data to a pre-quoted table and columns. + /** This factory can be useful when it's not convenient to provide the + * columns list in the form of a `std::initializer_list`, or when the list + * of columns is simply not known at compile time. + * + * Also use this if you need to create multiple streams using the same table + * path and/or columns list, and you want to save a bit of work on composing + * the internal SQL statement for starting the stream. It lets you compose + * the string representations for the table path and the columns list, so you + * can compute these once and then re-use them later. + * + * @param tx The transaction within which the stream will operate. + * @param path Name or path for the table upon which the stream will + * operate. If any part of the table path may contain special + * characters or be case-sensitive, quote the path using + * pqxx::connection::quote_table(). + * @param columns Columns to which the stream will write. They should be + * comma-separated and, if needed, quoted. You can produce the string + * using pqxx::connection::quote_columns(). If you omit this argument, + * the stream will write all columns in the table, in schema order. + */ + static stream_to raw_table( + transaction_base &tx, std::string_view path, std::string_view columns = "") + { + return {tx, path, columns}; + } + + /// Create a `stream_to` writing to a named table and columns. + /** Use this to stream data to a table, where the list of columns is known at + * compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns Optionally, the columns to which the stream should write. + * If you do not pass this, the stream will write to all columns in the + * table, in schema order. + */ + static stream_to table( + transaction_base &tx, table_path path, + std::initializer_list columns = {}) + { + auto const &conn{tx.conn()}; + return raw_table(tx, conn.quote_table(path), conn.quote_columns(columns)); + } + +#if defined(PQXX_HAVE_CONCEPTS) + /// Create a `stream_to` writing to a named table and columns. + /** Use this version to stream data to a table, when the list of columns is + * not known at compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns The columns to which the stream should write. + */ + template + static stream_to + table(transaction_base &tx, table_path path, COLUMNS const &columns) + { + auto const &conn{tx.conn()}; + return stream_to::raw_table( + tx, conn.quote_table(path), tx.conn().quote_columns(columns)); + } + + /// Create a `stream_to` writing to a named table and columns. + /** Use this version to stream data to a table, when the list of columns is + * not known at compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns The columns to which the stream should write. + */ + template + static stream_to + table(transaction_base &tx, std::string_view path, COLUMNS const &columns) + { + return stream_to::raw_table(tx, path, tx.conn().quote_columns(columns)); + } +#endif // PQXX_HAVE_CONCEPTS + + /// Create a stream, without specifying columns. + /** @deprecated Use @ref table or @ref raw_table as a factory. + * + * Fields will be inserted in whatever order the columns have in the + * database. + * + * You'll probably want to specify the columns, so that the mapping between + * your data fields and the table is explicit in your code, and not hidden + * in an "implicit contract" between your code and your schema. + */ + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &tx, std::string_view table_name) : + stream_to{tx, table_name, ""sv} + {} + + /// Create a stream, specifying column names as a container of strings. + /** @deprecated Use @ref table or @ref raw_table as a factory. + */ + template + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &, std::string_view table_name, Columns const &columns); + + /// Create a stream, specifying column names as a sequence of strings. + /** @deprecated Use @ref table or @ref raw_table as a factory. + */ + template + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &, std::string_view table_name, Iter columns_begin, + Iter columns_end); + + ~stream_to() noexcept; + + /// Does this stream still need to @ref complete()? + [[nodiscard]] constexpr operator bool() const noexcept + { + return not m_finished; + } + /// Has this stream been through its concluding @c complete()? + [[nodiscard]] constexpr bool operator!() const noexcept + { + return m_finished; + } + + /// Complete the operation, and check for errors. + /** Always call this to close the stream in an orderly fashion, even after + * an error. (In the case of an error, abort the transaction afterwards.) + * + * The only circumstance where it's safe to skip this is after an error, if + * you're discarding the entire connection. + */ + void complete(); + + /// Insert a row of data. + /** Returns a reference to the stream, so you can chain the calls. + * + * The @c row can be a tuple, or any type that can be iterated. Each + * item becomes a field in the row, in the same order as the columns you + * specified when creating the stream. + * + * If you don't already happen to have your fields in the form of a tuple or + * container, prefer @c write_values. It's faster and more convenient. + */ + template stream_to &operator<<(Row const &row) + { + write_row(row); + return *this; + } + + /// Stream a `stream_from` straight into a `stream_to`. + /** This can be useful when copying between different databases. If the + * source and the destination are on the same database, you'll get better + * performance doing it all in a regular query. + */ + stream_to &operator<<(stream_from &); + + /// Insert a row of data, given in the form of a @c std::tuple or container. + /** The @c row can be a tuple, or any type that can be iterated. Each + * item becomes a field in the row, in the same order as the columns you + * specified when creating the stream. + * + * The preferred way to insert a row is @c write_values. + */ + template void write_row(Row const &row) + { + fill_buffer(row); + write_buffer(); + } + + /// Insert values as a row. + /** This is the recommended way of inserting data. Pass your field values, + * of any convertible type. + */ + template void write_values(Ts const &...fields) + { + fill_buffer(fields...); + write_buffer(); + } + +private: + /// Stream a pre-quoted table name and columns list. + stream_to( + transaction_base &tx, std::string_view path, std::string_view columns); + + bool m_finished = false; + + /// Reusable buffer for a row. Saves doing an allocation for each row. + std::string m_buffer; + + /// Reusable buffer for converting/escaping a field. + std::string m_field_buf; + + /// Glyph scanner, for parsing the client encoding. + internal::glyph_scanner_func *m_scanner; + + /// Write a row of raw text-format data into the destination table. + void write_raw_line(std::string_view); + + /// Write a row of data from @c m_buffer into the destination table. + /** Resets the buffer for the next row. + */ + void write_buffer(); + + /// COPY encoding for a null field, plus subsequent separator. + static constexpr std::string_view null_field{"\\N\t"}; + + /// Estimate buffer space needed for a field which is always null. + template + static std::enable_if_t::always_null, std::size_t> + estimate_buffer(T const &) + { + return std::size(null_field); + } + + /// Estimate buffer space needed for field f. + /** The estimate is not very precise. We don't actually know how much space + * we'll need once the escaping comes in. + */ + template + static std::enable_if_t::always_null, std::size_t> + estimate_buffer(T const &field) + { + return is_null(field) ? std::size(null_field) : size_buffer(field); + } + + /// Append escaped version of @c data to @c m_buffer, plus a tab. + void escape_field_to_buffer(std::string_view data); + + /// Append string representation for @c f to @c m_buffer. + /** This is for the general case, where the field may contain a value. + * + * Also appends a tab. The tab is meant to be a separator, not a terminator, + * so if you write any fields at all, you'll end up with one tab too many + * at the end of the buffer. + */ + template + std::enable_if_t::always_null> + append_to_buffer(Field const &f) + { + // We append each field, terminated by a tab. That will leave us with + // one tab too many, assuming we write any fields at all; we remove that + // at the end. + if (is_null(f)) + { + // Easy. Append null and tab in one go. + m_buffer.append(null_field); + } + else + { + // Convert f into m_buffer. + + using traits = string_traits; + auto const budget{estimate_buffer(f)}; + auto const offset{std::size(m_buffer)}; + + if constexpr (std::is_arithmetic_v) + { + // Specially optimised for "safe" types, which never need any + // escaping. Convert straight into m_buffer. + + // The budget we get from size_buffer() includes room for the trailing + // zero, which we must remove. But we're also inserting tabs between + // fields, so we re-purpose the extra byte for that. + auto const total{offset + budget}; + m_buffer.resize(total); + auto const data{m_buffer.data()}; + char *const end{traits::into_buf(data + offset, data + total, f)}; + *(end - 1) = '\t'; + // Shrink to fit. Keep the tab though. + m_buffer.resize(static_cast(end - data)); + } + else if constexpr ( + std::is_same_v or + std::is_same_v or + std::is_same_v) + { + // This string may need escaping. + m_field_buf.resize(budget); + escape_field_to_buffer(f); + } + else + { + // This field needs to be converted to a string, and after that, + // escaped as well. + m_field_buf.resize(budget); + auto const data{m_field_buf.data()}; + escape_field_to_buffer( + traits::to_buf(data, data + std::size(m_field_buf), f)); + } + } + } + + /// Append string representation for a null field to @c m_buffer. + /** This special case is for types which are always null. + * + * Also appends a tab. The tab is meant to be a separator, not a terminator, + * so if you write any fields at all, you'll end up with one tab too many + * at the end of the buffer. + */ + template + std::enable_if_t::always_null> + append_to_buffer(Field const &) + { + m_buffer.append(null_field); + } + + /// Write raw COPY line into @c m_buffer, based on a container of fields. + template + std::enable_if_t> + fill_buffer(Container const &c) + { + // To avoid unnecessary allocations and deallocations, we run through c + // twice: once to determine how much buffer space we may need, and once to + // actually write it into the buffer. + std::size_t budget{0}; + for (auto const &f : c) budget += estimate_buffer(f); + m_buffer.reserve(budget); + for (auto const &f : c) append_to_buffer(f); + } + + /// Estimate how many buffer bytes we need to write tuple. + template + static std::size_t + budget_tuple(Tuple const &t, std::index_sequence) + { + return (estimate_buffer(std::get(t)) + ...); + } + + /// Write tuple of fields to @c m_buffer. + template + void append_tuple(Tuple const &t, std::index_sequence) + { + (append_to_buffer(std::get(t)), ...); + } + + /// Write raw COPY line into @c m_buffer, based on a tuple of fields. + template void fill_buffer(std::tuple const &t) + { + using indexes = std::make_index_sequence; + + m_buffer.reserve(budget_tuple(t, indexes{})); + append_tuple(t, indexes{}); + } + + /// Write raw COPY line into @c m_buffer, based on varargs fields. + template void fill_buffer(const Ts &...fields) + { + (..., append_to_buffer(fields)); + } + + constexpr static std::string_view s_classname{"stream_to"}; +}; + + +template +inline stream_to::stream_to( + transaction_base &tx, std::string_view table_name, Columns const &columns) : + stream_to{tx, table_name, std::begin(columns), std::end(columns)} +{} + + +template +inline stream_to::stream_to( + transaction_base &tx, std::string_view table_name, Iter columns_begin, + Iter columns_end) : + stream_to{ + tx, + tx.quote_name( + table_name, + separated_list(",", columns_begin, columns_end, [&tx](auto col) { + return tx.quote_name(*col); + }))} +{} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/subtransaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/subtransaction new file mode 100644 index 000000000..e0d154903 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/subtransaction @@ -0,0 +1,8 @@ +/** pqxx::subtransaction class. + * + * pqxx::subtransaction is a nested transaction, i.e. one inside a transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/subtransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/subtransaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/subtransaction.hxx new file mode 100644 index 000000000..e66b7a7a8 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/subtransaction.hxx @@ -0,0 +1,96 @@ +/* Definition of the pqxx::subtransaction class. + * + * pqxx::subtransaction is a nested transaction, i.e. one within a transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/subtransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SUBTRANSACTION +#define PQXX_H_SUBTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx +{ +/** + * @ingroup transactions + */ +/// "Transaction" nested within another transaction +/** A subtransaction can be executed inside a backend transaction, or inside + * another subtransaction. This can be useful when, for example, statements in + * a transaction may harmlessly fail and you don't want them to abort the + * entire transaction. Here's an example of how a temporary table may be + * dropped before re-creating it, without failing if the table did not exist: + * + * ```cxx + * void do_job(connection &C) + * { + * string const temptable = "fleetingtable"; + * + * work W(C, "do_job"); + * do_firstpart(W); + * + * // Attempt to delete our temporary table if it already existed. + * try + * { + * subtransaction S(W, "droptemp"); + * S.exec0("DROP TABLE " + temptable); + * S.commit(); + * } + * catch (undefined_table const &) + * { + * // Table did not exist. Which is what we were hoping to achieve anyway. + * // Carry on without regrets. + * } + * + * // S may have gone into a failed state and been destroyed, but the + * // upper-level transaction W is still fine. We can continue to use it. + * W.exec0("CREATE TEMP TABLE " + temptable + "(bar integer, splat + * varchar)"); + * + * do_lastpart(W); + * } + * ``` + * + * (This is just an example. If you really wanted to do drop a table without + * an error if it doesn't exist, you'd use DROP TABLE IF EXISTS.) + * + * There are no isolation levels inside a transaction. They are not needed + * because all actions within the same backend transaction are always performed + * sequentially anyway. + * + * @warning While the subtransaction is "live," you cannot execute queries or + * open streams etc. on its parent transaction. A transaction can have at most + * one object of a type derived from @ref pqxx::transaction_focus active on it + * at a time. + */ +class PQXX_LIBEXPORT subtransaction : public transaction_focus, + public dbtransaction +{ +public: + /// Nest a subtransaction nested in another transaction. + explicit subtransaction(dbtransaction &t, std::string_view tname = ""sv); + + /// Nest a subtransaction in another subtransaction. + explicit subtransaction(subtransaction &t, std::string_view name = ""sv); + + virtual ~subtransaction() noexcept override; + +private: + std::string quoted_name() const + { + return quote_name(transaction_focus::name()); + } + virtual void do_commit() override; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/time b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/time new file mode 100644 index 000000000..85df05744 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/time @@ -0,0 +1,6 @@ +/** Date/time string conversions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/time.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/time.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/time.hxx new file mode 100644 index 000000000..effed05e0 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/time.hxx @@ -0,0 +1,88 @@ +/** Support for date/time values. + * + * At the moment this supports dates, but not times. + */ +#ifndef PQXX_H_TIME +#define PQXX_H_TIME + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/internal/concat.hxx" +#include "pqxx/strconv.hxx" + + +#if defined(PQXX_HAVE_YEAR_MONTH_DAY) + +namespace pqxx +{ +using namespace std::literals; + +template<> +struct nullness + : no_null +{}; + + +/// String representation for a Gregorian date in ISO-8601 format. +/** @warning Experimental. There may still be design problems, particularly + * when it comes to BC years. + * + * PostgreSQL supports a choice of date formats, but libpqxx does not. The + * other formats in turn support a choice of "month before day" versus "day + * before month," meaning that it's not necessarily known which format a given + * date is supposed to be. So I repeat: ISO-8601-style format only! + * + * Invalid dates will not convert. This includes February 29 on non-leap + * years, which is why it matters that `year_month_day` represents a + * _Gregorian_ date. + * + * The range of years is limited. At the time of writing, PostgreSQL 14 + * supports years from 4713 BC to 294276 AD inclusive, and C++20 supports + * a range of 32767 BC to 32767 AD inclusive. So in practice, years must fall + * between 4713 BC and 32767 AD, inclusive. + * + * @warning Support for BC (or BCE) years is still experimental. I still need + * confirmation on this issue: it looks as if C++ years are astronomical years, + * which means they have a Year Zero. Regular BC/AD years do not have a year + * zero, so the year 1 AD follows directly after 1 BC. + * + * So, what to our calendars (and to PostgreSQL) is the year "0001 BC" seems to + * count as year "0" in a `std::chrono::year_month_day`. The year 0001 AD is + * still equal to 1 as you'd expect, and all AD years work normally, but all + * years before then are shifted by one. For instance, the year 543 BC would + * be -542 in C++. + */ +template<> struct PQXX_LIBEXPORT string_traits +{ + [[nodiscard]] static zview + to_buf(char *begin, char *end, std::chrono::year_month_day const &value) + { + return generic_to_buf(begin, end, value); + } + + static char * + into_buf(char *begin, char *end, std::chrono::year_month_day const &value); + + [[nodiscard]] static std::chrono::year_month_day + from_string(std::string_view text); + + [[nodiscard]] static std::size_t + size_buffer(std::chrono::year_month_day const &) noexcept + { + static_assert(int{(std::chrono::year::min)()} >= -99999); + static_assert(int{(std::chrono::year::max)()} <= 99999); + return 5 + 1 + 2 + 1 + 2 + std::size(s_bc) + 1; + } + +private: + /// The "BC" suffix for years before 1 AD. + static constexpr std::string_view s_bc{" BC"sv}; +}; +} // namespace pqxx +#endif // PQXX_HAVE_YEAR_MONTH_DAY +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction new file mode 100644 index 000000000..a7ae39d43 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction @@ -0,0 +1,8 @@ +/** pqxx::transaction class. + * + * pqxx::transaction represents a standard database transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction.hxx new file mode 100644 index 000000000..e90917e38 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction.hxx @@ -0,0 +1,108 @@ +/* Definition of the pqxx::transaction class. + * pqxx::transaction represents a standard database transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION +#define PQXX_H_TRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx::internal +{ +/// Helper base class for the @ref transaction class template. +class PQXX_LIBEXPORT basic_transaction : public dbtransaction +{ +protected: + basic_transaction( + connection &c, zview begin_command, std::string_view tname); + basic_transaction(connection &c, zview begin_command, std::string &&tname); + basic_transaction(connection &c, zview begin_command); + + virtual ~basic_transaction() noexcept override = 0; + +private: + virtual void do_commit() override; +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @ingroup transactions + */ +//@{ + +/// Standard back-end transaction, templatised on isolation level. +/** This is the type you'll normally want to use to represent a transaction on + * the database. + * + * Usage example: double all wages. + * + * ```cxx + * extern connection C; + * work T(C); + * try + * { + * T.exec0("UPDATE employees SET wage=wage*2"); + * T.commit(); // NOTE: do this inside try block + * } + * catch (exception const &e) + * { + * cerr << e.what() << endl; + * T.abort(); // Usually not needed; same happens when T's life ends. + * } + * ``` + */ +template< + isolation_level ISOLATION = isolation_level::read_committed, + write_policy READWRITE = write_policy::read_write> +class transaction final : public internal::basic_transaction +{ +public: + /// Begin a transaction. + /** + * @param c Connection for this transaction to operate on. + * @param tname Optional name for transaction. Must begin with a letter and + * may contain letters and digits only. + */ + transaction(connection &c, std::string_view tname) : + internal::basic_transaction{ + c, internal::begin_cmd, tname} + {} + + /// Begin a transaction. + /** + * @param c Connection for this transaction to operate on. + * may contain letters and digits only. + */ + explicit transaction(connection &c) : + internal::basic_transaction{ + c, internal::begin_cmd} + {} + + virtual ~transaction() noexcept override { close(); } +}; + + +/// The default transaction type. +using work = transaction<>; + +/// Read-only transaction. +using read_transaction = + transaction; + +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_base b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_base new file mode 100644 index 000000000..c39219aac --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_base @@ -0,0 +1,9 @@ +/** Base for the transaction classes. + * + * pqxx::transaction_base defines the interface for any abstract class that + * represents a database transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transaction_base.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_base.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_base.hxx new file mode 100644 index 000000000..4363cc56a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_base.hxx @@ -0,0 +1,810 @@ +/* Common code and definitions for the transaction classes. + * + * pqxx::transaction_base defines the interface for any abstract class that + * represents a database transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction_base instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION_BASE +#define PQXX_H_TRANSACTION_BASE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +/* End-user programs need not include this file, unless they define their own + * transaction classes. This is not something the typical program should want + * to do. + * + * However, reading this file is worthwhile because it defines the public + * interface for the available transaction classes such as transaction and + * nontransaction. + */ + +#include "pqxx/connection.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/isolation.hxx" +#include "pqxx/result.hxx" +#include "pqxx/row.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/util.hxx" + +namespace pqxx::internal::gate +{ +class transaction_subtransaction; +class transaction_sql_cursor; +class transaction_stream_to; +class transaction_transaction_focus; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +using namespace std::literals; + + +class transaction_focus; + + +/** + * @defgroup transactions Transaction classes + * + * All database access goes through instances of these classes. + * However, not all implementations of this interface need to provide full + * transactional integrity. + * + * Several implementations of this interface are shipped with libpqxx, + * including the plain transaction class, the entirely unprotected + * nontransaction, and the more cautious robusttransaction. + */ + +/// Interface definition (and common code) for "transaction" classes. +/** + * @ingroup transactions + * + * Abstract base class for all transaction types. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base +{ +public: + transaction_base() = delete; + transaction_base(transaction_base const &) = delete; + transaction_base(transaction_base &&) = delete; + transaction_base &operator=(transaction_base const &) = delete; + transaction_base &operator=(transaction_base &&) = delete; + + virtual ~transaction_base() = 0; + + /// Commit the transaction. + /** Make the effects of this transaction definite. If you destroy a + * transaction without invoking its @ref commit() first, that will implicitly + * abort it. (For the @ref nontransaction class though, "commit" and "abort" + * really don't do anything, hence its name.) + * + * There is, however, a minute risk that you might lose your connection to + * the database at just the wrong moment here. In that case, libpqxx may be + * unable to determine whether the database was able to complete the + * transaction, or had to roll it back. In that scenario, @ref commit() will + * throw an in_doubt_error. There is a different transaction class called + * @ref robusttransaction which takes some special precautions to reduce this + * risk. + */ + void commit(); + + /// Abort the transaction. + /** No special effort is required to call this function; it will be called + * implicitly when the transaction is destructed. + */ + void abort(); + + /** + * @ingroup escaping-functions + * + * Use these when writing SQL queries that incorporate C++ values as SQL + * constants. + * + * The functions you see here are just convenience shortcuts to the same + * functions on the connection object. + */ + //@{ + /// Escape string for use as SQL string literal in this transaction. + template [[nodiscard]] auto esc(ARGS &&...args) const + { + return conn().esc(std::forward(args)...); + } + + /// Escape binary data for use as SQL string literal in this transaction. + /** Raw, binary data is treated differently from regular strings. Binary + * strings are never interpreted as text, so they may safely include byte + * values or byte sequences that don't happen to represent valid characters + * in the character encoding being used. + * + * The binary string does not stop at the first zero byte, as is the case + * with textual strings. Instead, it may contain zero bytes anywhere. If + * it happens to contain bytes that look like quote characters, or other + * things that can disrupt their use in SQL queries, they will be replaced + * with special escape sequences. + */ + template [[nodiscard]] auto esc_raw(ARGS &&...args) const + { + return conn().esc_raw(std::forward(args)...); + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(zview text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return conn().unesc_raw(text); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard]] std::basic_string unesc_bin(zview text) + { + return conn().unesc_bin(text); + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(char const *text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return conn().unesc_raw(text); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard]] std::basic_string unesc_bin(char const text[]) + { + return conn().unesc_bin(text); + } + + /// Represent object as SQL string, including quoting & escaping. + /** Nulls are recognized and represented as SQL nulls. */ + template [[nodiscard]] std::string quote(T const &t) const + { + return conn().quote(t); + } + + [[deprecated( + "Use std::basic_string instead of binarystring.")]] std::string + quote(binarystring const &t) const + { + return conn().quote(t.bytes_view()); + } + + /// Binary-escape and quote a binary string for use as an SQL constant. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(unsigned char const bin[], std::size_t len) const + { + return quote(binary_cast(bin, len)); + } + + /// Binary-escape and quote a binary string for use as an SQL constant. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(zview bin) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Binary-escape and quote a binary string for use as an SQL constant. + /** For binary data you can also just use @ref quote(data). */ + template + [[nodiscard]] std::string quote_raw(DATA const &data) const + { + return conn().quote_raw(data); + } +#endif + + /// Escape an SQL identifier for use in a query. + [[nodiscard]] std::string quote_name(std::string_view identifier) const + { + return conn().quote_name(identifier); + } + + /// Escape string for literal LIKE match. + [[nodiscard]] std::string + esc_like(std::string_view bin, char escape_char = '\\') const + { + return conn().esc_like(bin, escape_char); + } + //@} + + /** + * @name Command execution + * + * There are many functions for executing (or "performing") a command (or + * "query"). This is the most fundamental thing you can do with the library, + * and you always do it from a transaction class. + * + * Command execution can throw many types of exception, including sql_error, + * broken_connection, and many sql_error subtypes such as + * feature_not_supported or insufficient_privilege. But any exception thrown + * by the C++ standard library may also occur here. All exceptions you will + * see libpqxx throw are derived from std::exception. + * + * One unusual feature in libpqxx is that you can give your query a name or + * description. This does not mean anything to the database, but sometimes + * it can help libpqxx produce more helpful error messages, making problems + * in your code easier to debug. + * + * Many of the execution functions used to accept a `desc` argument, a + * human-readable description of the statement for use in error messages. + * This could make failures easier to debug. Future versions will use + * C++20's `std::source_location` to identify the failing statement. + */ + //@{ + + /// Execute a command. + /** + * @param query Query or command to execute. + * @param desc Optional identifier for query, to help pinpoint SQL errors. + * @return A result set describing the query's or command's result. + */ + [[deprecated("The desc parameter is going away.")]] result + exec(std::string_view query, std::string_view desc); + + /// Execute a command. + /** + * @param query Query or command to execute. + * @return A result set describing the query's or command's result. + */ + result exec(std::string_view query) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec(query, std::string_view{}); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute a command. + /** + * @param query Query or command to execute. + * @param desc Optional identifier for query, to help pinpoint SQL errors. + * @return A result set describing the query's or command's result. + */ + [[deprecated( + "Pass your query as a std::string_view, not stringstream.")]] result + exec(std::stringstream const &query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec(query.str(), desc); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command, which should return zero rows of data. + /** Works like @ref exec, but fails if the result contains data. It still + * returns a result, however, which may contain useful metadata. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] result + exec0(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(0, query, desc); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command, which should return zero rows of data. + /** Works like @ref exec, but fails if the result contains data. It still + * returns a result, however, which may contain useful metadata. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + result exec0(zview query) { return exec_n(0, query); } + + /// Execute command returning a single row of data. + /** Works like @ref exec, but requires the result to contain exactly one row. + * The row can be addressed directly, without the need to find the first row + * in a result set. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] row + exec1(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(1, query, desc).front(); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command returning a single row of data. + /** Works like @ref exec, but requires the result to contain exactly one row. + * The row can be addressed directly, without the need to find the first row + * in a result set. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + row exec1(zview query) { return exec_n(1, query).front(); } + + /// Execute command, expect given number of rows. + /** Works like @ref exec, but checks that the result has exactly the expected + * number of rows. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] result + exec_n(result::size_type rows, zview query, std::string_view desc); + + /// Execute command, expect given number of rows. + /** Works like @ref exec, but checks that the result has exactly the expected + * number of rows. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + result exec_n(result::size_type rows, zview query) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(rows, query, std::string_view{}); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Perform query, expecting exactly 1 row with 1 field, and convert it. + /** This is convenience shorthand for querying exactly one value from the + * database. It returns that value, converted to the type you specify. + */ + template + [[deprecated("The desc parameter is going away.")]] TYPE + query_value(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row const r{exec1(query, desc)}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + if (std::size(r) != 1) + throw usage_error{internal::concat( + "Queried single value from result with ", std::size(r), " columns.")}; + return r[0].as(); + } + + /// Perform query, expecting exactly 1 row with 1 field, and convert it. + /** This is convenience shorthand for querying exactly one value from the + * database. It returns that value, converted to the type you specify. + */ + template TYPE query_value(zview query) + { + row const r{exec1(query)}; + if (std::size(r) != 1) + throw usage_error{internal::concat( + "Queried single value from result with ", std::size(r), " columns.")}; + return r[0].as(); + } + + /// Execute a query, and loop over the results row by row. + /** Converts the rows to `std::tuple`, of the column types you specify. + * + * Use this with a range-based "for" loop. It executes the query, and + * directly maps the resulting rows onto a `std::tuple` of the types you + * specify. It starts before all the data from the server is in, so if your + * network connection to the server breaks while you're iterating, you'll get + * an exception partway through. + * + * The stream lives entirely within the lifetime of the transaction. Make + * sure you destroy the stream before you destroy the transaction. Either + * iterate the stream all the way to the end, or destroy first the stream + * and then the transaction without touching either in any other way. Until + * the stream has finished, the transaction is in a special state where it + * cannot execute queries. + * + * As a special case, tuple may contain `std::string_view` fields, but the + * strings to which they point will only remain valid until you extract the + * next row. After that, the memory holding the string may be overwritten or + * deallocated. + * + * If any of the columns can be null, and the C++ type to which it translates + * does not have a null value, wrap the type in `std::optional` (or if + * you prefer, `std::shared_ptr` or `std::unique_ptr)`. These templates + * do recognise null values, and libpqxx will know how to convert to them. + * + * The connection is in a special state until the iteration finishes. So if + * it does not finish due to a `break` or a `return` or an exception, then + * the entire connection becomes effectively unusable. + * + * Querying in this way is faster than the `exec()` methods for larger + * results (but slower for small ones). You can start processing rows before + * the full result is in. Also, `stream()` scales better in terms of memory + * usage. Where @ref exec() reads the entire result into memory at once, + * `stream()` will read and process one row at at a time. + * + * Your query executes as part of a COPY command, not as a stand-alone query, + * so there are limitations to what you can do in the query. It can be + * either a SELECT or VALUES query; or an INSERT, UPDATE, or DELETE with a + * RETURNING clause. See the documentation for PostgreSQL's COPY command for + * the details: + * + * https://www.postgresql.org/docs/current/sql-copy.html + * + * Iterating in this way does require each of the field types you pass to be + * default-constructible, copy-constructible, and assignable. These + * requirements may be loosened once libpqxx moves on to C++20. + */ + template + [[nodiscard]] auto stream(std::string_view query) & + { + // Tricky: std::make_unique() supports constructors but not RVO functions. + return pqxx::internal::owning_stream_input_iteration{ + std::unique_ptr{ + new stream_from{stream_from::query(*this, query)}}}; + } + + // C++20: Concept like std::invocable, but without specifying param types. + /// Perform a streaming query, and for each result row, call `func`. + /** Here, `func` can be a function, a `std::function`, a lambda, or an + * object that supports the function call operator. Of course `func` must + * have an unambiguous signature; it can't be overloaded or generic. + * + * The `for_each` function executes `query` in a stream using + * @ref pqxx::stream_from. Every time a row of data comes in from the + * server, it converts the row's fields to the types of `func`'s respective + * parameters, and calls `func` with those values. + * + * This will not work for all queries, but straightforward `SELECT` and + * `UPDATE ... RETURNING` queries should work. Consult the documentation for + * @ref pqxx::stream_from and PostgreSQL's underlying `COPY` command for the + * full details. + * + * Streaming a query like this is likely to be slower than the @ref exec() + * functions for small result sets, but faster for large result sets. So if + * performance matters, you'll want to use `for_each` if you query large + * amounts of data, but not if you do lots of queries with small outputs. + */ + template + inline auto for_each(std::string_view query, CALLABLE &&func) + { + using param_types = + pqxx::internal::strip_types_t>; + param_types const *const sample{nullptr}; + auto data_stream{stream_like(query, sample)}; + for (auto const &fields : data_stream) std::apply(func, fields); + } + + /** + * @name Parameterized statements + * + * You'll often need parameters in the queries you execute: "select the + * car with this licence plate." If the parameter is a string, you need to + * quote it and escape any special characters inside it, or it may become a + * target for an SQL injection attack. If it's an integer (for example), + * you need to convert it to a string, but in the database's format, without + * locale-specific niceties like "," separators between the thousands. + * + * Parameterised statements are an easier and safer way to do this. They're + * like prepared statements, but for a single use. You don't need to name + * them, and you don't need to prepare them first. + * + * Your query will include placeholders like `$1` and `$2` etc. in the places + * where you want the arguments to go. Then, you pass the argument values + * and the actual query is constructed for you. + * + * Pass the exact right number of parameters, and in the right order. The + * parameters in the query don't have to be neatly ordered from `$1` to + * `$2` to `$3` - but you must pass the argument for `$1` first, the one + * for `$2` second, etc. + * + * @warning Beware of "nul" bytes. Any string you pass as a parameter will + * end at the first char with value zero. If you pass a string that contains + * a zero byte, the last byte in the value will be the one just before the + * zero. + */ + //@{ + /// Execute an SQL statement with parameters. + template result exec_params(zview query, Args &&...args) + { + params pp(args...); + return internal_exec_params(query, pp.make_c_params()); + } + + // Execute parameterised statement, expect a single-row result. + /** @throw unexpected_rows if the result does not consist of exactly one row. + */ + template row exec_params1(zview query, Args &&...args) + { + return exec_params_n(1, query, std::forward(args)...).front(); + } + + // Execute parameterised statement, expect a result with zero rows. + /** @throw unexpected_rows if the result contains rows. + */ + template result exec_params0(zview query, Args &&...args) + { + return exec_params_n(0, query, std::forward(args)...); + } + + // Execute parameterised statement, expect exactly a given number of rows. + /** @throw unexpected_rows if the result contains the wrong number of rows. + */ + template + result exec_params_n(std::size_t rows, zview query, Args &&...args) + { + auto const r{exec_params(query, std::forward(args)...)}; + check_rowcount_params(rows, std::size(r)); + return r; + } + //@} + + /** + * @name Prepared statements + * + * These are very similar to parameterised statements. The difference is + * that you prepare them in advance, giving them identifying names. You can + * then call them by these names, passing in the argument values appropriate + * for that call. + * + * You prepare a statement on the connection, using + * @ref pqxx::connection::prepare(). But you then call the statement in a + * transaction, using the functions you see here. + * + * Never try to prepare, execute, or unprepare a prepared statement manually + * using direct SQL queries when you also use the libpqxx equivalents. For + * any given statement, either prepare, manage, and execute it through the + * dedicated libpqxx functions; or do it all directly in SQL. Don't mix the + * two, or the code may get confused. + * + * See \ref prepared for a full discussion. + * + * @warning Beware of "nul" bytes. Any string you pass as a parameter will + * end at the first char with value zero. If you pass a string that contains + * a zero byte, the last byte in the value will be the one just before the + * zero. If you need a zero byte, you're dealing with binary strings, not + * regular strings. Represent binary strings on the SQL side as `BYTEA` + * (or as large objects). On the C++ side, use types like + * `std::basic_string` or `std::basic_string_view` + * or (in C++20) `std::vector`. Also, consider large objects on + * the SQL side and @ref blob on the C++ side. + */ + //@{ + + /// Execute a prepared statement, with optional arguments. + template + result exec_prepared(zview statement, Args &&...args) + { + params pp(args...); + return internal_exec_prepared(statement, pp.make_c_params()); + } + + /// Execute a prepared statement, and expect a single-row result. + /** @throw pqxx::unexpected_rows if the result was not exactly 1 row. + */ + template + row exec_prepared1(zview statement, Args &&...args) + { + return exec_prepared_n(1, statement, std::forward(args)...).front(); + } + + /// Execute a prepared statement, and expect a result with zero rows. + /** @throw pqxx::unexpected_rows if the result contained rows. + */ + template + result exec_prepared0(zview statement, Args &&...args) + { + return exec_prepared_n(0, statement, std::forward(args)...); + } + + /// Execute a prepared statement, expect a result with given number of rows. + /** @throw pqxx::unexpected_rows if the result did not contain exactly the + * given number of rows. + */ + template + result + exec_prepared_n(result::size_type rows, zview statement, Args &&...args) + { + auto const r{exec_prepared(statement, std::forward(args)...)}; + check_rowcount_prepared(statement, rows, std::size(r)); + return r; + } + + //@} + + /** + * @name Error/warning output + */ + //@{ + /// Have connection process a warning message. + void process_notice(char const msg[]) const { m_conn.process_notice(msg); } + /// Have connection process a warning message. + void process_notice(zview msg) const { m_conn.process_notice(msg); } + //@} + + /// The connection in which this transaction lives. + [[nodiscard]] constexpr connection &conn() const noexcept { return m_conn; } + + /// Set session variable using SQL "SET" command. + /** @deprecated To set a transaction-local variable, execute an SQL `SET` + * command. To set a session variable, use the connection's + * @ref set_session_var function. + * + * @warning When setting a string value, you must make sure that the string + * is "safe." If you call @ref quote() on the string, it will return a + * safely escaped and quoted version for use as an SQL literal. + * + * @warning This function executes SQL. Do not try to set or get variables + * while a pipeline or table stream is active. + * + * @param var The variable to set. + * @param value The new value to store in the variable. This can be any SQL + * expression. + */ + [[deprecated( + "Set transaction-local variables using SQL SET statements.")]] void + set_variable(std::string_view var, std::string_view value); + + /// Read session variable using SQL "SHOW" command. + /** @warning This executes SQL. Do not try to set or get variables while a + * pipeline or table stream is active. + */ + [[deprecated("Read variables using SQL SHOW statements.")]] std::string + get_variable(std::string_view); + + // C++20: constexpr. + /// Transaction name, if you passed one to the constructor; or empty string. + [[nodiscard]] std::string_view name() const &noexcept { return m_name; } + +protected: + /// Create a transaction (to be called by implementation classes only). + /** The name, if nonempty, must begin with a letter and may contain letters + * and digits only. + */ + transaction_base( + connection &c, std::string_view tname, + std::shared_ptr rollback_cmd) : + m_conn{c}, m_name{tname}, m_rollback_cmd{rollback_cmd} + {} + + /// Create a transaction (to be called by implementation classes only). + /** Its rollback command will be "ROLLBACK". + * + * The name, if nonempty, must begin with a letter and may contain letters + * and digits only. + */ + transaction_base(connection &c, std::string_view tname); + + /// Create a transaction (to be called by implementation classes only). + explicit transaction_base(connection &c); + + /// Register this transaction with the connection. + void register_transaction(); + + /// End transaction. To be called by implementing class' destructor. + void close() noexcept; + + /// To be implemented by derived implementation class: commit transaction. + virtual void do_commit() = 0; + + /// Transaction type-specific way of aborting a transaction. + /** @warning This will become "final", since this function can be called + * from the implementing class destructor. + */ + virtual void do_abort(); + + /// Set the rollback command. + void set_rollback_cmd(std::shared_ptr cmd) + { + m_rollback_cmd = cmd; + } + + /// Execute query on connection directly. + result direct_exec(std::string_view, std::string_view desc = ""sv); + result + direct_exec(std::shared_ptr, std::string_view desc = ""sv); + +private: + enum class status + { + active, + aborted, + committed, + in_doubt + }; + + PQXX_PRIVATE void check_pending_error(); + + result + internal_exec_prepared(zview statement, internal::c_params const &args); + + result internal_exec_params(zview query, internal::c_params const &args); + + /// Throw unexpected_rows if prepared statement returned wrong no. of rows. + void check_rowcount_prepared( + zview statement, result::size_type expected_rows, + result::size_type actual_rows); + + /// Throw unexpected_rows if wrong row count from parameterised statement. + void + check_rowcount_params(std::size_t expected_rows, std::size_t actual_rows); + + /// Describe this transaction to humans, e.g. "transaction 'foo'". + [[nodiscard]] std::string description() const; + + friend class pqxx::internal::gate::transaction_transaction_focus; + PQXX_PRIVATE void register_focus(transaction_focus *); + PQXX_PRIVATE void unregister_focus(transaction_focus *) noexcept; + PQXX_PRIVATE void register_pending_error(zview) noexcept; + PQXX_PRIVATE void register_pending_error(std::string &&) noexcept; + + /// Like @ref stream(), but takes a tuple rather than a parameter pack. + template + auto stream_like(std::string_view query, std::tuple const *) + { + return stream(query); + } + + connection &m_conn; + + /// Current "focus": a pipeline, a nested transaction, a stream... + /** This pointer is used for only one purpose: sanity checks against mistakes + * such as opening one while another is still active. + */ + transaction_focus const *m_focus = nullptr; + + status m_status = status::active; + bool m_registered = false; + std::string m_name; + std::string m_pending_error; + + /// SQL command for aborting this type of transaction. + std::shared_ptr m_rollback_cmd; + + static constexpr std::string_view s_type_name{"transaction"sv}; +}; + + +// C++20: Can borrowed_range help? +/// Forbidden specialisation: underlying buffer immediately goes out of scope. +template<> +std::string_view transaction_base::query_value( + zview query, std::string_view desc) = delete; +/// Forbidden specialisation: underlying buffer immediately goes out of scope. +template<> +zview transaction_base::query_value( + zview query, std::string_view desc) = delete; + +} // namespace pqxx + + +namespace pqxx::internal +{ +/// The SQL command for starting a given type of transaction. +template +extern const zview begin_cmd; + +// These are not static members, so "constexpr" does not imply "inline". +template<> +inline constexpr zview begin_cmd{ + "BEGIN"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN READ ONLY"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL REPEATABLE READ"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL SERIALIZABLE"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY"_zv}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_focus b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_focus new file mode 100644 index 000000000..fe78a9bcc --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_focus @@ -0,0 +1,7 @@ +/** + * Transaction focus: types which monopolise a transaction's attention. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/types.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_focus.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_focus.hxx new file mode 100644 index 000000000..0707e3cc4 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transaction_focus.hxx @@ -0,0 +1,89 @@ +/** Transaction focus: types which monopolise a transaction's attention. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION_FOCUS +#define PQXX_H_TRANSACTION_FOCUS + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Base class for things that monopolise a transaction's attention. +/** You probably won't need to use this class. But it can be useful to _know_ + * that a given libpqxx class is derived from it. + * + * Pipelines, SQL statements, and data streams are examples of classes derived + * from `transaction_focus`. For any given transaction, only one object of + * such a class can be active at any given time. + */ +class PQXX_LIBEXPORT transaction_focus +{ +public: + transaction_focus( + transaction_base &t, std::string_view cname, std::string_view oname) : + m_trans{t}, m_classname{cname}, m_name{oname} + {} + + transaction_focus( + transaction_base &t, std::string_view cname, std::string &&oname) : + m_trans{t}, m_classname{cname}, m_name{std::move(oname)} + {} + + transaction_focus(transaction_base &t, std::string_view cname) : + m_trans{t}, m_classname{cname} + {} + + transaction_focus() = delete; + transaction_focus(transaction_focus const &) = delete; + transaction_focus &operator=(transaction_focus const &) = delete; + + /// Class name, for human consumption. + [[nodiscard]] constexpr std::string_view classname() const noexcept + { + return m_classname; + } + + /// Name for this object, if the caller passed one; empty string otherwise. + [[nodiscard]] std::string_view name() const &noexcept { return m_name; } + + [[nodiscard]] std::string description() const + { + return pqxx::internal::describe_object(m_classname, m_name); + } + + /// Can't move a transaction_focus. + /** Moving the transaction_focus would break the transaction's reference back + * to the object. + */ + transaction_focus(transaction_focus &&) = delete; + + /// Can't move a transaction_focus. + /** Moving the transaction_focus would break the transaction's reference back + * to the object. + */ + transaction_focus &operator=(transaction_focus &&) = delete; + +protected: + void register_me(); + void unregister_me() noexcept; + void reg_pending_error(std::string const &) noexcept; + bool registered() const noexcept { return m_registered; } + + transaction_base &m_trans; + +private: + bool m_registered = false; + std::string_view m_classname; + std::string m_name; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transactor b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transactor new file mode 100644 index 000000000..29d1b9640 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transactor @@ -0,0 +1,8 @@ +/** pqxx::transactor class. + * + * pqxx::transactor is a framework-style wrapper for safe transactions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transactor.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transactor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transactor.hxx new file mode 100644 index 000000000..eefd04ba1 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/transactor.hxx @@ -0,0 +1,147 @@ +/* Transactor framework, a wrapper for safely retryable transactions. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transactor instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTOR +#define PQXX_H_TRANSACTOR + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/connection.hxx" +#include "pqxx/transaction.hxx" + +namespace pqxx +{ +/** + * @defgroup transactor Transactor framework + * + * Sometimes a transaction can fail for completely transient reasons, such as a + * conflict with another transaction in SERIALIZABLE isolation. The right way + * to handle those failures is often just to re-run the transaction from + * scratch. + * + * For example, your REST API might be handling each HTTP request in its own + * database transaction, and if this kind of transient failure happens, you + * simply want to "replay" the whole request, in a fresh transaction. + * + * You won't necessarily want to execute the exact same SQL commands with the + * exact same data. Some of your SQL statements may depend on state that can + * vary between retries. Data in the database may already have changed, for + * instance. So instead of dumbly replaying the SQL, you re-run the same + * application code that produced those SQL commands, from the start. + * + * The transactor framework makes it a little easier for you to do this safely, + * and avoid typical pitfalls. You encapsulate the work that you want to do + * into a callable that you pass to the @ref perform function. + * + * Here's how it works. You write your transaction code as a lambda or + * function, which creates its own transaction object, does its work, and + * commits at the end. You pass that callback to @ref pqxx::perform, which + * runs it for you. + * + * If there's a failure inside your callback, there will be an exception. Your + * transaction object goes out of scope and gets destroyed, so that it aborts + * implicitly. Seeing this, @ref perform tries running your callback again. It + * stops doing that when the callback succeeds, or when it has failed too many + * times, or when there's an error that leaves the database in an unknown + * state, such as a lost connection just while we're waiting for the database + * to confirm a commit. It all depends on the type of exception. + * + * The callback takes no arguments. If you're using lambdas, the easy way to + * pass arguments is for the lambda to "capture" them from your variables. Or, + * if you're using functions, you may want to use `std::bind`. + * + * Once your callback succeeds, it can return a result, and @ref perform will + * return that result back to you. + */ +//@{ + +/// Simple way to execute a transaction with automatic retry. +/** + * Executes your transaction code as a callback. Repeats it until it completes + * normally, or it throws an error other than the few libpqxx-generated + * exceptions that the framework understands, or after a given number of failed + * attempts, or if the transaction ends in an "in-doubt" state. + * + * (An in-doubt state is one where libpqxx cannot determine whether the server + * finally committed a transaction or not. This can happen if the network + * connection to the server is lost just while we're waiting for its reply to + * a "commit" statement. The server may have completed the commit, or not, but + * it can't tell you because there's no longer a connection. + * + * Using this still takes a bit of care. If your callback makes use of data + * from the database, you'll probably have to query that data within your + * callback. If the attempt to perform your callback fails, and the framework + * tries again, you'll be in a new transaction and the data in the database may + * have changed under your feet. + * + * Also be careful about changing variables or data structures from within + * your callback. The run may still fail, and perhaps get run again. The + * ideal way to do it (in most cases) is to return your result from your + * callback, and change your program's data state only after @ref perform + * completes successfully. + * + * @param callback Transaction code that can be called with no arguments. + * @param attempts Maximum number of times to attempt performing callback. + * Must be greater than zero. + * @return Whatever your callback returns. + */ +template +inline auto perform(TRANSACTION_CALLBACK &&callback, int attempts = 3) + -> std::invoke_result_t +{ + if (attempts <= 0) + throw std::invalid_argument{ + "Zero or negative number of attempts passed to pqxx::perform()."}; + + for (; attempts > 0; --attempts) + { + try + { + return std::invoke(callback); + } + catch (in_doubt_error const &) + { + // Not sure whether transaction went through or not. The last thing in + // the world that we should do now is try again! + throw; + } + catch (statement_completion_unknown const &) + { + // Not sure whether our last statement succeeded. Don't risk running it + // again. + throw; + } + catch (broken_connection const &) + { + // Connection failed. May be worth retrying, if the transactor opens its + // own connection. + if (attempts <= 1) + throw; + continue; + } + catch (transaction_rollback const &) + { + // Some error that may well be transient, such as serialization failure + // or deadlock. Worth retrying. + if (attempts <= 1) + throw; + continue; + } + } + throw pqxx::internal_error{"No outcome reached on perform()."}; +} +} // namespace pqxx +//@} +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/types b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/types new file mode 100644 index 000000000..23a5caae1 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/types @@ -0,0 +1,7 @@ +/** + * Basic typedefs and forward declarations. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/types.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/types.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/types.hxx new file mode 100644 index 000000000..f95b598f8 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/types.hxx @@ -0,0 +1,173 @@ +/* Basic type aliases and forward declarations. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TYPES +#define PQXX_H_TYPES + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#if defined(PQXX_HAVE_CONCEPTS) && __has_include() +# include +#endif + + +namespace pqxx +{ +/// Number of rows in a result set. +using result_size_type = int; + +/// Difference between result sizes. +using result_difference_type = int; + +/// Number of fields in a row of database data. +using row_size_type = int; + +/// Difference between row sizes. +using row_difference_type = int; + +/// Number of bytes in a field of database data. +using field_size_type = std::size_t; + +/// Number of bytes in a large object. +using large_object_size_type = int64_t; + + +// Forward declarations, to help break compilation dependencies. +// These won't necessarily include all classes in libpqxx. +class binarystring; +class connection; +class const_result_iterator; +class const_reverse_result_iterator; +class const_reverse_row_iterator; +class const_row_iterator; +class dbtransaction; +class field; +class largeobjectaccess; +class notification_receiver; +struct range_error; +class result; +class row; +class stream_from; +class transaction_base; + +/// Marker for @ref stream_from constructors: "stream from table." +/** @deprecated Use @ref stream_from::table() instead. + */ +struct from_table_t +{}; + +/// Marker for @ref stream_from constructors: "stream from query." +/** @deprecated Use @ref stream_from::query() instead. + */ +struct from_query_t +{}; + + +/// Format code: is data text or binary? +/** Binary-compatible with libpq's format codes. + */ +enum class format : int +{ + text = 0, + binary = 1, +}; + + +/// Remove any constness, volatile, and reference-ness from a type. +/** @deprecated In C++20 we'll replace this with std::remove_cvref. + */ +template +using strip_t = std::remove_cv_t>; + + +#if defined(PQXX_HAVE_CONCEPTS) +/// The type of a container's elements. +/** At the time of writing there's a similar thing in `std::experimental`, + * which we may or may not end up using for this. + */ +template +using value_type = strip_t()))>; +#else // PQXX_HAVE_CONCEPTS +/// The type of a container's elements. +/** At the time of writing there's a similar thing in `std::experimental`, + * which we may or may not end up using for this. + */ +template +using value_type = strip_t()))>; +#endif // PQXX_HAVE_CONCEPTS + + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: Any type that we can read as a string of `char`. +template +concept char_string = std::ranges::contiguous_range and + std::same_as < strip_t>, +char > ; + +/// Concept: Anything we can iterate to get things we can read as strings. +template +concept char_strings = + std::ranges::range and char_string>>; + +/// Concept: Anything we might want to treat as binary data. +template +concept potential_binary = std::ranges::contiguous_range and + (sizeof(value_type) == 1); +#endif // PQXX_HAVE_CONCEPTS + + +// C++20: Retire these compatibility definitions. +#if defined(PQXX_HAVE_CONCEPTS) + +/// Template argument type for a range. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_RANGE_ARG std::ranges::range + +/// Template argument type for @ref char_string. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRING_ARG pqxx::char_string + +/// Template argument type for @ref char_strings +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRINGS_ARG pqxx::char_strings + +#else // PQXX_HAVE_CONCEPTS + +/// Template argument type for a range. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_RANGE_ARG typename + +/// Template argument type for @ref char_string. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRING_ARG typename + +/// Template argument type for @ref char_strings +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRINGS_ARG typename + +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/util b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/util new file mode 100644 index 000000000..6d85ab611 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/util @@ -0,0 +1,6 @@ +/** Various utility definitions for libpqxx. + */ +// Actual definitions in .hxx file so editors and such recognize file type +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/util.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/util.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/util.hxx new file mode 100644 index 000000000..4aa5ecf57 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/util.hxx @@ -0,0 +1,521 @@ +/* Various utility definitions for libpqxx. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/util instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_UTIL +#define PQXX_H_UTIL + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if __has_include() +# include +#endif + +#include "pqxx/except.hxx" +#include "pqxx/internal/encodings.hxx" +#include "pqxx/types.hxx" +#include "pqxx/version.hxx" + + +/// The home of all libpqxx classes, functions, templates, etc. +namespace pqxx +{} + +#include + + +/// Internal items for libpqxx' own use. Do not use these yourself. +namespace pqxx::internal +{ + +// C++20: Retire wrapper. +/// Same as `std::cmp_less`, or a workaround where that's not available. +template +inline constexpr bool cmp_less(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_less(lhs, rhs); +#else + // We need a variable just because lgtm.com gives off a false positive + // warning when we compare the values directly. It considers that a + // "self-comparison." + constexpr bool left_signed{std::is_signed_v}; + if constexpr (left_signed == std::is_signed_v) + return lhs < rhs; + else if constexpr (std::is_signed_v) + return (lhs <= 0) ? true : (std::make_unsigned_t(lhs) < rhs); + else + return (rhs <= 0) ? false : (lhs < std::make_unsigned_t(rhs)); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_greater, or workaround if not available. +template +inline constexpr bool cmp_greater(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_greater(lhs, rhs); +#else + return cmp_less(rhs, lhs); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_less_equal, or workaround if not available. +template +inline constexpr bool cmp_less_equal(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_less_equal(lhs, rhs); +#else + return not cmp_less(rhs, lhs); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_greater_equal, or workaround if not available. +template +inline constexpr bool cmp_greater_equal(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_greater_equal(lhs, rhs); +#else + return not cmp_less(lhs, rhs); +#endif +} + + +/// Efficiently concatenate two strings. +/** This is a special case of concatenate(), needed because dependency + * management does not let us use that function here. + */ +[[nodiscard]] inline std::string cat2(std::string_view x, std::string_view y) +{ + std::string buf; + auto const xs{std::size(x)}, ys{std::size(y)}; + buf.resize(xs + ys); + x.copy(std::data(buf), xs); + y.copy(std::data(buf) + xs, ys); + return buf; +} +} // namespace pqxx::internal + + +namespace pqxx +{ +using namespace std::literals; + +/// Suppress compiler warning about an unused item. +template inline constexpr void ignore_unused(T &&...) noexcept +{} + + +/// Cast a numeric value to another type, or throw if it underflows/overflows. +/** Both types must be arithmetic types, and they must either be both integral + * or both floating-point types. + */ +template +inline TO check_cast(FROM value, std::string_view description) +{ + static_assert(std::is_arithmetic_v); + static_assert(std::is_arithmetic_v); + static_assert(std::is_integral_v == std::is_integral_v); + + // The rest of this code won't quite work for bool, but bool is trivially + // convertible to other arithmetic types as far as I can see. + if constexpr (std::is_same_v) + return static_cast(value); + + // Depending on our "if constexpr" conditions, this parameter may not be + // needed. Some compilers will warn. + ignore_unused(description); + + using from_limits = std::numeric_limits; + using to_limits = std::numeric_limits; + if constexpr (std::is_signed_v) + { + if constexpr (std::is_signed_v) + { + if (value < to_limits::lowest()) + throw range_error{internal::cat2("Cast underflow: "sv, description)}; + } + else + { + // FROM is signed, but TO is not. Treat this as a special case, because + // there may not be a good broader type in which the compiler can even + // perform our check. + if (value < 0) + throw range_error{internal::cat2( + "Casting negative value to unsigned type: "sv, description)}; + } + } + else + { + // No need to check: the value is unsigned so can't fall below the range + // of the TO type. + } + + if constexpr (std::is_integral_v) + { + using unsigned_from = std::make_unsigned_t; + using unsigned_to = std::make_unsigned_t; + constexpr auto from_max{static_cast((from_limits::max)())}; + constexpr auto to_max{static_cast((to_limits::max)())}; + if constexpr (from_max > to_max) + { + if (internal::cmp_greater(value, to_max)) + throw range_error{internal::cat2("Cast overflow: "sv, description)}; + } + } + else if constexpr ((from_limits::max)() > (to_limits::max)()) + { + if (value > (to_limits::max)()) + throw range_error{internal::cat2("Cast overflow: ", description)}; + } + + return static_cast(value); +} + + +/** Check library version at link time. + * + * Ensures a failure when linking an application against a radically + * different libpqxx version than the one against which it was compiled. + * + * Sometimes application builds fail in unclear ways because they compile + * using headers from libpqxx version X, but then link against libpqxx + * binary version Y. A typical scenario would be one where you're building + * against a libpqxx which you have built yourself, but a different version + * is installed on the system. + * + * The check_library_version template is declared for any library version, + * but only actually defined for the version of the libpqxx binary against + * which the code is linked. + * + * If the library binary is a different version than the one declared in + * these headers, then this call will fail to link: there will be no + * definition for the function with these exact template parameter values. + * There will be a definition, but the version in the parameter values will + * be different. + */ +inline PQXX_PRIVATE void check_version() noexcept +{ + // There is no particular reason to do this here in @ref connection, except + // to ensure that every meaningful libpqxx client will execute it. The call + // must be in the execution path somewhere or the compiler won't try to link + // it. We can't use it to initialise a global or class-static variable, + // because a smart compiler might resolve it at compile time. + // + // On the other hand, we don't want to make a useless function call too + // often for performance reasons. A local static variable is initialised + // only on the definition's first execution. Compilers will be well + // optimised for this behaviour, so there's a minimal one-time cost. + static auto const version_ok{internal::PQXX_VERSION_CHECK()}; + ignore_unused(version_ok); +} + + +/// Descriptor of library's thread-safety model. +/** This describes what the library knows about various risks to thread-safety. + */ +struct PQXX_LIBEXPORT thread_safety_model +{ + /// Is the underlying libpq build thread-safe? + bool safe_libpq = false; + + /// Is Kerberos thread-safe? + /** @warning Is currently always `false`. + * + * If your application uses Kerberos, all accesses to libpqxx or Kerberos + * must be serialized. Confine their use to a single thread, or protect it + * with a global lock. + */ + bool safe_kerberos = false; + + /// A human-readable description of any thread-safety issues. + std::string description; +}; + + +/// Describe thread safety available in this build. +[[nodiscard]] PQXX_LIBEXPORT thread_safety_model describe_thread_safety(); + + +#if defined(PQXX_HAVE_CONCEPTS) +# define PQXX_POTENTIAL_BINARY_ARG pqxx::potential_binary +#else +# define PQXX_POTENTIAL_BINARY_ARG typename +#endif + + +/// Cast binary data to a type that libpqxx will recognise as binary. +/** There are many different formats for storing binary data in memory. You + * may have yours as a `std::string`, or a `std::vector`, or one of + * many other types. + * + * But for libpqxx to recognise your data as binary, it needs to be a + * `std::basic_string`, or a `std::basic_string_view`; + * or in C++20 or better, any contiguous block of `std::byte`. + * + * Use `binary_cast` as a convenience helper to cast your data as a + * `std::basic_string_view`. + * + * @warning There are two things you should be aware of! First, the data must + * be contiguous in memory. In C++20 the compiler will enforce this, but in + * C++17 it's your own problem. Second, you must keep the object where you + * store the actual data alive for as long as you might use this function's + * return value. + */ +template +std::basic_string_view binary_cast(TYPE const &data) +{ + static_assert(sizeof(value_type) == 1); + return { + reinterpret_cast( + const_cast const *>( + std::data(data))), + std::size(data)}; +} + + +#if defined(PQXX_HAVE_CONCEPTS) +template +concept char_sized = (sizeof(CHAR) == 1); +# define PQXX_CHAR_SIZED_ARG char_sized +#else +# define PQXX_CHAR_SIZED_ARG typename +#endif + +/// Construct a type that libpqxx will recognise as binary. +/** Takes a data pointer and a size, without being too strict about their + * types, and constructs a `std::basic_string_view` pointing to + * the same data. + * + * This makes it a little easier to turn binary data, in whatever form you + * happen to have it, into binary data as libpqxx understands it. + */ +template +std::basic_string_view binary_cast(CHAR const *data, SIZE size) +{ + static_assert(sizeof(CHAR) == 1); + return { + reinterpret_cast(data), + check_cast(size, "binary data size")}; +} + + +/// The "null" oid. +constexpr oid oid_none{0}; +} // namespace pqxx + + +/// Private namespace for libpqxx's internal use; do not access. +/** This namespace hides definitions internal to libpqxx. These are not + * supposed to be used by client programs, and they may change at any time + * without notice. + * + * Conversely, if you find something in this namespace tremendously useful, by + * all means do lodge a request for its publication. + * + * @warning Here be dragons! + */ +namespace pqxx::internal +{ +using namespace std::literals; + + +/// A safer and more generic replacement for `std::isdigit`. +/** Turns out `std::isdigit` isn't as easy to use as it sounds. It takes an + * `int`, but requires it to be nonnegative. Which means it's an outright + * liability on systems where `char` is signed. + */ +template inline constexpr bool is_digit(CHAR c) noexcept +{ + return (c >= '0') and (c <= '9'); +} + + +/// Describe an object for humans, based on class name and optional name. +/** Interprets an empty name as "no name given." + */ +[[nodiscard]] std::string +describe_object(std::string_view class_name, std::string_view name); + + +/// Check validity of registering a new "guest" in a "host." +/** The host might be e.g. a connection, and the guest a transaction. The + * host can only have one guest at a time, so it is an error to register a new + * guest while the host already has a guest. + * + * If the new registration is an error, this function throws a descriptive + * exception. + * + * Pass the old guest (if any) and the new guest (if any), for both, a type + * name (at least if the guest is not null), and optionally an object name + * (but which may be omitted if the caller did not assign one). + */ +void check_unique_register( + void const *old_guest, std::string_view old_class, std::string_view old_name, + void const *new_guest, std::string_view new_class, + std::string_view new_name); + + +/// Like @ref check_unique_register, but for un-registering a guest. +/** Pass the guest which was registered, as well as the guest which is being + * unregistered, so that the function can check that they are the same one. + */ +void check_unique_unregister( + void const *old_guest, std::string_view old_class, std::string_view old_name, + void const *new_guest, std::string_view new_class, + std::string_view new_name); + + +/// Compute buffer size needed to escape binary data for use as a BYTEA. +/** This uses the hex-escaping format. The return value includes room for the + * "\x" prefix. + */ +inline constexpr std::size_t size_esc_bin(std::size_t binary_bytes) noexcept +{ + return 2 + (2 * binary_bytes) + 1; +} + + +/// Compute binary size from the size of its escaped version. +/** Do not include a terminating zero in `escaped_bytes`. + */ +inline constexpr std::size_t size_unesc_bin(std::size_t escaped_bytes) noexcept +{ + return (escaped_bytes - 2) / 2; +} + + +// TODO: Use actual binary type for "data". +/// Hex-escape binary data into a buffer. +/** The buffer must be able to accommodate + * `size_esc_bin(std::size(binary_data))` bytes, and the function will write + * exactly that number of bytes into the buffer. This includes a trailing + * zero. + */ +void PQXX_LIBEXPORT +esc_bin(std::basic_string_view binary_data, char buffer[]) noexcept; + + +/// Hex-escape binary data into a std::string. +std::string PQXX_LIBEXPORT +esc_bin(std::basic_string_view binary_data); + + +/// Reconstitute binary data from its escaped version. +void PQXX_LIBEXPORT +unesc_bin(std::string_view escaped_data, std::byte buffer[]); + + +/// Reconstitute binary data from its escaped version. +std::basic_string + PQXX_LIBEXPORT unesc_bin(std::string_view escaped_data); + + +/// Transitional: std::ssize(), or custom implementation if not available. +template auto ssize(T const &c) +{ +#if defined(__cpp_lib_ssize) && __cplusplus >= __cpp_lib_ssize + return std::ssize(c); +#else + using signed_t = std::make_signed_t; + return static_cast(std::size(c)); +#endif // __cpp_lib_ssize +} + + +/// Helper for determining a function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple args_f(RETURN (&func)(ARGS...)); + + +/// Helper for determining a `std::function`'s parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple args_f(std::function const &); + + +/// Helper for determining a member function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple member_args_f(RETURN (CLASS::*)(ARGS...)); + + +/// Helper for determining a const member function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple member_args_f(RETURN (CLASS::*)(ARGS...) const); + + +/// Helper for determining a callable type's parameter types. +/** This specialisation should work for lambdas. + * + * This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +auto args_f(CALLABLE const &f) + -> decltype(member_args_f(&CALLABLE::operator())); + + +/// A callable's parameter types, as a tuple. +template +using args_t = decltype(args_f(std::declval())); + + +/// Helper: Apply `strip_t` to each of a tuple type's component types. +/** This function has no definition. It is not meant to be called, only to be + * used to deduce the right types. + */ +template +std::tuple...> strip_types(std::tuple const &); + + +/// Take a tuple type and apply @ref strip_t to its component types. +template +using strip_types_t = decltype(strip_types(std::declval())); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/version b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/version new file mode 100644 index 000000000..8dd5e48d4 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/version @@ -0,0 +1,7 @@ +/** libpqxx version info. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/version.hxx" +#include "pqxx/internal/header-post.hxx" + diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/version.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/version.hxx new file mode 100644 index 000000000..a159f1bed --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/version.hxx @@ -0,0 +1,55 @@ +/* Version info for libpqxx. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/version instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_VERSION + +# if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +# endif + +/// Full libpqxx version string. +# define PQXX_VERSION "7.7.3" +/// Library ABI version. +# define PQXX_ABI "7.7" + +/// Major version number. +# define PQXX_VERSION_MAJOR 7 +/// Minor version number. +# define PQXX_VERSION_MINOR 7 + +# define PQXX_VERSION_CHECK check_pqxx_version_7_7 + +namespace pqxx::internal +{ +/// Library version check stub. +/** Helps detect version mismatches between libpqxx headers and the libpqxx + * library binary. + * + * Sometimes users run into trouble linking their code against libpqxx because + * they build their own libpqxx, but the system also has a different version + * installed. The declarations in the headers against which they compile their + * code will differ from the ones used to build the libpqxx version they're + * using, leading to confusing link errors. The solution is to generate a link + * error when the libpqxx binary is not the same version as the libpqxx headers + * used to compile the code. + * + * This function's definition is in the libpqxx binary, so it's based on the + * version as found in the binary. The headers contain a call to the function, + * whose name contains the libpqxx version as found in the headers. (The + * library build process will use its own local headers even if another version + * of the headers is installed on the system.) + * + * If the libpqxx binary was compiled for a different version than the user's + * code, linking will fail with an error: `check_pqxx_version_*_*` will not + * exist for the given version number. + */ +PQXX_LIBEXPORT int PQXX_VERSION_CHECK() noexcept; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/zview b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/zview new file mode 100644 index 000000000..66ea2a625 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/zview @@ -0,0 +1,6 @@ +/** Zero-terminated string view class. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/zview.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/zview.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/zview.hxx new file mode 100644 index 000000000..36a779f51 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/include/pqxx/zview.hxx @@ -0,0 +1,163 @@ +/* Zero-terminated string view. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/zview instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ZVIEW +#define PQXX_H_ZVIEW + +#include +#include +#include + +#include "pqxx/types.hxx" + + +namespace pqxx +{ +/// Marker-type wrapper: zero-terminated `std::string_view`. +/** @warning Use this only if the underlying string is zero-terminated. + * + * When you construct a zview, you are promising that if the data pointer is + * non-null, the underlying string is zero-terminated. It otherwise behaves + * exactly like a std::string_view. + * + * The terminating zero is not "in" the string, so it does not count as part of + * the view's length. + * + * The added guarantee lets the view be used as a C-style string, which often + * matters since libpqxx builds on top of a C library. For this reason, zview + * also adds a @ref c_str method. + */ +class zview : public std::string_view +{ +public: + constexpr zview() noexcept = default; + + /// Convenience overload: construct using pointer and signed length. + constexpr zview(char const text[], std::ptrdiff_t len) : + std::string_view{text, static_cast(len)} + {} + + /// Convenience overload: construct using pointer and signed length. + constexpr zview(char text[], std::ptrdiff_t len) : + std::string_view{text, static_cast(len)} + {} + + /// Explicitly promote a `string_view` to a `zview`. + explicit constexpr zview(std::string_view other) noexcept : + std::string_view{other} + {} + + /// Construct from any initialiser you might use for `std::string_view`. + /** @warning Only do this if you are sure that the string is zero-terminated. + */ + template + explicit constexpr zview(Args &&...args) : + std::string_view(std::forward(args)...) + {} + + // C++20: constexpr. + /// @warning There's an implicit conversion from `std::string`. + zview(std::string const &str) noexcept : + std::string_view{str.c_str(), str.size()} + {} + + /// Construct a `zview` from a C-style string. + /** @warning This scans the string to discover its length. So if you need to + * do it many times, it's probably better to create the `zview` once and + * re-use it. + */ + constexpr zview(char const str[]) : std::string_view{str} {} + + /// Construct a `zview` from a string literal. + /** A C++ string literal ("foo") normally looks a lot like a pointer to + * char const, but that's not really true. It's actually an array of char, + * which _devolves_ to a pointer when you pass it. + * + * For the purpose of creating a `zview` there is one big difference: if we + * know the array's size, we don't need to scan through the string in order + * to find out its length. + */ + template + constexpr zview(char const (&literal)[size]) : zview(literal, size - 1) + {} + + /// Either a null pointer, or a zero-terminated text buffer. + [[nodiscard]] constexpr char const *c_str() const &noexcept + { + return data(); + } +}; + + +/// Support @ref zview literals. +/** You can "import" this selectively into your namespace, without pulling in + * all of the @ref pqxx namespace: + * + * ```cxx + * using pqxx::operator"" _zv; + * ``` + */ +constexpr zview operator"" _zv(char const str[], std::size_t len) noexcept +{ + return zview{str, len}; +} +} // namespace pqxx + + +#if defined(PQXX_HAVE_CONCEPTS) +/// A zview is a view. +template<> inline constexpr bool std::ranges::enable_view{true}; + + +/// A zview is a borrowed range. +template<> +inline constexpr bool std::ranges::enable_borrowed_range{true}; + +namespace pqxx::internal +{ +/// Concept: T is a known zero-terminated string type. +/** There's no unified API for these string types. It's just a check for some + * known types. Any code that makes use of the concept will still have to + * support each of these individually. + */ +template +concept ZString = std::is_convertible_v < strip_t, +char const * > or std::is_convertible_v, zview> or + std::is_convertible_v; +} // namespace pqxx::internal +#endif // PQXX_HAVE_CONCEPTS + + +namespace pqxx::internal +{ +/// Get a raw C string pointer. +inline constexpr char const *as_c_string(char const str[]) noexcept +{ + return str; +} +/// Get a raw C string pointer. +template +inline constexpr char const *as_c_string(char (&str)[N]) noexcept +{ + return str; +} +/// Get a raw C string pointer. +inline constexpr char const *as_c_string(pqxx::zview str) noexcept +{ + return str.c_str(); +} +// C++20: Make this constexpr. +/// Get a raw C string pointer. +inline char const *as_c_string(std::string const &str) noexcept +{ + return str.c_str(); +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-config-version.cmake b/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-config-version.cmake new file mode 100644 index 000000000..c47d6956d --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-config-version.cmake @@ -0,0 +1,70 @@ +# This is a basic version file for the Config-mode of find_package(). +# It is used by write_basic_package_version_file() as input file for configure_file() +# to create a version-file which can be installed along a config.cmake file. +# +# The created file sets PACKAGE_VERSION_EXACT if the current version string and +# the requested version string are exactly the same and it sets +# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version, +# but only if the requested major version is the same as the current one. +# The variable CVF_VERSION must be set before calling configure_file(). + + +set(PACKAGE_VERSION "7.7.3") + +if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + + if("7.7.3" MATCHES "^([0-9]+)\\.") + set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}") + if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0) + string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}") + endif() + else() + set(CVF_VERSION_MAJOR "7.7.3") + endif() + + if(PACKAGE_FIND_VERSION_RANGE) + # both endpoints of the range must have the expected major version + math (EXPR CVF_VERSION_MAJOR_NEXT "${CVF_VERSION_MAJOR} + 1") + if (NOT PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL CVF_VERSION_MAJOR_NEXT))) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX))) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() + else() + if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() + + if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) + endif() + endif() +endif() + + +# if the installed project requested no architecture check, don't perform the check +if("FALSE") + return() +endif() + +# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: +if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "") + return() +endif() + +# check that the installed version has the same 32/64bit-ness as the one which is currently searching: +if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8") + math(EXPR installedBits "8 * 8") + set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") + set(PACKAGE_VERSION_UNSUITABLE TRUE) +endif() diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-config.cmake b/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-config.cmake new file mode 100644 index 000000000..cb25a05f2 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-config.cmake @@ -0,0 +1,4 @@ +include(CMakeFindDependencyMacro) +find_dependency(PostgreSQL) + +include("${CMAKE_CURRENT_LIST_DIR}/libpqxx-targets.cmake") diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake b/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake new file mode 100644 index 000000000..980f46098 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake @@ -0,0 +1,19 @@ +#---------------------------------------------------------------- +# Generated CMake target import file. +#---------------------------------------------------------------- + +# Commands may need to know the format version. +set(CMAKE_IMPORT_FILE_VERSION 1) + +# Import target "libpqxx::pqxx" for configuration "" +set_property(TARGET libpqxx::pqxx APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG) +set_target_properties(libpqxx::pqxx PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_NOCONFIG "CXX" + IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/lib/libpqxx-7.7.a" + ) + +list(APPEND _IMPORT_CHECK_TARGETS libpqxx::pqxx ) +list(APPEND _IMPORT_CHECK_FILES_FOR_libpqxx::pqxx "${_IMPORT_PREFIX}/lib/libpqxx-7.7.a" ) + +# Commands beyond this point should not need to know the version. +set(CMAKE_IMPORT_FILE_VERSION) diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-targets.cmake b/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-targets.cmake new file mode 100644 index 000000000..4716fb7b2 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/cmake/libpqxx/libpqxx-targets.cmake @@ -0,0 +1,99 @@ +# Generated by CMake + +if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6) + message(FATAL_ERROR "CMake >= 2.6.0 required") +endif() +cmake_policy(PUSH) +cmake_policy(VERSION 2.6...3.20) +#---------------------------------------------------------------- +# Generated CMake target import file. +#---------------------------------------------------------------- + +# Commands may need to know the format version. +set(CMAKE_IMPORT_FILE_VERSION 1) + +# Protect against multiple inclusion, which would fail when already imported targets are added once more. +set(_targetsDefined) +set(_targetsNotDefined) +set(_expectedTargets) +foreach(_expectedTarget libpqxx::pqxx) + list(APPEND _expectedTargets ${_expectedTarget}) + if(NOT TARGET ${_expectedTarget}) + list(APPEND _targetsNotDefined ${_expectedTarget}) + endif() + if(TARGET ${_expectedTarget}) + list(APPEND _targetsDefined ${_expectedTarget}) + endif() +endforeach() +if("${_targetsDefined}" STREQUAL "${_expectedTargets}") + unset(_targetsDefined) + unset(_targetsNotDefined) + unset(_expectedTargets) + set(CMAKE_IMPORT_FILE_VERSION) + cmake_policy(POP) + return() +endif() +if(NOT "${_targetsDefined}" STREQUAL "") + message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n") +endif() +unset(_targetsDefined) +unset(_targetsNotDefined) +unset(_expectedTargets) + + +# Compute the installation prefix relative to this file. +get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) +get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) +get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) +get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) +if(_IMPORT_PREFIX STREQUAL "/") + set(_IMPORT_PREFIX "") +endif() + +# Create imported target libpqxx::pqxx +add_library(libpqxx::pqxx STATIC IMPORTED) + +set_target_properties(libpqxx::pqxx PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include" + INTERFACE_LINK_LIBRARIES "/usr/lib/x86_64-linux-gnu/libpq.so" +) + +if(CMAKE_VERSION VERSION_LESS 2.8.12) + message(FATAL_ERROR "This file relies on consumers using CMake 2.8.12 or greater.") +endif() + +# Load information for each installed configuration. +get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +file(GLOB CONFIG_FILES "${_DIR}/libpqxx-targets-*.cmake") +foreach(f ${CONFIG_FILES}) + include(${f}) +endforeach() + +# Cleanup temporary variables. +set(_IMPORT_PREFIX) + +# Loop over all imported files and verify that they actually exist +foreach(target ${_IMPORT_CHECK_TARGETS} ) + foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} ) + if(NOT EXISTS "${file}" ) + message(FATAL_ERROR "The imported target \"${target}\" references the file + \"${file}\" +but this file does not exist. Possible reasons include: +* The file was deleted, renamed, or moved to another location. +* An install or uninstall procedure did not complete successfully. +* The installation package was faulty and contained + \"${CMAKE_CURRENT_LIST_FILE}\" +but not all the files it references. +") + endif() + endforeach() + unset(_IMPORT_CHECK_FILES_FOR_${target}) +endforeach() +unset(_IMPORT_CHECK_TARGETS) + +# This file does not depend on other imported targets which have +# been exported from the same project but in a separate export set. + +# Commands beyond this point should not need to know the version. +set(CMAKE_IMPORT_FILE_VERSION) +cmake_policy(POP) diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/libpqxx-7.7.a b/ext/libpqxx-7.7.3/install/ubuntu22.04/lib/libpqxx-7.7.a new file mode 100644 index 0000000000000000000000000000000000000000..fb941debbbf9db796aaefff0ca29f2730cf7f917 GIT binary patch literal 4600578 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

)hCpCaGX~rdX;bRU}hIgH;#mjPJqLNxAQU zxM(XStQJLG%Ew|_F}UpaEwZk8_A_eyd& zbuWIucT&GM=9rPcfoEvEJjj&skm0yw;wuN)PDST299LW_tAZBiZ56grBs;s2t%>ZJ zrtJ@#OxuVsab@QYuNqc{>qohy@;96lo0N7#i6#1QggUWeLeoyvt_8kacSj};e~Bd# zyG)@Q+IAM0LQJL3>01Ur_o?dGVaS-ubIU6SmtpQxSza{; z?_ek&Y6`iVo+%!lIsuCWf3abiq2-p{`28E^Zs{-AOXF7;yUT9nNKCrpo0Lffkwbs) zrfZ`xxfF|u{>vdQGa0qp3(5PMImFWqwIr+`X7~>}_Hg?nzUh~eb%1vhEY$IA0Ev>l zjF_19#O4Z%;Z|Q{|5P_PI<9SRIjYxKw`HAwvVt;gv_KPcMa3BPJr+rreBt5_8p9}U zD3Z#Pa51TyZ+krwegvA83*Dv3(8(1sG2NJ51qO}`4P=+g+Qpp;%LGN@T0gc3a%}$S z*E^KS6|{Wz8zL(HEr;y$*K?rFs>Jkn+_SHX_2NZP~JX|iZ%DkY= z%n9rS7mXbnxW6FKk(Kw*F_q^v9$mMr@L0FmF40!mbxIY+(5|@BGZ^<yX~(Dz{;Fnk>DsS9qZSo?)-QC^A4VU{A*hclRT zXOBje>RLW--0-2JG2JMVYuxKT-OBb)a?QyhKc*(4`I-5-o!2B5eJ;_N(vw>N$7sD? zm)N@64T#ilF-Z!N2;H7A$*{qxQd`p|Assyfi%cXqO1#GJpmFeD)km$12 z$EC7{z~u+5NV=5ao}EVLbUBnu&{c@pb&V{q-YbX1xqINkS#>b+$5<%$*;QigsIS2r zk&4VdFlvQcuZ^n7$>1)iPH2pxht%0+yYE6!4$E>gr41s%qEN=~Mi=t-jz^Sp-g~3r z;z(=+)z~>kE*01-CaF|Whrt!@_AS%(NPTL&L(ZX`iaMhSRaT50S&lhK`S=N`QKQ0^ ziEBf4@OJ45>M~LjoEl?NV<#;g%gRQ{w7}d55>|a&U<>9Uop9Mp#wW8cQeIp#utRt$ z!Zwj2xnnGBBh>afjjlL1Z0vz=BCe6vVBE59y+9ZEWzet++*{>_2Hh2EWK_?=-&n!w z459G>K8L8fVWbx)M!TKl=~E6-%1AhByxjeVdJyzv>lkI9G952X$=JRMmk-Ma55@(s zabt!QyACpi*`coc(Hc;da3^|Dl{EEIlT35V4iQ8{m92B6vK2L5+c?^DE6c|gyGxdG zjacrOv)0$K5{xRJU~W1#! z$3|W%cr)duSdl7&F{-SoS`#hsj!hT%x|L+o45Z24yn9duXa?ED2+%#!{o6T4S6mYq zSvESTrlZUxLux7dP;An;nSuB&=yr`)N(L6C8eh|;x;veqr%g+|MqJpqn{sr5nPCN` zu9?Cr$Ts|e<%8|OCMQOpYYP|tH>nHLCZ#J|+8w2A_0AVK#)iTzsybPSv@dK`jg}uQ zl?@+K+<#mpx?Zz5m-{f}Y6OySPWj03SeT{o3oWw^Q7Q#&?%%~M6}KZ}1!yt}9~aSj zz4N)l%BxHl7W{<4e{-|DgUNHYm;I?g5JA>&Kjh}E;NA}JS=}_sI_K`pHCvyaAC<%` zNAG!ZTlSGx7;9ps%ZU9pf?T2ZdFzj^B=sjBFPne3Wwm_Z@N-cH15Vd zctggRZ1%BPAyt&9Z%*l1X`2Y5mgJ``UNiYcs;P?ISR3{bOh+!H@6UB^vg?CiSx#Nrut zysfn!FGd5fPuv+q$zCzE{>aq*etZLb{}i8J>|5^F9IWSs|BQI|J8R)zA$}xeIfQ=? z9~V!RkT`^2iI3y&6%vQ=%kXjh(?a49emOple?v$d!n55r`pZ?}*=}3n*=|qbzlM&B z-#tM<;+app`-Qyl@)R2v-u+Tqe&X94pDFmrQK#`c{&GtfxL+VkJge|=@!Uq~`G)ve z#4jX%ZUR4_>^?!^|3>_`#4n+EUL^jX#D75imik*}Nk6A&p9H=;@h?+6M-l%w;?u-) z`Cdx=R}}tQ;=d#Qe&V?t=Mm5Kf8Hkk zP2xXS-ud}`>#l-T6#gv=zlQi9h~GpUi6hIO#J`R6uDo_pUhJ+WzAf=T65om9VLu;1 zJlD??i2sS=8A|+o;?E(T>*rMBxqjZHyz|=>#3jdVG2T59=U$43`=2L?=X$%4c&SJuPS*H)I`Jzho*~4qPw`A9p6%X2JllPacuxOn;y0xDH*FE7b0gxnCcZiG z?mg759l0lCouT0!@1F2fLGj2_v7CP<5Z^$4xPo|j8kY-yJ@E@E{LRF-r0}zeXFq&J zJp2C#;@SVFY#jQB`=24ibN@VEdFKcBB%w(Zp8Mx3iRb?L2I4utcM{L-`hMlbF89xK zi0A%!KE=cR$$P|ee!nE1^ZO&kFI6m$^7-Q$Soa_K`n_y1=S z&;9?|#B=nK|IHQ9q}Chy~K0;&m{1#6VLH~Ks?9)3Gv*|Y`1CXPk9=q^XDGK zZ$ej=Xxr42VT$;zsSI}^|OZAU!k_Ymb>e*0>EkEZaP-+sh%za-C>mm@yE8bv(k zw@P_2$NkcU#B;xtp?J96-AVjP#O3P4v&3&h_2eDm**{+szm($nRe9&1tJOanZ;n7X zB){A*wIQDSr9Fw~`p_YP@20$%<9?|p@!T(!P(19PGUC~874cjy7ZCq4Y&(BmO8no5 zm*@M-5ij=#i0AkpBc9`bmUxc;E#f)-UncNB6VLH))GACT$G;=-uONuauX}I0c5Vz zal~^wx{%^w|NMz~wtENhTrT$$&-L(e;<+BaOgzW`aRUD>@f`nui0AmX+yV~3A?3yO zyf5)w&j%6D^}JGfSB_h+Z=x-jNa4AjUrs#N^XbHMes3e5{dte_VwdarBgAt(ckiW- z*Yme2ey->4J@pb^p0e%g?Y}8J`)89aZN4S^QhZ$a9h7(e>81YJi^6j~?@atR6i*N0 z**_%-d>`fG_52LtzoqzxQ9NAFuO^=D-bFl@%Y(#oJ)BEC*TYwd=lDNM;QviL$6tWw zMam)m=lC}yp6huj@m!8&#B)6#t-LG8DlNzJC_LBmsl;=Q`qdBfAe1&+*JBp7+VWQQp<_DK`5Bt7H6|TK@~S3;nY@+1-lx z21@6?#PdF$yx&C*>EF2i985g#k$5hbi;3rY_zLlRkRQGv zp8J{aiGLG$cJ*q*HsS?&XQsVg=GLdJl^6fKg^vrrEAhNO-Jf{&XE);Crg#olUhK{$ zK21EYPy0|j+|LXrp4-d$#LL?_T>9&X=XP`*@!XE)5zqO0op{dIyTo%p^EvTczN?96 zyX$Wcr{IW>zb%O8`p}2?pP}dSJA!z5TZ!Y(A)f8tkig$TJf~mYGbD$klhf0D2SaC% zcf@l&+)H^^58eK42MW*i@Cf3$9v(+Lm)9x8b9tSqe7qhGBcAKwIEshsVTO42|INhj zME<{@_vJ#Sze3(zJ35(o zdCQLDM-k8ca5eECQaslw@9KYZNf?e9F@8_wXHq=v$nImr^E_}q@m!9tCh%`7FX?## zAD6GC#Pd9G1;xYdVoSX5N)Aaj+ubLD?@m0|pQDK9`Xle(l0)L>^16(8F0WgNZ%=-E zoOmv;SBdBH`bv3MUQkl-%ZQw*BI~0aU*>}hy**3(z8ABT#kDY&;Be*;JYgy zFUKQ^=W^^#@o+g-5zlrr3H_9~Rn)^B%_e@Y4sZQ{8XqAQn^ zm6!akPkg!ZV)qe>XPEL5{!!v9iRXAOP<}szXFp6)UgDoa@zg3W@!vuGRTQ4ne-nil zyV^Y#%%t#~{s$;Lr~h%{IiC5-$J753#n0(~o#J_%(*G`n=k$L@;l=Ku_{i~fp#f7~ zoc`~XkNdx1Hyd7fj;E#a@$_%0eBA&05YP2$UmLwi&jXNM{pm*hEaG*0#8&;A)|Sj*3c?7~kbegX0I%1ik+$H(RO2IVFG=kRgy+)e!R#ETE* zknr3dpEYbY|AO*jcM(1={x^u1Fpif#Uk-`?MSL9pvyeE1e+eJQ@7GM&Y`gA#aPf4O zQuvpl=i)hycj}za+pbtP0#BTf0}s7yR&;T@m!7-#Pj;AN_kg~uDxGG z;d%Xa1@T;t*Avg>cn9&kUbs*BcsV{sJeMQa2QEkPp&U{!?4N%a*7ARc?ELdR@f_a0 zF)<#Gdt+j}+)Jn&IbZJ0c@m!MLm7qV`Y@Pyt`FQlaJy!n)6ezc9m+4aYmR?^^22)+ zp6lC3#GgpvIi4=WbNFK7IXw4cpHTdqug{4uqv?zLzohUzh+jcG zw-l=EBE! zCVpQ^XIJ8jh?h3v;yH@=?!I{zJ_?Y$J6oL|8yb#b_&n_ zm$6t5X{YReuK)5jP#1qv{pWfpV}uLe*2He(??F8KU)~<-!t=aE-V*Bg6DXdei7zMq z7~)3}pC+FD#{I^f6uy|kOP?c$_~%&Sr7g%IJcnOtSj!(r;pLuQIV3!%Q?8N8Av}*4 zdlS#)C3Qv)3D4!#!LXKRzi~a3zS{Y-ABE@iloQW>JCAtw8_#pt4-Zjz_JfQCa>V`c zv8A*8!2V=E6eRe;turKkc?+z|Z+nXWc;Y$yVZ?Lz6Nu;b%YHtN;+MIQvwH^d?C0Uc zv!5pu&wjp@c=of*ndOlDGXI)kvw7*;<%s*A{mJ#v^}Q0F{l6>nD2MP|54l~-Z`Pb2 zb~d4Hc)ni4VPc%q8TA^Iuuo@Z6s?N1El3@SIM$)*y%QT%Y$L zp6j!WxpGK&uFt&;YkBtD2;ya~>+0tP#B+M463>2{K|K5IS>oAmGN+Y8(#iZP!)EjB zA0EHtnxGu}x4oSwD#D8E|%gfr+#n0_U_97g=Ib=B`9%(y{mwR305Wbvv z9tZh)-2N24C54x@gB%hMmse8%)6s;s;iV3^^c+b%&!77fFKyF>A4NRZ2Oh77Q24GC zekk#~5#N^h-oy_hekAb&iQk@hPCu^~Mo{=p6n-S}?TLQ|vdb^8*A^4c`$4i$RXw?Quyx-YxxU_moZBY3D5ED zPW(j_p67c5iRX4biFoceCKJ#7#>K?a)aON$Jm}-kwF_c^*Nh37LI|4j+;KSA+u{L-%T ziT~Dw_@7FMe{~M=BZxT=g}KM*fZdc(5dLZT7dwP{mAFEc#n0k9cl1y}_zfKi9H6rB z8>uWXNoC~+W?{5D3i|730>hw$4P$^MhEQV!v_Gm`!1>ag&x&d8ZJDg5>}sQLdL z@jDQ|wM2kJU`Hd_f1QbUYcx6IeorH(-5!YWRTO?VA@sPK_}v`|oK3u2gUIPOiQkjL ze@DDqBgkp@dty25+N|)M*O&h`Uv8}--}@5ZRtP=LAl|iQIduW?ngpY9V~p>s@yw0! z=PUnyjCc2M@pI?g+(}e6&_*IQ<#VbU-;8((zbig+v?E@EUZeK95HH~mlfXFo5-;KF zweeNO_+`pp9pigwqnsV%rz`(vjNhTTF4MqBOFV70Q<+D+g#S*%zfZh` zFWkbO_?&nNAM87;|0Jw@w$x5#GvX!uvD%*75ij9)(N3i##+N8RGRB{;{N*uzrt;H> z7rV0OBFAjv53rQ^|0eNn%_1khBVN*3ubtU{h?n?XzqXUs3+IPzwKLm`cnSZ8rl%M2 zZtaQF1%ru~xE|GbMiDRZe5UbSPP~NQRy)6G#7p=>If-L7@j{)fo#H&=CH&zU{xjl* znzIZ3;rNPp34gkVch8HHuN@?y9-Xxv2=Df?m4H|yamU7m%-6O1M{ zM^gB!i9d??*~IrEejf1>{~V3~ed1FT{uknpCVoThM@3!YS*Y>sN&GPs{s7`7{M#D7 zg!nXt??=3Z|6IdY5noKE++)FyoAl^MMOZYR1??vIuh#yS+0OF?*UrzjO z#1ABX5%GhFUq<|3;#=!{LDE@4e0So95I>msp~Tk{Ka6;>Qv{m-w@Zf1mhD;(sB29PvBp z{7dpxMf{<}k0*Wr@#hdfiTHDgch4h|_$Ls*fWn_g{Aa|wwSt`9Ko_49&mSrLp2WMk zt(@*f{6q>rnD`5cpF+I5RwbuzBYqNvUqJk1;y)w)V&XT@d8?$qn)tTFPa!@{d=2r# zh`)q*_xv1*|5D;-QuwLFFCsoe{4(M%BfiDf_KU<{OMF}6FDE`td>!%poS7?#pGx7c zBz`9G^~5hC{!hd&BmU3Cx6t{!r2i`7+Y&G5HZHU$)5K4w@WY6|j`*p>Ur+o@;%^{+ z5%D(?zl`{sh;N~rAd*J;1p7|y$DKE-s(fHUd%X71;xH#wR*WofkC$9j6||Sv*A=uM zIBr~lA==C9fbf19^8yWdt4Zh4<)h?{pYAN)Oo4Zjj2nJFUa~O;?>)h504pj-6|@hc zlo;go74q^@_tLpRDfco#c@IbX$}!ezM901@qX_S(9a>>u9Ae&j5slarNZtYC3FO`$ zk`zgBK0)8U!R4rqc#~oB%hNnBal!lk@Rr<^FG)q6;Q!&HhdQso7pchW4?ElUlNGcd zItcI6oiM0kY!zN{kN5tFPi@w7j>6+xk8b>>jq++Vk2B*bUmK4^vua*V)D^~Z&gySy zlYN8tElFiAUaRPP^&K>FaMh5pWhRak>Izu!fZV@8jz7*sWU z%;=)dmF4H+ZD#H}buhM5D$Hb*~1J23}UwY4AWY7;nEeO~zJC+uQjBuO#X`6z>x1*fGp#*~s$B zp%r5Wj({J0sg5Pu+RZIGpHI1_$KIA?lO}H`8dpUn5l^6T4*NBi6gC=bQ77|SsIpOb zb!7R_3Retpq^~dVdSET%H{OUFiRQ<32macwFK3GnZ+Ialx_p0U5VV2(V#G`0Qnpix zRWO&pHj#prz{@q_TD zNa=^QQozGQ##EkLUOBiJ?N02$|BY~;w8T$M@r|7 zi9vK+k>Sm};x^EXby1C|b{;k+GMP>^n$_!Ct5kP%m<&okw3@9On2l8AXzh`AFAgfN zDn1sqbOb8t+Ef|zD}4?s>owLt2?~8 z;_a*nud7V5X0n_*Cu!pAEpw?}>*^~SR@b2qFuh7_fNipj*QS8iqGebo{TG{}77OhD zmN`Vr8ax~W)968Hlvwa0ZvR_;y9^#K<5mR%+E>_G2SnTHTBHn<61)apX1SH)2UVFg znD_5?FO#=+>-ZbKm$<5YXfQsMV*jPyr(yKTYausPimVqg5vG9 zy~|JzW5mqz;5QkX<)!f9h`26Mc9W!{@8hN3y2R&w!FQzhU&j}S7a_sJ$CY8? zTRt*tGb(A7t%a7ts&?#o{Op|sX%LfgwI!~rzt_xn5 zNDqSRMpld-S~ZMg#0KQrcj|8Q0^NG{G#gWZb)IMAEy@+6vA&T$W0dwMGX9-ZItZ^+ z53I&I4|IB?u~%AIKGJRfjY!3JbVkHlyqTdz0_pUu)rE3x*G^=(;Yg$|DL!gsqGJRxhhHfFWSnQXQ@5vAQB2pq&i1v)J=D}^1;USK2R z5buuYOf+e$w8&gru#4EBx;K(0+s=}5vaZ#GbKkh75lG{I!K8aq1(ks zHhTQXk!54YNQYHfj5%9sV5zJdf*M)`4Rn5$R%HpUDIUg|FT#mE9`Y zt}DZE(Wi4*z%t3or`Iq$pl%+>CQYx1-5E@`r2b*oet6ZmV%gWJ>OAngs)|&qsKek2 z4Nzf9Q4;lAZXOkN#=NDnV(iFrELO_LPe_d#90#e?pD^vI6N|S zkGOVSVwZXGsPVF$i>igf%=Y@a#onh(`#4jeSzQKh04N_k7`v|H#tbQTRVjr*AhPj^ zs)vd?x{-<+ju^3kuBoCz$FDd`tBF+Tq9$v!$IQ8v-c;A6(ny8RTB}AXe6HhaSm(lmD=I5%tj4jOtP0Yx$qK^i zO%EU4gL2i;Uz53x+XP+FriWsCC+K3cstt11H8|^r3?A6JM@F?+>GrAWI%GH|Zli;G zKgx{7(!|jHW8LSO$zW9<4j#sjB?F66jnAY~-JMP_NJ!s+ZmM$`R>0ZI#N()DB#bhl z&%<^5@j2+3U5TK);vIYrb_0*1n+;8)B%qr$XAL}?yp5SW(d9~r_%YkH#Z^`wM4Me; zjh95UH^Ww|#u>&aHQ*f6%cA_VuX-SpCK2UDK~eIQ0F|R+wA_GHHhf5N|8bQV7t8`d zrdhHM#d6`C@{!}QrI_kkW_N8%r4pFCdt~ls@+^}$k#OG^ZdK`fvRg;dtzPbai-e$Z zy&sn|$KlQqcU`jy4Y@SqG|cS=O@uERFZUwY`_38<>TVoM2vuxzXKx>qFy>x2$#g;Z8Ba8$J zV;YWWV_A7+W%+sWPQt7;+xI#JJ;o4eHfRzD*?S?;`Wp{iHgv*-va#qV#*8i>iCyZl zb2=2XA2epvsEX0J({=Qis*3i<9N+H%T#XuZmVO^PdVKq_m1Ce(V^P z)gJx#^3XRAQbBn3-z|CQw?KWBgX`ai_?~P1+1jJOG!OkkkN&NB=(qFef0l=ScaQ#U zdFZ?6QgHiQo`-&4kNrKs;8+wa5M)dDx$!`fOjG?Url#xn~-2`&*EQ{n?)MzmbQ2gGYbMJktNNN55wt`b$)w z{dZ>`>0j#6|2z-;D_ybJcI{(O;8? zzI%TR+b=+#a<$*qV_(LkT=hG9^tZ}GzlTS^Fc19_kN)m?==WEBuK#WG&>!HjFJoe^ z{u}AhmuE2Lsz1S_-!TvUDIWck^U$yN=pUMg{*9{7{y!oQ{o6eD2j-za%cC#P`pnh; zb3OV!^3Y%8$-g`wHCOwKJ^J#T&0O`Dc+xM=kXJg+`i{TBLM0M;Lqhkk31zC2ScSNm;LpZovfJoNYU*dLpRemjr- zqw~=3?$MWLKINMKULO79^3X5!=$GW7f4b^(`B&zlKiFgc_&oH-dhCzOLw|zD{t0>L zPx0uN=AmEj(UU*3C=tNlYg`se1MpH_X&|AajBOFj1Gy$ZRe|8$SO zyni8A{b3$`c^^Zr`tCWFTz>LA{#^AZdF;#k8gkWl?@wa;@?M8r^{0F6UzCUbZ65te zdFanleXc(j=b=Bxqc885P&&Y*>pu;i^vioCa@Bv?V}D8>`tJFqTz>Lg|6J`a^`!sO zJoHz3^rz;b@1C>D>Cfb$zrlu>{NrH#%kt1~t@>PlYV*)<*$G*HzBG>$Hu#xoM(fu2F zzeKM3o2ovSf2%z7+j#8Xn}>d($Nme*Pp;{2=dmyExyV(&v&a67JoMf3(YgE|$U{Hv zvHxQp`S0t=zr0r?*ZiOEvHxuz_J?`wKb(jCv8vDa&)k)V{V5*(yYtX@&#`Cw_vE2} zug8Cz*yX2S! zBi905eQsk|`_2WiuiFL678JB>8;B7>!t&7$UnI`Bexd3Q;J}azW8aJLUE24IO9wIDo^@nAgr_R z(*H6zpZ(|6@PRnbM?9YkanfhMa6O4Nd}hA*PtqE<{|z{w{qJ+k|4Qil?3a4%-{!Hu z1&sUb@7W%KaWs|xO`+_wKgnbN4#XGFe^G+{zH0w?lZxfbGDU#@xa5&K%;_C$Kb61H0HPge!8Fa3W!|MG4p39?>Hzm+z;o!B^JjV@r< zhn{fp_Ork0?-hi!LR|k>5We!O-@t}+?L^XlAEJn-U*0PrA>;N-)&AKwnjjUiuLTD| z-)DcO+IRPXh<&+#F>e13wIBE2Gtx2R(8v4QFZds~zbiU^;o|9kTlIGdG_4TV-vRo* z^v~GHhGhTA`X`?L3lr>rr}lSm!v1*)_UCx)&-U1t_y73vzimfrxT*Tn2ATKiAFBGJ zV(CY5MUJhY@AKbcO+Sx6k3lo;zhe^Y->vqw83#7w_AgG*U!wZ)`V-feeM(>c|Ec== z80kd&?l*?c4KaSfUonZe%wZES;tQfaHJi-11wa@MM8IS$B z3HDobwg&fZ!v13k_Uk?QpYO51G3MDm|F>8BP32$K>Av!B@Z|qFkNq6Rf zKP1>+qV^k9U+SOCwc_RfklK&;|G%jH&0_X#tqRHQnp^+H>&2#BY?wmyk9>%)_}CKq z#(zvgp5DS*;`Z|*_;~u;tNr-+)2_RXu&ME9UuQp-fu(An>#xjps-$ zH9@~D$MnCLkp9)4^uOv!e|KcaSN|_m`@32<2LEGjD(D1#U;S^ru`NIL-)kQGwF&lb zQv1CF%T|cjze^JAw^jRT)tCDJhR6O#3HHBK`&%|)|AdYG{`*DsrO)9b?!RN9@AKbS zP5(?)mh{V#9?3O_^Xm->_Mbk;hHEPQ?6iTlKH}wnH1vJ`ORIh7C-I;B{v~ezk_7wx)qYd!x5)|i2YBp%;IaR1g8iv# zKi+@E>(5&W_9uAkf8?>h&nABV-;tyJ@&x?_s^3)qcVmM7yE)qbdxHMz9PPK+)Sv&& z4zaZ^9jkD$uLWB{-&g9?P%Z1L;0uJ$6YMXRjSU>!{+Hu>-2PseU`WXL_?3X0ie@X2hV55PiJz`%Aj!CfJLG2f+g82U{L=n&bqY3s`>&9ce{m1P; zm|(wDD-QR6UwiEDvbo>?+a6)_TVf&jAMby*hrZAM!_<@jP|CY(cIvkw-@9{nE zznc>5Z+xUtFZff;VC-wb^aT5bvayL{m?}v5t;YAb{monZ^MCzOM!lduW-#`(U}Na} z@;`M;8=*ox+dn_S{;I8P$PTJ0`TqrSJpX@7us=ZUr(y=< z?PpPf{lcxS;w04<`@eeZAF_qt|F<7)6Ryj6%|&+pM<(bmQT=g&rWNAp9}0b6`OVnI zCVYVEOZw%KLfn6g66}{8V->X<)>yKylgv-BU$CvU&*iti$Np}ZAWO*j_;Z=sZz}&g zLEo4E4r)J5`QOlEe_Vq7U)6q7^Cx+)pD+Det6`ju9P#qoV=KS@-m2d{qMhykU7+vF z{{)Z!Wl0k+{|giBpQ-knD*y8m?9WvDJpRd)C~kjFg8duSeti6m`)`x2{r-DG^_yBh z4@l5|H%I-467+vk{iepR^-#fl^`~{QE%i6KlkmLG?LEl$@8a(AE zLqZFU&z0+h1p5QkK8iPT#O*(kpg&&qM@O`?)Bi|9`j=?>2dKXEf6^t!)4w|kNYWJV ze?HC8e>+3p=fCdT*_=8*iG88s_D@T&zsIpQ;XO3{4s5LM8{RdXV87I3e|wMpg$ect zseRps2n@#UKbv5GnA+$5e@Bn~y|?rG|3hNU;BHj_F^SpufR!HodwG333rn{}&1AU*t*uZl3gSiwY`n#_Ru)YQJw_*$Q#{ zTR`9Eztw7AyFqjR#U38}B?s;f zEx~?&wLgID@8hw*G{OGvy6|ht{(A}b=XmVz>#=|A_Wts(SNpeU`W+yO$dQ7+ul(Cc zXM>|&LyQ0S_t>A4V83H;tJswNhZF42^w^iZgn0kE+YbKxzp3`oy+sb2tB^V|LH|qD z$MQCE#P#n?&|j_kI2}3S`djSiPyd$3TeZT7whhbFi3$20RsSRo3^_jkDuKSQ{JZa9 zQ_AhX6R5cV?@q8kMeXY_9Hb&{|Mmp?lhi(sKV3Zbo8bl(NolL>~_xXR3$NvX;>`zUw-$M<@>wi4|uO;Z8 ztoj`}v5@2Ge>oxjt!1)+gZ(GZe~8zg?RNH;-&D0P&wSt`p8hSN@AF?cZiRUM z2PfEXQ3zu=*#84O_HRwFe}UR>s{Ou}pnrwxH`V@LPDp>DC;fvw>2JMbDONj=$|NDgWFZGn4{FWhJf4c1D zFTd{nZHhN{30FiEkz-nd{?V#`VkES+#Z*1?Hvkd8f4i-0R^o8}llmvmpNXgc%LMz^ zs{M{8mhfLZ{hue;@8Pk3j>rCvd;9(Og4%Ct{Mi=zzWn$1*q`9BpHchrI~qRP{K0-} z%OqsyKSxhVus>Gq572<(|MNZeXD8V2k)! z1I&N>`@su6_P5=~mVey;^*P$#0{Xu4ulLxWy?}8?)-)zy$lHa;-KO-Ui(>47(f4tO_{*M#VU#Rx?kJ&Gbec!pQzy6h~zVnk)i>JR0^nLYjk;ng+ zdD4HB+K>BxtlG!r*~k(1=kSE|Pt7s?gA>xO6<`%TrKiiGrc&oTW264JlSlm2Tw>Axf){iSL@USHzh?^ONx{>uQ> zZ)*SGmW1?okc*u-I@n?~*I%#mr2n-9`&X#_16AKaY?@KLZSU*)m?SC9P( z3HFaw`%RVqxCHx!d&3wGu79_B?B4`^8Kc)Xp~HWZ)P9SQGLrl5aJsV}3sKh z|Lq?8_iO&+^S7x@*mvgca`s~lW0=SOogVw|CD^ae(f->B_9uDl-{rC291{%CK{>g6 zO;`Jvoyu;7i_cb`YzX4=bIBf3Q{e5nP2EU1nr0Mk#xy3j~`L_QN_m; z=O{i7d_v_X73V6>13snl(~1p>^A#5;J_meW<%PgSD!%}HQRSC_@*HGI+uwk%sQjwp zV&H2kzYcr@A9?QaTgtr+{JY9afbZb*E`AE5?iXQ_%QTbD#JkMCt z;huN!4}AXupJmD~SNsyVLS=b|@mDJU6Zo~ttAO9A{4MZbDt`z3x60oGe^6PTW&ESc zKPmnU{6*#e0Dr}2jeeH~)l5D}?|Q)X@sZ~l%l8d|8{yMjzqbHxta3}>CMs_V+)U-o zfvxaqt>3o*Zi$aPdqLvd8n_KU+v@l26y@0t+pD~T;*LOhwz25#4BSQKU4exv?*`mm zQeN=7>+*jrOfcvZ54tRjd?STiX+yPjmaz|h%l{*8wsN7Yt8?d{| z2LTUO`4FHy<5<#k81QhFj{x>ixhL>Qm5&1UQaJ@YT4j0uggon5;we@4z8qMm@)f`AL`&7Ok_<+i@fDfwtkmAF@*(yH*d{pJf6z3>DuK0xFlZtbJ^HhEc__WFmz-Lr` z7C2w!1;FQ2ejd0`Pl`VSe^L2Az+Y8f11#9kw*6*6d3KBR1M34f zPp*VOprXF|eh|n*cXec{AYVDz^f*R(T8HmMU)r+*;*rfZM9P9Z;T=ENR#t zxP!_&0(Vk*XW%X>?+Pqbc{kwhD(?Z@Q{}yYd#k(;u&v7b0{2sSe_%V64*<4T`9NR? zm5YEKRqh1rta2A%SCzW~QRGtK!tn$UcYL%w|YgE1jc&W-$ffyjJDu!0S}L9(aSwHv(@``7gkmRh|L- ztID?kZ&mp=;O#2k0lZV?nZUbLz8iRt%J%~AQ~7@211iq~KB)3Tz=u_y4SYo9M}d#2 zJO}u=%1;2FRCz9Np2|-FpH{g6_>9WW0_Ur|0Qj8B&jS~#yh!l{#TS7usr)kVZz{h6 zd{yPez}HlMUGWXzn<~Erd|TzeD=q=Pqw>3o?*ZRe`2*mGDu1N7RPkfrCn|pm{7mJ~ z75}051#p?l%N4&=Tmf9E@>jrrs{A!@mCD}$zg78P!0%N4x8nD}A5>ng_@m-az@JtA z1^6G8e+8~lSsuhH?X($iJ(br7%5$EC-w?Qw%FPv90Nrz>T0-7Ld3gr&W-4#4*b3NM z0)s=O6&Yn8VFZmaTkKzSCk*xnwvgUUMscT#z0;4Uifs#plzP37Gc_WOz)mX5vzNQ5+!feOiW3zt1YV@_ zB*n?Vi&d@$PEolAc!|oFDo$0*054Oy7I?YJb-*iBzEZIs_$QVBtaz2;)xc>gUjw{W z<>|odRK8yE2H=e<-vs=N$~OaNsQg#OTNH0qyiM_T#XA)51kP0XF2%bQ?*ZPc@_mZ; z10PU%7VtrpA5wf6I9ugMfRC#D7;uitj{~1j`AOhhmFFowrT8?kLFH$F&#F8hxIpFS z6rTq!RCy8b1(ja}zNGTYihl#XqVlW2#VWrBd|l-?6yF5CrSjXrzpK0i_>Ri&D!vDN zU*!*gAFBM3;!?$r6+Z!fs`6*R&sF{h@C%ifDK1z161YO;mB6o5{wMHjl~*Z#1N>Iy ze*wQ!`QO0rRsKP7HSkB3e**rj@-K@2QT$bLjiPKgOTWs<@fr=8CO=tySIvD9_pxyITRbR(Tu6ZGrAter+Iculx?c9aY{5xUlv!CMrz;-Gh0CdmxI}maQ<%@tFRqh1r zta2B{uE1_8cUL?}@nFS6fQPDl81QhFj{x>ixhL>Qm5&1UQaPn~wBj*}X<)I+#{!R2 zxdhl-<>P@Ts9Xv>QRR~q`vCi@+z)uN%BKMPtNaJWQ-P9~)DxU=$sq!e`XqCqR$Etibuu|o5z$%r;E1sixE^va%=P91A z_($LcDo+GnsPaX?Nh(iPyck%m@)X4y;3Xanx@GX_! z2L4^;CBS!7ei!(j%I_3wmZOQCv?^ zE_rRB@`k{TRBjGzq4LIxErFY;yeV)ql{W{rQn@v73zfH2+zPn0%G)Sz3*1iSHo)yw z-T}Cy$~ysfR(TiTt|}KQ?grdlpVu<=(*KRXzb&s`81zlT_{l?5lD=;K?eVqS#;Y55QAZJ`H%f%4Y!2 zRJlxX0I*!;fxtm34+d7KJOnsY7b#8xPFDG1#cJRbm1}^PsC+4Ks>&I~%M@#Ym#bU{ zyh7zGf%Pi?3HWD~uL54J@-*NzDqjnnuJU!j>s7u%@kYg)fPYc>X5b8!|EhS4;;q2j zRK8vD4&a?C&jjA3^4*H}0Pj`#KH&W-KLDJi@`J#KRDM`-Ht-RZ9|b<9@*LpfDn9{y zQsue8c`82zd|KrO;4>;e3!Ja=0^oBhKM!1}@*?01D!&MPN#&P;e^dDt#aDrgRelZl zy2@`TzNz>Y@NJd4uEpTMtGUIqL{E&_H`xf8In%3Tz@0=uc)9e9w+2P+-|JXGbw6b}a;p>hw!o{C2* z9;Mg|m{R#@#bbbJm5YJ$jA<#$I+s@#ddlT_{l?5lD=;K?eV0_?By z9~4goo~H8Yie~`NRJlxX0I*!;fr^6^2P;+php0RhI85c?z!55+r8rV?6mYc4V}N5- zJ{wr6@;JpR;CPkK0iLV!1mJlppAY<_$`>e3RJ;&)k;;>RlU2T0u^Ko<RluuNo~C#W@LH9pD_#e@UgaBrH>!LS@GmOg z44k3zUlngrycKwx%C{@t0lZV?nZUbLz8iRt%J%~AQ~7@211iq~KB)3Tz=u_y4SYo9 zM}d#wGY6l?m3spCq{?%F^HhEc__WFmz-Lr`7C2w!1;FQ2ejd0`m>-1HQ1xd7RG;+Zl~WN45llq{lhT=K z6V|L*GdNwl!Cq|*pITPbfM_SBYir~T#hlK}PuHbpq-)KuB=|&KzZp2wkj{MQQegsW zitH(yIvdB$VX%HTBmGDUYtm_nRP%*!%Lb?Sx9O}ZTCtyGGb_GOA)Q&`bd6(-o!T>2 zhyLjUSGIvCmcbKCaT=f2VkMoiu&_r9@u;Dy8{l-!g9NE=XiMLh)|U2{U>O5T`AmAD z#8I%Kqf2hKw!{|39ws{-No~)*lHLJG@662j+tQhS_32FS>G6`QOM!O2cIoXmGo4uv z>6@7jvoteeRL(`SG;?8({*rK`R$Gv+X&7H5)A$1GOw@(UN9tExOqCk-Y+7y)5b62w z9OBjFRIhH-s%ytIsPzAXCvo3+Ah4l;d(~@uW&h zqBygF>*b2(AsMDeb6Ar3)Sj2x=J8a-lVS1IBP`X}4Q-aI7YsP9=jmt6uNQ;To^837 zO1Z`hQ*6QYfde;ab?KJ4{X5f;uG_lCxZ38jc7yfO)6;dfT{c^M_?o5v<34^q^>o4W zsi&H02|h*L#qtH1p5lBnoGMic0&a@}U8 zG^|DK)sd+eG_X>cah>Q+18H)HLd#P4}~{ zx<6WVq>El6gKKKKwCc6(P^UXzRVO!#J6#xOEYhXkiJos(I#L1gmAh1Y4Z74Yu1304 zV@GwC|2e1w&lP9hw8m_7D_YtDRz8e6=xLXgWIkE3frLs||J1CiMUW7epp5j1)`O0c zuXdC*rD2pa^L2y?CIQe|63!oj-nc&suICxlA4lg`sZ~J=YWuCW!zjRJhv!<=D+^KB zIE7hRrr)x3ZEt*1tDcBA_C{lAYAoo{0@bGKod2oj4%gF6#niw5;lu=!Fl`L-(A)nR z@7Ri+&!pmixYJ9Tp2T`GGwUo(oSpo?8X1}E(j5B#)kxP(<~sQ2RwL0rOHaE@7HvFX zUTua}&^mI-dM=bheqm~r>67Jr9hT4G(ply+wug_d=g^V&TOCYvs_fA5LTm=VV3LgW zNK`$#|EXA-O)AOMjKvDNBva>GVpmU`TF|Oy13T4)j!pHHhN=tW{nspa65~k_FrAUb z(X6}{M`1*bjO5AIow+)lSnbFZCfM~z*Vc)z z)3s(hBR0QT{%$ZKN$j7)R0dO#p!zh?wKt`jIFXry`~{h6Z0e#j8gWP9gK(V*I(wNZ zL916zip)xbnT_linHgx+7Em^_x^~5ebEI*EdnAEQ^~BW$RhygOVOY3)jVEjv=OZRS zu+|M?TbmSwvDzdCvGz2x?a3=8>FLb8{!$S#t4!_qHl3;IVZKjG8(36=hLd>_bO%d! z2XHrn8TwNaf3TTh>m2qAiZgGe>n5U;vN6`$7;7J~_FlsVh@EoQO`L@=Ci>cG5`DUE ze0_1Ip*Zte5Gm5|ZSduJ)sq^nHN0-#08zA&_s%TsomrlSdSIf)oDM>>X4pqae@au{ zgI9EN70EOnYbxB?h-@7#aY?aho4i1rt5ao(#q3IGB9n1fx4N1 zJls3aw&EJ2T{}&*;RG8cWgmI0n`VOgI-`1*_H^C6hA;-78&}Ecx;hD!HB+y%Wms1y zfwIq%&ueQ;-c1KtXX{n4x<^VWq{bN(T#ZRU_|+sg_!<^vy3ULxE@RP>Z8ha;6wdO? z@Xu4gP_;?QD({GKss}Zk3gW}$5E)5V_MWTt%;W`9N8&3j*KXU|`m;pJBJ;>%1Ji68 z>K5T!9`(mGPor8pO;k~NYm*cmjj1WMXC+Y9+1eVD|GH@=5RGhgRxPL$HO5Bx)ubr+%83ojD_UQw#;zD1RFpho zr&15iFc~(yaCEZ$hvshb0x9dPdSKQVV=;f4%0+E1M1%umCUs-=#2eRZb)~#m08+vD ztab1Wu6VGFeYK zdKuGo{gxu+Dxy|wY6;gsu|A6izEs;Xc_8m$_#4mMwHnqj9e zuH$JC%}4dJX6a^2;HX1e!plh7HYS$Z6zl{`niV@^4{;5ca`~H59irFjIA&ZYk}J1C%;>;n;uNJ)4Nu`ZctMyTzStYL$i`Ou!L{|w8_btv zP%Ymz>oeUCc6rUD<{)60!mJFLf=()itZRJ1y2o6z4_068QHNF)RJD;>C<`*VnjiXL zMJvZ^s<7Q0maWdcml%i4Ya=s@%p)>2;9@nG8|;Jumm4mMt?hMX-x7%*G8u?G}vWo+Dc~P0kGXM&CGmEQi8^Sa3)ULc*EMx z=0r1O;|u*Ny;BFN+;I~wL%Ilg#5y&YIi{sTBriL3wIG+}sTxxqicaCv(P_DJr(0)6 z=IrjITw~Y#qPCEk%tAz`neJe`XA(~{R5W~-y=Zx9e08O5kw06=f7f0tl7MYtFsz)r7civOq&V|P#Q;_-ofv;Q>$6VUh>Phn?NI|P9G9Wd!(L;5h&UFYj*|~NI)bve)ZDk9cQa8^! z#WpkDDyn@%j8MaMn@Z6ZknAwqimjuTFF+<;!;+yd+7J%oQ(7<-vWC?Jx#sl@3PwU=ZX})ftELz-HG@G_&y)YSa`7X4A6Ye) z)ZXriy*Tq6q8}(`gWOFsUr`wi`&von%aY7L!qYW_qM^;#x|(`nJu{PO_JoNod*y7^ z0@Ja$H3^#USUTmwH&XDPJILZ5i;ij1e=e`aKi9rA@tO)A)}mRBB!`1V{1=RVbXQuu z1hckpr4DC}T38=UURfv|Y-ZjPbUT?U`g0=^6e(6KOkGvM6#KaC%Q%QRlRzRS+BL4@>N2X zIv-}TBqMl2mh9l3eGk|=WGSp>)-BcvVf_gz%u?6L^4F+O^Dc^8Z%$qywa08G1S=D_ z*2#?juD0KIP?M!iIKiNMW@L4p#_DHpel?AqyNQI22v{t7x*6sGLm>ic{$Yyp;kX3EM z-d}7IkX*~rft$8dYwyo!Y1-y;xp{P9&89K|!V!dN4X3$P%K&6>`BTVjwF%cu1C`Vb zko7?@xlY%%NxNyDYjbY>h~)F#+>)D;%olb|5xMM!2*YxS$EM4vX=c_`{Vb+=!5mKJ zsIN-~A_?k`Y{dNI7J#MFn{c9{;q+piogJ?@4$;_2v1Y8ce_^_IeYx|gq_&W4)|v^l zja&+>=NjDX7S(mvko;5a@mC|f)pt%z)klW?v@1s`BRI>ZuKGvZDv zD>M0#EuFR~+(-sY8K2260A&t>Kvx;<-peFXNb)~jj>R~pq7v>HuCM&w#9sdr?gaT=rd(6UwjeNpSpfuAP8ogn8kk* z>0(o1pvcT2G7N`d;#Ef?tzJ+VsXH=X=NJENM<;2(0HizTa?ZO zH=xK&rr(@+vdvb%>)ag5-Zqk3K$$5;z0IT~^SWudMolL} z;q1qhmx~%HQ!$cZU1Cd6lcD-Z+qJcGl~d&!EGvrXGB!tlV3y99`?GLM+%R+|*_obX zw!iD-WLodxs(oavd~?am$UWa@Oh>_8i-MY=u2>&$+ygbk_Le;DKnTrPUFuqr8v@zf zL3b^DG&MSZ^oEYjekEVZ1>>)ICi9s`2AEt=>mT!zY~{ISJ*vH)yVyvf`J?h%pRUGU%rzT-JX9}tI z5mBUFE81>GsGuaGBOq#5c-jU?W2OkN<>PnWvR)6srae>0gi z_2zo)%4Vi58!3(GH8dUm%}rojpMQh<$B=z<`OC93K)JeF{lD%GF>zJQ?>$fHd9w9n z^~z!B5~iactVg$pD$#o?I)e#tD?4wIR`NOt5msRRDQa~?hamg*-r96oXg#hK@y5?2QI+d10Y(H9MiSV}ScfBoxyPFw!foo zB0eR@IPW?(sx^^Yf;DY49V4&8!-2b9F6fG)UDLO7XR@Zr?gXg>>Cw_x^JYG$9aylQ zMcB0XQae+s_&VwKoUk{a*46YE#ZY6#k%-K4&Twlmc1#If;}{JSQ_*|S92=S+J#Ue}NUtw^Y}#laJk~D3eLE&6uH4QYcC7ASZ(HCHp}6JIv7~w_UQ53`YtHp9v0EoO?R81D@Aj{iE8 zvX0SGYdsZEW=GiTft7L-_W9z>-_zz^wD=MbsWD+o5O+!D`;rWPq3}&f=I3r=K3rXw$WUhu*fxjn6dV`p6Y%=AItSgD~>Z06xpVTU;Gk(%LfBQ zLu+%{3*UlkUNZd*nwY7KE3UP5GU`G%mvMcw47cc;P0x{eqz6i!-6&o3LemowE)f4wOx%`jy2 zD7F-r%WbKqNoD4zrhGQOm8+F5Y&h|EqXiA<;YOu@XHo_iZ}6Cd{n~b4lPXV`Y?@`E z(T78y>lD-%lNU(yjn9_NT_nLw85Lz!aK|1x#C}s_4LsVaTTPitZCAbITJ~7ivQzgs z2P6NGxxTwq*oWS7lk>=3gVJE%@4|7DC+WtlDYf z09R4tODEL9$kj&b)skC4eYETOZ%!y&&b77d`PP0b8sv*-FW>V532SgrnBkTaT!h~(;n`z^*2y_SM#<(h|FdTugHxID8g+)s$vLymf501lt)w;C%# z)N~ktO-W8L2X8uV=^ZAote5(lnKwa3lZ;-SnI;`Bn=!qG8CK=jA*Z*hxlgoo46klz zChUY(HP_m@9~PK~aAg^w49N%;mLXjiHy0>P3T(Rx1J(AHW<6bg-H~|}{H)?N z+AnrjX6K-?&q8HK517^Aq0+%?G8Tlstec1e5smPkYUxYNy)AZL9i6VoYB9)}lnkXZ za$z|LM47U6AnX3Fc-m(m?K9&w+9WiE^qbB4|Cs~_BTcNOds;bKxAuv(=zwaa17Z(1 z(Ubh&^N5+fESTi>6Y*42d+pf!T7EdrHCA8FkoG$?Up8C7isz{J5RwwK(LpnGr%9Wkdex> z#ukO@1!wO!ANbG8K&a2QlOV*dA_s0)y@kmzrb!uvr49aCyn>cZ=@rOfPZD;(e zTRnPGi&js)9(LO+3d6Hd-7<1AU7cDb^R89tLsHAezgxbY~`Bc##`gA@Zfgg$UQmKwIV&$3%VOe$F85E4vNREr=8u@FVz!&DHxC6(a9{V zK$3OMoZ#*X`DLrUn_jk+RL2Aj^=nhVg!4VSVjBQ6GvUV>@ZiKOXBm`&pom;RoKs^X&YlaRNmvUqcwg+T>xaQ1D|l#k47 zPVi3axYrCK;a(F(qOoQ7n$zu4g;!Q>;Zs!Y=#TqlE?*b9kq^D8jWvi|1}MD;FsK4C zrKCw(<9Gkr`_5b%*Jgjh*7-G6t!&M2hK9BL4`zZN?nt2AvmPVzq{}3-_M|CiS8kj` zc%6sfpb(%y5hU-S#Wzey>Az^Tp|;=LpjzgZz2q!KXXLG>Jb=Dt`R(`@P74Az@w6b! zdN3_m>dN5vQq8vHwjJ!oPtfB~&CBj*TtA0A7HD;ARr3qJm_AS&$^YN#SXO5~am6{m zS21#9YpO_tzJ%^U7#1H(*6pq|jD2>^Ufs~f)nNY}X`Wl6f=z6@>UZ7uGg$hUWWN6Y z*!v#%uB)p5&-eS?2T4h0qLEU5Rn)13prjK`hcF#EbP5zD2xA+9j%{w=As8qMCUefF zl3~&lCfPDGD$-e~s3^0?Y8BOfMY)PU-MJ;oZA?_*-wcl@KYj(ORY6@=;s_{e`IflF~4>L2|m`Y#I+39O|)Hrx_0cTGt zXx9y&mrtW1H!$DC{F<*h>n?k`H&b@9{wIY{a(G$m9B8ji%k$HEJEyD=DEgB=(AV;5 z)jwLxvOp2H%vfF4GH)I9KS3?Ga|gskd#ze}^mp_-)pN!Ac-$IwO{7DQZ0HWlC!YNY z2G-RZK-A}Jbf?kh07o(UWS0EA5kH^HHW{o4QWfze9t^b;>n3pNe&RJsY^foOi>{H! zlkN0y*S$Cam2Z9Qqy4%3PB>_MQD;iIX`X7DsAXcuoZCHVL}E_e(wlZrKa0%Qvv9(L z!Q<6*VHC|&fzw63v?8yTu#~?tv;V>8OBT>bi+?Lq_UUb21IV{Bwy34_HxTo0e3s!u zg1-mIn~Z!E##h?2u3`cH!EBd*Rkl;T;T8Gt?5qL}>!8_LG;-KvD%M672|}MTbOfP# z!|cFZiS=5QeCt4J?#4rc{k=u+J^9^%WZ^eAd4tF2KWa%vf4ELQy3LktS+y4;gU-nY zn6;LtTTAzTqf7On?|2|BQIIQ-dpc#1UkPB&>*3!*WLM_m6^q=!M>9S^_=9-p8v)z7 zC|Ujf9DdVb4N9t|aX%sSv+anTidZq4fBr@PEQBfYx(i&AzXN0&f!>WlBPYPdVdwOq z4IUDuS@RH9YW04YcjK+{lK!3}KT@h6;n1!WQ4KjV+(k{phRui`+LV_&M|pr|@^89C zE&P{%f`>tYX_t&mku|03s28j&J4Y4TJPrM3J6yU-(59b))Dz`D(*vhm8qK0DbFv16 zmsd~)JJlkrRt49kJafM(Ub)Ob@pM2`)om;yr5AFovdh+}Lcp(f^UN|9hWPqkuF7}8 zG>!%z${qRTXUn{jH~Ge+7nvh#3VsUO{Z%J;X*HR4k~Dj%ZVXh2umqt!tuDHNv|49u zK=#$v+KN7f2PoJ=5`1C*4Pm~?YO(g9TcZL%kM|Up5vQ~%udRNxP8oof@W@;0z?5SD zRNB&}Z9E9Z7c;H37(262O2h-pA~WFFjr9kX80u?U6akNxV>3Ie{3H}T%*S21qGi=? zdt-k)2B#01t7HX( zAany9EK5OIwEl)sD1|i@*oN*x=lo8I5zdEVT>O7dX=mfZw5+Q5!oaDnHJs=Dq|*3T z;7xJbo&AWkLWbeFvmNMi)*>w}up!i9uNCmYw6KR^cxN9Sh~WdC@AS*@5p-K8TuY#**isq9s-}2pKVk)@utXWL4VH`HsSGE%2d;=P#-W zY8RL;8)fkX_*3H7{P^V-8L?}jtr^VZ8u91G>(>mXb6BiT-`L;_vPKZ(3?s;~O4FVo zSE-+)``>Hm1)e29QK|>t31<7>Zpx+ODeaPcBm66=`<6%XocAj%Gi5_R^w?8sM`ey0 z{nVP;9nVoLt5yI5VzVARoj@4^hCGfK_PVRK1LpGs7Ae3Qj6Gs7s*6|+#5!NVV1m(x zmC%p=XqJjFrllF4C2#^`&8oe43tj`v>84eEG(Q@7OBLCg3DJy+`loCx-x#y-mj661 z#A6EnKVJ;YDPO$)Bq>9y`7Ah$dC$UPf*%@hjLS8fAxim$c)zAv;S89nWf!5;mYJw& zk9Jl5J35U6vtHY2dKW$ILVIJzF@W2>rMgrpbV=)rjzNC3+WwJ>du04tl7Y+D_8Li zxv_4V1NrIod{#oW!s&C|y#+wTL{7t#~ z#v0Buf7z0n>n5w}A{mQLro5Nb*Db8Auet`@fz!IWnyTEA`nqgGeQj;Fu_o8tSXWb> ztzXzwUt5!_$(~dR^0JzfP<&;shAJOY{^q)C>gunn%Py;|ZC1Gq*Z#jV>X#7-IC99h2#jW@VUKJ(hNz z^64{Ym0pr{PSQ3tC6}vN+K{8}(^#{#epyY{7@^T^_9SQaB_`JuRh4yBHMR2`zaL#y zgFc9!LI04oPtH=wKE27KpVXA~`q0w)YDziPmvAj4J|3^SK1mf&y1c5ULD|@nI&u$D zn*(3?B&Qpfg^gz`Yn#x*O7x88T(*8ub}1U$xZ>a;~y3Bt>H(&OGOeipxtYrd(c{b*7b0DKEct>XcddUbDQWYJNjwO+zI*n`3oa zhcw@mTLQ)D?mHDC3HclN*xH&b$v1{ZZUD`L7V4@gpV45`c;|}JOQvO~URv?tc_cJ^ zF0ZLnX&?$%G|D8tvx_QGd^IURgN;a)T~b%GyrC9deqrs3>~%GDxol>#wZj?ZNwx)9Fe2~e!jf2Kd^nt3HCb0M+lu+a4w^&j9 zYJR8|6xS5wDZmc(vZdLI%Nm+XrSH&YYfvZ2Aonx^L39PEGceI zXU3AM#`>lj^!Dl|V;?Y;tKfoX#-hue`HCt0nOT!l?XId_LXxSetEyLW)sh^KejBct z`9rsus`8X_7A-Nq-_$S6RYGu~g2%J{R5n&FZ9@H1E9*|mWvLHZ&dQ9U76h5mAnT0_ zvl^E`7+U_-%~drRKkDL#xP>(sMj`ZE_PWZZY&HD%cn2**bD^4kfN614B9NEu8>|lPAxgF&}x5q`8W7kuXrzl4`nB3m^D3f~sJpu&}0F z_2kLRU@#aWYbzVCqEG}wWp-)hauw9*m_TI|{+#lWOC~j3yL|b?3BD30o(c14T+xu5 z-%#1qbX|R8b!o-LRWnbYkN-+%*V5nl!61!iXnLJ|a2>_QfxwW1QN)~T?nWoiik}&I zmmSZA&&{t{)#Eht4TkrEc{L}+67BM`ouz}+nErWKMWK}eUPYmG5`68lB3L9ps1q~J zSNlJrmtss>&K5~aGVaIy{H23*m~9ZNEH z#pEIO;@$=AvPZ?y| z6SH0#y8jFkLMkI&TJudVbW#8-b#iCCVks{IW zXoG7Wc`Ec9-DGt#*#C)ct)BUKNiS4ltE^CMoO;z5JNM@I=+eGOg04VYPe6r{a)_$# z)7R|8TDMh#NPiv5;Jaj`+KkQZEE!I&gk9nwE+Zk0l6$1@qt(AVOR|*49*2zJtm1uV zriCya|iA4@BsqHD3X?BK-qx$HwW&ppMOZvFp4D}s+rigJT|VQB7U(sg-!vd z&5!b3+&_&hCG^OWeR|KU+y|vCUvpR=9cT3Fl>1!T`Bci?l6Jn3a_>t!KTF+=VK>$; zXtM z7^1z!4&pK3JK@t5=rNw^!46KKDf(D;N5s%xk0S-#Eo4G#|iTeCIy zI>fpdT(YK<_&v<)oyG&TYAa@Arh3Ul)r%3lX%N^HS~c9%5ZjX1G=s1!V`bYOjv=%z z&gZr z{OO~b&Z)A@9P(`yZllv`2a3=>Y(hE{OS2nOERIt1q?o3D!a`7?Dl6nW5hIN}AJf*) zrQBU9=fA0X3Rb@XS`ne8d}wsdA+>aebK>W68-1L-4f$vB^+ni0^g z!mLU$efm7NC*#z*&t{xW#QN`2?%f5{r2ok{U!r_}O}pPIaBj=Ej~6&kW*$XeH1)OQ zx^G5mDq_lKGS0@7`=yN2P1UVQyMN0#cctCFjPpEI_x<#U2MSXENnanxxGxttzsg+h zI9&w?f4{)lQ*gXu-tbPG*#94SCl&cZ%H5fU(A}@5on9&jsZRPR{@svr*A_U>rrbYd zXw~7z8RylM`&7p1NW1r;^(0s%J$gC*?MS)b%{V_ux!7698{Ah5 zoUc-CzfQRWuG5-!zw0^=q}^}0&L61G$20DW!&gV1kFAALJGVTin&Zi4p;5%I;0c*;_zL_F*eLLlLXPm** z6vw$E<9@2Z*_3f_E^z)mv&3u2+orfHoV!R&)aKc#X^kX_n^Nvg!<^341&*^l?d}@p zd^hbrHO%>8#{I)E=c@&o+YZXy>$;yg*!jjVNl=FG253C+~0sgIYZ%H}-#>mKdr-0X#`-znEh=Hy^BACQ0Dd&@HE2Cxs zy4uBCzn)Bue>ClUC4HhQ?}$~vKZ)FF=b4ndI_*5d8IG6^!uL`QH)Wizw7VA*b7d>{ zK_7Rg+%LGPucX}H6=d!$IC`C%d6Wd%A2hzVrge`C@_l^I^_63fvclIe#P*{+{dJdXV#pVf6MFNMSts z#Et^=FdXsPmv(XJX-&rcbAj{44EoZ#0y5Z77Py~tou>*Q7RoV|JQq5^x5)V1ue;7m zR57~ff4k28X?Kt7D1UNu#@#y1xijN_W*AvJPGuFi-x=oovfwUl=A+1{Zgh92Na8zF zkXeZqV-EN?QtrcP>ZzYhJAX^fR)m8uJpa~|c0%Cd$U9OcTQbfaBx6+aos9EB<}{V= z(8;46=Nk9pDPmG1r0E6j+LZHY5jl1-()=;yKA3S;DNVV1eSOF0jvKB}M*C!wmz?iA-E_!ku%dd5+B&}4jT%Gt~fBNQVo zFUjBs0rdYNH4mlkOgj&;G!CA%^7|>LpK~2tx$>nH9E2`4kpGamcc=cCa&F^%rnq2! zgC0`*bPB!`eM_-7e4bnFP+zq92$pvkEaQ$eneTt6V7}A6v;iiLyC>yt&d|vFapleM zQq#2i10_|wmhVsLgQ?U0lyU}A$cz;Cosc?eZk6LapK?EzPW^#$-J3r6fi$cRUtxFpV@ceU zI26`QTKV6h*Izi(?Mgdegw)c`FIXoBUq*gp3;&8sK{X$O(CncU4eF{fuip2r)X4en zqSP&jlu{Iv_zexE#?OPVcH2_URu<>*3!%OmWC&9HIk$>GvG=9s(wJ+sz5|nEd-`l9 zLMoW21QeKhku#=wf$7KuTJS*Z9lZpN=58jQr89`uju0JsZ$r^-v{mU9jhL6V6?uhP zAK8B)u)0FgGZqyBXKzt(pE_cUI@<8RSEmW%;|h(PPnn!(u+_wXywutQR&BcNIgt@q zC=$z*sp@$|yt<{-!Md%cDiy&VdSlguNsX=V z=+Rx$rqy_};r{xSryFarA14co94px%-D-VI>G`O}SOYE2R|ZeNEn|oxG3J<157xo` z6hTixEma4Q^EJa-Goa~s5%p3s0qlfemD8HYdR-E5pzGV4v&d@P1{{mYLY>@x2bVvW zhA&eqeacn!1#T1evbWfe#*mNIcAc+LLAxk1ZjN@K@OaSnsCoO$(jAnvJb6spA`?^z?W8HH{l~~jDWg{jsn6P^LoNQsoOxi2yn$ztk+mMX zaJ_$vtv@h|qwsXoCf^T>7@xanZKlRE+gn2hNUFo;xlzpI`SgSqtTel`Q`r_#Kw zPrGATwfMF=^yVrn(A8Tyfv#am%9`vk(Ttj^XA(8<8ho6~vZ@<`5B6-tvtKK};?F49 z<~^ZamGAXf3pQGVS`}MXU#G5>+zG`3tdS!!5*XuyIYnQ@+&YieM13b^u|!6s?*H0i z84{V~fo}8|_i6?OSY0qq)O{BHlC7E^(hXcpg%fBquq|(I0nlX#-cEfx z#+afRvb<;Cb=nGg_T6YRu7~}-J@j?XpH*Io{IlnOW(;T_z{7_pZwJCpoK^WYN8HYVQZa<-T^@vBTcmfy+T&>( zUJOg`i*0Sz?#}ZxWd114a(nhDOfecMgSN6QoPq`Qn76XbQ%5)YEZgZH3kjh28@BZ?a7trO7- z)DtCyxP`ES0dnSNKcgOH^)1YgAIgHqSFDM=9gC8;4?FC52kF&8wo`06wQa)QyolDW zP%iXD({g*KTZLVK*?!d=1h!?nc-g&s9C!?R0--p{Gss}vO}ZR}E|CH=10~l$YCur6 z=};tDq^`&&4BGyH;T5ln4r}JM41!kF32xrtz|=74$yBvpG6{YTMGMI!dM$b}I#G7a zLJvO&AE!BJ5b>4oB!apw3@Rg_XG>$=;Rw$td<$s7NJtSJS%K$@{JfUq^uvQ_CxA_} zMX8Vg_qK#aZ>r`^5EZ;Jt~A!Bd{2WO4&kOr#=c-Z`x{E14(d5H!+C42VvH{|*NN#* z|A*%)#?H8-s>QUZC(G*%gKp4ReZ)oNcMt#YptmhFVfY9603+|WdMn;V<#{{HzTWDs zSbt~_P9Wpt z=7=_UKG#N%CwZ}zw~+CVUz)IN2dixA31k)+DaU*6O|nVj(L5>BS=w;u80ysvpk1^+ zc%duJ{o80UV>U>>$+oGjd_4o3CO2%r}H$Z9e4PD-?K-6WoEc{dLHn^=4<@O#J_F{AuaQH{eL@ zNUP8J<45$YfBf_^97B4Z9sS!gY8dSsy1E=^lD;SnwWWC<`r}}0={|JHh{p&#X&HC| zxE&pQLs<0o+f{d#stZBz9#;6U8`0Pf+yRI$TnAif@EvVWjwFX{p08$ipxz5O15U4b z!}ONz(_6kbgU%3iPj4A0CqX`=PhKeR?Ttt9CvY#O0CkX0?V0j7KOKz-fz6UL`%j}- zM0^&Tj{#Wk5!Usa$716>sTxBDEr%CX0y%Z>e23>4|ITzQ0^5sG|0#l-(H=VP?WnXU z$)ana4Y7IM;LUQmw)Du6_gU>y2JPjhZ8IyQ7d%3lq0KRJd?+VwIT;+F?^t661QmZa z#R?){*YW})3){Oo0c6DW58g7j8eFJG4$EUId)ir2L_3zyze#G^qJ*s$p93l)jX~I^ zJ#+vDDT9m8$|hpgrQRqvqB|H}^UyJJBi_Rhb{gu^nSZ3yP) zw*yQb^o6#~mBBu{XwKGxmthTQ#Kt?b$cg)7Wy>2pMQg(g@~rC2?s0gV_>CE{qvM8| zJH53U^ww&So~OQU=S+O(kGu6T7GsFDcKFnmBVvHSu}8Jh9=IEx1{Ql#hCIwU9+mgSrLj` z={DehXxthz1ksxyRD6w>4`>NQhsu9`eEm-vg3MG0GV%<>w>E7J4H%-kg1w78V5W>m4bUbqZiS1V{4%YdmJsLTk)%>74OjPR9^~POSkGB5%ocDz{#$LLV*+RYT|sAV&UE}qd#Rvqw?uYO;_YqpO- zjeR>yw+jsQfjof6XIe^kAj1GL)TO?Fiyexg0b;02F+_>6Fp0!3w$6SL$p%9V<=&}k z#cmY64pyzRX=VbpM{`d)Or)g+=5XBrUJMhI*0D&!%gxeW)mT+P`W>Y`62`z6%` z8$v2m5EWv+tMkq#D8Sm8YCxA=7>y#W7|YZFD{B-17r`@E{pXsI*{;AJnGIFtGHvRy zIEmSlA$7+r|5=_vokG+@v?$Ri`k`9>VUy5HLB6Hv-$BL0wJAAR-p)RG%km5LSz z0!{#)r+*glOHKy=;(rCIucm+Kw~j$nA)|s2^u2$O3uO)p6F*@_&7Y- z3((QT0Kehi)Z{9+zk~*ZfCRxAStV3IR8V@PLy@g?p5OOaZ51@_ z9iT_Vtj0t`jRVb3Mumz3+g;six!gXhjk_dikfTfT)xT)$y;-8x%HSA$iKvqq-kw;fO=yx9 zB?>l~EQRE!Midj4v8R0uB<92eIv%~q+d3~2@FcJPU;uyG&z7KGOB98qMr2X!#ds zs4R~PL(RXt`u8yB_XV0du%6;n~9011Aei z2MvV2UKjU#PJ+kqGI;$eYO8&Io4{z&ppduUft!*zp(_J|ScAgSo(59z0}={GS}2}Z z$KfDCpJa7Lb=3l;!qCx%4h~V;hcnS{!jH2C{nG^Sh*l#v9;b>JIto^s40hF)GIv7l z1FCA}!(b#>iew|nUo+X{VpP2WRkz#KYMTV?+1eJg$^PB>@;fjQfMsm}VT+%TcHG-Z zj?^Xf#SV2>uw@-g>jW*_>P-+et)k*z^3#4CM{XOAsJ{a7$rik^^;hbR!stf zBmC0H5C0YDVF|um52{{~I>hk@^3ZUj2h<*82j1|RRcr9J2O}XMUGRbl_zeHyIA|aB z*z%w&fWzH1ZW>0d%%=kKkZ%RKi9xP0S@K~;#-{!+#kjZ7BB>R7#EgTXI2e}Ixes1D z5GWQxc7t$%gQi>fMZV@pDV!0V+PL1(1jk$SgEzJVi-1<&noIrKD9Kk{SjGq+w2a@- zxs=h1a*nVX&zXAbRN>Q>qv6c@9Q871KQZD16{~nFR;+&82WzixP0Mr@WUF3V}FDIYX5M{h`ikL#i<9I)Su z5XI7fnmB+NZ3g*gkJD*dK_Qb)T%H=R=aUoEd~(W_zO_L{N*|Fy`*jF1f{kFy@Fl93 z=Aia)Y|!^4Ek&CqV5)9gk9KQ`3qYvbT3`xTx7}0~56|lX4>ZQ(#wedX_0tPjHB}20 zHf^sv+w&)z(|Ea3FjN?cCulu5F?i68hQJEJ05YgMBxuFVuhqDGn$uINLB5jDPGj39 z(y^u3Ql?UjguP+{tHt5Doqlhk-+fzlDz(z<6BQHo+{Ipdk*x2)q~y0>D(|&eGo%n` zbNII{M;2lpTO~Umuu65CnMg8{feJUjoU*-WBQ!w9G2^*P9ojN z=(Q~HJ}g2#_e%W~m)Th?nrc-NHTOeuukQqUeZ)%9`E>8*Hu`;ndY4@e{j@sqYt0wO z0gXkvg)MM}cA(V)E?&b*T%gT{Q`H>L8~J_tKu{m<Vb!}=h0?7Aj?tbK@n`wdC=kB_{;8QmPe+9ff=i*pE!))*ET7{z}90TkP_u##Q26@rtxN@ftXP9 z;$#L=N*cz6y4=_EP)&(mq&ODe|%ir>(ovk_jR_a$iL zA75o&YCw*9eSghhCfA5RH(tMHFrC9;(e#ZCc)i3yIJ%uXs=o#e^Zl^7TD-7-hL*Nj zKM09%bUz&-w?s_JK{1|1^uOIMw>|H%Dq|zDLr!o-K`*{~^_I8%GGGvEcIYifQ=&Kb zdkvCI$m?5q5nk4zu96*MttKb@P|$3OVNI}i{|r-TrL_Npyh7A%3{kJ^Y!4m_(C_#? z3i3xfwR3N!FYWFx)D)vxq*}A8+i89P{kjVaqY$pAMWpNnOdI8a7d{08O4DU*cFjSe zHe6^M-n>m*Y|U%oTpK!L^8gmp&{5Tl8s9y(tuY|bAEaH(yne-W@o4m222v;3h`D73 zuqR(S2Vwv2>MsWZrIBv%f``Bf3hGB&ESu&7L`bd6>mLzJk8&vgE!&&Fh$9rx-wZl? z1BH8|0_fe4Q4dCpqyrCRnH)j-mZ{pWQ8+=Gs|S{5*qZ(Hx))a6scxkZep3S+k=e za{3`66k8zr{?+bgE?J>(o0v1*Z#NJ`Qxt#OVA!`UMtcTUTwNtk#*S z{$qk^Nh}b*S0RSOyc;3X3codofaSK*|FX)AFVY+DsE-!IULaT5_fw zzyW)`FMv0gz-#wI+Ld}*mSnP|SSZ)u65c&I8UaH^o!k!Vn!hUW= zzsnE&db)z%n%sG-iqpy;)6mpX1!rCpWow#Zhqll z-{}2cD&{qEH~vW2E3gEQE<1ottkL)vjz|6LIZ1e*^E7=1dObM=I80n5a2dG<%2mj@ z=-&bJ<|Y0aX7X!ph`z5~JyVsS%53wBeOU=x@LmneC;Fik0oWw)FyI>()r2 z>axxu=JjwvHF|8eUXIQX|8ku`Ydiz6I>b;tBr5AQ9g&ZKicZtmL#S-40P&9a#4`V- zY|MMK4s)B>r;OlrBad^CON~5(VUK&o^?Dy57YvN5h8S=(q&%;@LDA-PN!>W(I zH5-cYH@>X$OEQ5^f#T0oqexg%=u6C2>u6N&j{-C)+bKUBuEm77!!(LR z|F}^oj%!PRK9gQMiOY~ogZn{Y$+gYN2DtYH8y<7=TjSqDWzTI%-;}0=6^VYI?mNcs zuQ4rtBdsXZ!7vjxifknt#2k)I(HIA#74`~d)RsavYUG>bJ70BQ646gL( zqNN9Hw8YH7yJ?Q~@(pR4w9Ve2vwA(@giBYk5B%^$GBPXq_{>2*(|dl68CE>vx6dcRO`4<`FPPBZl(-_p=Y zbR-RCytyiBk1kTJ*+Gw5NzsZm6Z1WgB-XE~WgH_3FN%OEVsFIrYjGo8zM6(o zw-JBHw<`O5YkUsem1xG>Ax1}0Js+5?y#e3Tf6OTU=8s!qq=ufF*KExtYoX;ZefY!g z&Sr6+!b)0iA}7aPNWJIZ!m}#@=vC)2no|pyN2PYR<3RK&Ph7Si$ zX8@&xMFSP$Co&eow+#eQBr5zDXQj}{DzMfY^kF2qLA6#Ex4*46w+G4nVqMCP2Ls-( zwPZM*P@q!>NLw~s|Leq@UG$U~nfH+vjLW4Vfb;~uydfYwi7<1woh5Y853yMOxsbk@Lk1hZnTo4y2+8!Lv9Q$e=oHkfetHyA z#Z)wSkDesi){?@qQ>j<*bT7EmV?0Uxd?#Ec>C&4fzR0*Fop8bpvWSo)dT(&N4yxG z-^jVP=W&fQ3wRLj@@CcDvUtxKSbf0KC%M(Y#!t}phnVuM7$|TTD)kim?35b30#Xjy zeldJ=4~EKaL^xe`k5*fQe!v5#{MMbneD*#vDn)vT<&~nnAcFk8HXInXtdP$Pa-PSH z>tQM)@gf7St9nd&u|ka3dGpT=yk>X}iv(#D26mUFwwI;4)lCFSY6I3dW%U>nds<#D zApFQ0X;9+9=!F8%yfLAF*UJJ_yaBzm9ldlNP9+B(e(b^NfL6e5rH@!#<0lq3W=9|| zAf;7FmFvq^uJX2}Uq%G5+PHdL3sc@&v!%S{H&0DK7{N=B&z85mQr_}=bDv*X3r>T# zm7*LDFHm*phz^#Y)Q#|kD7@24N3Ur?G)|oQS-~-zBhvQxS9i|ppFv8T-tru{F;$nh z^oMIU+4b95=m|X~7-lVef46?k<&=4WyKTs7;7RT9En-OFPTOnhEmI2}R^*?wX_?1+ zgep<}&9BH`o^Fpu%DPk)Iaw~jTOAJ?rq4qB5|c4<%UM`1&ZY+Pd%nZmS+w{cXU8=m zJEpsGw_w>kWXHd=jOia^$0zvj7|U;%i`At|maB=_pzn@6Nt+oR>=$z)djd-FmOcHV z2`NFa)bIGV8+ZEI4hvqx?9k_p8-TL`MbT#ANyDs#M*K8QOUQkoYtlb{2Qz4JE^q3> z$;gCKjq5Sx45f724PB`ZS}CX#sO_| zR{Rta)|+BH3yfG+nCOp*ve7Al%6)!XONF7Gi4lu+olGV z>E%Wp+!9}OAsOek#TXfqVgq>JS-cso-IHmor3dw~|Khgq^$v282Yj=Jmpim19SWrTPl6Zh9r>uU4o{u7&HgX^!hqlhT5IsCwz4&) zcu6S*?&p;DG=H}pUk_*>F{FnB4Ns!B7CQwD)$*no*I$dLQ{!0RdT>LWug9HGPYsQ#deuqYd?_wFS!QI{;Eimd8X^HpaO|>+7zk{hsu(}A zIZ4g+$1=~?kp73hHyUq0lwVell4IU@W~hFVc#Y8pS!*#=-Gk_>JAU08B#s_DYXC%1 zOApS&;$PvR8Sj}bEIQ#T4B$EIMO4X+8dRD2+Fq~t4iMj4zQ00sz$X!RopVa8WT!dXQ1Bf`XZ++C?MYc zxzT}6XpQT!Pmz%4e*UR4I3E+IdioDtE~5$j3kY?cCkiZNboE55N z17mjoTx%Wew?AntGz|N8KNQ5bE7CycZ2fTqoh&rs_`Z)~(!V{QV9HZLlC<*V zmlj#F!0Lwazy4x1!Wnq$;QDzaXY67}*arm00@XY)8fZ_T0SQrF*n@dvT71Ns6c5J< z-V*GA*Jfqb!BbwXSgBvHswkR6M1Z-8IeoUXgdSs4a}{6FwA98IMZBSRS_OO86*DWLb7ijCh61Qa8og5*h|DGtz zL~2Pw;~Vy_)BFQRVY4T5Jal~L#|&q0j*SJO6Sz1DhuA}kL%qDhi_NKse`51d*pguTIB3TgFwcz_gl8DKN{ zIC@e28~(8xtS!V_9fZ*m)1K`n#iEq<$qF!RjQtR`B&97tK6s0FR!nN${44gp%jKvb^WJLTvSt;Yi_KW zUss=--_+dDP~Qma7(y93|HO%nm33Fu%&%!|tZ&Sli_;fFy~}DEo1ohH_4v}*JVX_9 z{xhxo$(4H2Gwq!?sj~5^=A|`txg?fN`YOHvHY_ZHr8KLQ-^L@ zS65SY02Z(LJ8Mzpl3J)QujrK&U_WQt{U5eeGd-dAzRqI=P3NsK;;qt2F>3UDvq{F< zH9O!)U_!i>{T0y2J_>FXv^EB5T|6)$vFxOTrfi|32Vk%(SOBf11TOGa_e;-s32<-l zgs?Xe&?H^0&duKu+l2Qct(aTKehBZPCzSQH4KDyx7h?CCOPu`KD~@Xh_I>bs7zsP> z(!fXzAK*b#6KB3^K8FfoW(PcP@B|+d!NGr=P5xtP3^Km^_M%T<%OxEM;tV~9S1MQ0H^=y^KSZ6 zdT8Ot(o^3)Y!(vWC(+I&9G~~nA49M9>2nFk=Sccv=rer!O2Y9uoc3D3B~~0O*lU9pg)E_-Os(Nfn}lq<;`bRYdZ+Q=u1 zA7cr@=REvRGWF_c_Ul+chgk3-emwe2pT3&ur`hyHK7A9@vo`%hK7BjWPqOJ(`t)9= z@386VZ>j`}Cl~~Ms0|)}7XMkMs}bDDaHU^<3DYmO^QSNH%3r|rIRW~m9(^^_53}iI ze)*f2F4@?2rc3hcWxB+_=?GH!S?(xO`6W!3@-IlpznbYI?e<@2wLgKro$2qf^UwD4 z_cHwmn_jNzWWRkZp8$siiQd=Ho`tf%DkNEjtWco2S{ewPzZ$kbNs|-&o|yF@HEtw$t@bdTWaX8?a-ud2GJU*Fukm#@ng)4%BziH^rTXV2(3dCBHzd$I z6X-n&^uYxB=(p+iOYJLWdNCz4Hd61~;T)zn+H}&P6(6nSG}73zk?E4Z+s1T>$K6bq z`sIG6m)JaB=i9)TgNficQvK&LUGnF1nJ)3SlIc?XwUOykKikIiQ;12U1FMhhX8K7s z-HMI&=gCigsetL9q3?DXq{lmbIZZo+h>lZEe+(b#sVV{WwQ8nIe6D4>6bEl+dYl}I z&xe`Mw}<_B8Tj0<`J{BaINc-o9%;`eKb?`wkHh8ZacC!v3sl}%=4%&Xj6iuh-Hr^> z6(L2<0?l0gyk(-B|a2C6TMbQPR#621rcx<>O(X>y!qTsTdY zPDA``VSbLqcaNVrei@xZsAo5)p)vxza5%30tV-*Q(vIV_=Z9rr(w;(6 zfUJ;q4yQdxO8bf~mt?z^(^8Ba;8WXI1KAhJWXGZSgOB8=_Aot8W|Y4`1>a}~6=HO3 z$$Tu+Yi)X3C!qY(m_92&zgV@I=+#U=&ZcvGlm%AH{QU{v1MN)jRb^0`4ld&feD`=H zKlEjlM9nW>ZBzf-QdRoFd)$&|HlFuUDeol88z6bfy6EkX4F)b?K6X%mi&n3)D zTUd9-CYF=-v`y4<+S{bG%{pxsor_2S$hpgvxG>!z?Ug_IFH}e&z7pkj=%Xlzc z2HDaEznsykVe;BeaUMF=Q^I^)f_OZ@t8UXdE~+9qujX>%Y?kPo66o6#=)HO9S(M+$ zeA0Lm;M0ng$EtzZapoh9*Z0zTVwnXrj_X)}?}0MXdZC8oQNd}R45v|jFZ~Efp3*Jn zbYBgpBmHdF`k{12F5inw_pGnSUglld!xUb_v*yfZ0Z_7+;hg`}u+KnjkvYmA114~~ ztHbF`f1j<>l1_8H=r|GIJ$WwHJX7CU$z@$Al{Hb9H34ZmIPGKMv@<@Qxuc-Xy?xl4 zgVO&!zOZh*lfE8RQ2qP3{tA5e>Q7&!7$Ev6wO9h3#n6erF`WM($zQ#q`*s#-%Q)?^ z_#Utg9&4$-wOrph`0nx3=*wd>(`kJ0=yv;F(rHN^om}4q`Q-8W@!9k(e))Sj&rhWG zJg5CH@j5{T*3#9ue_ zNAmV$#j>Vydbpeg@#R!dIh0N>T072{@im|~>WBAh*-?EZ@1(?z(?EYr?2x`nB_R3& zrq2z~^#U-_S2JDef9tqC$Asmn{pbjiCh@z4({01|2*1j^==JIzPWP3#bPxFL8m%58 z0RKqmx6AiuS>`)mImA~Pr#mFfzt-Ddjo#KJ)YrlEM{R!Cri@=Cd3JNUwUo~IyY!8! zVHDr>Fh4Kjdq7ThfBJzhhpbxgL<~pedHTIVCCCCQVfvqJy7uY6rbHxza^`7P*ydnM znF~n*S~odP_W<$)cq5zpgyxCL+sNrw#LIMvv56g=?)%|-wd|jvn#pJE<#gM^>1>(2 zGQRM7%ZC;pg^c)IPJcYP=*<<-b5mLFViVr^ynNb65TnP{>1w;qGy?|hGo-EYY(X;fxdw0QvIu$ejG7j%D2`| zH!=NYo1R|b*-Qtw@2s%yw2n_Q{i~15QQhCvW9`K$VWN&WeUUy2IsX!TkJzT}4r&fk zp@ixMrXWt zLse{Jx+II;Oh46b%R;{$`h@8J}4dUmrz~f zR6}H6QOK|iI*8bRtEM<)M0jm93 zMUM3mL@!UE*Cx1Wfhq%Mt-YVq7_I_sf~21}n!|O^Lm7w3DTJW-(pr2RWuoW8!+I z6Hi|G))=#u>8d%VerrCpi|LZ?_A&h?yL{4JlW%LIk0+wzoJ@aA9oAlNG1E(Jx^*sM z4%6d!AQ>%ZdYlZX-K&|$`|-WNt|R1=wkOon%XDe4(;Q-v+L={Ka2!e2B}|W-%TqfS zFkLEtHPg?v+sJw#(mLk8>1$gdB(p4`rHKi$^`mG zrc3>ITb}%+lO5c?eEqkN(1N|{+crk>^ z$#OjdVH?zbq}TY71ze6Kx5Zq}3-RSVZp!IMD96Z!-U=I*e`cKS6RQ1OU*xP5_0?B> zJ&jfq8hJiY%yg;m%t@dxPoQr|pm!$Fdzdcuoxwc$v!rvT=j%ITIZaaEsa8zH_Z_m? zwM>5p)oX0lT4UdwK;OaiiO{{5KU1WXPUY`m`ck`mUZ^3P*vsvp{1MwZUfT|pGwuv3 zz;Q07KZeir1YF*{vowy6vwS|bayf_Fd|1!T>|(lPoBNnP z(#~%^b1-TW5gdnnncq%*ke%8&iRn`LvzRWGpG%;xXZqEF`YSy-Z)JL%Pa*zxG5sBO ze#@TrCD2DH1>szmouAi>Rr{GPl|PH=l74bbFR{zF_9)gT(6=)ELOcH|-*@d|x}=|d z3G`8CQo-_bQInWnLWzu>Tl~*r`jIx>+H1-sl)s+oicM2Kk6|SLtxPB19g?NZe!Z&r`tHq zv34439dtL-B|F*AbjeP}6jQD6}mX}w@f^gRjr3sk|5bDW*u+Jha-bhQO)+Nrk;oh-4#OA@0abH6D!_{Jk<2+#JPk%}^fcPt7`icNuFM4Ew zl`;J}j9s2BKn9t|{Bf(6)079wnCjJWJJS~g=pXXv4>LV(u9rog7nvUDGb$cUs|{#s z#{j3fAy9{2JS2Ld+RT)nS)IUiNskpwmwZkkVU>(Ob_UR`h(@WmU9~NBc8ojdpsMMF8Q`jrb}aN57VVK3^HAH z3)819pE8;@rSXyURLt~zdYa2=;^Z_2Wv|Rr2hle&U24O&1p4kg^=DE3ex~QsQ}#S0 z#3xP5yb+d8I8ZS7#XB+D+QUvKlk13t;JkLhtf zp4u_|e98zvOn(f27vGU-E4bZVGc2u6Bv3gMIGyCfDwtkrmy_0mGUabzx*C#9J=Sw$ z?M%Pc&QE=(${$O%a+*u+G~BtUj$KTTTW2ErKBlX!HN%5-CU{f{6&$Z~%0H=us4{(4 zi6T2?^p7cDAHh@SUUE#A_+QU-Nyb~5F3m4?CD8XV{TK%y!=H5yV$>8OIF4E>HFQ1w zaI(P1l;96Om*M|_&8Pk6Bj#`!hf+dQ2CoHX0WD|x*8+6t`E$OWH*y-u=C?6j$-%7A zSo6T$HV=kw&4czcT}^)t-HNlvDCZ~pz;l^?W4H}goV|e4NNrf1rw+2UO-z4}T?e1T zAo}(MdT*ZkvsC6(`hzix{&;!{j#Xnh&9QbGjam_hT*q|D zraPD}*=!fnkF_1G;w~3c-+nO)A8N2Me97>ex@H`)64z-JVp)RjuRInk42uboIh#p zzM9L48w-igwM>^}xtZxwtiK~q{w&Jh!}NeGLpC*hIuha&*H+@Oi0P7lEn|9|J}LiV zrc3j}bxfCRx`XNYZ2H9n9`@#`gLoXFI;}kK8<#*YXL_6rvM9fn=>a{2Y`UG(NH)EN z=_+P1eV?Blqc(IiUDDG4((*`pjj1pP0aOX`HTL`f+xCYaZ0V^iyoQ z60(@Vqalb(|(n4%CJYrb{;0#q>CP$s&Ir)8Co0cu=;IIfzzhsg4m! zfR6J#zI%M8pHNH^eH_zg2IzXinFUtP^ha$v>8itTX9K5EL$Z;DwKmYsbg7+N66oDb zKQzFDU;hBpm)dmeZl^+;)Z_DB`eXRB&h$@U`iE_LT3>`lGOA#@PDh`_SqH`q~8gW~Ohn+rejXNRB(0z92yN z_f7UBlwY6%GMWFeOplXe7IjWz`U`gb)bGFP_q)ZMCNA!wHmu822hls2e!N|WwPx9s zK<{I^+VV908a&c;h{_*6n+lG%`7H1vrqlT%&z6wioGqd<$~lc>@3l-n6KTCNmijWf zo#}x&h;^>`VW!Wq^QZM)npt2kGW}MYPI{og2pI7=z-a<epjFM3u<>;@kxK+ywecrXNm~7+G8Ew;L1kZ)19#{~}rLX8LJ%`PMvQ zKhxEgsHxvtBN?L%O!{tc* zvOo>yvYy8#(5Eq7nU#@aS}&wfJFA&~q%9|FZFX%!`J0(8#S}Z3F2xjkm@es|;3LGC zJl`41^f>utk#8E)^Tia4IZYf7q{{~8F-ezO^6)~k?oOZ&B+v`5Kq2_NoBkMG&hq`^ z1g1-Us)FfpvLgN(m@f7CcBY?h*Ke)aZDD#`pUEOmC%11hz6W9!?$?xNAD3|rzI$z? zal(3*X7pSl%6+1k>2dm`cFswlFK7DsREd!@cpx?@{|2T@<4`BlrFHZkrpNJ@MfrnF zSK_kj=WeUU$}#hh5FbgG=O)nSCeT+hUE*;q^EeJX1a!%J!CBzjxr}_e+{0<4Iak4z zC5nA~T9(fO8q4(SGeLSr-NJ#h;DF0G%^&dHD?_hEyhOcc4B%Q$bDW*VS{u8a z>2dO){0}odj!&Y$$n^Kvzb_&GsD)Iqe4pkdrqdYX$;XNtXE8ls1N!*5KL5e=_uKic_2u3AwNJf|>1s*L=+`Sr?bE(F+HD;n!{-%AGJJzz9A2tc<5w$zHxsyr#S}cJw00E&3>jUJs3S-rp!Rc zKZ_`%+z-xWx@5<56X+|M9`F;^Sg|or{aNs}jp_OH(93BgJvdiU3+3@Hn?NsNdYr9~ zMY&~Mf6_BO>k{heV7lb$Pp7DX>+dOls<&S@lF zJ)A&)F@e69>2W-gUl^erp1kilj_FeVa;8iDp_b{Vlc-I9W4~PlD98Lo?%ejyp=PSh zUQH*Lb+}!YwRY5#!0RB>FS7Ha@0mT+(N_~e?ia;OKZ_EXwje(>hh#a2>C!&Ra;8gT z{Dy@3JM-ixS#Ia{Mf#n&hx81Rq#o}IloOTx+}H&AG^VR9StEtv$K1Os9FMN4L%+PhJFG*aL1VEVCk9ac=<#q>*TIzN0*<@YgN>bt|$h9KUNX6Lv1LlM&@ z{>qpx^@qhwf3ID>wXe92=~92_V7gR)S3>?irc3+{uOr6fea|AMOZ=53&=)gZ;(r~} z#}gCA2CaRA4yH@`>tgy;J3sVCPxdJNGyN2s&gX83KD?d?j`L3XW9q*|xd>&SMNF6c zZ5h+!;s7dtG1HH?%eVHg)-nA=n{KVgbue9$Ul-Fy+xhj@kmA3O=_=$i?X%vMH@tx| z@?+nIZk?+tV)~(!$i&1}OkT$HVw-O53oT~4iZxAsYi(v7(_-r_BT<%jw8u`64NF5&tkeH{~Xh$`qwAq-^%neh)L7_t9|+IV!GsO_A&iD zJ3l!}{3iL1$`K*Y`VZ43`<})0xb>GT%AL#g(_Ewg|9fq))`&K68IlY;nJ)SBo&+8T z^U!JD<}m#gd=2o3F(tjnmsLqKC6@cjf&}_%rc1WAiRqH9Z)dt>OTBsWXNmD;^v7|Y zr9Z}&sEuFu+c=ifoNA}xyN^g#*MxtzGRWI?~3>Fe;_<3*RD zR_~~cEu2P@S9hK|DE|P{C3zKIN0rNSfeB2P>aR%1-;h9WPoQsMx-`yrGhKx{MxSXN zNU8QS{cviepI-8&N(JXR|H5=>A7d`lCH<~sy2Rhcgz~pBU6SAKg#7!NzL6Sf^k>DP zV^$I&kN)$}v&c7>=>cD){keMbaSYO|<}@4eJ&uP>OqXP|o#~PedK1cbR#C-r8?#K8 z_$x`szkunZsS+b&YhJdR=>Zv8{(4hF`P-TPe!F~YFRhp9adA=+^7OHM{vF=~W4E{F zn0}0U)ELmm-9VMdvMOi##gxdj6=Q?h7prBuB#YabuBNIcKVQmD^*_w?IDbHG*~)FD za3s(cb0>|pW;MuVN$W|YZ$u&ZNOo78K%c|(iByPbi#4BK&h#T~x^*UO1JmR9qqc5h z{)eKsJ$cF^xfZO(AAI8KBKp|X_=AtsmT9Yr>Nr=@AJf*fp4?OZ>ecvzk2GIeyPBwu za~l0I`K@z`n^zOTalV?uA4BJthEn-ER^tyoQu%vU6ICw1;3iF%@{eV@#NV`p{M8Bh z*CyoOoREJ2hzsJsRtsU)PdYq4={Ck)#_2q&!RIohX9n180Q6j^ie&mCY*iQ;*f%C^# zM+N*b0q+#>#|8YG0=`YapAhgT1^g)i-!9-!NAN-jIOX^_ z>4QELD-mvfn}5q0Pg5d%3{J~_l-^Wea7vSLo;5K2^gbD9hk!pP;5!BU1p)te0snRc zZwFVz|GCVa8W;I{#_5ivCsM}wzJSx4o}-_P^CJQ85pa6bVDyu5b_@8=1-w_le<9$% z67XLO_-_QfFM>aY=8&9AxLH9tzZ^+V$uiFG1bnZ6|6afc1pE~N-zVUI7Vtp<|BHbC zRlxry;I9g}4&zv)-ai>9ZHw2!3k2L1@Ph<=xPTul;3EY5PysI#@WTZBZ~-4B;71Dh zI|Y2SfFC8`M+^A71^gHRKUTnx7x1wHeu99XDBwi`eu{vP6Y%i@K0&}w7w|~}er5!x zc%S^t@7U_?j+1fDilnDx8Ru*PKS#jdAHnx=z5l`WnsJc!^ogI}hj99tan6sFqwy&M zK2^X=1^glbpDy4Z5b%oye1?EuD&Ut1_)GzxCEy|r|B>l%Y{kK?P4+hdN zjilFdtB>Fhb2&GhsS7wJP|mfH^nc>?WB7cMniFxJjMEfJuj_4&;4=}ZlHS|S*O|}Z zGHwH&a{PG&#liIXI^*W|a1A@ZWIW5i&A(INSg4#5#!Y(qnQ^X*@bg(tU%}~3Jrt2r zISUvMma`&K4n-8yt`S%34D_A?`aF)5gr7M_|6Z&AagK8}zGA5cHZb1F`2Q@_z~zk7 zKN;tvk$N@0O2BUv@S6mDjexHe@LL4@RsnAj@Y@9Zb^*Ubz}p4jM6mfOiTw^~&fc z<9tKFzbW9`1pG+>-!91>Ge_p`51pHe9{-S_?N5H!U{QCmFOTd35;5`EV69L~X z;6E4e-U$95@VDgWd)XYamRV$+Uq;dsIph3F!1oCFuLb2fa{Eq_u zih%DE@IMRqpn(5H!2c@Xe-rRm1v~|9Mn4%RBjB!pA0*&!6YxU>{OtlhQos)r@WTcC z2mybmfWJ$?j~4KE3-~bteyo5WFW@H#_(=kOvVfl|;O`ai(*%5?fS)1Y?-TH|1pI6P zKS#jdFW~11c!_{tAmGyk{6YaQ6YviRc)5UIBH$Gf{H$R*P7cpIKEe25Y6IGFMsl|w zbC6D-W&BXa+ZZ3uxY`p0?I;BH6ray$`~psY599YU&Rda+nsF|V@JWP>GfTifDByDh z{38NBSHQ0n@C5?CP{6ANe35`J7VxVDyjH;L1iV4O8wETk;L8Mjxqx3U;420E1_56! z;5Q5SS^@u|@^vSBf`cKArIFg0Hv;}!0e@M*e<$Gm0#38V=qKa+ zLBRhg;QuM$e-iLN3;3Xb|F?kuMZot9`2PsFgXk;z$v7zi&j`3H;0Fo#Z~;G9z()x9 zp#nZqzz-Af!v*{Z0e`1}ze~W67Vviq_%Q;W74YK({CELBLBLNG@FD>}MZm`i_;>-I zAmFD9_#^>8Q^1P_e6oO_BjD!>_;~_eBH$MY_*4Ne74VA$e7b;tK)}ld{1O4L5b(jb<-z*_~pO~5}c;Ozo_R|J2K=Rw(e zJ-!$7Fn`s-G*5Xt^DW*8<>`v^9OM5U!cRR!&!^^aIj3+rUuOJf#?5~B^bu74_ffn4 zn0?q=fYbWSc20j3(|^tQPZ)pDWW>K2=k7?mh@5fO3-~<(zCpl0CE)i7_@@Q@GXj3U zfPYrN9}w`(0{%Gxe^9_bFW_Gg@P`Eaivs>70e?imw+Q%G1^jCQ{&fL=Ou!!(@NWwE z69WFEfIlVRPYd|70{)zUKQG{20{$%le^J1{E#Ti3@b3xu4+MOdfd5Fqdj$L^0{&A0 z|CxZlB;dUQ{tE&BrGW1d@ZSh{pMbwC;J*{_y#oGw0Ur?XKMMGN3izJ{{J#WzP{98p z;QIyqZvy^50{*IiJJ@B2elRZ<@Qi@F0)CKy4;S#a3HZSRK0?6XF5rg>_(%aiOu!Ep z@FN8LNC6)$;718K?G{Bp8RtC$evE)0E8xcq_z41jl7JTp_$dN@s(`;&z)utKi2{Cx zfWJ?`&lK=t0Y6*7CkyyF0{(shKVQJ72>4V1FBR|$1^glbFB9+&2za@GUn1ZY0)DxG z&lK?40{$TZ|FD36M8M|?_>}^_K)@FYc(s7n2>4Y3zC^&U5%8q~UN7L+3V4%%Hw*YO z0l!YbR|xp^0{&3}UnSr-3iwR|ezSnD74TaG{8j;P5%5+4r&9#cPsaIp1i$g^dfvLa zL8mwK)?UUx#ke`2Fd1KHo@?$4Gx)=dKg#K+aP=pQ)an0=adVzwE8|7i>V!vI>}H%h zBYYA$jnHC0pB3tpAzu<1bm}_|C@ks67bIo_+|lrP{2Pg;9n5%hXnj#0e?im zw+Q%G1$?W3e_g;I6Y$3c{F?&4O~9WN@a+QrjDSBY;Li#8P62;G!2eyqzb)Y374Yu~ z`1b{Tmw^9BzZMz^es(k$^82@T R>127yk5W?1iVqea{|6hz^@bV6$1WI0beEH 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%0Axb}Yye~*0q7VbP@9()}7ui?%I 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

Set>}Q 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 OmN^g8T=Q%ylr<&9QZ2+f7F-nFGqXPR4FeJ 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 << '\t'; + std::cout << '\n'; + } +``` + +Result sets are immutable, so all iterators on results and rows are actually +`const_iterator`s. There are also `const_reverse_iterator` types, which +iterate backwards from `rbegin()` to `rend()` exclusive. + +All these iterator types provide one extra bit of convenience that you won't +normally find in C++ iterators: referential transparency. You don't need to +dereference them to get to the row or field they refer to. That is, instead +of `row->end()` you can also choose to say `row.end()`. Similarly, you +may prefer `field.c_str()` over `field->c_str()`. + +This becomes really helpful with the array-indexing operator. With regular +C++ iterators you would need ugly expressions like `(*row)[0]` or +`row->operator[](0)`. With the iterator types defined by the result and +row classes you can simply say `row[0]`. + + +Streaming rows +-------------- + +There's another way to go through the rows coming out of a query. It's +usually easier and faster, but there are drawbacks. + +**One,** you start getting rows before all the data has come in from the +database. That speeds things up, but what happens if you lose your network +connection while transferring the data? Your application may already have +processed some of the data before finding out that the rest isn't coming. If +that is a problem for your application, streaming may not be the right choice. + +**Two,** streaming only works for some types of query. The `stream()` function +wraps your query in a PostgreSQL `COPY` command, and `COPY` only supports a few +commands: `SELECT`, `VALUES`, `or an `INSERT`, `UPDATE`, or `DELETE` with a +`RETURNING` clause. See the `COPY` documentation here: +https://www.postgresql.org/docs/current/sql-copy.html + +**Three,** when you convert a field to a "view" type (such as +`std::string_view` or `std::basic_string_view`), the view points to +underlying data which only stays valid until you iterate to the next row or +exit the loop. So if you want to use that data for longer than a single +iteration of the streaming loop, you'll have to store it somewhere yourself. + +Now for the good news. Streaming does make it very easy to query data and loop +over it: + +```cxx + for (auto [id, name, x, y] : + tx.stream( + "SELECT id, name, x, y FROM point")) + process(id + 1, "point-" + name, x * 10.0, y * 10.0); +``` + +The conversion to C++ types (here `int`, `std::string_view`, and two `float`s) +is built into the function. You never even see `row` objects, `field` objects, +iterators, or conversion methods. You just put in your query and you receive +your data. diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/binary-data.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/binary-data.md new file mode 100644 index 000000000..20da8dc0c --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/binary-data.md @@ -0,0 +1,56 @@ +Binary data {#binary} +=========== + +The database has two ways of storing binary data: `BYTEA` is like a string, but +containing bytes rather than text characters. And _large objects_ are more +like a separate table containing binary objects. + +Generally you'll want to use `BYTEA` for reasonably-sized values, and large +objects for very large values. + +That's the database side. On the C++ side, in libpqxx, all binary data must be +either `std::basic_string` or `std::basic_string_view`; +or if you're building in C++20 or better, anything that's a block of +contiguous `std::byte` in memory. + +So for example, if you want to write a large object, you'd create a +`pqxx::blob` object. And you might use that to write data in the form of +`std::basic_string_view`. + +Your particular binary data may look different though. You may have it in a +`std::string`, or a `std::vector`, or a pointer to `char` +accompanied by a size (which could be signed or unsigned, and of any of a few +different widths). Sometimes that's your choice, or sometimes some other +library will dictate what form it takes. + +So long as it's _basically_ still a block of bytes though, you can use +`pqxx::binary_cast` to construct a `std::basic_string_view` from it. + +There are two forms of `binary_cast`. One takes a single argument that must +support `std::data()` and `std::size()`: + + std::string hi{"Hello binary world"}; + my_blob.write(pqxx::binary_cast(hi); + +The other takes a pointer and a size: + + char const greeting[] = "Hello binary world"; + char const *hi = greeting; + my_blob.write(pqxx::binary_cast(hi, sizeof(greeting))); + + +Caveats +------- + +There are some restrictions on `binary_cast` that you must be aware of. + +First, your data must of a type that gives us _bytes._ So: `char`, +`unsigned char`, `signed char`, `int8_t`, `uint8_t`, or of course `std::byte`. +You can't feed in a vector of `double`, or anything like that. + +Second, the data must be laid out as a contiguous block in memory. If there's +no `std::data()` implementation for your type, it's not suitable. + +Third, `binary_cast` only constructs something like a `std::string_view`. It +does not make a copy of your actual data. So, make sure that your data remains +alive and in the same place while you're using it. diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/datatypes.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/datatypes.md new file mode 100644 index 000000000..bc14c8b90 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/datatypes.md @@ -0,0 +1,373 @@ +Supporting additional data types {#datatypes} +================================ + +Communication with the database mostly happens in a text format. When you +include an integer value in a query, you use `to_string` to convert it to that +text format. When you get a query result field "as a float," it converts from +the text format to a floating-point type. These conversions are everywhere in +libpqxx. + +The conversion sydstem supports many built-in types, but it is also extensible. +You can "teach" libpqxx (in the scope of your own application) to convert +additional types of values to and from PostgreSQL's string format. + +This is massively useful, but it's not for the faint of heart. You'll need to +specialise some templates. And, **the API for doing this can change with any +major libpqxx release.** + + +Converting types +---------------- + +In your application, a conversion is driven entirely by a C++ type you specify. +The value's SQL type has nothing to do with it, nor is there anything in the +string that would identify its type. + +So, if you've SELECTed a 64-bit integer from the database, and you try to +convert it to a C++ "short," one of two things will happen: either the number +is small enough to fit in your `short` (and it just works), or else it throws a +conversion exception. + +Or, your database table might have a text column, but a given field may contain +a string that _looks_ just like a number. You can convert that value to an +integer type just fine. Or to a floating-point type. All that matters to the +conversion is the actual value, and the type. + +In some cases the templates for these conversions can tell the type from the +arguments you pass them: + + auto x = to_string(99); + +In other cases you may need to instantiate template explicitly: + + auto y = from_string("99"); + + +Supporting a new type +--------------------- + +Let's say you have some other SQL type which you want to be able to store in, +or retrieve from, the database. What would it take to support that? + +Sometimes you do not need _complete_ support. You might need a conversion _to_ +a string but not _from_ a string, for example. The conversion is defined at +compile time, so don't be too afraid to be incomplete. If you leave out one of +these steps, it's not going to crash at run time or mess up your data. The +worst that can happen is that your code won't build. + +So what do you need for a complete conversion? + +First off, of course, you need a C++ type. It may be your own, but it +doesn't have to be. It could be a type from a third-party library, or even one +from the standard library that libpqxx does not yet support. + +You also specialise the `pqxx::type_name` variable to specify the type's name. +This is important for all code which mentions your type in human-readable text, +such as error messages. + +Then, does your type have a built-in null value? You specialise the +`pqxx::nullness` template to specify the details. + +Finally, you specialise the `pqxx::string_traits` template. This is where you +define the actual conversions. + +Let's go through these steps one by one. + + +Your type +--------- + +You'll need a type for which the conversions are not yet defined, because the +C++ type is what determines the right conversion. One type, one set of +conversions. + +The type doesn't have to be one that you create. The conversion logic was +designed such that you can build it around any type. So you can just as +easily build a conversion for a type that's defined somewhere else. There's +no need to include any special methods or other members inside it. That's also +how libpqxx can support converting built-in types like `int`. + +By the way, if the type is an enum, you don't need to do any of this. Just +invoke the preprocessor macro `PQXX_DECLARE_ENUM_CONVERSION`, from the global +namespace near the top of your translation unit, and pass the type as an +argument. + +The library also provides specialisations for `std::optional`, +`std::shared_ptr`, and `std::unique_ptr`. If you have conversions for +`T`, you'll also have conversions for those. + + +Specialise `type_name` +---------------------- + +When errors happen during conversion, libpqxx will compose error messages for +the user. Sometimes these will include the name of the type that's being +converted. + +To tell libpqxx the name of each type, there's a template variable called +`pqxx::type_name`. For any given type `T`, it should have a specialisation +that provides that `T`'s human-readable name: + + namespace pqxx + { + template<> std::string const type_name{"T"}; + } + +(Yes, this means that you need to define something inside the pqxx namespace. +Future versions of libpqxx may move this into a separate namespace.) + +Define this early on in your translation unit, before any code that might cause +libpqxx to need the name. That way, the libpqxx code which needs to know the +type's name can see your definition. + + +Specialise `nullness` +--------------------- + +A struct template `pqxx::nullness` defines whether your type has a natural +"null value" built in. If so, it also provides member functions for producing +and recognising null values. + +The simplest scenario is also the most common: most types don't have a null +value built in. In that case, derive your nullness traits from +`pqxx::no_null`: + + namespace pqxx + { + template<> struct nullness : pqxx::no_null {}; + } + +(Here again you're defining this in the pqxx namespace.) + +If your type does have a natural null value, the definition gets a little more +complex: + + namespace pqxx + { + template<> struct nullness + { + static constexpr bool has_null{true}; + static constexpr bool always_null{false}; + + static bool is_null(T const &value) + { + // Return whether "value" is null. + return ...; + } + + [[nodiscard]] static T null() + { + // Return a null value. + return ...; + } + }; + } + +You may be wondering why there's a function to produce a null value, but also a +function to check whether a value is null. Why not just compare the value to +the result of `null()`? Because two null values may not be equal. `T` may +have several different null values. Or it may override the comparison +operator, similar to SQL where NULL is not equal to NULL. + +As a third case, your type may be one that _always_ represents a null value. +This is the case for `std::nullptr_t` and `std::nullopt_t`. In that case, you +set `nullness::always_null` to `true` (as well as `has_null` of course), +and you won't need to define any actual conversions. + + +Specialise `string_traits` +------------------------- + +This part is more work. (You can skip it for types that are _always_ null, +but those will be rare.) Specialise the `pqxx::string_traits` template: + + namespace pqxx + { + template<> struct string_traits + { + static T from_string(std::string_view text); + static zview to_buf(char *begin, char *end, T const &value); + static char *into_buf(char *begin, char *end, T const &value); + static std::size_t size_buffer(T const &value) noexcept; + }; + } + +You'll also need to write those member functions, or as many of them as needed +to get your code to build. + + +### `from_string` + +We start off simple: `from_string` parses a string as a value of `T`, and +returns that value. + +The string may not be zero-terminated; it's just the `string_view` from +beginning to end (exclusive). In your tests, cover cases where the string +does not end in a zero byte. + +It's perfectly possible that the string isn't actually a `T` value. Mistakes +happen. In that case, throw a `pqxx::conversion_error`. + +(Of course it's also possible that you run into some other error, so it's fine +to throw different exceptions as well. But when it's definitely "this is not +the right format for a `T`," throw `conversion_error`.) + + +### `to_buf` + +In this function, you convert a value of `T` into a string that the postgres +server will understand. + +The caller will provide you with a buffer where you can write the string, if +you need it: from `begin` to `end` exclusive. It's a half-open interval, so +don't access `*end`. + +If the buffer is insufficient for you to do the conversion, throw a +`pqxx::conversion_overrun`. It doesn't have to be exact: you can be a little +pessimistic and demand a bit more space than you need. Just be sure to throw +the exception if there's any risk of overrunning the buffer. + +You don't _have_ to use the buffer for this function though. For example, +`pqxx::string_traits::to_buf` returns a compile-time constant string and +ignores the buffer. + +Even if you do use the buffer, your string does not _have_ to start at the +beginning of the buffer. For example, the integer conversions start by writing +the _least_ significant digit to the _end_ of the buffer, and then writes the +more significant digits before it. It was just more convenient. + +Return a `pqxx::zview`. This is basically a `std::string_view`, but with one +difference: a `zview` guarantees that there will be a valid zero byte right +after the `string_view`. The zero byte is not counted as part of its size, but +it will be there. + +Expressed in code, this rule must hold: + + void invariant(zview z) + { + assert(z[std::size(z)] == 0); + } + +Make sure you write your trailing zero _before_ the `end`. If the trailing +zero doesn't fit in the buffer, then there's just not enough room to perform +the conversion. + +Beware of locales when converting. If you use standard library features like +`sprintf`, they may obey whatever locale is currently set on the system. That +means that a simple integer like 1000000 may come out as "1000000" on your +system, but as "1,000,000" on mine, or as "1.000.000" for somebody else, and on +an Indian system it may be "1,00,000". Values coming from or going to the +database should be in non-localised formats. You can use libpqxx functions for +those conversions: `pqxx::from_string`, `pqxx::to_string`, `pqxx::to_buf`. + + +### `into_buf` + +This is a stricter version of `to_buf`. All the same requirements apply, but +in addition you must write your string into the buffer provided, starting +_exactly_ at `begin`. + +That's why this function returns just a simple pointer: the address right +behind the trailing zero. If the caller wants to use the string, they can +find it at `begin`. If they want to write a different value into the rest of +the buffer, they can start at the location you returned. + + +### `size_buffer` + +Here you estimate how much buffer space you need for converting a `T` to a +string. Be precise if you can, but pessimistic if you must. It's usually +better to waste a few unnecessary bytes than to spend a lot of time computing +the exact buffer space you need. And failing the conversion because you +under-budgeted the buffer is worst of all. + +Include the trailing zero in the buffer size. If your `to_buf` takes more +space than just what's needed to store the result, include that too. + +Make `size_buffer` a `constexpr` function if you can. It can allow the caller +to allocate the buffer on the stack, with a size known at compile time. + + +Optional: Specialise `is_unquoted_safe` +--------------------------------------- + +When converting arrays or composite values to strings, libpqxx may need to +quote values and escape any special characters. This takes time. + +Some types though, such as integral or floating-point types, can never have +any special characters such as quotes, commas, or backslashes in their string +representations. In such cases, there's no need to quote or escape such values +in arrays or composite types. + +If your type is like that, you can tell libpqxx about this by defining: + + namespace pqxx + { + template<> inline constexpr bool is_unquoted_safe{true}; + } + +The code that converts this type of field to strings in an array or a composite +type can then use a simpler, more efficient variant of the code. It's always +safe to leave this out; it's _just_ an optimisation for when you're completely +sure that it's safe. + +Do not do this if a string representation of your type may contain a comma; +semicolon; parenthesis; brace; quote; backslash; newline; or any other +character that might need escaping. + + +Optional: Specialise `param_format` +----------------------------------- + +This one you don't generally need to worry about. Read on if you're writing a +type which represents raw binary data, or if you're writing a template where +_some specialisations_ may contain raw binary data. + +When you call parameterised statements, or prepared statements with parameters, +libpqxx needs to your parameters on to libpq, the underlying C-level PostgreSQL +client library. + +There are two formats for doing that: _text_ and _binary._ In the first, we +represent all values as strings, and the server then converts them into its own +internal binary representation. That's what the string conversions are all +about, and it's what we do for almost all types of parameters. + +But we do it differently when the parameter is a contiguous series of raw bytes +and the corresponding SQL type is `BYTEA`. There is a text format for those, +but we bypass it for efficiency. The server can use the binary data in the +exact same form, without any conversion or extra processing. The binary data +is also twice as compact during transport. + +(People sometimes ask why we can't just treat all types as binary. However the +general case isn't so clear-cut. The binary formats are not documented, there +are no guarantees that they will be platform-independent or that they will +remain stable, and there's no really solid way to detect when we might get the +format wrong. But also, the conversions aren't necessarily as straightforward +and efficient as they sound. So, for the general case, libpqxx sticks with the +text formats. Raw binary data alone stands out as a clear win.) + +Long story short, the machinery for passing parameters needs to know: is this +parameter a binary string, or not? In the normal case it can assume "no," and +that's what it does. The text format is always a safe choice; we just try to +use the binary format where it's faster. + +The `param_format` function template is what makes the decision. We specialise +it for types which may be binary strings, and use the default for all other +types. + +"Types which _may_ be binary"? You might think we know whether a type is a +binary type or not. But there are some complications with generic types. + +Templates like `std::shared_ptr`, `std::optional`, and so on act like +"wrappers" for another type. A `std::optional` is binary if `T` is binary. +Otherwise, it's not. If you're building support for a template of this nature, +you'll probably want to implement `param_format` for it. + +The decision to use binary format is made based on a given object, not +necessarily based on the type in general. Look at `std::variant`. If you have +a `std::variant` type which can hold an `int` or a binary string, is that a +binary parameter? We can't decide without knowing the individual object. + +Containers are another hard case. Should we pass `std::vector` in binary? +Even when `T` is a binary type, we don't currently have any way to pass an +array in binary format, so we always pass it as text. diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/escaping.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/escaping.md new file mode 100644 index 000000000..2ad9fe3db --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/escaping.md @@ -0,0 +1,74 @@ +String escaping {#escaping} +=============== + +Writing queries as strings is easy. But sometimes you need a variable in +there: `"SELECT id FROM user WHERE name = '" + name + "'"`. + +This is dangerous. See the bug? If `name` can contain quotes, you may have +an SQL injection vulnerability there, where users can enter nasty stuff like +"`.'; DROP TABLE user`". Or if you're lucky, it's just a nasty bug that you +discover when `name` happens to be "d'Arcy". + +So, you'll need to _escape_ the `name` before you insert it. This is where +quotes and other problematic characters are marked as "this is just a character +in the string, not the end of the string." There are +[several functions](@ref escaping-functions) in libpqxx to do this for you. + + +SQL injection +------------- + +To understand what SQL injection vulnerabilities are and why they should be +prevented, imagine you use the following SQL statement somewhere in your +program: + + TX.exec( + "SELECT number,amount " + "FROM accounts " + "WHERE allowed_to_see('" + userid + "','" + password + "')"); + +This shows a logged-in user important information on all accounts he is +authorized to view. The userid and password strings are variables entered +by the user himself. + +Now, if the user is actually an attacker who knows (or can guess) the +general shape of this SQL statement, imagine he enters the following +password: + + x') OR ('x' = 'x + +Does that make sense to you? Probably not. But if this is inserted into +the SQL string by the C++ code above, the query becomes: + + SELECT number,amount + FROM accounts + WHERE allowed_to_see('user','x') OR ('x' = 'x') + +Is this what you wanted to happen? Probably not! The neat `allowed_to_see()` +clause is completely circumvented by the "`OR ('x' = 'x')`" clause, which is +always `true`. Therefore, the attacker will get to see all accounts in the +database! + + +Using the esc functions +----------------------- + +Here's how you can fix the problem in the example above: + + TX.exec( + "SELECT number,amount " + "FROM accounts " + "WHERE allowed_to_see('" + TX.esc(userid) + "', " + "'" + TX.esc(password) + "')"); + +Now, the quotes embedded in the attacker's string will be neatly escaped so +they can't "break out" of the quoted SQL string they were meant to go into: + + SELECT number,amount + FROM accounts + WHERE allowed_to_see('user', 'x'') OR (''x'' = ''x') + +If you look carefully, you'll see that thanks to the added escape characters +(a single-quote is escaped in SQL by doubling it) all we get is a very +strange-looking password string--but not a change in the SQL statement. + diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/getting-started.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/getting-started.md new file mode 100644 index 000000000..1b87b881f --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/getting-started.md @@ -0,0 +1,142 @@ +Getting started {#getting-started} +=============== + +The most basic three types in libpqxx are the _connection_, the _transaction_, +and the _result_. + +They fit together as follows: +* You connect to the database by creating a `pqxx::connection` object (see + @ref connections). + +* You create a transaction object (see @ref transactions) operating on that + connection. You'll usually want the `pqxx::work` variety. + + Once you're done you call the transaction's `commit` function to make its + work final. If you don't call this, the work will be rolled back when the + transaction object is destroyed. + +* Until then, use the transaction's `exec`, `query_value`, and `stream` + functions (and variants) to execute SQL statements. You pass the statements + themselves in as simple strings. (See @ref streams for more about data + streaming). + +* Most of the `exec` functions return a `pqxx::result` object, which acts + as a standard container of rows: `pqxx::row`. + + Each row in a result, in turn, acts as a container of fields: `pqxx::field`. + See @ref accessing-results for more about results, rows, and fields. + +* Each field's data is stored internally as a text string, in a format defined + by PostgreSQL. You can convert field or row values using their `as()` and + `to()` member functions. + +* After you've closed the transaction, the connection is free to run a next + transaction. + +Here's a very basic example. It connects to the default database (you'll +need to have one set up), queries it for a very simple result, converts it to +an `int`, and prints it out. It also contains some basic error handling. + + #include + #include + + int main() + { + try + { + // Connect to the database. In practice we may have to pass some + // arguments to say where the database server is, and so on. + // The constructor parses options exactly like libpq's + // PQconnectdb/PQconnect, see: + // https://www.postgresql.org/docs/10/static/libpq-connect.html + pqxx::connection c; + + // Start a transaction. In libpqxx, you always work in one. + pqxx::work w(c); + + // work::exec1() executes a query returning a single row of data. + // We'll just ask the database to return the number 1 to us. + pqxx::row r = w.exec1("SELECT 1"); + + // Commit your transaction. If an exception occurred before this + // point, execution will have left the block, and the transaction will + // have been destroyed along the way. In that case, the failed + // transaction would implicitly abort instead of getting to this point. + w.commit(); + + // Look at the first and only field in the row, parse it as an integer, + // and print it. + // + // "r[0]" returns the first field, which has an "as<...>()" member + // function template to convert its contents from their string format + // to a type of your choice. + std::cout << r[0].as() << std::endl; + } + catch (std::exception const &e) + { + std::cerr << e.what() << std::endl; + return 1; + } + } + +This prints the number 1. Notice that you can keep the result object around +after you've closed the transaction or even the connection. There are +situations where you can't do it, but generally it's fine. If you're +interested: you can install your own callbacks for receiving error messages +from the database, and in that case you'll have to keep the connection object +alive. But otherwise, it's nice to be able to "fire and forget" your +connection and deal with the data. + +You can also convert an entire row to a series of C++-side types in one go, +using the @c as member function on the row: + + pqxx::connection c; + pqxx::work w(c); + pqxx::row r = w.exec1("SELECT 1, 2, 'Hello'"); + auto [one, two, hello] = r.as(); + std::cout << (one + two) << ' ' << std::strlen(hello) << std::endl; + +Here's a slightly more complicated example. It takes an argument from the +command line and retrieves a string with that value. The interesting part is +that it uses the escaping-and-quoting function `quote` to embed this +string value in SQL safely. It also reads the result field's value as a +plain C-style string using its `c_str` function. + + #include + #include + #include + + int main(int argc, char *argv[]) + { + try + { + if (!argv[1]) throw std::runtime_error("Give me a string!"); + + pqxx::connection c; + pqxx::work w(c); + + // work::exec() returns a full result set, which can consist of any + // number of rows. + pqxx::result r = w.exec("SELECT " + w.quote(argv[1])); + + // End our transaction here. We can still use the result afterwards. + w.commit(); + + // Print the first field of the first row. Read it as a C string, + // just like std::string::c_str() does. + std::cout << r[0][0].c_str() << std::endl; + } + catch (std::exception const &e) + { + std::cerr << e.what() << std::endl; + return 1; + } + } + +You can find more about converting field values to native types, or +converting values to strings for use with libpqxx, under +@ref stringconversion. More about getting to the rows and fields of a +result is under @ref accessing-results. + +If you want to handle exceptions thrown by libpqxx in more detail, for +example to print the SQL contents of a query that failed, see @ref exception. diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/mainpage.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/mainpage.md new file mode 100644 index 000000000..5d4b8f9b2 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/mainpage.md @@ -0,0 +1,28 @@ +libpqxx {#mainpage} +======= + +@version 7.7.3 +@author Jeroen T. Vermeulen +@see http://pqxx.org +@see https://github.com/jtv/libpqxx + +Welcome to libpqxx, the C++ API to the PostgreSQL database management system. + +Compiling this package requires PostgreSQL to be installed -- including the +C headers for client development. The library builds on top of PostgreSQL's +standard C API, libpq. The libpq headers are not needed to compile client +programs, however. + +For a quick introduction to installing and using libpqxx, see the README.md +file. The latest information can be found at http://pqxx.org/ + + +Some links that should help you find your bearings: +* @ref getting-started +* @ref thread-safety +* @ref connections +* @ref transactions +* @ref escaping +* @ref performance +* @ref transactor +* @ref datatypes diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/parameters.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/parameters.md new file mode 100644 index 000000000..7ac792025 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/parameters.md @@ -0,0 +1,90 @@ +Statement parameters {#parameters} +==================== + +When you execute a prepared statement (see @ref prepared), or a parameterised +statement (using functions like `pqxx::connection::exec_params`), you may write +special _placeholders_ in the query text. They look like `$1`, `$2`, and so +on. + +If you execute the query and pass parameter values, the call will respectively +substitute the first where it finds `$1`, the second where it finds `$2`, et +cetera. + +Doing this saves you work. If you don't use statement parameters, you'll need +to quote and escape your values (see `connection::quote()` and friends) as you +insert them into your query as literal values. + +Or if you forget to do that, you leave yourself open to horrible +[SQL injection attacks](https://xkcd.com/327/). Trust me, I was born in a town +whose name started with an apostrophe! + +Statement parameters save you this work. With these parameters you can pass +your values as-is, and they will go across the wire to the database in a safe +format. + +In some cases it may even be faster! When a parameter represents binary data +(as in the SQL `BYTEA` type), libpqxx will send it directly as binary, which is +a bit more efficient. If you insert the binary data directly in your query +text, your CPU will have some extra work to do, converting the data into a text +format, escaping it, and adding quotes. + + +Dynamic parameter lists +----------------------- + +In rare cases you may just not know how many parameters you'll pass into your +statement when you call it. + +For these situations, have a look at `params`. It lets you compose your +parameters list on the fly, even add whole ranges of parameters at a time. + +You can pass a `params` into your statement as a normal parameter. It will +fill in all the parameter values it contains into that position of the +statement's overall parameter list. + +So if you call your statement passing a regular parameter `a`, a +`params` containing just a parameter `b`, and another regular parameter `c`, +then your call will pass parameters `a`, `b`, and `c`. Or if the params object +is empty, it will pass just `a` and `c`. If the params object contains `x` and +`y`, your call will pass `a, x, y, c`. + +You can mix static and dynamic parameters freely. Don't go overboard though: +complexity is where bugs happen! + + +Generating placeholders +----------------------- + +If your code gets particularly complex, it may sometimes happen that it becomes +hard to track which parameter value belongs with which placeholder. Did you +intend to pass this numeric value as `$7`, or as `$8`? The answer may depend +on an `if` that happened earlier in a different function. + +(Generally if things get that complex, it's a good idea to look for simpler +solutions. But especially when performance matters, sometimes you can't avoid +complexity like that.) + +There's a little helper class called `placeholders`. You can use it as a +counter which produces those placeholder strings, `$1`, `$2`, `$3`, et cetera. +When you start generating a complex statement, you can create both a `params` +and a `placeholders`: + + pqxx::params values; + pqxx::placeholders name; + +Let's say you've got some complex code to generate the conditions for an SQL +"WHERE" clause. You'll generally want to do these things close together in +your, so that you don't accidentally update one part and forget another: + + if (extra_clause) + { + // Extend the query text, using the current placeholder. + query += " AND x = " + name.get(); + // Add the parameter value. + values.append(my_x); + // Move on to the next placeholder value. + name.next(); + } + +Depending on the starting value of `name`, this might add to `query` a fragment +like "` AND x = $3`" or "` AND x = $5`". diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/performance.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/performance.md new file mode 100644 index 000000000..6c403684f --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/performance.md @@ -0,0 +1,24 @@ +Performance features {#performance} +==================== + +If your program's database interaction is not as efficient as it needs to be, +the first place to look is usually the SQL you're executing. But libpqxx +has a few specialized features to help you squeeze more performance out +of how you issue commands and retrieve data: + +* @ref streams. Use these as a faster way to transfer data between your + code and the database. +* `std::string_view` and `pqxx::zview`. In places where traditional C++ worked + with `std::string`, see whether `std::string_view` or `pqxx::zview` will + do. Of course that means that you'll have to look at the data's lifetime + more carefully, but it'll save the computer a lot of copying. +* @ref prepared. These can be executed many times without the server + parsing and planning them anew each time. They also save you having to + escape string parameters. +* `pqxx::pipeline` lets you send queries to the database in batches, and + continue other processing while they are executing. +* `pqxx::connecting` lets you start setting up a database connection, but + without blocking the thread. + +As always of course, don't risk the quality of your code for optimizations +that you don't need! diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/prepared-statement.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/prepared-statement.md new file mode 100644 index 000000000..5193866a6 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/prepared-statement.md @@ -0,0 +1,125 @@ +Prepared statements {#prepared} +=================== + +Prepared statements are SQL queries that you define once and then invoke +as many times as you like, typically with varying parameters. It's basically +a function that you can define ad hoc. + +If you have an SQL statement that you're going to execute many times in +quick succession, it may be more efficient to prepare it once and reuse it. +This saves the database backend the effort of parsing complex SQL and +figuring out an efficient execution plan. Another nice side effect is that +you don't need to worry about escaping parameters. Some corporate coding +standards require all SQL parameters to be passed in this way, to reduce the +risk of programmer mistakes leaving room for SQL injections. + + +Preparing a statement +--------------------- + +You create a prepared statement by preparing it on the connection (using the +`pqxx::connection::prepare` functions), passing an identifier and its SQL text. + +The identifier is the name by which the prepared statement will be known; it +should consist of ASCII letters, digits, and underscores only, and start with +an ASCII letter. The name is case-sensitive. + +```cxx + void prepare_my_statement(pqxx::connection &c) + { + c.prepare( + "my_statement", + "SELECT * FROM Employee WHERE name = 'Xavier'"); + } +``` + +Once you've done this, you'll be able to call `my_statement` from any +transaction you execute on the same connection. For this, use the +`pqxx::transaction_base::exec_prepared` functions. + +```cxx + pqxx::result execute_my_statement(pqxx::transaction_base &t) + { + return t.exec_prepared("my_statement"); + } +``` + + +Parameters +---------- + +Did I mention that prepared statements can have parameters? The query text +can contain `$1`, `$2` etc. as placeholders for parameter values that you +will provide when you invoke the prepared satement. + +See @ref parameters for more about this. And here's a simple example of +preparing a statement and invoking it with parameters: + +```cxx + void prepare_find(pqxx::connection &c) + { + // Prepare a statement called "find" that looks for employees with a + // given name (parameter 1) whose salary exceeds a given number + // (parameter 2). + c.prepare( + "find", + "SELECT * FROM Employee WHERE name = $1 AND salary > $2"); + } +``` + +This example looks up the prepared statement "find," passes `name` and +`min_salary` as parameters, and invokes the statement with those values: + +```cxx + pqxx::result execute_find( + pqxx::transaction_base &t, std::string name, int min_salary) + { + return t.exec_prepared("find", name, min_salary); + } +``` + + +A special prepared statement +---------------------------- + +There is one special case: the _nameless_ prepared statement. You may prepare +a statement without a name, i.e. whose name is an empty string. The unnamed +statement can be redefined at any time, without un-preparing it first. + + +Performance note +---------------- + +Don't assume that using prepared statements will speed up your application. +There are cases where prepared statements are actually slower than plain SQL. + +The reason is that the backend can often produce a better execution plan when +it knows the statement's actual parameter values. + +For example, say you've got a web application and you're querying for users +with status "inactive" who have email addresses in a given domain name X. If +X is a very popular provider, the best way for the database engine to plan the +query may be to list the inactive users first and then filter for the email +addresses you're looking for. But in other cases, it may be much faster to +find matching email addresses first and then see which of their owners are +"inactive." A prepared statement must be planned to fit either case, but a +direct query will be optimised based on table statistics, partial indexes, etc. + + +Zero bytes +---------- + +@warning Beware of "nul" bytes! + +Any string you pass as a parameter will end at the _first char with value +zero._ If you pass a string that contains a zero byte, the last byte in the +value will be the one just before the zero. + +So, if you need a zero byte in a string, consider that it's really a _binary +string,_ which is not the same thing as a text string. SQL represents binary +data as the `BYTEA` type, or in binary large objects ("blobs"). + +In libpqxx, you represent binary data as a range of `std::byte`. They must be +contiguous in memory, so that libpqxx can pass pointers to the underlying C +library. So you might use `std::basic_string`, or +`std::basic_string_view`, or `std::vector`. diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/streams.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/streams.md new file mode 100644 index 000000000..3df4d6126 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/streams.md @@ -0,0 +1,107 @@ +Streams {#streams} +======= + +Most of the time it's fine to retrieve data from the database using `SELECT` +queries, and store data using `INSERT`. But for those cases where efficiency +matters, there are two classes to help you do this better: `stream_from` and +`stream_to`. They're less flexible than SQL queries, and there's the risk of +losing your connection while you're in mid-stream, but you get some speed and +memory efficiencies in return. + +Both stream classes do data conversion for you: `stream_from` receives values +from the database in PostgreSQL's text format, and converts them to the C++ +types you specify. Likewise, `stream_to` converts C++ values you provide to +PostgreSQL's text format for transfer. (On its end, the database of course +converts values to and from their SQL types.) + + +Null values +----------- + +So how do you deal with nulls? It depends on the C++ type you're using. Some +types may have a built-in null value. For instance, if you have a +`char const *` value and you convert it to an SQL string, then converting a +`nullptr` will produce a NULL SQL value. + +But what do you do about C++ types which don't have a built-in null value, such +as `int`? The trick is to wrap it in `std::optional`. The difference between +`int` and `std::optional` is that the former always has an `int` value, +and the latter doesn't have to. + +Actually it's not just `std::optional`. You can do the same thing with +`std::unique_ptr` or `std::shared_ptr`. A smart pointer is less efficient than +`std::optional` in most situations because they allocate their value on the +heap, but sometimes that's what you want in order to save moving or copying +large values around. + +This part is not generic though. It won't work with just any smart-pointer +type, just the ones which are explicitly supported: `shared_ptr` and +`unique_ptr`. If you really need to, you can build support for additional +wrappers and smart pointers by copying the implementation patterns from the +existing smart-pointer support. + + +stream\_from +------------ + +Use `stream_from` to read data directly from the database. It's faster than +the transaction's `exec` functions if the result contains enough rows. But +also, you won't need to keep your full result set in memory. That can really +matter with larger data sets. + +And, you can start processing your data right after the first row of data comes +in from the server. With `exec()` you need to wait to receive all data, and +then you begin processing. With `stream_from` you can be processing data on +the client side while the server is still sending you the rest. + +You don't actually need to create a `stream_from` object yourself, though you +can. Two shorthand functions, @ref pqxx::transaction_base::stream +and @ref pqxx::transaction_base::for_each, can create the streams for you with +a minimum of overhead. + +Not all kinds of queries will work in a stream. Internally the streams make +use of PostgreSQL's `COPY` command, so see the PostgreSQL documentation for +`COPY` for the exact limitations. Basic `SELECT` and `UPDATE ... RETURNING` +queries should just work. + +As you read a row, the stream converts its fields to a tuple type containing +the value types you ask for: + + auto stream pqxx::stream_from::query( + tx, "SELECT name, points FROM score"); + std::tuple row; + while (stream >> row) + process(row); + stream.complete(); + +As the stream reads each row, it converts that row's data into your tuple, +goes through your loop body, and then promptly forgets that row's data. This +means you can easily process more data than will fit in memory. + + +stream\_to +---------- + +Use `stream_to` to write data directly to a database table. This saves you +having to perform an `INSERT` for every row, and so it can be significantly +faster if you want to insert more than just one or two rows at a time. + +As with `stream_from`, you can specify the table and the columns, and not much +else. You insert tuple-like objects of your choice: + + pqxx::stream_to stream{ + tx, + "score", + std::vector{"name", "points"}}; + for (auto const &entry: scores) + stream << entry; + stream.complete(); + +Each row is processed as you provide it, and not retained in memory after that. + +The call to `complete()` is more important here than it is for `stream_from`. +It's a lot like a "commit" or "abort" at the end of a transaction. If you omit +it, it will be done automatically during the stream's destructor. But since +destructors can't throw exceptions, any failures at that stage won't be visible +in your code. So, always call `complete()` on a `stream_to` to close it off +properly! diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/thread-safety.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/thread-safety.md new file mode 100644 index 000000000..07c7f9984 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/share/doc/libpqxx/thread-safety.md @@ -0,0 +1,29 @@ +Thread safety {#thread-safety} +============= + +This library does not contain any locking code to protect objects against +simultaneous modification in multi-threaded programs. Therefore it is up +to you, the user of the library, to ensure that your threaded client +programs perform no conflicting operations concurrently. + +Most of the time this isn't hard. Result sets are immutable, so you can +share them between threads without problem. The main rule is: + +@li Treat a connection, together with any and all objects related to it, as +a "world" of its own. You should generally make sure that the same "world" +is never accessed by another thread while you're doing anything non-const +in there. + +That means: don't issue a query on a transaction while you're also opening +a subtransaction, don't access a cursor while you may also be committing, +and so on. + +In particular, cursors are tricky. It's easy to perform a non-const +operation without noticing. So, if you're going to share cursors or +cursor-related objects between threads, lock very conservatively! + +Use `pqxx::describe_thread_safety` to find out at runtime what level of +thread safety is implemented in your build and version of libpqxx. It +returns a `pqxx::thread_safety_model` describing what you can and cannot rely +on. A command-line utility `tools/pqxxthreadsafety` prints out the same +information. diff --git a/ext/libpqxx-7.7.3/libpqxx.pc.in b/ext/libpqxx-7.7.3/libpqxx.pc.in new file mode 100644 index 000000000..eb7dcff49 --- /dev/null +++ b/ext/libpqxx-7.7.3/libpqxx.pc.in @@ -0,0 +1,10 @@ +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 new file mode 100644 index 000000000..28f8f8ad1 --- /dev/null +++ b/ext/libpqxx-7.7.3/requirements.json @@ -0,0 +1,9 @@ +{ + "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 new file mode 100644 index 000000000..1d697ab7c --- /dev/null +++ b/ext/libpqxx-7.7.3/src/CMakeLists.txt @@ -0,0 +1,91 @@ +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 new file mode 100644 index 000000000..dfd520941 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/Makefile.am @@ -0,0 +1,44 @@ +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 new file mode 100644 index 000000000..3c0152727 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/Makefile.in @@ -0,0 +1,809 @@ +# 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 new file mode 100644 index 000000000..e35aaddce --- /dev/null +++ b/ext/libpqxx-7.7.3/src/array.cxx @@ -0,0 +1,240 @@ +/** 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 new file mode 100644 index 000000000..936437006 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/binarystring.cxx @@ -0,0 +1,108 @@ +/** 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 new file mode 100644 index 000000000..1492d9107 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/blob.cxx @@ -0,0 +1,337 @@ +#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 new file mode 100644 index 000000000..bef8c79aa --- /dev/null +++ b/ext/libpqxx-7.7.3/src/connection.cxx @@ -0,0 +1,1274 @@ +/** 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 new file mode 100644 index 000000000..28e8ba42f --- /dev/null +++ b/ext/libpqxx-7.7.3/src/cursor.cxx @@ -0,0 +1,339 @@ +/** 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 new file mode 100644 index 000000000..99f038724 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/encodings.cxx @@ -0,0 +1,839 @@ +/** 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 new file mode 100644 index 000000000..de120ff3d --- /dev/null +++ b/ext/libpqxx-7.7.3/src/errorhandler.cxx @@ -0,0 +1,43 @@ +/** 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 new file mode 100644 index 000000000..4974e8ac0 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/except.cxx @@ -0,0 +1,126 @@ +/** 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 new file mode 100644 index 000000000..f5026ced2 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/field.cxx @@ -0,0 +1,80 @@ +/** 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 new file mode 100644 index 000000000..c57de3c73 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/largeobject.cxx @@ -0,0 +1,322 @@ +/** 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 new file mode 100644 index 000000000..eb8d5e1a1 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/notification.cxx @@ -0,0 +1,35 @@ +/** 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 new file mode 100644 index 000000000..bd3fc108c --- /dev/null +++ b/ext/libpqxx-7.7.3/src/params.cxx @@ -0,0 +1,122 @@ +/* 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 new file mode 100644 index 000000000..854b1a70e --- /dev/null +++ b/ext/libpqxx-7.7.3/src/pipeline.cxx @@ -0,0 +1,448 @@ +/** 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 new file mode 100644 index 000000000..1a8f5fb11 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/pqxx-source.hxx @@ -0,0 +1,30 @@ +/* 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 new file mode 100644 index 000000000..86a739004 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/result.cxx @@ -0,0 +1,536 @@ +/** 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 new file mode 100644 index 000000000..5bbfd64f8 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/robusttransaction.cxx @@ -0,0 +1,221 @@ +/** 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 new file mode 100644 index 000000000..f0974c839 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/row.cxx @@ -0,0 +1,250 @@ +/** 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 new file mode 100644 index 000000000..1e5d6a790 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/sql_cursor.cxx @@ -0,0 +1,276 @@ +/** 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 new file mode 100644 index 000000000..2bd206b2a --- /dev/null +++ b/ext/libpqxx-7.7.3/src/strconv.cxx @@ -0,0 +1,785 @@ +/** 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 new file mode 100644 index 000000000..f710300ea --- /dev/null +++ b/ext/libpqxx-7.7.3/src/stream_from.cxx @@ -0,0 +1,327 @@ +/** 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 new file mode 100644 index 000000000..1693ba377 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/stream_to.cxx @@ -0,0 +1,170 @@ +/** 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 new file mode 100644 index 000000000..186ad13e8 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/subtransaction.cxx @@ -0,0 +1,68 @@ +/** 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 new file mode 100644 index 000000000..6b3ffdb1c --- /dev/null +++ b/ext/libpqxx-7.7.3/src/time.cxx @@ -0,0 +1,226 @@ +/** 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 new file mode 100644 index 000000000..61ed29ef7 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/transaction.cxx @@ -0,0 +1,107 @@ +/** 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 new file mode 100644 index 000000000..c7d01ac08 --- /dev/null +++ b/ext/libpqxx-7.7.3/src/transaction_base.cxx @@ -0,0 +1,539 @@ +/** 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 new file mode 100644 index 000000000..fe859bd2a --- /dev/null +++ b/ext/libpqxx-7.7.3/src/util.cxx @@ -0,0 +1,194 @@ +/** 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 new file mode 100644 index 000000000..e216ecd4f --- /dev/null +++ b/ext/libpqxx-7.7.3/src/version.cxx @@ -0,0 +1,27 @@ +/** 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 new file mode 100644 index 000000000..276d9659e --- /dev/null +++ b/ext/libpqxx-7.7.3/src/wait.cxx @@ -0,0 +1,136 @@ +/** 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 new file mode 100644 index 000000000..331631145 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/CMakeLists.txt @@ -0,0 +1,24 @@ +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 new file mode 100644 index 000000000..e3ce4be7b --- /dev/null +++ b/ext/libpqxx-7.7.3/test/Makefile.am @@ -0,0 +1,129 @@ +# ############################################################################## +# 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 new file mode 100644 index 000000000..2a21f6ef7 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/Makefile.am.template @@ -0,0 +1,38 @@ +# 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 new file mode 100644 index 000000000..8ffcca06c --- /dev/null +++ b/ext/libpqxx-7.7.3/test/Makefile.in @@ -0,0 +1,1302 @@ +# 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 new file mode 100644 index 000000000..38c9849d8 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/runner.cxx @@ -0,0 +1,203 @@ +/* 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 new file mode 100644 index 000000000..698c9b81b --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test00.cxx @@ -0,0 +1,114 @@ +#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 new file mode 100644 index 000000000..84b7f3b78 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test01.cxx @@ -0,0 +1,33 @@ +#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 new file mode 100644 index 000000000..f98e18d08 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test02.cxx @@ -0,0 +1,76 @@ +#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 new file mode 100644 index 000000000..623446398 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test04.cxx @@ -0,0 +1,77 @@ +#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 new file mode 100644 index 000000000..875ee8d50 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test07.cxx @@ -0,0 +1,133 @@ +#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 new file mode 100644 index 000000000..4cb4aaba1 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test10.cxx @@ -0,0 +1,106 @@ +#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 new file mode 100644 index 000000000..4b42a66d5 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test11.cxx @@ -0,0 +1,76 @@ +#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 new file mode 100644 index 000000000..b3577a5d3 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test13.cxx @@ -0,0 +1,86 @@ +#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 new file mode 100644 index 000000000..c82f2323c --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test14.cxx @@ -0,0 +1,36 @@ +#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 new file mode 100644 index 000000000..211bbba6a --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test16.cxx @@ -0,0 +1,46 @@ +#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 new file mode 100644 index 000000000..7c99a35cc --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test17.cxx @@ -0,0 +1,29 @@ +#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 new file mode 100644 index 000000000..9718d2daa --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test18.cxx @@ -0,0 +1,80 @@ +#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 new file mode 100644 index 000000000..1ddd4b09a --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test20.cxx @@ -0,0 +1,95 @@ +#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 new file mode 100644 index 000000000..1090050d9 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test21.cxx @@ -0,0 +1,70 @@ +#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 new file mode 100644 index 000000000..69b04d839 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test26.cxx @@ -0,0 +1,86 @@ +#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 new file mode 100644 index 000000000..4547523f1 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test29.cxx @@ -0,0 +1,108 @@ +#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 new file mode 100644 index 000000000..fb6a05da0 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test30.cxx @@ -0,0 +1,73 @@ +#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 new file mode 100644 index 000000000..90f0db68c --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test32.cxx @@ -0,0 +1,78 @@ +#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 new file mode 100644 index 000000000..fe231d39b --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test37.cxx @@ -0,0 +1,78 @@ +#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 new file mode 100644 index 000000000..d26855811 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test39.cxx @@ -0,0 +1,89 @@ +#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 new file mode 100644 index 000000000..0fa88915a --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test46.cxx @@ -0,0 +1,74 @@ +#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 new file mode 100644 index 000000000..3aef757bb --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test56.cxx @@ -0,0 +1,24 @@ +#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 new file mode 100644 index 000000000..a29ce9ff7 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test60.cxx @@ -0,0 +1,85 @@ +#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 new file mode 100644 index 000000000..a9c871bdb --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test61.cxx @@ -0,0 +1,61 @@ +#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 new file mode 100644 index 000000000..d23e49e5a --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test62.cxx @@ -0,0 +1,61 @@ +#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 new file mode 100644 index 000000000..d15ff1489 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test69.cxx @@ -0,0 +1,55 @@ +#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 new file mode 100644 index 000000000..0f72089f1 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test70.cxx @@ -0,0 +1,101 @@ +#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 new file mode 100644 index 000000000..e669d9ad5 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test71.cxx @@ -0,0 +1,74 @@ +#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 new file mode 100644 index 000000000..716081ed7 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test72.cxx @@ -0,0 +1,53 @@ +#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 new file mode 100644 index 000000000..ff1abd993 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test74.cxx @@ -0,0 +1,72 @@ +#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 new file mode 100644 index 000000000..07f00141e --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test75.cxx @@ -0,0 +1,108 @@ +#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 new file mode 100644 index 000000000..122c0445c --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test76.cxx @@ -0,0 +1,52 @@ +#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 new file mode 100644 index 000000000..88e83c26d --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test77.cxx @@ -0,0 +1,28 @@ +#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 new file mode 100644 index 000000000..f970cc926 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test78.cxx @@ -0,0 +1,69 @@ +#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 new file mode 100644 index 000000000..761e5f3c3 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test79.cxx @@ -0,0 +1,70 @@ +#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 new file mode 100644 index 000000000..e7b2769c7 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test82.cxx @@ -0,0 +1,154 @@ +#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 new file mode 100644 index 000000000..d35dc521b --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test84.cxx @@ -0,0 +1,109 @@ +#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 new file mode 100644 index 000000000..3a9a58b16 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test87.cxx @@ -0,0 +1,83 @@ +#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 new file mode 100644 index 000000000..d5deaea75 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test88.cxx @@ -0,0 +1,91 @@ +#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 new file mode 100644 index 000000000..2b96dfcd2 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test89.cxx @@ -0,0 +1,44 @@ +#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 new file mode 100644 index 000000000..d7d97f9f3 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test90.cxx @@ -0,0 +1,23 @@ +#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 new file mode 100644 index 000000000..6db3ab971 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test_helpers.hxx @@ -0,0 +1,305 @@ +#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 new file mode 100644 index 000000000..38c045370 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/test_types.hxx @@ -0,0 +1,242 @@ +/* + * 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 new file mode 100644 index 000000000..f938a4181 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/CMakeLists.txt @@ -0,0 +1,25 @@ +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 new file mode 100644 index 000000000..229ac5145 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_array.cxx @@ -0,0 +1,548 @@ +#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 new file mode 100644 index 000000000..e6097d039 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_binarystring.cxx @@ -0,0 +1,211 @@ +#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 new file mode 100644 index 000000000..709c1f489 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_blob.cxx @@ -0,0 +1,644 @@ +#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 new file mode 100644 index 000000000..5329d195f --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_cancel_query.cxx @@ -0,0 +1,25 @@ +#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 new file mode 100644 index 000000000..9c50faff4 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_column.cxx @@ -0,0 +1,61 @@ +#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 new file mode 100644 index 000000000..dcd65360c --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_composite.cxx @@ -0,0 +1,98 @@ +#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 new file mode 100644 index 000000000..bbb780854 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_connection.cxx @@ -0,0 +1,212 @@ +#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 new file mode 100644 index 000000000..8761f6946 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_cursor.cxx @@ -0,0 +1,50 @@ +#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 new file mode 100644 index 000000000..4374671c6 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_encodings.cxx @@ -0,0 +1,114 @@ +#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 new file mode 100644 index 000000000..67dc88763 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_error_verbosity.cxx @@ -0,0 +1,37 @@ +#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 new file mode 100644 index 000000000..c2cd4a797 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_errorhandler.cxx @@ -0,0 +1,223 @@ +#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 new file mode 100644 index 000000000..baff4d62c --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_escape.cxx @@ -0,0 +1,228 @@ +#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 new file mode 100644 index 000000000..4b84b7fba --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_exceptions.cxx @@ -0,0 +1,45 @@ +#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 new file mode 100644 index 000000000..013ea1a82 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_field.cxx @@ -0,0 +1,57 @@ +#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 new file mode 100644 index 000000000..a0463e4d0 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_float.cxx @@ -0,0 +1,175 @@ +#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 new file mode 100644 index 000000000..8184fa2f8 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_largeobject.cxx @@ -0,0 +1,58 @@ +#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 new file mode 100644 index 000000000..d1a32ac64 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_nonblocking_connect.cxx @@ -0,0 +1,27 @@ +#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 new file mode 100644 index 000000000..6487169b4 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_notification.cxx @@ -0,0 +1,86 @@ +#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 new file mode 100644 index 000000000..63b97662b --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_pipeline.cxx @@ -0,0 +1,64 @@ +#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 new file mode 100644 index 000000000..c9eb4ee84 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_prepared_statement.cxx @@ -0,0 +1,334 @@ +#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 new file mode 100644 index 000000000..b40d9b043 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_range.cxx @@ -0,0 +1,555 @@ +#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 new file mode 100644 index 000000000..402f2a06f --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_read_transaction.cxx @@ -0,0 +1,22 @@ +#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 new file mode 100644 index 000000000..3d26e3c3e --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_result_iteration.cxx @@ -0,0 +1,137 @@ +#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 new file mode 100644 index 000000000..be2055ee3 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_result_slicing.cxx @@ -0,0 +1,157 @@ +#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 new file mode 100644 index 000000000..41770e3b1 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_row.cxx @@ -0,0 +1,84 @@ +#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 new file mode 100644 index 000000000..748379b47 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_separated_list.cxx @@ -0,0 +1,33 @@ +#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 new file mode 100644 index 000000000..9c1e2fe9c --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_simultaneous_transactions.cxx @@ -0,0 +1,20 @@ +#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 new file mode 100644 index 000000000..a0109a00b --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_sql_cursor.cxx @@ -0,0 +1,270 @@ +#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 new file mode 100644 index 000000000..79307c19e --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_stateless_cursor.cxx @@ -0,0 +1,85 @@ +#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 new file mode 100644 index 000000000..602084e18 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_strconv.cxx @@ -0,0 +1,143 @@ +#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 new file mode 100644 index 000000000..d8adb8bd1 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_stream_from.cxx @@ -0,0 +1,344 @@ +#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 new file mode 100644 index 000000000..ae4eb3c65 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_stream_to.cxx @@ -0,0 +1,445 @@ +#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 new file mode 100644 index 000000000..30bc084f5 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_string_conversion.cxx @@ -0,0 +1,178 @@ +#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 new file mode 100644 index 000000000..4ba909bec --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_subtransaction.cxx @@ -0,0 +1,78 @@ +#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 new file mode 100644 index 000000000..89cde627e --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_test_helpers.cxx @@ -0,0 +1,214 @@ +#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 new file mode 100644 index 000000000..cf7627cb3 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_thread_safety_model.cxx @@ -0,0 +1,23 @@ +#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 new file mode 100644 index 000000000..2fb79d472 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_time.cxx @@ -0,0 +1,86 @@ +#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 new file mode 100644 index 000000000..2ae016a26 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_transaction.cxx @@ -0,0 +1,113 @@ +#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 new file mode 100644 index 000000000..bea15b190 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_transaction_base.cxx @@ -0,0 +1,106 @@ +#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 new file mode 100644 index 000000000..48fdfdd3f --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_transaction_focus.cxx @@ -0,0 +1,53 @@ +#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 new file mode 100644 index 000000000..43034807e --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_transactor.cxx @@ -0,0 +1,130 @@ +#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 new file mode 100644 index 000000000..af1c93eb5 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_type_name.cxx @@ -0,0 +1,19 @@ +#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 new file mode 100644 index 000000000..f8ce5b9e1 --- /dev/null +++ b/ext/libpqxx-7.7.3/test/unit/test_zview.cxx @@ -0,0 +1,16 @@ +#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 new file mode 100644 index 000000000..9f918cd5a --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/Makefile.am @@ -0,0 +1,20 @@ +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 new file mode 100644 index 000000000..4e21cb265 --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/Makefile.in @@ -0,0 +1,638 @@ +# 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 new file mode 100755 index 000000000..f3970838b --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/deprecations @@ -0,0 +1,6 @@ +#! /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 new file mode 100755 index 000000000..920ed9aad --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/extract_version @@ -0,0 +1,73 @@ +#! /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 new file mode 100755 index 000000000..2645ccdf6 --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/format @@ -0,0 +1,20 @@ +#! /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 new file mode 100755 index 000000000..7beadbb27 --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/lint @@ -0,0 +1,197 @@ +#! /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 new file mode 100755 index 000000000..355169db2 --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/m4esc.py @@ -0,0 +1,70 @@ +#! /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 new file mode 100644 index 000000000..afa8fb01f --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/pqxxthreadsafety.cxx @@ -0,0 +1,10 @@ +// 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 new file mode 100644 index 000000000..5db9605f1 --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/rmlo.cxx @@ -0,0 +1,39 @@ +// 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 new file mode 100755 index 000000000..2f4be957f --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/splitconfig @@ -0,0 +1,244 @@ +#! /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 new file mode 100755 index 000000000..9a5286d95 --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/template2mak.py @@ -0,0 +1,194 @@ +#! /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 new file mode 100755 index 000000000..29f33050c --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/test_all.py @@ -0,0 +1,630 @@ +#! /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 new file mode 100755 index 000000000..87429f4b2 --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/todo @@ -0,0 +1,31 @@ +#! /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 new file mode 100755 index 000000000..9d1eb5a97 --- /dev/null +++ b/ext/libpqxx-7.7.3/tools/update-copyright @@ -0,0 +1,29 @@ +#! /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