pax_global_header00006660000000000000000000000064147320545470014525gustar00rootroot0000000000000052 comment=d280c6c9a6d063638b5bb0d2450bc15ed641c27c libpqxx-7.10.0/000077500000000000000000000000001473205454700133015ustar00rootroot00000000000000libpqxx-7.10.0/.circleci/000077500000000000000000000000001473205454700151345ustar00rootroot00000000000000libpqxx-7.10.0/.circleci/config.yml000066400000000000000000000043201473205454700171230ustar00rootroot00000000000000# CircleCI config for automated test builds triggered from Github. version: 2 jobs: build: docker: - image: debian:unstable 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 clang shellcheck python3-virtualenv - run: name: Identify command: lsb_release -a && c++ --version && clang++ --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 --template=template0 --encoding=UNICODE root - run: name: Autogen command: ./autogen.sh - run: name: Configure command: | ./configure \ --enable-maintainer-mode \ --enable-audit \ --enable-shared --disable-static \ CXXFLAGS='-O3 -std=c++17' \ CXX=clang++ - store_artifacts: path: config.log - run: name: Make command: make -j$(nproc) - run: name: Test command: PGDATA=db/data make -j$(nproc) check - run: name: Analyse command: ./tools/lint --full >lint.log - store_artifacts: path: lint.log # The resource_class feature allows configuring CPU and RAM resources for each job. Different resource classes are available for different executors. https://circleci.com/docs/2.0/configuration-reference/#resourceclass resource_class: large libpqxx-7.10.0/.clang-format000066400000000000000000000040371473205454700156600ustar00rootroot00000000000000Language: 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 --- libpqxx-7.10.0/.clang-tidy000066400000000000000000000217741473205454700153500ustar00rootroot00000000000000# Somebody decided it would be a good idea to represet a "list of strings" # (a list that can get very long, and the indivdual strings tend to be # relatively long as well) as a single long comma-separated string, with # no tolerance for whitespace. Well done! # # We use clever YAML multiline-string syntax to work around this. Checks: > abseil-*, boost-*, bugprone-argument-comment, bugprone-assert-side-effect, bugprone-assignment-in-if-condition, bugprone-bad-signal-to-kill-thread, bugprone-bool-pointer-implicit-conversion, bugprone-copy-constructor-init, bugprone-dangling-handle, bugprone-dynamic-static-initializers, bugprone-fold-init-type, bugprone-forward-declaration-namespace, bugprone-forwarding-reference-overload, bugprone-implicit-widening-of-multiplication-result, bugprone-inaccurate-erase, bugprone-incorrect-roundings, bugprone-infinite-loop, bugprone-integer-division, bugprone-lambda-function-name, bugprone-macro-parentheses, bugprone-macro-repeated-side-effects, bugprone-misplaced-operator-in-strlen-in-alloc, bugprone-misplaced-pointer-arithmetic-in-alloc, bugprone-misplaced-widening-cast, bugprone-move-forwarding-reference, bugprone-multiple-statement-macro, bugprone-narrowing-conversions, bugprone-no-escape, bugprone-not-null-terminated-result, bugprone-parent-virtual-call, bugprone-posix-return, bugprone-redundant-branch-condition, bugprone-reserved-identifier, bugprone-shared-ptr-array-mismatch, bugprone-signal-handler, bugprone-signed-char-misuse, bugprone-sizeof-container, bugprone-sizeof-expression, bugprone-spuriously-wake-up-functions, bugprone-standalone-empty, bugprone-string-constructor, bugprone-string-integer-assignment, bugprone-string-literal-with-embedded-nul, bugprone-stringview-nullptr, bugprone-suspicious-enum-usage, bugprone-suspicious-include, bugprone-suspicious-memory-comparison, bugprone-suspicious-memset-usage, bugprone-suspicious-missing-comma, bugprone-suspicious-realloc-usage, bugprone-suspicious-semicolon, bugprone-suspicious-string-compare, bugprone-swapped-arguments, bugprone-terminating-continue, bugprone-throw-keyword-missing, bugprone-too-small-loop-variable, bugprone-unchecked-optional-access, bugprone-undefined-memory-manipulation, bugprone-undelegated-constructor, bugprone-unhandled-exception-at-new, bugprone-unhandled-self-assignment, bugprone-unused-raii, bugprone-unused-return-value, bugprone-use-after-move, bugprone-virtual-near-miss, cert-con36-c, cert-con54-cpp, cert-dcl03-c, cert-dcl16-c, cert-dcl37-c, cert-dcl50-cpp, cert-dcl51-cpp, cert-dcl54-cpp, cert-dcl58-cpp, cert-dcl59-cpp, cert-env33-c, cert-err09-cpp, cert-err33-c, cert-err34-c, cert-err52-cpp, cert-err58-cpp, cert-err60-cpp, cert-err61-cpp, cert-exp42-c, cert-fio38-c, cert-flp30-c, cert-flp37-c, cert-mem57-cpp, cert-msc30-c, cert-msc32-c, cert-msc50-cpp, cert-msc51-cpp, cert-msc54-cpp, cert-oop11-cpp, cert-oop54-cpp, cert-oop57-cpp, cert-oop58-cpp, cert-pos44-c, cert-pos47-c, cert-sig30-c, cert-str34-c, clang-analyzer-*, cppcoreguidelines-avoid-const-or-ref-data-members, cppcoreguidelines-avoid-goto, cppcoreguidelines-avoid-non-const-global-variables, cppcoreguidelines-avoid-reference-coroutine-parameters, cppcoreguidelines-c-copy-assignment-signature, cppcoreguidelines-explicit-virtual-functions, cppcoreguidelines-init-variables, cppcoreguidelines-interfaces-global-init, cppcoreguidelines-narrowing-conversions, cppcoreguidelines-no-malloc, cppcoreguidelines-non-private-member-variables-in-classes, cppcoreguidelines-owning-memory, cppcoreguidelines-prefer-member-initializer, cppcoreguidelines-pro-bounds-array-to-pointer-decay, cppcoreguidelines-pro-bounds-constant-array-index, cppcoreguidelines-pro-type-const-cast, cppcoreguidelines-pro-type-cstyle-cast, cppcoreguidelines-pro-type-member-init, cppcoreguidelines-pro-type-static-cast-downcast, cppcoreguidelines-pro-type-union-access, cppcoreguidelines-slicing, cppcoreguidelines-special-member-functions, cppcoreguidelines-virtual-class-destructor, darwin-dispatch-once-nonstatic, fuchsia-header-anon-namespaces, fuchsia-multiple-inheritance, fuchsia-trailing-return, fuchsia-virtual-inheritance, google-build-explicit-make-pair, google-build-namespaces, google-build-using-namespace, google-default-arguments, google-explicit-constructor, google-global-names-in-headers, google-readability-avoid-underscore-in-googletest-name, google-readability-function-size, google-readability-namespace-comments, google-runtime-operator, google-upgrade-googletest-case, hicpp-avoid-goto, hicpp-deprecated-headers, hicpp-exception-baseclass, hicpp-explicit-conversions, hicpp-function-size, hicpp-invalid-access-moved, hicpp-member-init, hicpp-multiway-paths-covered, hicpp-new-delete-operators, hicpp-no-array-decay, hicpp-no-assembler, hicpp-no-malloc, hicpp-special-member-functions, hicpp-undelegated-constructor, hicpp-use-auto, hicpp-use-emplace, hicpp-use-equals-default, hicpp-use-equals-delete, hicpp-use-noexcept, hicpp-use-nullptr, hicpp-use-override, llvm-header-guard, llvm-include-order, llvm-namespace-comment, llvm-prefer-isa-or-dyn-cast-in-conditionals, llvm-prefer-register-over-unsigned, llvm-twine-local, misc-confusable-identifiers, misc-const-correctness, misc-definitions-in-headers, misc-misleading-bidirectional, misc-misleading-identifier, misc-misplaced-const, misc-new-delete-overloads, misc-non-copyable-objects, misc-non-private-member-variables-in-classes, misc-redundant-expression, misc-throw-by-value-catch-by-reference, misc-unconventional-assign-operator, misc-uniqueptr-reset-release, misc-unused-alias-decls, misc-unused-parameters, misc-unused-using-decls, misc-use-anonymous-namespace, modernize-avoid-bind, modernize-concat-nested-namespaces, modernize-deprecated-headers, modernize-deprecated-ios-base-aliases, modernize-loop-convert, modernize-macro-to-enum, modernize-make-shared, modernize-make-unique, modernize-pass-by-value, modernize-raw-string-literal, modernize-redundant-void-arg, modernize-replace-auto-ptr, modernize-replace-disallow-copy-and-assign-macro, modernize-replace-random-shuffle, modernize-return-braced-init-list, modernize-shrink-to-fit, modernize-unary-static-assert, modernize-use-auto, modernize-use-bool-literals, modernize-use-default-member-init, modernize-use-emplace, modernize-use-equals-default, modernize-use-equals-delete, modernize-use-nodiscard, modernize-use-noexcept, modernize-use-nullptr, modernize-use-override, modernize-use-transparent-functors, modernize-use-uncaught-exceptions, modernize-use-using, performance-faster-string-find, performance-for-range-copy, performance-implicit-conversion-in-loop, performance-inefficient-algorithm, performance-inefficient-string-concatenation, performance-inefficient-vector-operation, performance-move-const-arg, performance-move-constructor-init, performance-no-automatic-move, performance-no-int-to-ptr, performance-trivially-destructible, performance-type-promotion-in-math-fn, performance-unnecessary-copy-initialization, performance-unnecessary-value-param, portability-restrict-system-includes, portability-simd-intrinsics, portability-std-allocator-const, readability-avoid-const-params-in-decls, readability-const-return-type, readability-container-contains, readability-container-data-pointer, readability-container-size-empty, readability-delete-null-pointer, readability-function-size, readability-identifier-naming, readability-inconsistent-declaration-parameter-name, readability-misplaced-array-index, readability-non-const-parameter, readability-redundant-access-specifiers, readability-redundant-control-flow, readability-redundant-declaration, readability-redundant-function-ptr-dereference, readability-redundant-member-init, readability-redundant-preprocessor, readability-redundant-smartptr-get, readability-redundant-string-cstr, readability-redundant-string-init, readability-simplify-boolean-expr, readability-simplify-subscript-expr, readability-static-accessed-through-instance, readability-static-definition-in-anonymous-namespace, readability-string-compare, readability-suspicious-call-argument, readability-uniqueptr-delete-release, readability-use-anyofallof, zircon-temporary-objects libpqxx-7.10.0/.cmake-format000066400000000000000000000214011473205454700156460ustar00rootroot00000000000000format: _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' libpqxx-7.10.0/.github/000077500000000000000000000000001473205454700146415ustar00rootroot00000000000000libpqxx-7.10.0/.github/workflows/000077500000000000000000000000001473205454700166765ustar00rootroot00000000000000libpqxx-7.10.0/.github/workflows/codeql.yml000066400000000000000000000030201473205454700206630ustar00rootroot00000000000000name: "CodeQL" on: push: branches: [ "master" ] pull_request: branches: [ "master" ] schedule: - cron: "33 21 * * 6" jobs: analyze: name: Analyze runs-on: ubuntu-latest permissions: actions: read contents: read security-events: write strategy: fail-fast: false matrix: language: [ python, cpp ] steps: - name: Checkout uses: actions/checkout@v3 - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} queries: +security-and-quality # For some reason, this seems to detect neither the configure script or the # CMake setup. # # - name: Autobuild # uses: github/codeql-action/autobuild@v3 # # Instead, we'll have to build manually: - name: Build run: | gcc --version sudo apt-get install -y postgresql virtualenv sudo service postgresql start sudo su postgres -c "createuser --createdb $(whoami)" createdb "$(whoami)" # Using clang because currently the gcc build fails with an # address sanitizer (asan) link error. ./configure --enable-maintainer-mode --enable-audit --disable-static CXXFLAGS='-O1 -std=c++17' CXX=clang++ make -j4 check || (cat test-suite.log && exit 1 || true) - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: category: "/language:${{ matrix.language }}" libpqxx-7.10.0/.github/workflows/stale.yml000066400000000000000000000012631473205454700205330ustar00rootroot00000000000000name: Mark stale issues and pull requests on: schedule: - cron: "30 1 * * *" permissions: contents: read jobs: stale: permissions: issues: write # for actions/stale to close stale issues pull-requests: write # for actions/stale to close stale PRs runs-on: ubuntu-latest steps: - uses: actions/stale@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' libpqxx-7.10.0/.gitignore000066400000000000000000000003771473205454700153000ustar00rootroot00000000000000autom4te.cache build-*.out ChangeLog CMakeFiles/CMakeTmp confdefs.h config.log config.status conftest conftest.cpp conftest.err libpqxx.pc libpqxx-*.tar.gz libtool pqxx-config win32/common **/*.out **/.*.swp **/.swp **/*.tmp **/*~ **/lint.log **/lint.trs libpqxx-7.10.0/.lgtm.yml000066400000000000000000000002201473205454700150370ustar00rootroot00000000000000# Config file for lgtm.com static analysis. path_classifiers: test: - test generated: - aclocal.m4 - configure - ltmain.sh libpqxx-7.10.0/.lift/000077500000000000000000000000001473205454700143155ustar00rootroot00000000000000libpqxx-7.10.0/.lift/ignoreFiles000066400000000000000000000001061473205454700165030ustar00rootroot00000000000000# Make Sonatype Lift ignore these generated files. configure config/* libpqxx-7.10.0/.mdl_style.rb000066400000000000000000000015411473205454700157010ustar00rootroot00000000000000all # Allow mixing of header styles, within reason. # I use "setext" style when I can, but have to switch to "atx" (hash marks) # for the more fine-grained sections which setext does not support. rule 'MD003', :style => :setext_with_atx # Multiple consecutive blank lines. Sorry, but I want my Markdown to look # nice. And there does not seem to be an option for "allow a maximum of 2." exclude_rule 'MD012' # What joker came up with this? There may be some sense to warning about # trailing punctuation, but not when it's a question mark or exclamantion mark! rule 'MD026', :punctuation => '.,;:' # In an ordered list, I like to start each item with the right number, not with # "1." rule 'MD029', :style => :ordered # Allow bare URLs. Hate to have to disable this, but mainpage.md has some # special syntax which requires bare URLs. exclude_rule 'MD034' libpqxx-7.10.0/.mdlrc000066400000000000000000000003071473205454700144030ustar00rootroot00000000000000# Markdownlint config. Basically it's code, not config. :-( # Also, it seems all we can really do in this file is point to another file # containing our actual configuration. style '.mdl_style.rb' libpqxx-7.10.0/.readthedocs.yaml000066400000000000000000000013631473205454700165330ustar00rootroot00000000000000# Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details version: 2 # Set the version of Python and other tools you might need build: os: "ubuntu-24.04" tools: python: "3.12" apt_packages: - "graphviz" jobs: pre_build: - "./configure --enable-documentation CXXFLAGS='-O0 -std=c++23'" - "mkdir -p doc/doxygen-html" - "cd doc && doxygen" - "mkdir -p -- $READTHEDOCS_OUTPUT/html" post_build: - "mv -- $READTHEDOCS_OUTPUT/html $READTHEDOCS_OUTPUT/sphinx-html" - "mv -- doc/doxygen-html $READTHEDOCS_OUTPUT/html" python: install: - requirements: doc/requirements.txt sphinx: configuration: doc/source/conf.py fail_on_warning: true libpqxx-7.10.0/AUTHORS000066400000000000000000000002211473205454700143440ustar00rootroot00000000000000Jeroen T. Vermeulen. Wrote the code. Ray Dassen. Did most of the autoconf etc. stuff. Lots of others helped with various other contributions. libpqxx-7.10.0/BUILDING-cmake.md000066400000000000000000000317341473205454700161060ustar00rootroot00000000000000Building using CMake ==================== First of all, the libpqxx build requires the full PostgreSQL development package. You must have that package 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. There are two ways to use libpqxx in your project with CMake: * _(A)_ copy and build the libpqxx source tree. * Or _(B),_ make use of a separately installed libpqxx. We'll go through both of these. Option (A): Copy and build the libpqxx source tree -------------------------------------------------- This option is nice and portable. If you want others to be able to compile your project on their own systems, this method probably requires a bit less setup than the other option. It's easier to keep compatible compilation options between libpqxx and your project. On the flip side, building your project will take a bit longer, because it will build libpqxx along the way. And of course, you'll need to make sure that there's a copy of the libpqxx tree somewhere. You could do that by having the libpqxx git repo as a submodule inside yours. As mentioned, you'll need to have the PostgreSQL dev libraries installed on your system, including their headers. Let's say you have a copy of the libpqxx source tree inside your source tree as `deps/libpqxx`, and you want to want to build libpqxx in a subdirectory of your build directory called `build-pqxx`. Given that, make sure you have a line like this in your `CMakeLists.txt`: ```cmake add_subdirectory(deps/libpqxx build-pqxx) ``` You'll also need to mention libpqxx in your `target_link_libraries`, so that your code will link with libpqxx. For example, if your project is named `ausom` and links to no other libraries: ```cmake target_link_libraries(ausom PRIVATE pqxx) ``` So a simple working `CMakeLists.txt` might be: ```cmake cmake_minimum_required(VERSION 3.18) project(ausom) set(CMAKE_CXX_STANDARD 20) add_executable(ausom src/ausom.cxx) add_subdirectory(deps/libpqxx build-pqxx) target_link_libraries(ausom PRIVATE pqxx) ``` Option (B): Make use of a separately installed libpqxx ------------------------------------------------------ If libpqxx is already installed, you can just make use of that in your own `CMakeLists.txt`: ```cmake find_package(libpqxx REQUIRED) ``` For this to work, there must be a configuration file `libpqxxConfig.cmake` or `libpqxx-config.cmake` that CMake can find. If this file exists but CMake can't find it, you may have to set `libpqxx_DIR` in your `CMakeLists.txt` to point to a directory containing that configuration file. You'll also need to mention libpqxx in your `target_link_libraries`, so that your code will link with libpqxx. For example, if your project is named `ausom` and links to no other libraries: ```cmake target_link_libraries(ausom PRIVATE pqxx) ``` So a simple working `CMakeLists.txt` might be: ```cmake cmake_minimum_required(VERSION 3.18) project(ausom) set(CMAKE_CXX_STANDARD 20) add_executable(ausom src/ausom.cxx) find_package(libpqxx REQUIRED) target_link_libraries(ausom PRIVATE pqxx) ``` Of course that does mean that you need libpqxx installed on your system. We'll look into that next. Installing a libpqxx OS package ------------------------------- Your operating system provider may have a packaged version of libpqxx ready for you to install. For example, on a Debian or Ubuntu system you might run: ```shell sudo apt-get install libpqxx-dev ``` But the exact name of the package you need may depend on the system. In a Debian-flavoured system, the `-dev` suffix is a convention for saying that you want not just a binary library installed, but its header files as well. You definitely need those. On a RedHat-flavoured system, the convention is a suffix of `-devel` after the name, i.e. `libpqxx-devel`. Other systems may conventionally include the headers with the library package. For example, on macOS using HomeBrew, you would just... ```shell brew install libpqxx ``` Of course if there is no ready-made libpqxx package for your system, or it's not up to date, or it does not provide a `libpqxx-config.cmake` configuration file, another option is to build and install libpqxx using CMake. Building and installing libpqxx yourself ---------------------------------------- If you just want to get libpqxx itself 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 . ``` The rest of this document will go deeper into the details of this, but you may not need it. 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 ](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. Here's an example of a `CMakeLists.txt` fragment. You'll probably still need to provide details specific to your project. ```cmake # (First set LIBVERSION to the libpqxx version you have.) set(libpqxxdir "libpqxx-${LIBVERSION}") # You can usually skip building the tests. set(SKIP_BUILD_TEST ON) # On Windows we generally recommend building libpqxx as a shared # library. On other platforms, we recommend a static library. IF (WIN32) set(BUILD_SHARED_LIBS ON) ELSE() set(BUILD_SHARED_LIBS OFF) ENDIF() add_subdirectory(${libpqxxdir}) ``` If you are using shared libraries (which is recommended when building on Windows), you may need to ensure that libpq and the libraries it in turn requires are all in your dynamic link path. libpqxx-7.10.0/BUILDING-configure.md000066400000000000000000000244211473205454700170020ustar00rootroot00000000000000Building using `configure` ========================== 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. Prerequisites ------------- Before building and installing the `libpqxx` library, you first need to install the `libpq` library. This is the official C client library for PostgreSQL that allows `libpqxx` to communicate with the database backend server. Methods for installing the `libpq` library will vary depending on your operating system and individual setup. Quick start ----------- Once you have downloaded the `libpqxx` source code, you can build and install it quickly by entering the following commands: ```shell ./configure --disable-shared make sudo make install ``` This installation automatically places the `libpqxx` libraries in the appropriate locations for your system. If you wish, you may delete the downloaded folder after the installation process completes. 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 ](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. libpqxx-7.10.0/CMakeLists.txt000066400000000000000000000030371473205454700160440ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.12) 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) libpqxx-7.10.0/COPYING000066400000000000000000000027261473205454700143430ustar00rootroot00000000000000Copyright (c) 2000-2024 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. libpqxx-7.10.0/INSTALL000066400000000000000000000002061473205454700143300ustar00rootroot00000000000000For installation instructions, see `BUILDING-configure.md` (for the `configure` build) and `BUILDING-cmake.md` (for the CMake build). libpqxx-7.10.0/Makefile.am000066400000000000000000000011441473205454700153350ustar00rootroot00000000000000SUBDIRS = 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 $< $@ libpqxx-7.10.0/Makefile.in000066400000000000000000001217051473205454700153540ustar00rootroot00000000000000# Makefile.in generated by automake 1.16.5 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)/pqxx_cxx_feature_checks.ac \ $(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@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ 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: libpqxx-7.10.0/NEWS000066400000000000000000001604001473205454700140010ustar00rootroot000000000000007.10.0 - Deprecate `errorhandler`; replace with lambda-friendly "notice handlers." - Deprecate `notification_receiver`; replace with "notification handlers" - Bump minimum CMake version to 3.28. (#874) - Fixed error message on clashing transaction focuses. (#879) - Don't call`/bin/true`; macOS doesn't have it. Just call `true`. (#885) - Deprecate `exec_prepared()`; just use `exec()` with a `pqxx::prepped`. - Deprecate `exec1()` etc. Use `result::expect_rows()` etc. - Fix error-reporting crash in non-blocking connection constructor. (#894) - Fix buffer overrun when converting array containing nulls to string. (#906) - Fix nullness check for `std::optional` containing a nullable value. (#907) - `connection::process_notice()` no longer appends newline if missing. 7.9.2 - Fix CMake documentation install. (#848) - More CMake build fix. (#869) - Bump gcc/clang/postgres minimum version requirements. - Another fix to the readthedocs documentation build. (#845) - Remove obsolete CMake workaround kludges. (#851, #866, #867) - Remove obscure deprecated `stream_to` constructor that never worked. (#853) - Support reading a field as an SQL array using `as_sql_array()`. (#841) - Make row iterator a _proper_ `random_access_iterator`. (#846) - Downgrade result iterator to "bidirectional"; was never really RA. (#846) 7.9.1 - Fix bad conversion of array of empty strings to string. (#816) - Move `[[likely]]` feature check back to compile time, to speed up configure. - Support `[[assume(...)]]`. - Fix `throw_null_conversion` compile error when converting enums. (#807) - Fix memory leak when failing to connect. - Improve introductory docs for connections and transactions. - Re-do entire documentation build. No more Sphinx in readthedocs. (#802) - No more autodetection of doxygen etc. Run it, or don't. - Docs build now disabled by default; use `--enable-documentation` to change. 7.9.0 - Support standard libraries without `std::basic_string` etc. - `std::basic_string` becomes `bytes_view`. (#726) - Fix assertion failure when streaming row ending in empty string. (#774) - CMake users can `shared_link_libraries(... libpqxx::pqxx)`. (#784) - Support parameterised versions of `query()` etc. (#646) - Put all feature tests back in config header. (#732) - Automate integration of feature tests into both CMake & autoconf. (#747) - Streaming query result implements `std::input_iterator`. (#771) - Fix broken `to_buf()` on `zview`. (#728) - Support `PQfsize()` and `PQfmod()`. (#727) - Implement conversion from `string_view` to string. (#728) - Rename `splitconfig` to `splitconfig.py`. (#763) - Document need for conversions more clearly, link to docs. (#757) - Experimental support for converting `std::span` to SQL arrays. (#769) 7.8.1 - Regenerate build files. Should fix ARM Mac build. (#715) - Reinstate `` that MSVC can't live with or without. (#713) 7.8.0 - Streaming large data sets now benchmarks faster than similar C/libpq code! - New `array` class for easier parsing of SQL arrays. - Deprecating `stream_from`. Use `transaction_base::stream()`. - Use `array_parser` only on comma-separated types, i.e. most of them. (#590) - Bumping requirements versions: need postgres 10. - Fix `array_parser` bug when parsing semicolon in an unquoted string. - Make some `zview` constructors `noexcept` if `string_view` does it. - Handle result status code for starting streaming replication. (#631) - Faster text decoding and escaping in data streaming. (#601) - Deprecate `basic_fieldstream` and `fieldstream`. - Deprecate `<<` operator inserting a field into an `ostream`. - New string conversion fields: `converts_to_string` & `converts_from_string`. - Ran `autoupdate` (because the autotools told me to). - Documentation tweak. (#584) - Typo in README.md. (#586) - Support `std::optional` etc. in `stream_to`. (#596) - Remove support for single-quoted array/composite elements. No such thing! - Optimise out a kink in composite field parser. - Work around build warning in MinGW: include `winsock2.h` before `windows.h`. - Drop some redundant encoding groups. - If CMake can't find libpq, fall back to pkg-config. (#664) - Work around spurious compile error on g++ pre-gcc-10. (#665) - Include `` and `` headers in ``. (#667) - Don't use `std::function` as deleter for smart pointers. - Work around gcc compile error with regex + address sanitizer + analyzers. - Fix "double free" on exit when built as shared library on Debian. (#681) - Stop including ``; should be built into compilers. (#680) - New `broken_connection` exception subclass: `protocol_violation`. (#686) - Retired unused `blob_already_exists` exception class. (#686) - Support for `PQinitOpenSSL()`. (#678) - Slightly more helpful error for unsupported conversions. (#695) - Replace some C++ feature tests with C++20 feature macros. - Support moving of `stream_to`. (#706) - Incorporate `source_location` in exceptions. 7.7.4 - `transaction_base::for_each()` is now called `for_stream()`. (#580) - New `transaction_base::for_query()` is similar, but non-streaming. (#580) - Query data and iterate directly as client-side types: `query()`. (#580) - New ways to query a single row! `query01()` and `query1()`. (#580) - We now have 3 kinds of execution: "exec", "query", and "stream" functions. - Use C++23 `std::unreachable()` where available. - `result::iter()` return value now keeps its `result` alive. 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... libpqxx-7.10.0/README.md000066400000000000000000000252361473205454700145700ustar00rootroot00000000000000libpqxx ======= Welcome to libpqxx, the C++ API to the PostgreSQL database management system. Home page: [ http://pqxx.org/development/libpqxx ](http://pqxx.org/development/libpqxx/) Find libpqxx on Github: [ https://github.com/jtv/libpqxx ](https://github.com/jtv/libpqxx) Documentation on Read The Docs: [ https://libpqxx.readthedocs.io ](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: ```sh 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`](./BUILDING-configure.md) and [`BUILDING-cmake.md`](./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 may also need the result class (`pqxx/result.hxx`). In a nutshell, you create a pqxx::connection based on a Postgres connection string (see below), create a pqxx::work (a transaction object) in the context of that connection, and run one or more queries and/or SQL commands on that. Depending on how you execute a query, it can return a stream of `std::tuple` (each representing one row); or a pqxx::result object which holds both the result data and additional metadata: how many rows your query returned and/or modified, what the column names are, and so on. A pqxx::result is a container of pqxx::row, and a pqxx::row is a container of pqxx::field. Here's an example with all the basics to get you going: ```c++ #include #include int main() { try { // Connect to the database. You can have multiple connections open // at the same time, even to the same database. pqxx::connection c; std::cout << "Connected to " << c.dbname() << '\n'; // Start a transaction. A connection can only have one transaction // open at the same time, but after you finish a transaction, you // can start a new one on the same connection. pqxx::work tx{c}; // Query data of two columns, converting them to std::string and // int respectively. Iterate the rows. for (auto [name, salary] : tx.query( "SELECT name, salary FROM employee ORDER BY name")) { std::cout << name << " earns " << salary << ".\n"; } // For large amounts of data, "streaming" the results is more // efficient. It does not work for all types of queries though. // // You can read fields as std::string_view here, which is not // something you can do in most places. A string_view becomes // meaningless when the underlying string ceases to exist. In this // one situation, you can convert a field to string_view and it // will be valid for just that one iteration of the loop. The next // iteration may overwrite or deallocate its buffer space. for (auto [name, salary] : tx.stream( "SELECT name, salary FROM employee")) { std::cout << name << " earns " << salary << ".\n"; } // Execute a statement, and check that it returns 0 rows of data. // This will throw pqxx::unexpected_rows if the query returns rows. std::cout << "Doubling all employees' salaries...\n"; tx.exec0("UPDATE employee SET salary = salary*2"); // Shorthand: conveniently query a single value from the database. int my_salary = tx.query_value( "SELECT salary FROM employee WHERE name = 'Me'"); std::cout << "I now earn " << my_salary << ".\n"; // Or, query one whole row. This function will throw an exception // unless the result contains exactly 1 row. auto [top_name, top_salary] = tx.query1( R"( SELECT name, salary FROM employee WHERE salary = max(salary) LIMIT 1 )"); std::cout << "Top earner is " << top_name << " with a salary of " << top_salary << ".\n"; // If you need to access the result metadata, not just the actual // field values, use the "exec" functions. Most of them return // pqxx::result objects. pqxx::result res = tx.exec("SELECT * FROM employee"); std::cout << "Columns:\n"; for (pqxx::row_size_type col = 0; col < res.columns(); ++col) std::cout << res.column_name(col) << '\n'; // Commit the transaction. If you don't do this, the database will // undo any changes you made in the transaction. std::cout << "Making changes definite: "; tx.commit(); std::cout << "OK.\n"; } catch (std::exception const &e) { std::cerr << "ERROR: " << 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 these 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.. libpqxx-7.10.0/README.rst000066400000000000000000000000211473205454700147610ustar00rootroot00000000000000See `README.md`. libpqxx-7.10.0/VERSION000066400000000000000000000000071473205454700143460ustar00rootroot000000000000007.10.0 libpqxx-7.10.0/aclocal.m4000066400000000000000000001261721473205454700151520ustar00rootroot00000000000000# generated automatically by aclocal 1.16.5 -*- 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.71],, [m4_warning([this file was generated for autoconf 2.71. 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.5], [], [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.5])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 m4_ifdef([_$0_ALREADY_INIT], [m4_fatal([$0 expanded multiple times ]m4_defn([_$0_ALREADY_INIT]))], [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])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]) libpqxx-7.10.0/appveyor.yml000066400000000000000000000014741473205454700156770ustar00rootroot00000000000000# 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 libpqxx-7.10.0/autogen.sh000077500000000000000000000025731473205454700153110ustar00rootroot00000000000000#! /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. # shellcheck disable=SC2046 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 # Generate feature test snippets for C++ features that we simply detect by # checking a C++ feature test macro. ./tools/generate_cxx_checks.py # Generate autoconf and CMake configuration for our feature test snippets. ./tools/generate_check_config.py autoheader libtoolize --force --automake --copy aclocal -I . -I config/m4 automake --add-missing --copy autoconf echo "Done." libpqxx-7.10.0/cmake/000077500000000000000000000000001473205454700143615ustar00rootroot00000000000000libpqxx-7.10.0/cmake/config.cmake000066400000000000000000000026661473205454700166420ustar00rootroot00000000000000include(CheckFunctionExists) include(CMakeFindDependencyMacro) if(NOT PostgreSQL_FOUND) find_package(PostgreSQL) endif() if(NOT PostgreSQL_FOUND) find_package(PkgConfig REQUIRED) pkg_check_modules(PostgreSQL REQUIRED libpq) endif() check_function_exists("poll" PQXX_HAVE_POLL) # Incorporate feature checks based on C++ feature test mac include(pqxx_cxx_feature_checks) # This variable is set by one of the snippets in config-tests. if(!no_need_fslib) # TODO: This may work for gcc 8, but some clang versions may need -lc++fs. link_libraries(stdc++fs) endif() 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") libpqxx-7.10.0/cmake/libpqxx-config.cmake000066400000000000000000000001721473205454700203150ustar00rootroot00000000000000include(CMakeFindDependencyMacro) find_dependency(PostgreSQL) include("${CMAKE_CURRENT_LIST_DIR}/libpqxx-targets.cmake") libpqxx-7.10.0/cmake/pqxx_cxx_feature_checks.cmake000066400000000000000000000054401473205454700223030ustar00rootroot00000000000000# Configuration for feature checks. Generated by generate_check_config.py. try_compile( PQXX_HAVE_ASSUME ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_ASSUME.cxx ) try_compile( PQXX_HAVE_CHARCONV_FLOAT ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_CHARCONV_FLOAT.cxx ) try_compile( PQXX_HAVE_CHARCONV_INT ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_CHARCONV_INT.cxx ) try_compile( PQXX_HAVE_CMP ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_CMP.cxx ) try_compile( PQXX_HAVE_CONCEPTS ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_CONCEPTS.cxx ) try_compile( PQXX_HAVE_CXA_DEMANGLE ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_CXA_DEMANGLE.cxx ) try_compile( PQXX_HAVE_GCC_PURE ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_GCC_PURE.cxx ) try_compile( PQXX_HAVE_GCC_VISIBILITY ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_GCC_VISIBILITY.cxx ) try_compile( PQXX_HAVE_LIKELY ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_LIKELY.cxx ) try_compile( PQXX_HAVE_MULTIDIM ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_MULTIDIM.cxx ) try_compile( PQXX_HAVE_PATH ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_PATH.cxx ) try_compile( PQXX_HAVE_POLL ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_POLL.cxx ) try_compile( PQXX_HAVE_SLEEP_FOR ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_SLEEP_FOR.cxx ) try_compile( PQXX_HAVE_SOURCE_LOCATION ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_SOURCE_LOCATION.cxx ) try_compile( PQXX_HAVE_SPAN ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_SPAN.cxx ) try_compile( PQXX_HAVE_SSIZE ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_SSIZE.cxx ) try_compile( PQXX_HAVE_STRERROR_R ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_STRERROR_R.cxx ) try_compile( PQXX_HAVE_STRERROR_S ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_STRERROR_S.cxx ) try_compile( PQXX_HAVE_THREAD_LOCAL ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_THREAD_LOCAL.cxx ) try_compile( PQXX_HAVE_YEAR_MONTH_DAY ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/PQXX_HAVE_YEAR_MONTH_DAY.cxx ) try_compile( no_need_fslib ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/no_need_fslib.cxx ) # End of config. libpqxx-7.10.0/compile_flags.in000066400000000000000000000000261473205454700164330ustar00rootroot00000000000000@CPPFLAGS@ @CXXFLAGS@ libpqxx-7.10.0/config-tests/000077500000000000000000000000001473205454700157065ustar00rootroot00000000000000libpqxx-7.10.0/config-tests/PQXX_HAVE_ASSUME.cxx000066400000000000000000000001261473205454700211110ustar00rootroot00000000000000int main(int argc, char **argv) { [[assume(argv != nullptr)]]; return argc - 1; } libpqxx-7.10.0/config-tests/PQXX_HAVE_CHARCONV_FLOAT.cxx000066400000000000000000000006251473205454700222500ustar00rootroot00000000000000// 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; } libpqxx-7.10.0/config-tests/PQXX_HAVE_CHARCONV_INT.cxx000066400000000000000000000006141473205454700220330ustar00rootroot00000000000000// 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; } libpqxx-7.10.0/config-tests/PQXX_HAVE_CMP.cxx000066400000000000000000000002571473205454700205400ustar00rootroot00000000000000// Test for C++20 std::cmp_greater etc. support. // C++20: Assume support. #include int main() { return std::cmp_greater(-1, 2u) && std::cmp_less_equal(3, 0); } libpqxx-7.10.0/config-tests/PQXX_HAVE_CONCEPTS.cxx000066400000000000000000000004541473205454700213360ustar00rootroot00000000000000// Feature check for 'PQXX_HAVE_CONCEPTS'. // Generated by generate_cxx_checks.py. #include #if !defined(__cpp_concepts) # error "No PQXX_HAVE_CONCEPTS: __cpp_concepts is not set." #endif #if !__cpp_concepts # error "No PQXX_HAVE_CONCEPTS: __cpp_concepts is false." #endif int main() {} libpqxx-7.10.0/config-tests/PQXX_HAVE_CXA_DEMANGLE.cxx000066400000000000000000000006521473205454700217670ustar00rootroot00000000000000// 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; } libpqxx-7.10.0/config-tests/PQXX_HAVE_GCC_PURE.cxx000066400000000000000000000001641473205454700213450ustar00rootroot00000000000000// Test for gcc-style "pure" attribute. int __attribute__((pure)) f() { return 0; } int main() { return f(); } libpqxx-7.10.0/config-tests/PQXX_HAVE_GCC_VISIBILITY.cxx000066400000000000000000000002521473205454700222570ustar00rootroot00000000000000// Test for gcc-style "visibility" attribute. struct __attribute__((visibility("hidden"))) D { D() {} int f() { return 0; } }; int main() { D d; return d.f(); } libpqxx-7.10.0/config-tests/PQXX_HAVE_LIKELY.cxx000066400000000000000000000004351473205454700211100ustar00rootroot00000000000000// Test for C++20 [[likely]] and [[unlikely]] attributes. // C++20: Assume support. 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; } libpqxx-7.10.0/config-tests/PQXX_HAVE_MULTIDIM.cxx000066400000000000000000000005641473205454700213460ustar00rootroot00000000000000// Feature check for 'PQXX_HAVE_MULTIDIM'. // Generated by generate_cxx_checks.py. #include #if !defined(__cpp_multidimensional_subscript) # error "No PQXX_HAVE_MULTIDIM: __cpp_multidimensional_subscript is not set." #endif #if !__cpp_multidimensional_subscript # error "No PQXX_HAVE_MULTIDIM: __cpp_multidimensional_subscript is false." #endif int main() {} libpqxx-7.10.0/config-tests/PQXX_HAVE_PATH.cxx000066400000000000000000000003301473205454700206450ustar00rootroot00000000000000// 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{}; } libpqxx-7.10.0/config-tests/PQXX_HAVE_POLL.cxx000066400000000000000000000001241473205454700206600ustar00rootroot00000000000000// Test for poll(). #include int main() { return poll(nullptr, 0, 0); } libpqxx-7.10.0/config-tests/PQXX_HAVE_SLEEP_FOR.cxx000066400000000000000000000015611473205454700214760ustar00rootroot00000000000000// 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 and OS headers that we don't strictly need * here. */ #include #include #include #include #include #include #include #if __has_include() # include #endif #if __has_include() # include #endif #if __has_include() # include #endif int main() { std::this_thread::sleep_for(std::chrono::microseconds{10u}); } libpqxx-7.10.0/config-tests/PQXX_HAVE_SOURCE_LOCATION.cxx000066400000000000000000000005551473205454700224120ustar00rootroot00000000000000// Feature check for 'PQXX_HAVE_SOURCE_LOCATION'. // Generated by generate_cxx_checks.py. #include #if !defined(__cpp_lib_source_location) # error "No PQXX_HAVE_SOURCE_LOCATION: __cpp_lib_source_location is not set." #endif #if !__cpp_lib_source_location # error "No PQXX_HAVE_SOURCE_LOCATION: __cpp_lib_source_location is false." #endif int main() {} libpqxx-7.10.0/config-tests/PQXX_HAVE_SPAN.cxx000066400000000000000000000004401473205454700206540ustar00rootroot00000000000000// Feature check for 'PQXX_HAVE_SPAN'. // Generated by generate_cxx_checks.py. #include #if !defined(__cpp_lib_span) # error "No PQXX_HAVE_SPAN: __cpp_lib_span is not set." #endif #if !__cpp_lib_span # error "No PQXX_HAVE_SPAN: __cpp_lib_span is false." #endif int main() {} libpqxx-7.10.0/config-tests/PQXX_HAVE_SSIZE.cxx000066400000000000000000000004471473205454700210170ustar00rootroot00000000000000// Feature check for 'PQXX_HAVE_SSIZE'. // Generated by generate_cxx_checks.py. #include #if !defined(__cpp_lib_ssize) # error "No PQXX_HAVE_SSIZE: __cpp_lib_ssize is not set." #endif #if !__cpp_lib_ssize # error "No PQXX_HAVE_SSIZE: __cpp_lib_ssize is false." #endif int main() {} libpqxx-7.10.0/config-tests/PQXX_HAVE_STRERROR_R.cxx000066400000000000000000000005271473205454700216640ustar00rootroot00000000000000// 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; } libpqxx-7.10.0/config-tests/PQXX_HAVE_STRERROR_S.cxx000066400000000000000000000003411473205454700216570ustar00rootroot00000000000000// 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); } libpqxx-7.10.0/config-tests/PQXX_HAVE_THREAD_LOCAL.cxx000066400000000000000000000007531473205454700220030ustar00rootroot00000000000000// Test for std::to_string/std::from_string for floating-point types. // TODO: Probably no longer needed once we always have float std::charconv. #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(); } libpqxx-7.10.0/config-tests/PQXX_HAVE_YEAR_MONTH_DAY.cxx000066400000000000000000000001631473205454700223170ustar00rootroot00000000000000// Test for std::chrono::year_month_day etc. #include int main() { return int(std::chrono::year{1}); } libpqxx-7.10.0/config-tests/README.md000066400000000000000000000023671473205454700171750ustar00rootroot00000000000000Configuration tests =================== Libpqxx comes with support for two different build systems: the GNU autotools, and CMake. We need to teach both of these to test things like "does this compiler environment support `std::to_chars` for floating-point types?" In both build systems we test these things by trying to compile a particular snippet of code, found in this directry, 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. We generate autoconf and cmake configuration automatically to inject those checks, avoiding tedious repetition. Some of the checks are based on C++20 feature test macros. We generate those automatically using `tools/generate_cxx_checks.py`. It took a bit of nasty magic to read a C++ source file into m4 for the autoconf side 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. libpqxx-7.10.0/config-tests/no_need_fslib.cxx000066400000000000000000000011171473205454700212200ustar00rootroot00000000000000// 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 } libpqxx-7.10.0/config/000077500000000000000000000000001473205454700145465ustar00rootroot00000000000000libpqxx-7.10.0/config/Makefile.am000066400000000000000000000004341473205454700166030ustar00rootroot00000000000000EXTRA_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 libpqxx-7.10.0/config/Makefile.in000066400000000000000000000314451473205454700166220ustar00rootroot00000000000000# Makefile.in generated by automake 1.16.5 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)/pqxx_cxx_feature_checks.ac \ $(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@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ 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: libpqxx-7.10.0/config/compile000077500000000000000000000163501473205454700161310ustar00rootroot00000000000000#! /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: libpqxx-7.10.0/config/config.guess000077500000000000000000001405121473205454700170710ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-01-09' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2022 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 # Just in case it came from the environment. GUESS= # 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. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039,SC3028 { 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" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c89 c99 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver 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 } # 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 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case $UNAME_SYSTEM in Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu #else #include /* First heuristic to detect musl libc. */ #ifdef __DEFINED_va_list LIBC=musl #endif #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl; then LIBC=musl fi # If the system lacks a compiler, then just pick glibc. # We could probably try harder. if [ "$LIBC" = unknown ]; then LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` case $UNAME_MACHINE_ARCH in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case $UNAME_VERSION in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. GUESS=$machine-${os}${release}${abi-} ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE ;; *:SecBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE ;; *:MidnightBSD:*:*) GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE ;; *:ekkoBSD:*:*) GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE ;; *:SolidBSD:*:*) GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE ;; *:OS108:*:*) GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE ;; macppc:MirBSD:*:*) GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE ;; *:MirBSD:*:*) GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE ;; *:Sortix:*:*) GUESS=$UNAME_MACHINE-unknown-sortix ;; *:Twizzler:*:*) GUESS=$UNAME_MACHINE-unknown-twizzler ;; *:Redox:*:*) GUESS=$UNAME_MACHINE-unknown-redox ;; mips:OSF1:*.*) GUESS=mips-dec-osf1 ;; alpha:OSF1:*:*) # Reset EXIT trap before exiting to avoid spurious non-zero exit code. trap '' 0 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. OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` GUESS=$UNAME_MACHINE-dec-osf$OSF_REL ;; Amiga*:UNIX_System_V:4.0:*) GUESS=m68k-unknown-sysv4 ;; *:[Aa]miga[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-amigaos ;; *:[Mm]orph[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-morphos ;; *:OS/390:*:*) GUESS=i370-ibm-openedition ;; *:z/VM:*:*) GUESS=s390-ibm-zvmoe ;; *:OS400:*:*) GUESS=powerpc-ibm-os400 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) GUESS=arm-acorn-riscix$UNAME_RELEASE ;; arm*:riscos:*:*|arm*:RISCOS:*:*) GUESS=arm-unknown-riscos ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) GUESS=hppa1.1-hitachi-hiuxmpp ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. case `(/bin/universe) 2>/dev/null` in att) GUESS=pyramid-pyramid-sysv3 ;; *) GUESS=pyramid-pyramid-bsd ;; esac ;; NILE*:*:*:dcosx) GUESS=pyramid-pyramid-svr4 ;; DRS?6000:unix:4.0:6*) GUESS=sparc-icl-nx6 ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) GUESS=sparc-icl-nx7 ;; esac ;; s390x:SunOS:*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL ;; sun4H:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-hal-solaris2$SUN_REL ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris2$SUN_REL ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) GUESS=i386-pc-auroraux$UNAME_RELEASE ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) 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 test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$SUN_ARCH-pc-solaris2$SUN_REL ;; 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. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris3$SUN_REL ;; 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'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; sun3*:SunOS:*:*) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; 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) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac ;; aushp:SunOS:*:*) GUESS=sparc-auspex-sunos$UNAME_RELEASE ;; # 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:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) GUESS=m68k-milan-mint$UNAME_RELEASE ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) GUESS=m68k-hades-mint$UNAME_RELEASE ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) GUESS=m68k-unknown-mint$UNAME_RELEASE ;; m68k:machten:*:*) GUESS=m68k-apple-machten$UNAME_RELEASE ;; powerpc:machten:*:*) GUESS=powerpc-apple-machten$UNAME_RELEASE ;; RISC*:Mach:*:*) GUESS=mips-dec-mach_bsd4.3 ;; RISC*:ULTRIX:*:*) GUESS=mips-dec-ultrix$UNAME_RELEASE ;; VAX*:ULTRIX*:*:*) GUESS=vax-dec-ultrix$UNAME_RELEASE ;; 2020:CLIX:*:* | 2430:CLIX:*:*) GUESS=clipper-intergraph-clix$UNAME_RELEASE ;; mips:*:*:UMIPS | mips:*:*:RISCos) 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; } GUESS=mips-mips-riscos$UNAME_RELEASE ;; Motorola:PowerMAX_OS:*:*) GUESS=powerpc-motorola-powermax ;; Motorola:*:4.3:PL8-*) GUESS=powerpc-harris-powermax ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) GUESS=powerpc-harris-powermax ;; Night_Hawk:Power_UNIX:*:*) GUESS=powerpc-harris-powerunix ;; m88k:CX/UX:7*:*) GUESS=m88k-harris-cxux7 ;; m88k:*:4*:R4*) GUESS=m88k-motorola-sysv4 ;; m88k:*:3*:R3*) GUESS=m88k-motorola-sysv3 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then GUESS=m88k-dg-dgux$UNAME_RELEASE else GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else GUESS=i586-dg-dgux$UNAME_RELEASE fi ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) GUESS=m88k-dolphin-sysv3 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 GUESS=m88k-motorola-sysv3 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) GUESS=m88k-tektronix-sysv3 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) GUESS=m68k-tektronix-bsd ;; *:IRIX*:*:*) IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` GUESS=mips-sgi-irix$IRIX_REL ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) GUESS=i386-ibm-aix ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then 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 GUESS=$SYSTEM_NAME else GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then GUESS=rs6000-ibm-aix3.2.4 else GUESS=rs6000-ibm-aix3.2 fi ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$IBM_ARCH-ibm-aix$IBM_REV ;; *:AIX:*:*) GUESS=rs6000-ibm-aix ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) GUESS=romp-ibm-bsd4.4 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) GUESS=rs6000-bull-bosx ;; DPX/2?00:B.O.S.:*:*) GUESS=m68k-bull-sysv3 ;; 9000/[34]??:4.3bsd:1.*:*) GUESS=m68k-hp-bsd ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) GUESS=m68k-hp-bsd4.4 ;; 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 test -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 test "$HP_ARCH" = ""; then 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 test "$HP_ARCH" = hppa2.0w then 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 GUESS=$HP_ARCH-hp-hpux$HPUX_REV ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` GUESS=ia64-hp-hpux$HPUX_REV ;; 3050*:HI-UX:*:*) 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; } GUESS=unknown-hitachi-hiuxwe2 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) GUESS=hppa1.1-hp-bsd ;; 9000/8??:4.3bsd:*:*) GUESS=hppa1.0-hp-bsd ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) GUESS=hppa1.0-hp-mpeix ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) GUESS=hppa1.1-hp-osf ;; hp8??:OSF1:*:*) GUESS=hppa1.0-hp-osf ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then GUESS=$UNAME_MACHINE-unknown-osf1mk else GUESS=$UNAME_MACHINE-unknown-osf1 fi ;; parisc*:Lites*:*:*) GUESS=hppa1.1-hp-lites ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) GUESS=c1-convex-bsd ;; 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*:*) GUESS=c34-convex-bsd ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) GUESS=c38-convex-bsd ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) GUESS=c4-convex-bsd ;; CRAY*Y-MP:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=ymp-cray-unicos$CRAY_REL ;; 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:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=t90-cray-unicos$CRAY_REL ;; CRAY*T3E:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=alphaev5-cray-unicosmk$CRAY_REL ;; CRAY*SV1:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=sv1-cray-unicos$CRAY_REL ;; *:UNICOS/mp:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=craynv-cray-unicosmp$CRAY_REL ;; 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/ /_/'` GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; 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/ /_/'` GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE ;; sparc*:BSD/OS:*:*) GUESS=sparc-unknown-bsdi$UNAME_RELEASE ;; *:BSD/OS:*:*) GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi else FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf fi ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL ;; i*:CYGWIN*:*) GUESS=$UNAME_MACHINE-pc-cygwin ;; *:MINGW64*:*) GUESS=$UNAME_MACHINE-pc-mingw64 ;; *:MINGW*:*) GUESS=$UNAME_MACHINE-pc-mingw32 ;; *:MSYS*:*) GUESS=$UNAME_MACHINE-pc-msys ;; i*:PW*:*) GUESS=$UNAME_MACHINE-pc-pw32 ;; *:SerenityOS:*:*) GUESS=$UNAME_MACHINE-pc-serenity ;; *:Interix*:*) case $UNAME_MACHINE in x86) GUESS=i586-pc-interix$UNAME_RELEASE ;; authenticamd | genuineintel | EM64T) GUESS=x86_64-unknown-interix$UNAME_RELEASE ;; IA64) GUESS=ia64-unknown-interix$UNAME_RELEASE ;; esac ;; i*:UWIN*:*) GUESS=$UNAME_MACHINE-pc-uwin ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) GUESS=x86_64-pc-cygwin ;; prep*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=powerpcle-unknown-solaris2$SUN_REL ;; *:GNU:*:*) # the GNU system GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL ;; *:GNU/*:*:*) # other systems with GNU libc and userland GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi ;; avr32*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; cris:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; crisv32:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; e2k:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; frv:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; hexagon:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:Linux:*:*) GUESS=$UNAME_MACHINE-pc-linux-$LIBC ;; ia64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m68*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel #undef mips64 #undef mips64el #if ${IS_GLIBC} && defined(_ABI64) LIBCABI=gnuabi64 #else #if ${IS_GLIBC} && defined(_ABIN32) LIBCABI=gnuabin32 #else LIBCABI=${LIBC} #endif #endif #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa64r6 #else #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa32r6 #else #if defined(__mips64) CPU=mips64 #else CPU=mips #endif #endif #endif #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) MIPS_ENDIAN= #else MIPS_ENDIAN= #endif #endif EOF cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` eval "$cc_set_vars" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; openrisc*:Linux:*:*) GUESS=or1k-unknown-linux-$LIBC ;; or32:Linux:*:* | or1k*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; padre:Linux:*:*) GUESS=sparc-unknown-linux-$LIBC ;; parisc64:Linux:*:* | hppa64:Linux:*:*) GUESS=hppa64-unknown-linux-$LIBC ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; *) GUESS=hppa-unknown-linux-$LIBC ;; esac ;; ppc64:Linux:*:*) GUESS=powerpc64-unknown-linux-$LIBC ;; ppc:Linux:*:*) GUESS=powerpc-unknown-linux-$LIBC ;; ppc64le:Linux:*:*) GUESS=powerpc64le-unknown-linux-$LIBC ;; ppcle:Linux:*:*) GUESS=powerpcle-unknown-linux-$LIBC ;; riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; s390:Linux:*:* | s390x:Linux:*:*) GUESS=$UNAME_MACHINE-ibm-linux-$LIBC ;; sh64*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sh*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sparc:Linux:*:* | sparc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; tile*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; vax:Linux:*:*) GUESS=$UNAME_MACHINE-dec-linux-$LIBC ;; x86_64:Linux:*:*) set_cc_for_build LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_X32 >/dev/null then LIBCABI=${LIBC}x32 fi fi GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; 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. GUESS=i386-sequent-sysv4 ;; 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. GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; i*86:XTS-300:*:STOP) GUESS=$UNAME_MACHINE-unknown-stop ;; i*86:atheos:*:*) GUESS=$UNAME_MACHINE-unknown-atheos ;; i*86:syllable:*:*) GUESS=$UNAME_MACHINE-pc-syllable ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) GUESS=i386-unknown-lynxos$UNAME_RELEASE ;; i*86:*DOS:*:*) GUESS=$UNAME_MACHINE-pc-msdosdjgpp ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi ;; 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 GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ;; 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 GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv32 fi ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. GUESS=i586-pc-msdosdjgpp ;; Intel:Mach:3*:*) GUESS=i386-pc-mach3 ;; paragon:*:*:*) GUESS=i860-intel-osf1 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi ;; mini*:CTIX:SYS*5:*) # "miniframe" GUESS=m68010-convergent-sysv ;; mc68k:UNIX:SYSTEM5:3.51m) GUESS=m68k-convergent-sysv ;; M680?0:D-NIX:5.3:*) GUESS=m68k-diab-dnix ;; 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*:*) GUESS=m68k-unknown-lynxos$UNAME_RELEASE ;; mc68030:UNIX_System_V:4.*:*) GUESS=m68k-atari-sysv4 ;; TSUNAMI:LynxOS:2.*:*) GUESS=sparc-unknown-lynxos$UNAME_RELEASE ;; rs6000:LynxOS:2.*:*) GUESS=rs6000-unknown-lynxos$UNAME_RELEASE ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) GUESS=powerpc-unknown-lynxos$UNAME_RELEASE ;; SM[BE]S:UNIX_SV:*:*) GUESS=mips-dde-sysv$UNAME_RELEASE ;; RM*:ReliantUNIX-*:*:*) GUESS=mips-sni-sysv4 ;; RM*:SINIX-*:*:*) GUESS=mips-sni-sysv4 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` GUESS=$UNAME_MACHINE-sni-sysv4 else GUESS=ns32k-sni-sysv fi ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm GUESS=hppa1.1-stratus-sysv4 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. GUESS=i860-stratus-sysv4 ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. GUESS=$UNAME_MACHINE-stratus-vos ;; *:VOS:*:*) # From Paul.Green@stratus.com. GUESS=hppa1.1-stratus-vos ;; mc68*:A/UX:*:*) GUESS=m68k-apple-aux$UNAME_RELEASE ;; news*:NEWS-OS:6*:*) GUESS=mips-sony-newsos6 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then GUESS=mips-nec-sysv$UNAME_RELEASE else GUESS=mips-unknown-sysv$UNAME_RELEASE fi ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. GUESS=powerpc-be-beos ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. GUESS=powerpc-apple-beos ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. GUESS=i586-pc-beos ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; x86_64:Haiku:*:*) GUESS=x86_64-unknown-haiku ;; SX-4:SUPER-UX:*:*) GUESS=sx4-nec-superux$UNAME_RELEASE ;; SX-5:SUPER-UX:*:*) GUESS=sx5-nec-superux$UNAME_RELEASE ;; SX-6:SUPER-UX:*:*) GUESS=sx6-nec-superux$UNAME_RELEASE ;; SX-7:SUPER-UX:*:*) GUESS=sx7-nec-superux$UNAME_RELEASE ;; SX-8:SUPER-UX:*:*) GUESS=sx8-nec-superux$UNAME_RELEASE ;; SX-8R:SUPER-UX:*:*) GUESS=sx8r-nec-superux$UNAME_RELEASE ;; SX-ACE:SUPER-UX:*:*) GUESS=sxace-nec-superux$UNAME_RELEASE ;; Power*:Rhapsody:*:*) GUESS=powerpc-apple-rhapsody$UNAME_RELEASE ;; *:Rhapsody:*:*) GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE ;; arm64:Darwin:*:*) GUESS=aarch64-apple-darwin$UNAME_RELEASE ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac if command -v xcode-select > /dev/null 2> /dev/null && \ ! xcode-select --print-path > /dev/null 2> /dev/null ; then # Avoid executing cc if there is no toolchain installed as # cc will be a stub that puts up a graphical alert # prompting the user to install developer tools. CC_FOR_BUILD=no_compiler_found else set_cc_for_build fi if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE ;; *:QNX:*:4*) GUESS=i386-pc-qnx ;; NEO-*:NONSTOP_KERNEL:*:*) GUESS=neo-tandem-nsk$UNAME_RELEASE ;; NSE-*:NONSTOP_KERNEL:*:*) GUESS=nse-tandem-nsk$UNAME_RELEASE ;; NSR-*:NONSTOP_KERNEL:*:*) GUESS=nsr-tandem-nsk$UNAME_RELEASE ;; NSV-*:NONSTOP_KERNEL:*:*) GUESS=nsv-tandem-nsk$UNAME_RELEASE ;; NSX-*:NONSTOP_KERNEL:*:*) GUESS=nsx-tandem-nsk$UNAME_RELEASE ;; *:NonStop-UX:*:*) GUESS=mips-compaq-nonstopux ;; BS2000:POSIX*:*:*) GUESS=bs2000-siemens-sysv ;; DS/*:UNIX_System_V:*:*) GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE ;; *: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 elif test "x${cputype-}" != x; then UNAME_MACHINE=$cputype fi GUESS=$UNAME_MACHINE-unknown-plan9 ;; *:TOPS-10:*:*) GUESS=pdp10-unknown-tops10 ;; *:TENEX:*:*) GUESS=pdp10-unknown-tenex ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) GUESS=pdp10-dec-tops20 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) GUESS=pdp10-xkl-tops20 ;; *:TOPS-20:*:*) GUESS=pdp10-unknown-tops20 ;; *:ITS:*:*) GUESS=pdp10-unknown-its ;; SEI:*:*:SEIUX) GUESS=mips-sei-seiux$UNAME_RELEASE ;; *:DragonFly:*:*) DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case $UNAME_MACHINE in A*) GUESS=alpha-dec-vms ;; I*) GUESS=ia64-dec-vms ;; V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) GUESS=i386-pc-xenix ;; i*86:skyos:*:*) SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL ;; i*86:rdos:*:*) GUESS=$UNAME_MACHINE-pc-rdos ;; i*86:Fiwix:*:*) GUESS=$UNAME_MACHINE-pc-fiwix ;; *:AROS:*:*) GUESS=$UNAME_MACHINE-unknown-aros ;; x86_64:VMkernel:*:*) GUESS=$UNAME_MACHINE-unknown-esx ;; amd64:Isilon\ OneFS:*:*) GUESS=x86_64-unknown-onefs ;; *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; esac # Do we have a guess based on uname results? if test "x$GUESS" != x; then echo "$GUESS" exit fi # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" < #include #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #include #if defined(_SIZE_T_) || defined(SIGLOST) #include #endif #endif #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 (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 #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname un; uname (&un); printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname *un; uname (&un); printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else printf ("mips-dec-ultrix\n"); exit (0); #endif #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; } echo "$0: unable to guess system type" >&2 case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&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 fi exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libpqxx-7.10.0/config/config.sub000077500000000000000000001051161473205454700165350ustar00rootroot00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-01-03' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2022 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 ;; *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 # Split fields of configuration type # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova*) basic_machine=$field1 basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown basic_os=linux-android ;; *) basic_machine=$field1-$field2 basic_os=$field3 ;; esac ;; *-*) # A lone config we happen to match not fitting any pattern case $field1-$field2 in decstation-3100) basic_machine=mips-dec basic_os= ;; *-*) # Second component is usually, but not always the OS case $field2 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 basic_os=$field2 ;; zephyr*) basic_machine=$field1-unknown basic_os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc533* | 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* | sim | cisco \ | oki | wec | wrs | winbond) basic_machine=$field1-$field2 basic_os= ;; *) basic_machine=$field1 basic_os=$field2 ;; esac ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc basic_os=bsd ;; a29khif) basic_machine=a29k-amd basic_os=udi ;; adobe68k) basic_machine=m68010-adobe basic_os=scout ;; alliant) basic_machine=fx80-alliant basic_os= ;; altos | altos3068) basic_machine=m68k-altos basic_os= ;; am29k) basic_machine=a29k-none basic_os=bsd ;; amdahl) basic_machine=580-amdahl basic_os=sysv ;; amiga) basic_machine=m68k-unknown basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo basic_os=bsd ;; aros) basic_machine=i386-pc basic_os=aros ;; aux) basic_machine=m68k-apple basic_os=aux ;; balance) basic_machine=ns32k-sequent basic_os=dynix ;; blackfin) basic_machine=bfin-unknown basic_os=linux ;; cegcc) basic_machine=arm-unknown basic_os=cegcc ;; convex-c1) basic_machine=c1-convex basic_os=bsd ;; convex-c2) basic_machine=c2-convex basic_os=bsd ;; convex-c32) basic_machine=c32-convex basic_os=bsd ;; convex-c34) basic_machine=c34-convex basic_os=bsd ;; convex-c38) basic_machine=c38-convex basic_os=bsd ;; cray) basic_machine=j90-cray basic_os=unicos ;; crds | unos) basic_machine=m68k-crds basic_os= ;; da30) basic_machine=m68k-da30 basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec basic_os= ;; delta88) basic_machine=m88k-motorola basic_os=sysv3 ;; dicos) basic_machine=i686-pc basic_os=dicos ;; djgpp) basic_machine=i586-pc basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson basic_os=ose ;; gmicro) basic_machine=tron-gmicro basic_os=sysv ;; go32) basic_machine=i386-pc basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi basic_os=hms ;; harris) basic_machine=m88k-harris basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp basic_os=osf ;; hppro) basic_machine=hppa1.1-hp basic_os=proelf ;; i386mach) basic_machine=i386-mach basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown basic_os=linux ;; magnum | m3230) basic_machine=mips-mips basic_os=sysv ;; merlin) basic_machine=ns32k-utek basic_os=sysv ;; mingw64) basic_machine=x86_64-pc basic_os=mingw64 ;; mingw32) basic_machine=i686-pc basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k basic_os=coff ;; morphos) basic_machine=powerpc-unknown basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown basic_os=moxiebox ;; msdos) basic_machine=i386-pc basic_os=msdos ;; msys) basic_machine=i686-pc basic_os=msys ;; mvs) basic_machine=i370-ibm basic_os=mvs ;; nacl) basic_machine=le32-unknown basic_os=nacl ;; ncr3000) basic_machine=i486-ncr basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony basic_os=newsos ;; news1000) basic_machine=m68030-sony basic_os=newsos ;; necv70) basic_machine=v70-nec basic_os=sysv ;; nh3000) basic_machine=m68k-harris basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris basic_os=cxux ;; nindy960) basic_machine=i960-intel basic_os=nindy ;; mon960) basic_machine=i960-intel basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson basic_os=ose ;; os68k) basic_machine=m68k-none basic_os=os68k ;; paragon) basic_machine=i860-intel basic_os=osf ;; parisc) basic_machine=hppa-unknown basic_os=linux ;; psp) basic_machine=mipsallegrexel-sony basic_os=psp ;; pw32) basic_machine=i586-unknown basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc basic_os=rdos ;; rdos32) basic_machine=i386-pc basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k basic_os=coff ;; sa29200) basic_machine=a29k-amd basic_os=udi ;; sei) basic_machine=mips-sei basic_os=seiux ;; sequent) basic_machine=i386-sequent basic_os= ;; sps7) basic_machine=m68k-bull basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem basic_os= ;; stratus) basic_machine=i860-stratus basic_os=sysv4 ;; sun2) basic_machine=m68000-sun basic_os= ;; sun2os3) basic_machine=m68000-sun basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun basic_os=sunos4 ;; sun3) basic_machine=m68k-sun basic_os= ;; sun3os3) basic_machine=m68k-sun basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun basic_os=sunos4 ;; sun4) basic_machine=sparc-sun basic_os= ;; sun4os3) basic_machine=sparc-sun basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun basic_os= ;; sv1) basic_machine=sv1-cray basic_os=unicos ;; symmetry) basic_machine=i386-sequent basic_os=dynix ;; t3e) basic_machine=alphaev5-cray basic_os=unicos ;; t90) basic_machine=t90-cray basic_os=unicos ;; toad1) basic_machine=pdp10-xkl basic_os=tops20 ;; tpf) basic_machine=s390x-ibm basic_os=tpf ;; udi29k) basic_machine=a29k-amd basic_os=udi ;; ultra3) basic_machine=a29k-nyu basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec basic_os=none ;; vaxv) basic_machine=vax-dec basic_os=sysv ;; vms) basic_machine=vax-dec basic_os=vms ;; vsta) basic_machine=i386-pc basic_os=vsta ;; vxworks960) basic_machine=i960-wrs basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs basic_os=vxworks ;; xbox) basic_machine=i686-pc basic_os=mingw32 ;; ymp) basic_machine=ymp-cray basic_os=unicos ;; *) basic_machine=$1 basic_os= ;; esac ;; esac # Decode 1-component or ad-hoc basic machines case $basic_machine in # 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) cpu=hppa1.1 vendor=winbond ;; op50n) cpu=hppa1.1 vendor=oki ;; op60c) cpu=hppa1.1 vendor=oki ;; ibm*) cpu=i370 vendor=ibm ;; orion105) cpu=clipper vendor=highlevel ;; mac | mpw | mac-mpw) cpu=m68k vendor=apple ;; pmac | pmac-mpw) cpu=powerpc vendor=apple ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) cpu=m68000 vendor=att ;; 3b*) cpu=we32k vendor=att ;; bluegene*) cpu=powerpc vendor=ibm basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) cpu=m68k vendor=motorola ;; dpx2*) cpu=m68k vendor=bull basic_os=sysv3 ;; encore | umax | mmax) cpu=ns32k vendor=encore ;; elxsi) cpu=elxsi vendor=elxsi basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 vendor=alliant ;; genix) cpu=ns32k vendor=ns ;; h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) cpu=m68000 vendor=hp ;; hp9k3[2-9][0-9]) cpu=m68k vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) cpu=hppa1.1 vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; i*86v32) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv32 ;; i*86v4*) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv4 ;; i*86v) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv ;; i*86sol2) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi case $basic_os in irix*) ;; *) basic_os=irix4 ;; esac ;; miniframe) cpu=m68000 vendor=convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next case $basic_os in openstep*) ;; nextstep*) ;; ns2*) basic_os=nextstep2 ;; *) basic_os=nextstep3 ;; esac ;; np1) cpu=np1 vendor=gould ;; op50n-* | op60c-*) cpu=hppa1.1 vendor=oki basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; pbd) cpu=sparc vendor=tti ;; pbb) cpu=m68k vendor=tti ;; pc532) cpu=ns32k vendor=pc532 ;; pn) cpu=pn vendor=gould ;; power) cpu=power vendor=ibm ;; ps2) cpu=i386 vendor=ibm ;; rm[46]00) cpu=mips vendor=siemens ;; rtpc | rtpc-*) cpu=romp vendor=ibm ;; sde) cpu=mipsisa32 vendor=sde basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs basic_os=vxworks ;; tower | tower-32) cpu=m68k vendor=ncr ;; vpp*|vx|vx-*) cpu=f301 vendor=fujitsu ;; w65) cpu=w65 vendor=wdc ;; w89k-*) cpu=hppa1.1 vendor=winbond basic_os=proelf ;; none) cpu=none vendor=none ;; leon|leon[3-9]) cpu=sparc vendor=$basic_machine ;; leon-*|leon[3-9]-*) cpu=sparc vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read cpu vendor <&2 exit 1 ;; esac ;; esac # Here we canonicalize certain aliases for manufacturers. case $vendor in digital*) vendor=dec ;; commodore*) vendor=cbm ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if test x$basic_os != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. case $basic_os in gnu/linux*) kernel=linux os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` ;; os2-emx) kernel=os2 os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` ;; nto-qnx*) kernel=nto os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read kernel os <&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. case $kernel-$os in linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ | linux-musl* | linux-relibc* | linux-uclibc* ) ;; uclinux-uclibc* ) ;; -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) # These are just libc implementations, not actual OSes, and thus # require a kernel. echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 exit 1 ;; kfreebsd*-gnu* | kopensolaris*-gnu*) ;; vxworks-simlinux | vxworks-simwindows | vxworks-spe) ;; nto-qnx*) ;; os2-emx) ;; *-eabi* | *-gnueabi*) ;; -*) # Blank kernel with real OS is always fine. ;; *-*) echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 exit 1 ;; esac # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) case $cpu-$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 ;; *-clix*) vendor=intergraph ;; *-mvs* | *-opened*) vendor=ibm ;; *-os400*) vendor=ibm ;; s390-* | s390x-*) 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 ;; esac echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libpqxx-7.10.0/config/depcomp000077500000000000000000000560201473205454700161260ustar00rootroot00000000000000#! /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: libpqxx-7.10.0/config/install-sh000077500000000000000000000357761473205454700165740ustar00rootroot00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2020-11-14.01; # 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. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # 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_mkdir= # Desired mode of installed file. mode=0755 # Create dirs (including intermediate dirs) using mode 755. # This is like GNU 'install' as of coreutils 8.32 (2020). mkdir_umask=22 backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly 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 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. -p pass -p to $cpprog. -s $stripprog installed files. -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -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 By default, rm is invoked with -f; when overridden with RMPROG, it's up to you to specify -f if you want it. If -S is not specified, no backups are attempted. Email bug reports to bug-automake@gnu.org. Automake home page: https://www.gnu.org/software/automake/ " 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 *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -p) cpprog="$cpprog -p";; -s) stripcmd=$stripprog;; -S) backupsuffix="$2" shift;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi 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 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac 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 if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 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 problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? # Don't chown directories that already exist. if test $dstdir_status = 0; then chowncmd="" fi 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 # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dstbase=`basename "$src"` case $dst in */) dst=$dst$dstbase;; *) dst=$dst/$dstbase;; esac dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi case $dstdir in */) dstdirslash=$dstdir;; *) dstdirslash=$dstdir/;; esac obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # 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 # The $RANDOM variable is not portable (e.g., dash). Use it # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap ' ret=$? rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null exit $ret ' 0 # Because "mkdir -p" follows existing symlinks and we likely work # directly in world-writeable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p'. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/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-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # 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 oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && 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=${dstdirslash}_inst.$$_ rmtmp=${dstdirslash}_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 && { test -z "$stripcmd" || { # Create $dsttmp read-write so that cp doesn't create it read-only, # which would cause strip to fail. if test -z "$doit"; then : >"$dsttmp" # No need to fork-exec 'touch'. else $doit touch "$dsttmp" fi } } && $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` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # If $backupsuffix is set, and the file being installed # already exists, attempt a backup. Don't worry if it fails, # e.g., if mv doesn't support -f. if test -n "$backupsuffix" && test -f "$dst"; then $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null fi # 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 "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd "$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 '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: libpqxx-7.10.0/config/ltmain.sh000077500000000000000000012123751473205454700164040ustar00rootroot00000000000000#! /usr/bin/env sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2019-02-19.15 # libtool (GNU libtool) 2.4.7 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2019, 2021-2022 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.7 Debian-2.4.7-7build1" package_revision=2.4.7 ## ------ ## ## 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=2019-02-19.15; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Copyright (C) 2004-2019, 2021 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license # , and GPL version 2 or later # . You must apply one of # these licenses when using or redistributing this software or any of # the files within it. See the URLs above, or the file `LICENSE` # included in the Bootstrap distribution for the full license texts. # Please report bugs or propose patches to: # ## ------ ## ## 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 # These NLS vars are set unconditionally (bootstrap issue #24). Unset those # in case the environment reset is needed later and the $save_* variant is not # defined (see the code above). LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL # 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 # func_unset VAR # -------------- # Portably unset VAR. # In some shells, an 'unset VAR' statement leaves a non-zero return # status if VAR is already unset, which might be problematic if the # statement is used at the end of a function (thus poisoning its return # value) or when 'set -e' is active (causing even a spurious abort of # the script in this case). func_unset () { { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; } } # Make sure CDPATH doesn't cause `cd` commands to output the target dir. func_unset CDPATH # Make sure ${,E,F}GREP behave sanely. func_unset GREP_OPTIONS ## ------------------------- ## ## 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" # require_check_ifs_backslash # --------------------------- # Check if we can use backslash as IFS='\' separator, and set # $check_ifs_backshlash_broken to ':' or 'false'. require_check_ifs_backslash=func_require_check_ifs_backslash func_require_check_ifs_backslash () { _G_save_IFS=$IFS IFS='\' _G_check_ifs_backshlash='a\\b' for _G_i in $_G_check_ifs_backshlash do case $_G_i in a) check_ifs_backshlash_broken=false ;; '') break ;; *) check_ifs_backshlash_broken=: break ;; esac done IFS=$_G_save_IFS require_check_ifs_backslash=: } ## ----------------- ## ## 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. # _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. if test -z "$_G_HAVE_PLUSEQ_OP" && \ __PLUSEQ_TEST="a" && \ __PLUSEQ_TEST+=" b" 2>/dev/null && \ test "a b" = "$__PLUSEQ_TEST"; then _G_HAVE_PLUSEQ_OP=yes fi 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_arg pretty "$2" eval "$1+=\\ \$func_quote_arg_result" }' else func_append_quoted () { $debug_cmd func_quote_arg pretty "$2" eval "$1=\$$1\\ \$func_quote_arg_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_portable EVAL ARG # ---------------------------- # Internal function to portably implement func_quote_arg. Note that we still # keep attention to performance here so we as much as possible try to avoid # calling sed binary (so far O(N) complexity as long as func_append is O(1)). func_quote_portable () { $debug_cmd $require_check_ifs_backslash func_quote_portable_result=$2 # one-time-loop (easy break) while true do if $1; then func_quote_portable_result=`$ECHO "$2" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` break fi # Quote for eval. case $func_quote_portable_result in *[\\\`\"\$]*) # Fallback to sed for $func_check_bs_ifs_broken=:, or when the string # contains the shell wildcard characters. case $check_ifs_backshlash_broken$func_quote_portable_result in :*|*[\[\*\?]*) func_quote_portable_result=`$ECHO "$func_quote_portable_result" \ | $SED "$sed_quote_subst"` break ;; esac func_quote_portable_old_IFS=$IFS for _G_char in '\' '`' '"' '$' do # STATE($1) PREV($2) SEPARATOR($3) set start "" "" func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy IFS=$_G_char for _G_part in $func_quote_portable_result do case $1 in quote) func_append func_quote_portable_result "$3$2" set quote "$_G_part" "\\$_G_char" ;; start) set first "" "" func_quote_portable_result= ;; first) set quote "$_G_part" "" ;; esac done done IFS=$func_quote_portable_old_IFS ;; *) ;; esac break done func_quote_portable_unquoted_result=$func_quote_portable_result case $func_quote_portable_result 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. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_portable_result=\"$func_quote_portable_result\" ;; esac } # func_quotefast_eval ARG # ----------------------- # Quote one ARG (internal). This is equivalent to 'func_quote_arg eval ARG', # but optimized for speed. Result is stored in $func_quotefast_eval. if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then printf -v _GL_test_printf_tilde %q '~' if test '\~' = "$_GL_test_printf_tilde"; then func_quotefast_eval () { printf -v func_quotefast_eval_result %q "$1" } else # Broken older Bash implementations. Make those faster too if possible. func_quotefast_eval () { case $1 in '~'*) func_quote_portable false "$1" func_quotefast_eval_result=$func_quote_portable_result ;; *) printf -v func_quotefast_eval_result %q "$1" ;; esac } fi else func_quotefast_eval () { func_quote_portable false "$1" func_quotefast_eval_result=$func_quote_portable_result } fi # func_quote_arg MODEs ARG # ------------------------ # Quote one ARG to be evaled later. MODEs argument may contain zero or more # specifiers listed below separated by ',' character. This function returns two # values: # i) func_quote_arg_result # double-quoted (when needed), suitable for a subsequent eval # ii) func_quote_arg_unquoted_result # has all characters that are still active within double # quotes backslashified. Available only if 'unquoted' is specified. # # Available modes: # ---------------- # 'eval' (default) # - escape shell special characters # 'expand' # - the same as 'eval'; but do not quote variable references # 'pretty' # - request aesthetic output, i.e. '"a b"' instead of 'a\ b'. This might # be used later in func_quote to get output like: 'echo "a b"' instead # of 'echo a\ b'. This is slower than default on some shells. # 'unquoted' # - produce also $func_quote_arg_unquoted_result which does not contain # wrapping double-quotes. # # Examples for 'func_quote_arg pretty,unquoted string': # # string | *_result | *_unquoted_result # ------------+-----------------------+------------------- # " | \" | \" # a b | "a b" | a b # "a b" | "\"a b\"" | \"a b\" # * | "*" | * # z="${x-$y}" | "z=\"\${x-\$y}\"" | z=\"\${x-\$y}\" # # Examples for 'func_quote_arg pretty,unquoted,expand string': # # string | *_result | *_unquoted_result # --------------+---------------------+-------------------- # z="${x-$y}" | "z=\"${x-$y}\"" | z=\"${x-$y}\" func_quote_arg () { _G_quote_expand=false case ,$1, in *,expand,*) _G_quote_expand=: ;; esac case ,$1, in *,pretty,*|*,expand,*|*,unquoted,*) func_quote_portable $_G_quote_expand "$2" func_quote_arg_result=$func_quote_portable_result func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result ;; *) # Faster quote-for-eval for some shells. func_quotefast_eval "$2" func_quote_arg_result=$func_quotefast_eval_result ;; esac } # func_quote MODEs ARGs... # ------------------------ # Quote all ARGs to be evaled later and join them into single command. See # func_quote_arg's description for more info. func_quote () { $debug_cmd _G_func_quote_mode=$1 ; shift func_quote_result= while test 0 -lt $#; do func_quote_arg "$_G_func_quote_mode" "$1" if test -n "$func_quote_result"; then func_append func_quote_result " $func_quote_arg_result" else func_append func_quote_result "$func_quote_arg_result" fi shift done } # 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_arg pretty,expand "$_G_cmd" eval "func_notquiet $func_quote_arg_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_arg expand,pretty "$_G_cmd" eval "func_echo $func_quote_arg_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 # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Copyright (C) 2010-2019, 2021 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license # , and GPL version 2 or later # . You must apply one of # these licenses when using or redistributing this software or any of # the files within it. See the URLs above, or the file `LICENSE` # included in the Bootstrap distribution for the full license texts. # Please report bugs or propose patches to: # # Set a version string for this script. scriptversion=2019-02-19.15; # UTC ## ------ ## ## 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 '# Copyright'. # # 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 in 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 # in the main code. A hook is just a list of function names 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 hook functions to be called by # FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_propagate_result FUNC_NAME_A FUNC_NAME_B # --------------------------------------------- # If the *_result variable of FUNC_NAME_A _is set_, assign its value to # *_result variable of FUNC_NAME_B. func_propagate_result () { $debug_cmd func_propagate_result_result=: if eval "test \"\${${1}_result+set}\" = set" then eval "${2}_result=\$${1}_result" else func_propagate_result_result=false fi } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It's 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 functions." ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do func_unset "${_G_hook}_result" eval $_G_hook '${1+"$@"}' func_propagate_result $_G_hook func_run_hooks if $func_propagate_result_result; then eval set dummy "$func_run_hooks_result"; shift fi done } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list from your hook function. You may remove # or edit any options that you action, and then pass back the remaining # unprocessed options in '_result', escaped # suitably for 'eval'. # # The '_result' variable is automatically unset # before your hook gets called; for best performance, only set the # *_result variable when necessary (i.e. don't call the 'func_quote' # function unnecessarily because it can be an expensive operation on some # machines). # # 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). Leave # # my_options_prep_result variable intact. # } # 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 "$@" in case we need it later, # # if $args_changed was set to 'true'. # set dummy "$_G_opt" ${1+"$@"}; shift; break ;; # esac # done # # # Only call 'func_quote' here if we processed at least one argument. # if $args_changed; then # func_quote eval ${1+"$@"} # my_silent_option_result=$func_quote_result # fi # } # 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." # } # 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 func_run_hooks func_options ${1+"$@"} func_propagate_result func_run_hooks func_options_finish } # 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_options_quoted=false for my_func in options_prep parse_options validate_options options_finish do func_unset func_${my_func}_result func_unset func_run_hooks_result eval func_$my_func '${1+"$@"}' func_propagate_result func_$my_func func_options if $func_propagate_result_result; then eval set dummy "$func_options_result"; shift _G_options_quoted=: fi done $_G_options_quoted || { # As we (func_options) are top-level options-parser function and # nobody quoted "$@" for us yet, we need to do it explicitly for # caller. func_quote eval ${1+"$@"} func_options_result=$func_quote_result } } # 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. func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} func_propagate_result func_run_hooks func_options_prep } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd _G_parse_options_requote=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. func_run_hooks func_parse_options ${1+"$@"} func_propagate_result func_run_hooks func_parse_options if $func_propagate_result_result; then eval set dummy "$func_parse_options_result"; shift # Even though we may have changed "$@", we passed the "$@" array # down into the hook and it quoted it for us (because we are in # this if-branch). No need to quote it again. _G_parse_options_requote=false fi # Break out of the loop if we already parsed every option. test $# -gt 0 || break # We expect that one of the options parsed in this function matches # and thus we remove _G_opt from "$@" and need to re-quote. _G_match_parse_options=: _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" >&2 $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_parse_options_requote=: 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_parse_options_requote=: ; break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift _G_match_parse_options=false break ;; esac if $_G_match_parse_options; then _G_parse_options_requote=: fi done if $_G_parse_options_requote; then # save modified positional parameters for caller func_quote eval ${1+"$@"} func_parse_options_result=$func_quote_result fi } # 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 # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} func_propagate_result func_run_hooks func_validate_options # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE } ## ----------------- ## ## 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#*=} if test "x$func_split_equals_lhs" = "x$1"; then func_split_equals_rhs= fi }' 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. # The version message is extracted from the calling file's header # comments, with leading '# ' stripped: # 1. First display the progname and version # 2. Followed by the header comment line matching /^# Written by / # 3. Then a blank line followed by the first following line matching # /^# Copyright / # 4. Immediately followed by any lines between the previous matches, # except lines preceding the intervening completely blank line. # For example, see the header comments of this file. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /^# Written by /!b s|^# ||; p; n :fwd2blnk /./ { n b fwd2blnk } p; n :holdwrnt s|^# || s|^# *$|| /^Copyright /!{ /./H n b holdwrnt } s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| G s|\(\n\)\n*|\1|g p; q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.7' # 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.7-7build1 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=: _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 eval ${1+"$@"} libtool_options_prep_result=$func_quote_result fi } 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 eval ${1+"$@"} libtool_parse_options_result=$func_quote_result fi } 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 eval ${1+"$@"} libtool_validate_options_result=$func_quote_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_arg pretty "$libobj" test "X$libobj" != "X$func_quote_arg_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_arg pretty "$srcfile" qsrcfile=$func_quote_arg_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 -Xcompiler 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 -Wa,FLAG -Xassembler FLAG pass linker-specific FLAG directly to the assembler -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_arg pretty "$nonopt" install_prog="$func_quote_arg_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_arg pretty "$arg" func_append install_prog "$func_quote_arg_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_arg pretty "$arg" func_append install_prog " $func_quote_arg_result" if test -n "$arg2"; then func_quote_arg pretty "$arg2" fi func_append install_shared_prog " $func_quote_arg_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_arg pretty "$install_override_mode" func_append install_shared_prog " -m $func_quote_arg_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_arg expand,pretty "$relink_command" eval "func_echo $func_quote_arg_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\"" func_quote_arg pretty "$ECHO" qECHO=$func_quote_arg_result $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_arg pretty,unquoted "$arg" qarg=$func_quote_arg_unquoted_result func_append libtool_args " $func_quote_arg_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 ;; xassembler) func_append compiler_flags " -Xassembler $qarg" prev= func_append compile_command " -Xassembler $qarg" func_append finalize_command " -Xassembler $qarg" 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* | *-*-midnightbsd*) # 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* | *-*-midnightbsd*) # 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 ;; # Solaris ld rejects as of 11.4. Refer to Oracle bug 22985199. -pthread) case $host in *solaris2*) ;; *) case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac ;; esac continue ;; -mt|-mthreads|-kthread|-Kthread|-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_arg pretty "$flag" func_append arg " $func_quote_arg_result" func_append compiler_flags " $func_quote_arg_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_arg pretty "$flag" func_append arg " $wl$func_quote_arg_result" func_append compiler_flags " $wl$func_quote_arg_result" func_append linker_flags " $func_quote_arg_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xassembler) prev=xassembler continue ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_arg pretty "$arg" arg=$func_quote_arg_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++ # -Wa,* Pass flags directly to the assembler -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|-Wa,*) func_quote_arg pretty "$arg" arg=$func_quote_arg_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_arg pretty "$arg" arg=$func_quote_arg_result fi ;; # Some other compiler flag. -* | +*) func_quote_arg pretty "$arg" arg=$func_quote_arg_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_arg pretty "$arg" arg=$func_quote_arg_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|midnightbsd-elf|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 | midnightbsd-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* | *-*-midnightbsd*) # 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_arg expand,pretty "$cmd" eval "func_echo $func_quote_arg_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_arg expand,pretty "$cmd" eval "func_echo $func_quote_arg_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_arg pretty "$var_value" relink_command="$var=$func_quote_arg_result; export $var; $relink_command" fi done func_quote eval cd "`pwd`" func_quote_arg pretty,unquoted "($func_quote_result; $relink_command)" relink_command=$func_quote_arg_unquoted_result 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_arg pretty,unquoted "$var_value" relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command" fi done # Quote the link command for shipping. func_quote eval cd "`pwd`" relink_command="($func_quote_result; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" func_quote_arg pretty,unquoted "$relink_command" relink_command=$func_quote_arg_unquoted_result 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: libpqxx-7.10.0/config/m4/000077500000000000000000000000001473205454700150665ustar00rootroot00000000000000libpqxx-7.10.0/config/m4/Makefile.am000066400000000000000000000001501473205454700171160ustar00rootroot00000000000000MAINTAINERCLEANFILES=Makefile.in config.guess config.sub install-sh \ ltmain.sh missing mkinstalldirs libpqxx-7.10.0/config/m4/libtool.m4000066400000000000000000011316521473205454700170050ustar00rootroot00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2019, 2021-2022 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 59 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_DECL_FILECMD])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 and # ICC, which need '.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 $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR $AR_FLAGS 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*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _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], [m4_require([_LT_DECL_SED])dnl 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 `$FILECMD 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 `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD 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 `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD 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 `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD 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 `$FILECMD 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} _LT_DECL([], [AR], [1], [The archiver]) # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS _LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)]) # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. _LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], [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* | midnightbsd* | 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 -z "$STRIP"; then AC_MSG_RESULT([no]) else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi 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* | *,icl*) # Native MSVC or ICC 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 and ICC 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* | midnightbsd*) # 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='$FILECMD -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* | midnightbsd*) 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=$FILECMD 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=$FILECMD 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=$FILECMD 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++ or ICC, # 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* | midnightbsd*) # 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 == "L") || (\$ 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* | icl*) _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++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) 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 _LT_TAGVAR(file_list_spec, $1)='@' ;; 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(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _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 == "L") || (\$ 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++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC _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 and ICC 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* | midnightbsd*) _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' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; 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 _LT_TAGVAR(file_list_spec, $1)='@' ;; 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* | ,icl* | no,icl*) # Native MSVC or ICC # 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 _LT_TAGVAR(file_list_spec, $1)='@' ;; 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* | midnightbsd*) # 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_FILECMD # ---------------- # Check for a file(cmd) program that can be used to detect file type and magic m4_defun([_LT_DECL_FILECMD], [AC_CHECK_TOOL([FILECMD], [file], [:]) _LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) ])# _LD_DECL_FILECMD # _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 libpqxx-7.10.0/config/m4/ltoptions.m4000066400000000000000000000342751473205454700173760ustar00rootroot00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 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])]) libpqxx-7.10.0/config/m4/ltsugar.m4000066400000000000000000000104531473205454700170140ustar00rootroot00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 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 ]) libpqxx-7.10.0/config/m4/ltversion.m4000066400000000000000000000013121473205454700173520ustar00rootroot00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2019, 2021-2022 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 4245 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.7]) m4_define([LT_PACKAGE_REVISION], [2.4.7]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.7' macro_revision='2.4.7' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) libpqxx-7.10.0/config/m4/lt~obsolete.m4000066400000000000000000000140071473205454700177040ustar00rootroot00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 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])]) libpqxx-7.10.0/config/missing000077500000000000000000000153361473205454700161550ustar00rootroot00000000000000#! /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: libpqxx-7.10.0/config/mkinstalldirs000077500000000000000000000066721473205454700173670ustar00rootroot00000000000000#! /bin/sh # mkinstalldirs --- make directory hierarchy scriptversion=2020-07-26.22; # UTC # Original author: Noah Friedman # Created: 1993-05-16 # Public domain. # # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' IFS=" "" $nl" errstatus=0 dirmode= usage="\ Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... Create each directory DIR (with mode MODE, if specified), including all leading file name components. Report bugs to ." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" exit $? ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --version) echo "$0 $scriptversion" exit $? ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac # Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and # mkdir -p a/c at the same time, both will detect that a is missing, # one will create a, then the other will try to create a and die with # a "File exists" error. This is a problem when calling mkinstalldirs # from a parallel make. We use --version in the probe to restrict # ourselves to GNU mkdir, which is thread-safe. case $dirmode in '') if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" else # On NextStep and OpenStep, the 'mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because '.' already # exists. test -d ./-p && rmdir ./-p test -d ./--version && rmdir ./--version fi ;; *) if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "umask 22" umask 22 echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" else # Clean up after NextStep and OpenStep mkdir. for d in ./-m ./-p ./--version "./$dirmode"; do test -d $d && rmdir $d done fi ;; esac echo "umask 22" umask 22 for file do case $file in /*) pathcomp=/ ;; *) pathcomp= ;; esac oIFS=$IFS IFS=/ set fnord $file shift IFS=$oIFS for d do test "x$d" = x && continue 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 if test ! -z "$dirmode"; then echo "chmod $dirmode $file" chmod "$dirmode" "$file" || errstatus=$? fi done exit $errstatus # 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: libpqxx-7.10.0/config/test-driver000077500000000000000000000114171473205454700167500ustar00rootroot00000000000000#! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2018-03-07.03; # UTC # Copyright (C) 2011-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. # 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" "$@" >>"$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 '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: libpqxx-7.10.0/configitems000066400000000000000000000017271473205454700155420ustar00rootroot00000000000000PACKAGE internal autotools PACKAGE_BUGREPORT internal autotools PACKAGE_NAME internal autotools PACKAGE_STRING internal autotools PACKAGE_TARNAME internal autotools PACKAGE_VERSION internal autotools PQXX_HAVE_ASSUME public compiler 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_MULTIDIM public compiler PQXX_HAVE_LIKELY public compiler PQXX_HAVE_PATH public compiler PQXX_HAVE_POLL internal compiler PQXX_HAVE_SLEEP_FOR internal compiler PQXX_HAVE_SOURCE_LOCATION public compiler PQXX_HAVE_SPAN public compiler PQXX_HAVE_SSIZE public compiler PQXX_HAVE_STRERROR_R public compiler PQXX_HAVE_STRERROR_S public compiler PQXX_HAVE_THREAD_LOCAL internal compiler PQXX_HAVE_YEAR_MONTH_DAY public compiler VERSION internal autotools libpqxx-7.10.0/configure000077500000000000000000023573661473205454700152360ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for libpqxx 7.10.0. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 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 as_nop=: if test ${ZSH_VERSION+y} && (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 $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; 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 # 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # 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'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 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="as_nop=: if test \${ZSH_VERSION+y} && (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 \$as_nop 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 \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || 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_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi 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'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$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_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # 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=`printf "%s\n" "$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 || printf "%s\n" 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_nop 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_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # 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 printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$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 || printf "%s\n" 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" || { printf "%s\n" "$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 } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. 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 # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' 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.10.0' PACKAGE_STRING='libpqxx 7.10.0' 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_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= 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_DOCS_FALSE BUILD_DOCS_TRUE MKDIR CXXCPP LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP FILECMD 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 CXXCPP' # 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 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=`printf "%s\n" "$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=`printf "%s\n" "$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=`printf "%s\n" "$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=`printf "%s\n" "$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. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$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" ;; *) printf "%s\n" "$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 || printf "%s\n" 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.10.0 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.10.0:";; 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. CXXCPP C++ preprocessor 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=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$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 configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. 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 printf "%s\n" "$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.10.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 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 conftest.beam 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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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 conftest.beam 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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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.beam 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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop 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 $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop 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. */ #include #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 (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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.beam 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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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_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_cxx_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_compile ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac 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.10.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "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=`printf "%s\n" "$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=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## 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_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$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 printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$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 printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C++ compiler supports C++98 (global declarations) ac_cxx_conftest_cxx98_globals=' // Does the compiler advertise C++98 conformance? #if !defined __cplusplus || __cplusplus < 199711L # error "Compiler does not advertise C++98 conformance" #endif // These inclusions are to reject old compilers that // lack the unsuffixed header files. #include #include // and are *not* freestanding headers in C++98. extern void assert (int); namespace std { extern int strcmp (const char *, const char *); } // Namespaces, exceptions, and templates were all added after "C++ 2.0". using std::exception; using std::strcmp; namespace { void test_exception_syntax() { try { throw "test"; } catch (const char *s) { // Extra parentheses suppress a warning when building autoconf itself, // due to lint rules shared with more typical C programs. assert (!(strcmp) (s, "test")); } } template struct test_template { T const val; explicit test_template(T t) : val(t) {} template T add(U u) { return static_cast(u) + val; } }; } // anonymous namespace ' # Test code for whether the C++ compiler supports C++98 (body of main) ac_cxx_conftest_cxx98_main=' assert (argc); assert (! argv[0]); { test_exception_syntax (); test_template tt (2.0); assert (tt.add (4) == 6.0); assert (true && !false); } ' # Test code for whether the C++ compiler supports C++11 (global declarations) ac_cxx_conftest_cxx11_globals=' // Does the compiler advertise C++ 2011 conformance? #if !defined __cplusplus || __cplusplus < 201103L # error "Compiler does not advertise C++11 conformance" #endif namespace cxx11test { constexpr int get_val() { return 20; } struct testinit { int i; double d; }; class delegate { public: delegate(int n) : n(n) {} delegate(): delegate(2354) {} virtual int getval() { return this->n; }; protected: int n; }; class overridden : public delegate { public: overridden(int n): delegate(n) {} virtual int getval() override final { return this->n * 2; } }; class nocopy { public: nocopy(int i): i(i) {} nocopy() = default; nocopy(const nocopy&) = delete; nocopy & operator=(const nocopy&) = delete; private: int i; }; // for testing lambda expressions template Ret eval(Fn f, Ret v) { return f(v); } // for testing variadic templates and trailing return types template auto sum(V first) -> V { return first; } template auto sum(V first, Args... rest) -> V { return first + sum(rest...); } } ' # Test code for whether the C++ compiler supports C++11 (body of main) ac_cxx_conftest_cxx11_main=' { // Test auto and decltype auto a1 = 6538; auto a2 = 48573953.4; auto a3 = "String literal"; int total = 0; for (auto i = a3; *i; ++i) { total += *i; } decltype(a2) a4 = 34895.034; } { // Test constexpr short sa[cxx11test::get_val()] = { 0 }; } { // Test initializer lists cxx11test::testinit il = { 4323, 435234.23544 }; } { // Test range-based for int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; for (auto &x : array) { x += 23; } } { // Test lambda expressions using cxx11test::eval; assert (eval ([](int x) { return x*2; }, 21) == 42); double d = 2.0; assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); assert (d == 5.0); assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); assert (d == 5.0); } { // Test use of variadic templates using cxx11test::sum; auto a = sum(1); auto b = sum(1, 2); auto c = sum(1.0, 2.0, 3.0); } { // Test constructor delegation cxx11test::delegate d1; cxx11test::delegate d2(); cxx11test::delegate d3(45); } { // Test override and final cxx11test::overridden o1(55464); } { // Test nullptr char *c = nullptr; } { // Test template brackets test_template<::test_template> v(test_template(12)); } { // Unicode literals char const *utf8 = u8"UTF-8 string \u2500"; char16_t const *utf16 = u"UTF-8 string \u2500"; char32_t const *utf32 = U"UTF-32 string \u2500"; } ' # Test code for whether the C compiler supports C++11 (complete). ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} ${ac_cxx_conftest_cxx11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} ${ac_cxx_conftest_cxx11_main} return ok; } " # Test code for whether the C compiler supports C++98 (complete). ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} return ok; } " # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*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 do not provoke an error unfortunately, instead are silently treated as an "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 is necessary to write \x00 == 0 to get something that is 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 **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" # Auxiliary files required by this configure script. ac_aux_files="compile config.guess config.sub ltmain.sh missing install-sh" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}/config" # Search for a directory containing all of the required auxiliary files, # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. # If we don't find one directory that contains all the files we need, # we report the set of missing files from the *first* directory in # $ac_aux_dir_candidates and give up. ac_missing_aux_files="" ac_first_candidate=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in $ac_aux_dir_candidates do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 ac_aux_dir_found=yes ac_install_sh= for ac_aux in $ac_aux_files do # As a special case, if "install-sh" is required, that requirement # can be satisfied by any of "install-sh", "install.sh", or "shtool", # and $ac_install_sh is set appropriately for whichever one is found. if test x"$ac_aux" = x"install-sh" then if test -f "${as_dir}install-sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 ac_install_sh="${as_dir}install-sh -c" elif test -f "${as_dir}install.sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 ac_install_sh="${as_dir}install.sh -c" elif test -f "${as_dir}shtool"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 ac_install_sh="${as_dir}shtool install -c" else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} install-sh" else break fi fi else if test -f "${as_dir}${ac_aux}"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" else break fi fi fi done if test "$ac_aux_dir_found" = yes; then ac_aux_dir="$as_dir" break fi ac_first_candidate=false as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$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. if test -f "${ac_aux_dir}config.guess"; then ac_config_guess="$SHELL ${ac_aux_dir}config.guess" fi if test -f "${ac_aux_dir}config.sub"; then ac_config_sub="$SHELL ${ac_aux_dir}config.sub" fi if test -f "$ac_aux_dir/configure"; then ac_configure="$SHELL ${ac_aux_dir}configure" 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,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$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=`printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-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 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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test ${ac_cv_path_install+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac # Account for fact that we put trailing slashes in our PATH walk. 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+y}; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 printf "%s\n" "$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' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "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=`printf "%s\n" "$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= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 printf %s "checking for a race-free mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test ${ac_cv_path_mkdir+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 ('*'coreutils) '* | \ 'BusyBox '* | \ '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+y}; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 printf "%s\n" "$AWK" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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+y} 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} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else $as_nop if printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$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.10.0' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h # 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.10 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 clang++ 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 printf "%s\n" "$CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 clang++ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 printf "%s\n" "$ac_ct_CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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. printf "%s\n" "$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\"" printf "%s\n" "$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 printf "%s\n" "$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 (void) { ; 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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 printf %s "checking whether the C++ compiler works... " >&6; } ac_link_default=`printf "%s\n" "$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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$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+y} && 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 $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 printf %s "checking for C++ compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$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_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$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 (void) { 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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$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 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$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_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 printf %s "checking whether the compiler supports GNU C++... " >&6; } if test ${ac_cv_cxx_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+y} ac_save_CXXFLAGS=$CXXFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 printf %s "checking whether $CXX accepts -g... " >&6; } if test ${ac_cv_prog_cxx_g+y} then : printf %s "(cached) " >&6 else $as_nop 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 (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes else $as_nop CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : else $as_nop ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } if test $ac_test_CXXFLAGS; 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_prog_cxx_stdcxx=no if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 printf %s "checking for $CXX option to enable C++11 features... " >&6; } if test ${ac_cv_prog_cxx_cxx11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx11=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx11_program _ACEOF for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx11" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx11" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 ac_prog_cxx_stdcxx=cxx11 fi fi if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 printf %s "checking for $CXX option to enable C++98 features... " >&6; } if test ${ac_cv_prog_cxx_cxx98+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx98=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx98_program _ACEOF for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx98=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx98" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx98" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx98" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx98" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 ac_prog_cxx_stdcxx=cxx98 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" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 printf %s "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.* { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 printf "%s\n" "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test ${enable_dependency_tracking+y} 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= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CXX_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 printf "%s\n" "$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+y} 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 $as_nop enable_shared=no fi case `pwd` in *\ * | *\ *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.7' macro_revision='2.4.7' 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 printf %s "checking build system type... " >&6; } if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 printf %s "checking host system type... " >&6; } if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 printf %s "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*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 printf "%s\n" "printf" >&6; } ;; print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 printf "%s\n" "print -r" >&6; } ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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}clang" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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="clang" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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. printf "%s\n" "$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 -version; 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\"" printf "%s\n" "$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 printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop 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 (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; 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 ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _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 conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 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 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 printf %s "checking whether $CC understands -c and -o together... " >&6; } if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$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= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 printf %s "checking for a sed that does not truncate output... " >&6; } if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '' >> "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 printf %s "checking for grep that handles long lines and -e... " >&6; } if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 printf %s "checking for egrep... " >&6; } if test ${ac_cv_path_EGREP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 printf %s "checking for fgrep... " >&6; } if test ${ac_cv_path_FGREP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 printf "%s\n" "$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+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop 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 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if test ${lt_cv_path_NM+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 printf "%s\n" "$DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 printf "%s\n" "$ac_ct_DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 printf %s "checking the name lister ($NM) interface... " >&6; } if test ${lt_cv_nm_interface+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 printf "%s\n" "$lt_cv_nm_interface" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 printf %s "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 printf "%s\n" "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 printf %s "checking the maximum length of command line arguments... " >&6; } if test ${lt_cv_sys_max_cmd_len+y} then : printf %s "(cached) " >&6 else $as_nop 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* | midnightbsd* | 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 printf %s "checking how to convert $build file names to $host format... " >&6; } if test ${lt_cv_to_host_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 printf %s "checking how to convert $build file names to toolchain format... " >&6; } if test ${lt_cv_to_tool_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop #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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 printf %s "checking for $LD option to reload object files... " >&6; } if test ${lt_cv_ld_reload_flag+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_reload_flag='-r' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 printf "%s\n" "$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}file", so it can be a program name with args. set dummy ${ac_tool_prefix}file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$FILECMD"; then ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_FILECMD="${ac_tool_prefix}file" printf "%s\n" "$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 FILECMD=$ac_cv_prog_FILECMD if test -n "$FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FILECMD" >&5 printf "%s\n" "$FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_FILECMD"; then ac_ct_FILECMD=$FILECMD # Extract the first word of "file", so it can be a program name with args. set dummy file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_FILECMD"; then ac_cv_prog_ac_ct_FILECMD="$ac_ct_FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_FILECMD="file" printf "%s\n" "$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_FILECMD=$ac_cv_prog_ac_ct_FILECMD if test -n "$ac_ct_FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FILECMD" >&5 printf "%s\n" "$ac_ct_FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_FILECMD" = x; then FILECMD=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac FILECMD=$ac_ct_FILECMD fi else FILECMD="$ac_cv_prog_FILECMD" fi 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 printf "%s\n" "$OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 printf %s "checking how to recognize dependent libraries... " >&6; } if test ${lt_cv_deplibs_check_method+y} then : printf %s "(cached) " >&6 else $as_nop 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='$FILECMD -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* | midnightbsd*) 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=$FILECMD 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=$FILECMD 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=$FILECMD 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 printf "%s\n" "$DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 printf %s "checking how to associate runtime and link libraries... " >&6; } if test ${lt_cv_sharedlib_from_linklib_cmd+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AR+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 printf "%s\n" "$AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AR+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 printf "%s\n" "$ac_ct_AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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} # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 printf %s "checking for archiver @FILE support... " >&6; } if test ${lt_cv_ar_at_file+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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=$? printf "%s\n" "$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=$? printf "%s\n" "$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.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 printf "%s\n" "$RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 printf "%s\n" "$ac_ct_RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 printf %s "checking command to parse $NM output from $compiler object... " >&6; } if test ${lt_cv_sys_global_symbol_pipe+y} then : printf %s "(cached) " >&6 else $as_nop # 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++ or ICC, # 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=$? printf "%s\n" "$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=$? printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 printf "%s\n" "failed" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 printf %s "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test ${with_sysroot+y} then : withval=$with_sysroot; else $as_nop 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|'') ;; #( *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 printf "%s\n" "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 printf "%s\n" "${lt_sysroot:-no}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 printf %s "checking for a working dd... " >&6; } if test ${ac_cv_path_lt_DD+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 printf "%s\n" "$ac_cv_path_lt_DD" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 printf %s "checking how to truncate binary pipes... " >&6; } if test ${lt_cv_truncate_bin+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 printf "%s\n" "$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+y} 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=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD 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=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD 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=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD 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=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD 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" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 printf %s "checking whether the C compiler needs -belf... " >&6; } if test ${lt_cv_cc_needs_belf+y} then : printf %s "(cached) " >&6 else $as_nop 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 (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_cc_needs_belf=yes else $as_nop lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 printf "%s\n" "$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=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 printf "%s\n" "$MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if test ${lt_cv_path_mainfest_tool+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 printf "%s\n" "$DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 printf "%s\n" "$NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 printf "%s\n" "$ac_ct_NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 printf "%s\n" "$LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 printf "%s\n" "$ac_ct_LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 printf "%s\n" "$OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 printf "%s\n" "$ac_ct_OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 printf "%s\n" "$OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 printf "%s\n" "$ac_ct_OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 printf %s "checking for -single_module linker flag... " >&6; } if test ${lt_cv_apple_cc_single_mod+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 printf %s "checking for -exported_symbols_list linker flag... " >&6; } if test ${lt_cv_ld_exported_symbols_list+y} then : printf %s "(cached) " >&6 else $as_nop 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 (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_ld_exported_symbols_list=yes else $as_nop lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 printf %s "checking for -force_load linker flag... " >&6; } if test ${lt_cv_ld_force_load+y} then : printf %s "(cached) " >&6 else $as_nop 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 $AR_FLAGS libconftest.a conftest.o" >&5 $AR $AR_FLAGS 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 printf "%s\n" "$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*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[012],*|,*powerpc*-darwin[5-8]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _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_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi 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 : printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h fi 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+y} 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 $as_nop enable_static=yes fi # Check whether --with-pic was given. if test ${with_pic+y} 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 $as_nop pic_mode=default fi # Check whether --enable-fast-install was given. if test ${enable_fast_install+y} 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 $as_nop enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 printf %s "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test ${with_aix_soname+y} 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 $as_nop if test ${lt_cv_with_aix_soname+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 printf %s "checking for objdir... " >&6; } if test ${lt_cv_objdir+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 printf "%s\n" "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h 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 and # ICC, which need '.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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 printf %s "checking for ${ac_tool_prefix}file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 printf %s "checking for file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if test ${lt_cv_prog_compiler_rtti_exceptions+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if test ${lt_cv_prog_compiler_pic_works+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 printf "%s\n" "$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\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "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++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) 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 file_list_spec='@' ;; 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*) hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' 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 == "L") || (\$ 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 test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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.beam \ 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 test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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.beam \ 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++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC 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 and ICC 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* | midnightbsd*) 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) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 printf %s "checking if $CC understands -b... " >&6; } if test ${lt_cv_prog_compiler__b+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 printf "%s\n" "$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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if test ${lt_cv_irix_exported_symbol+y} then : printf %s "(cached) " >&6 else $as_nop 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 $as_nop lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 printf "%s\n" "$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' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' ;; 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 file_list_spec='@' ;; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 printf "%s\n" "$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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc+y} then : printf %s "(cached) " >&6 else $as_nop $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=$? printf "%s\n" "$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=$? printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "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* | *,icl*) # Native MSVC or ICC 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 and ICC 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* | midnightbsd*) # 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 test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop 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 (void) { ; 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.beam \ 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop 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. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$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_nop 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_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 printf %s "checking for shl_load in -ldld... " >&6; } if test ${ac_cv_lib_dld_shl_load+y} then : printf %s "(cached) " >&6 else $as_nop 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. */ char shl_load (); int main (void) { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_shl_load=yes else $as_nop ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 printf "%s\n" "$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 $as_nop 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_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop 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. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$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_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 printf %s "checking for dlopen in -lsvld... " >&6; } if test ${ac_cv_lib_svld_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop 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. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_svld_dlopen=yes else $as_nop ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 printf "%s\n" "$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_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 printf %s "checking for dld_link in -ldld... " >&6; } if test ${ac_cv_lib_dld_dld_link+y} then : printf %s "(cached) " >&6 else $as_nop 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. */ char dld_link (); int main (void) { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_dld_link=yes else $as_nop ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 printf "%s\n" "$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" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 printf %s "checking whether a program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self+y} then : printf %s "(cached) " >&6 else $as_nop 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=$? printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 printf "%s\n" "$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\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 printf %s "checking whether a statically linked program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self_static+y} then : printf %s "(cached) " >&6 else $as_nop 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=$? printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 printf "%s\n" "$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= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 printf %s "checking whether stripping libraries is possible... " >&6; } if test -z "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ;; esac fi fi # Report what library types will actually be built { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 printf %s "checking if libtool supports shared libraries... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 printf "%s\n" "$can_build_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 printf "%s\n" "$enable_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 printf %s "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 printf %s "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if test ${ac_cv_prog_CXXCPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CXX needs to be expanded for CXXCPP in "$CXX -E" cpp /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. # 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. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # 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 $as_nop # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 printf "%s\n" "$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. # 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. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # 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 $as_nop # 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_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop 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 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "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 test ${lt_cv_aix_libpath__CXX+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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.beam \ 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 test ${lt_cv_aix_libpath__CXX+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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.beam \ 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* | ,icl* | no,icl*) # Native MSVC or ICC # 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 file_list_spec_CXX='@' ;; 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* | midnightbsd*) # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 printf "%s\n" "$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=$? printf "%s\n" "$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* | midnightbsd*) # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if test ${lt_cv_prog_compiler_pic_works_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 printf "%s\n" "$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\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "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 == "L") || (\$ 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* | icl*) 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 printf "%s\n" "$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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc_CXX+y} then : printf %s "(cached) " >&6 else $as_nop $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=$? printf "%s\n" "$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=$? printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "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* | *,icl*) # Native MSVC or ICC 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 and ICC 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* | midnightbsd*) # 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 test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop 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 (void) { ; 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.beam \ 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 printf "%s\n" "$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: { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_MKDIR+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR" >&5 printf "%s\n" "$MKDIR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi # Check whether --enable-documentation was given. if test ${enable_documentation+y} then : enableval=$enable_documentation; enable_documentation="${enableval}" fi if test "$enable_documentation" = "yes"; then BUILD_DOCS_TRUE= BUILD_DOCS_FALSE='#' else BUILD_DOCS_TRUE='#' BUILD_DOCS_FALSE= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 printf %s "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test ${enable_maintainer_mode+y} then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else $as_nop USE_MAINTAINER_MODE=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 printf "%s\n" "$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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking maintainer mode" >&5 printf %s "checking maintainer mode... " >&6; } # Check whether --enable-maintainer-mode was given. if test ${enable_maintainer_mode+y} then : enableval=$enable_maintainer_mode; fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${enable_maintainer_mode}" >&5 printf "%s\n" "${enable_maintainer_mode}" >&6; } # See if we want runtime debug checking. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking audit" >&5 printf %s "checking audit... " >&6; } # Check whether --enable-audit was given. if test ${enable_audit+y} then : enableval=$enable_audit; fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${enable_audit}" >&5 printf "%s\n" "${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.) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking suggest" >&5 printf %s "checking suggest... " >&6; } # Check whether --enable-suggest was given. if test ${enable_suggest+y} then : enableval=$enable_suggest; fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${enable_suggest}" >&5 printf "%s\n" "${enable_suggest}" >&6; } # Check whether --enable-shared was given. if test ${enable_shared+y} 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" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts $option" >&5 printf %s "checking whether $CXX accepts $option... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : has_option=yes else $as_nop has_option=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $has_option" >&5 printf "%s\n" "$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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sufficient C++ language/library level" >&5 printf %s "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 $as_nop sufficient_cxx=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $sufficient_cxx" >&5 printf "%s\n" "$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 \ -Wextra-semi \ -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 \ -Wzero-as-null-pointer-constant \ # "Iffy" g++ options. Some reasonably current g++-like # compilers may not support these. # The -fanalyzer one is a macro option for many of the others. add_compiler_opts_if_ok \ -fanalyzer \ -Wanalyzer-double-fclose \ -Wanalyzer-double-free \ -Wanalyzer-exposure-through-output-file \ -Wanalyzer-file-leak \ -Wanalyzer-free-of-non-heap \ -Wanalyzer-malloc-leak \ -Wanalyzer-possible-null-dereference \ -Wanalyzer-mismatching-deallocation \ -Wanalyzer-null-dereference \ -Wanalyzer-null-argument \ -Wanalyzer-possible-null-argument \ -Wanalyzer-shift-count-negative \ -Wanalyzer-overflow \ -Wanalyzer-stale-setjmp-buffer \ -Wanalyzer-tainted-array-index \ -Wanalyzer-unsafe-call-within-signal-handler \ -Wanalyzer-use-after-free \ -Wanalyzer-use-of-pointer-in-stale-stack-frame \ -Wanalyzer-use-of-uninitialized-value \ -Wanalyzer-write-to-const \ -Wanalyzer-write-to-string-literal \ -fnothrow-opt \ -Wattribute-alias=2 \ -Wlogical-op \ -Wmismatched-tags \ -Wredundant-tags \ -Wrestrict \ -Wstringop-overflow \ -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 fi # End of gcc-specific part. # Configuration for feature checks. Generated by generate_check_config.py. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_ASSUME" >&5 printf %s "checking PQXX_HAVE_ASSUME... " >&6; } PQXX_HAVE_ASSUME=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(int argc, char **argv) { [[assume(argv != nullptr)]]; return argc - 1; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_ASSUME 1" >>confdefs.h else $as_nop PQXX_HAVE_ASSUME=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_ASSUME" >&5 printf "%s\n" "$PQXX_HAVE_ASSUME" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_CHARCONV_FLOAT" >&5 printf %s "checking PQXX_HAVE_CHARCONV_FLOAT... " >&6; } PQXX_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_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_CHARCONV_FLOAT 1" >>confdefs.h else $as_nop PQXX_HAVE_CHARCONV_FLOAT=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_CHARCONV_FLOAT" >&5 printf "%s\n" "$PQXX_HAVE_CHARCONV_FLOAT" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_CHARCONV_INT" >&5 printf %s "checking PQXX_HAVE_CHARCONV_INT... " >&6; } PQXX_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_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_CHARCONV_INT 1" >>confdefs.h else $as_nop PQXX_HAVE_CHARCONV_INT=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_CHARCONV_INT" >&5 printf "%s\n" "$PQXX_HAVE_CHARCONV_INT" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_CMP" >&5 printf %s "checking PQXX_HAVE_CMP... " >&6; } PQXX_HAVE_CMP=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // Test for C++20 std::cmp_greater etc. support. // C++20: Assume 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 : printf "%s\n" "#define PQXX_HAVE_CMP 1" >>confdefs.h else $as_nop PQXX_HAVE_CMP=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_CMP" >&5 printf "%s\n" "$PQXX_HAVE_CMP" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_CONCEPTS" >&5 printf %s "checking PQXX_HAVE_CONCEPTS... " >&6; } PQXX_HAVE_CONCEPTS=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // Feature check for 'PQXX_HAVE_CONCEPTS'. // Generated by generate_cxx_checks.py. #include #if !defined(__cpp_concepts) # error "No PQXX_HAVE_CONCEPTS: __cpp_concepts is not set." #endif #if !__cpp_concepts # error "No PQXX_HAVE_CONCEPTS: __cpp_concepts is false." #endif int main() {} _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_CONCEPTS 1" >>confdefs.h else $as_nop PQXX_HAVE_CONCEPTS=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_CONCEPTS" >&5 printf "%s\n" "$PQXX_HAVE_CONCEPTS" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_CXA_DEMANGLE" >&5 printf %s "checking PQXX_HAVE_CXA_DEMANGLE... " >&6; } PQXX_HAVE_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 : printf "%s\n" "#define PQXX_HAVE_CXA_DEMANGLE 1" >>confdefs.h else $as_nop PQXX_HAVE_CXA_DEMANGLE=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_CXA_DEMANGLE" >&5 printf "%s\n" "$PQXX_HAVE_CXA_DEMANGLE" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_GCC_PURE" >&5 printf %s "checking PQXX_HAVE_GCC_PURE... " >&6; } PQXX_HAVE_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 : printf "%s\n" "#define PQXX_HAVE_GCC_PURE 1" >>confdefs.h else $as_nop PQXX_HAVE_GCC_PURE=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_GCC_PURE" >&5 printf "%s\n" "$PQXX_HAVE_GCC_PURE" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_GCC_VISIBILITY" >&5 printf %s "checking PQXX_HAVE_GCC_VISIBILITY... " >&6; } PQXX_HAVE_GCC_VISIBILITY=yes 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 : printf "%s\n" "#define PQXX_HAVE_GCC_VISIBILITY 1" >>confdefs.h else $as_nop PQXX_HAVE_GCC_VISIBILITY=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_GCC_VISIBILITY" >&5 printf "%s\n" "$PQXX_HAVE_GCC_VISIBILITY" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_LIKELY" >&5 printf %s "checking PQXX_HAVE_LIKELY... " >&6; } PQXX_HAVE_LIKELY=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // Test for C++20 [[likely]] and [[unlikely]] attributes. // C++20: Assume support. 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 : printf "%s\n" "#define PQXX_HAVE_LIKELY 1" >>confdefs.h else $as_nop PQXX_HAVE_LIKELY=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_LIKELY" >&5 printf "%s\n" "$PQXX_HAVE_LIKELY" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_MULTIDIM" >&5 printf %s "checking PQXX_HAVE_MULTIDIM... " >&6; } PQXX_HAVE_MULTIDIM=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // Feature check for 'PQXX_HAVE_MULTIDIM'. // Generated by generate_cxx_checks.py. #include #if !defined(__cpp_multidimensional_subscript) # error "No PQXX_HAVE_MULTIDIM: __cpp_multidimensional_subscript is not set." #endif #if !__cpp_multidimensional_subscript # error "No PQXX_HAVE_MULTIDIM: __cpp_multidimensional_subscript is false." #endif int main() {} _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_MULTIDIM 1" >>confdefs.h else $as_nop PQXX_HAVE_MULTIDIM=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_MULTIDIM" >&5 printf "%s\n" "$PQXX_HAVE_MULTIDIM" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_PATH" >&5 printf %s "checking PQXX_HAVE_PATH... " >&6; } PQXX_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 : printf "%s\n" "#define PQXX_HAVE_PATH 1" >>confdefs.h else $as_nop PQXX_HAVE_PATH=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_PATH" >&5 printf "%s\n" "$PQXX_HAVE_PATH" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_POLL" >&5 printf %s "checking PQXX_HAVE_POLL... " >&6; } PQXX_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_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_POLL 1" >>confdefs.h else $as_nop PQXX_HAVE_POLL=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_POLL" >&5 printf "%s\n" "$PQXX_HAVE_POLL" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_SLEEP_FOR" >&5 printf %s "checking PQXX_HAVE_SLEEP_FOR... " >&6; } PQXX_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 and OS headers that we don't strictly need * here. */ #include #include #include #include #include #include #include #if __has_include() # include #endif #if __has_include() # include #endif #if __has_include() # include #endif int main() { std::this_thread::sleep_for(std::chrono::microseconds{10u}); } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_SLEEP_FOR 1" >>confdefs.h else $as_nop PQXX_HAVE_SLEEP_FOR=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_SLEEP_FOR" >&5 printf "%s\n" "$PQXX_HAVE_SLEEP_FOR" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_SOURCE_LOCATION" >&5 printf %s "checking PQXX_HAVE_SOURCE_LOCATION... " >&6; } PQXX_HAVE_SOURCE_LOCATION=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // Feature check for 'PQXX_HAVE_SOURCE_LOCATION'. // Generated by generate_cxx_checks.py. #include #if !defined(__cpp_lib_source_location) # error "No PQXX_HAVE_SOURCE_LOCATION: __cpp_lib_source_location is not set." #endif #if !__cpp_lib_source_location # error "No PQXX_HAVE_SOURCE_LOCATION: __cpp_lib_source_location is false." #endif int main() {} _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_SOURCE_LOCATION 1" >>confdefs.h else $as_nop PQXX_HAVE_SOURCE_LOCATION=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_SOURCE_LOCATION" >&5 printf "%s\n" "$PQXX_HAVE_SOURCE_LOCATION" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_SPAN" >&5 printf %s "checking PQXX_HAVE_SPAN... " >&6; } PQXX_HAVE_SPAN=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // Feature check for 'PQXX_HAVE_SPAN'. // Generated by generate_cxx_checks.py. #include #if !defined(__cpp_lib_span) # error "No PQXX_HAVE_SPAN: __cpp_lib_span is not set." #endif #if !__cpp_lib_span # error "No PQXX_HAVE_SPAN: __cpp_lib_span is false." #endif int main() {} _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_SPAN 1" >>confdefs.h else $as_nop PQXX_HAVE_SPAN=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_SPAN" >&5 printf "%s\n" "$PQXX_HAVE_SPAN" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_SSIZE" >&5 printf %s "checking PQXX_HAVE_SSIZE... " >&6; } PQXX_HAVE_SSIZE=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // Feature check for 'PQXX_HAVE_SSIZE'. // Generated by generate_cxx_checks.py. #include #if !defined(__cpp_lib_ssize) # error "No PQXX_HAVE_SSIZE: __cpp_lib_ssize is not set." #endif #if !__cpp_lib_ssize # error "No PQXX_HAVE_SSIZE: __cpp_lib_ssize is false." #endif int main() {} _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_SSIZE 1" >>confdefs.h else $as_nop PQXX_HAVE_SSIZE=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_SSIZE" >&5 printf "%s\n" "$PQXX_HAVE_SSIZE" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_STRERROR_R" >&5 printf %s "checking PQXX_HAVE_STRERROR_R... " >&6; } PQXX_HAVE_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_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_STRERROR_R 1" >>confdefs.h else $as_nop PQXX_HAVE_STRERROR_R=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_STRERROR_R" >&5 printf "%s\n" "$PQXX_HAVE_STRERROR_R" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_STRERROR_S" >&5 printf %s "checking PQXX_HAVE_STRERROR_S... " >&6; } PQXX_HAVE_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_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_STRERROR_S 1" >>confdefs.h else $as_nop PQXX_HAVE_STRERROR_S=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_STRERROR_S" >&5 printf "%s\n" "$PQXX_HAVE_STRERROR_S" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_THREAD_LOCAL" >&5 printf %s "checking PQXX_HAVE_THREAD_LOCAL... " >&6; } PQXX_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. // TODO: Probably no longer needed once we always have float std::charconv. #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_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_THREAD_LOCAL 1" >>confdefs.h else $as_nop PQXX_HAVE_THREAD_LOCAL=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_THREAD_LOCAL" >&5 printf "%s\n" "$PQXX_HAVE_THREAD_LOCAL" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PQXX_HAVE_YEAR_MONTH_DAY" >&5 printf %s "checking PQXX_HAVE_YEAR_MONTH_DAY... " >&6; } PQXX_HAVE_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_compile "$LINENO" then : printf "%s\n" "#define PQXX_HAVE_YEAR_MONTH_DAY 1" >>confdefs.h else $as_nop PQXX_HAVE_YEAR_MONTH_DAY=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PQXX_HAVE_YEAR_MONTH_DAY" >&5 printf "%s\n" "$PQXX_HAVE_YEAR_MONTH_DAY" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking no_need_fslib" >&5 printf %s "checking no_need_fslib... " >&6; } no_need_fslib=yes 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_compile "$LINENO" then : printf "%s\n" "#define no_need_fslib 1" >>confdefs.h else $as_nop no_need_fslib=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $no_need_fslib" >&5 printf "%s\n" "$no_need_fslib" >&6; } # End of config. # One of the generated checks sets this variable. if test "$PQXX_HAVE_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 # One of the generated checks sets this variable. if test "$PQXX_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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing select" >&5 printf %s "checking for library containing select... " >&6; } if test ${ac_cv_search_select+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int select (); } int main (void) { return conftest::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.beam \ conftest$ac_exeext if test ${ac_cv_search_select+y} then : break fi done if test ${ac_cv_search_select+y} then : else $as_nop ac_cv_search_select=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_select" >&5 printf "%s\n" "$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=`printf "%s\n" "ac_cv_lib_$l""_main" | $as_tr_sh` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -l$l" >&5 printf %s "checking for main in -l$l... " >&6; } if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-l$l $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int main (); } int main (void) { return conftest::main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : eval "$as_ac_Lib=yes" else $as_nop eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 printf "%s\n" "$PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PG_CONFIG" >&5 printf "%s\n" "$PG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$PG_CONFIG" && break done # Check whether --with-postgres-include was given. if test ${with_postgres_include+y} 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: finding PostgreSQL headers using $POSTGRES_INCLUDE" >&5 printf "%s\n" "$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_compile "$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_nop 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+y} 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 : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: using PostgreSQL libraries at $with_postgres_lib" >&5 printf "%s\n" "$as_me: using PostgreSQL libraries at $with_postgres_lib" >&6;} else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: using PostgreSQL libraries in default location" >&5 printf "%s\n" "$as_me: using PostgreSQL libraries in default location" >&6;} fi ac_fn_cxx_check_header_compile "$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_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ability to compile source files using libpq" >&5 printf %s "checking for ability to compile source files using libpq... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { PQexec(nullptr,"") ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : else $as_nop 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.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "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}" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PQexec in -lpq" >&5 printf %s "checking for PQexec in -lpq... " >&6; } if test ${ac_cv_lib_pq_PQexec+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lpq ${with_postgres_libpath} $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int PQexec (); } int main (void) { return conftest::PQexec (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : ac_cv_lib_pq_PQexec=yes else $as_nop ac_cv_lib_pq_PQexec=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pq_PQexec" >&5 printf "%s\n" "$ac_cv_lib_pq_PQexec" >&6; } if test "x$ac_cv_lib_pq_PQexec" = xyes then : printf "%s\n" "#define HAVE_LIBPQ 1" >>confdefs.h LIBS="-lpq $LIBS" else $as_nop 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 # TODO: PQresultMemorySize() { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we need a link option for support" >&5 printf %s "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 $as_nop LIBS="$LIBS_SAVE" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ 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 set your own build options for this. " "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $result_msg" >&5 printf "%s\n" "$result_msg" >&6; } # Remove redundant occurrances of -lpq LIBS=$(echo "$LIBS" | sed -e 's/-lpq * -lpq\>/-lpq/g') { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that type of libpq's Oid is as expected" >&5 printf %s "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 (void) { Oid o;f(o) ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : else $as_nop 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.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi ac_config_files="$ac_config_files Makefile config/Makefile doc/Makefile 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_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$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+y} || &/ 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$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=`printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 printf "%s\n" "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_DOCS_TRUE}" && test -z "${BUILD_DOCS_FALSE}"; then as_fn_error $? "conditional \"BUILD_DOCS\" 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" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$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 as_nop=: if test ${ZSH_VERSION+y} && (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 $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; 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 # 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # 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 printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$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_nop 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_nop 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 || printf "%s\n" 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 # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. 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 # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' 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=`printf "%s\n" "$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 || printf "%s\n" 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.10.0, which was generated by GNU Autoconf 2.71. 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 ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ libpqxx config.status 7.10.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 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 ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$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=`printf "%s\n" "$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 ) printf "%s\n" "$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 \printf "%s\n" "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 printf "%s\n" "$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"`' FILECMD='`$ECHO "$FILECMD" | $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"`' lt_ar_flags='`$ECHO "$lt_ar_flags" | $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 \ FILECMD \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ 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" ;; "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+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers test ${CONFIG_COMMANDS+y} || 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=`printf "%s\n" "$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 '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$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 || printf "%s\n" 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=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$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@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$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"; } && { printf "%s\n" "$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 printf "%s\n" "$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 { printf "%s\n" "/* $configure_input */" >&1 \ && 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$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 printf "%s\n" "/* $configure_input */" >&1 \ && 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 || printf "%s\n" 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) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 printf "%s\n" "$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=`printf "%s\n" "$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 || printf "%s\n" 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 || printf "%s\n" 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 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 # A file(cmd) program that detects file types. FILECMD=$lt_FILECMD # 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 (by configure). lt_ar_flags=$lt_ar_flags # Flags to create an archive. AR_FLAGS=\${ARFLAGS-"\$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.py" "${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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi libpqxx-7.10.0/configure.ac000066400000000000000000000341651473205454700156000ustar00rootroot00000000000000# Generate configure script for libpqxx. This needs the autoconf archive # package installed. (The configure script itself does not require it though.) AC_PREREQ([2.71]) 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_HEADERS([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 LT_INIT AC_PROG_MAKE_SET AC_PATH_PROG([MKDIR], [mkdir]) AC_ARG_ENABLE( documentation, [AS_HELP_STRING([--enable-documentation], [Generate documentation])], [enable_documentation="${enableval}"]) AM_CONDITIONAL( [BUILD_DOCS], [test "$enable_documentation" = "yes"]) 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 \ -Wextra-semi \ -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 \ -Wzero-as-null-pointer-constant \ # "Iffy" g++ options. Some reasonably current g++-like # compilers may not support these. # The -fanalyzer one is a macro option for many of the others. add_compiler_opts_if_ok \ -fanalyzer \ -Wanalyzer-double-fclose \ -Wanalyzer-double-free \ -Wanalyzer-exposure-through-output-file \ -Wanalyzer-file-leak \ -Wanalyzer-free-of-non-heap \ -Wanalyzer-malloc-leak \ -Wanalyzer-possible-null-dereference \ -Wanalyzer-mismatching-deallocation \ -Wanalyzer-null-dereference \ -Wanalyzer-null-argument \ -Wanalyzer-possible-null-argument \ -Wanalyzer-shift-count-negative \ -Wanalyzer-overflow \ -Wanalyzer-stale-setjmp-buffer \ -Wanalyzer-tainted-array-index \ -Wanalyzer-unsafe-call-within-signal-handler \ -Wanalyzer-use-after-free \ -Wanalyzer-use-of-pointer-in-stale-stack-frame \ -Wanalyzer-use-of-uninitialized-value \ -Wanalyzer-write-to-const \ -Wanalyzer-write-to-string-literal \ -fnothrow-opt \ -Wattribute-alias=2 \ -Wlogical-op \ -Wmismatched-tags \ -Wredundant-tags \ -Wrestrict \ -Wstringop-overflow \ -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 fi # End of gcc-specific part. m4_include([pqxx_cxx_feature_checks.ac]) # One of the generated checks sets this variable. if test "$PQXX_HAVE_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 # One of the generated checks sets this variable. if test "$PQXX_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}) # TODO: PQresultMemorySize() 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(no_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 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 src/Makefile test/Makefile tools/Makefile include/Makefile include/pqxx/Makefile libpqxx.pc]) AC_CONFIG_COMMANDS([configitems], ["${srcdir}/tools/splitconfig.py" "${srcdir}"]) AC_CONFIG_FILES([compile_flags]) AC_OUTPUT libpqxx-7.10.0/cxx_features.txt000066400000000000000000000014051473205454700165420ustar00rootroot00000000000000# Feature checks that we can perform simply by testing a C++ feature # test macro. # # Each (non-empty, non-comment) line consists of a libpqxx feature macro # and the corresponding C++ feature test macro that we need to check in # order to detect that feature. # # From these, the autogen script generates code snippets that the build # configuration step can try to compile, as well as the bits of config # to do that in the supported build systems. # # Remember to enter each of these in configitems as well, or they won't # end up in the actual configuration headers. PQXX_HAVE_CONCEPTS __cpp_concepts PQXX_HAVE_MULTIDIM __cpp_multidimensional_subscript PQXX_HAVE_SOURCE_LOCATION __cpp_lib_source_location PQXX_HAVE_SPAN __cpp_lib_span PQXX_HAVE_SSIZE __cpp_lib_ssize libpqxx-7.10.0/doc/000077500000000000000000000000001473205454700140465ustar00rootroot00000000000000libpqxx-7.10.0/doc/CMakeLists.txt000066400000000000000000000012301473205454700166020ustar00rootroot00000000000000find_program(HAVE_DOXYGEN doxygen) 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}") add_custom_target(build-docs ALL COMMAND cp -r ${CMAKE_CURRENT_SOURCE_DIR}/../src/*.[ch]xx ../src/ COMMAND cp -r ${CMAKE_CURRENT_SOURCE_DIR}/../include/pqxx/* ../include/pqxx/ COMMAND doxygen ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile COMMENT Building documentation ) install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doxygen-html/ DESTINATION ${CMAKE_INSTALL_DOCDIR}/html ) libpqxx-7.10.0/doc/Doxyfile000066400000000000000000000303351473205454700155600ustar00rootroot00000000000000# Doxyfile 1.9.4 # Set up to run Doxygen from the "doc" directory. PROJECT_NAME = "libpqxx" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "The C++ client library for PostgreSQL" # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. 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. # Path to where to generate Doxygen output. Defaults to working directory # when doxygen was run. Relative paths are relative to there. OUTPUT_DIRECTORY = GENERATE_LATEX = NO # If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 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 causes # performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to # control the number of sub-directories. # The default value is: NO. CREATE_SUBDIRS = NO # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = YES # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = YES # The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use # during processing. When set to 0 doxygen will base this on the number of # cores available in the system. You can set it explicitly to a value larger # than 0 to get more control over the balance between CPU load and processing # speed. At this moment only the input processing can be done using multiple # threads. Since this is still an experimental feature the default is set to 1, # which effectively disables parallel processing. Please report any issues you # encounter. Generating dot graphs in parallel is controlled by the # DOT_NUM_THREADS setting. # Minimum value: 0, maximum value: 32, default value: 1. NUM_PROC_THREADS = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # 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. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = 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, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = YES # If the SHOW_HEADERFILE tag is set to YES then the documentation for a class # will show which file needs to be included to use the class. # The default value is: YES. SHOW_HEADERFILE = NO INPUT = ../src ../include # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = YES # 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 = ../test ../test/unit # 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 = *.cxx # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = ../include/pqxx/doc/mainpage.md #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all # C-preprocessor directives found in the sources and include files. # The default value is: YES. 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, only conditional compilation will be # performed. Macro expansion can be done in a controlled way by setting # EXPAND_ONLY_PREDEF to YES. # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. MACRO_EXPANSION = 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. Note that the INCLUDE_PATH is not recursive, so the setting of # RECURSIVE has no effect here. # This tag requires that the tag SEARCH_INCLUDES is set to YES. INCLUDE_PATH = ../include /usr/include/postgresql # 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. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. INCLUDE_FILE_PATTERNS = * # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will # remove all references to 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. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. SKIP_FUNCTION_MACROS = NO #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the # clang parser (see: # http://clang.llvm.org/) for more accurate parsing at the cost of reduced # performance. This can be particularly helpful with template rich C++ code for # which doxygen's built-in parser lacks the necessary type information. # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse_libclang=ON option for CMake. # The default value is: NO. # TODO: Re-enable this once clang parser gets better. CLANG_ASSISTED_PARSING = NO # If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS # tag is set to YES then doxygen will add the directory of each input to the # include path. # The default value is: YES. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. CLANG_ADD_INC_PATHS = NO # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that # the include paths will already be set by doxygen for the files and directories # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. CLANG_OPTIONS = -O0 -std=c++23 #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # 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. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = doxygen-html # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a color-wheel, see # https://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 200 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use gray-scales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 80 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # 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. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = YES # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value 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 # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine tune the look of the index (see "Fine-tuning the output"). As an # example, the default style sheet generated by doxygen has an example that # shows how to put an image at the root of the tree instead of the PROJECT_NAME. # Since the tree basically has the same information as the tab index, you could # consider setting DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = YES #--------------------------------------------------------------------------- # 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. # The default value is: NO. # TODO: Not really doing Sphinx/Breathe for now. Should we? # GENERATE_XML = YES # 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. # The default directory is: xml. # This tag requires that the tag GENERATE_XML is set to YES. XML_OUTPUT = doxygen-xml libpqxx-7.10.0/doc/Makefile.am000066400000000000000000000012471473205454700161060ustar00rootroot00000000000000MAINTAINERCLEANFILES = Makefile.in maintainer-clean-local: $(RM) -rf doxygen-html $(MKDIR) doxygen-html EXTRA_DIST = Doxyfile all-local: docs if BUILD_DOCS DOXYGEN = doxygen # Doxygen config needs the source files in its local tree. That means the # build tree. If that differs from the source tree, copy the files. docs: if ! [ "$(srcdir)/../src" -ef ../src ]; then \ cp "$(srcdir)"/../src/*.[ch]xx ../src/ ; \ cp -r "$(srcdir)"/../include/pqxx/* ../include/pqxx/ ; \ cp -r "$(srcdir)"/../test ../test/ ; \ fi $(DOXYGEN) "$(srcdir)"/Doxyfile else docs: endif dist-hook: if [ -d doxygen-html ]; then \ cp -pR doxygen-html $(distdir)/html ; \ fi libpqxx-7.10.0/doc/Makefile.in000066400000000000000000000325021473205454700161150ustar00rootroot00000000000000# Makefile.in generated by automake 1.16.5 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)/pqxx_cxx_feature_checks.ac \ $(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 \ $(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@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ 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 @BUILD_DOCS_TRUE@DOXYGEN = doxygen 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): 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 doxygen-html $(MKDIR) doxygen-html all-local: docs # Doxygen config needs the source files in its local tree. That means the # build tree. If that differs from the source tree, copy the files. @BUILD_DOCS_TRUE@docs: @BUILD_DOCS_TRUE@ if ! [ "$(srcdir)/../src" -ef ../src ]; then \ @BUILD_DOCS_TRUE@ cp "$(srcdir)"/../src/*.[ch]xx ../src/ ; \ @BUILD_DOCS_TRUE@ cp -r "$(srcdir)"/../include/pqxx/* ../include/pqxx/ ; \ @BUILD_DOCS_TRUE@ cp -r "$(srcdir)"/../test ../test/ ; \ @BUILD_DOCS_TRUE@ fi @BUILD_DOCS_TRUE@ $(DOXYGEN) "$(srcdir)"/Doxyfile @BUILD_DOCS_FALSE@docs: dist-hook: if [ -d doxygen-html ]; then \ cp -pR doxygen-html $(distdir)/html ; \ 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: libpqxx-7.10.0/doc/requirements.txt000066400000000000000000000001401473205454700173250ustar00rootroot00000000000000# TODO: Pin versions. # TODO: Do we even still need this file? dia sphinx-rtd-theme myst-parser libpqxx-7.10.0/doc/source/000077500000000000000000000000001473205454700153465ustar00rootroot00000000000000libpqxx-7.10.0/doc/source/conf.py000066400000000000000000000017321473205454700166500ustar00rootroot00000000000000# Configuration file for the Sphinx documentation builder. from pathlib import Path project = 'libpqxx' copyright = '2000-2024, Jeroen T. Vermeulen' author = 'Jeroen T. Vermeulen' version = (Path(__file__).parents[2] / 'VERSION').read_text().strip() release = '.'.join(version.split('.')[:2]) extensions = [ # TODO: Not actually using Sphinx for now. Should we? # From readthedocs template: # 'sphinx.ext.duration', # 'sphinx.ext.doctest', # 'sphinx.ext.autodoc', # 'sphinx.ext.autosummary', # 'sphinx.ext.intersphinx', # Additional: # TODO: Not using Breathe for now. Should we? # 'breathe', 'myst_parser', ] # TODO: What do these actually mean? # intersphinx_mapping = { # 'python': ('https://docs.python.org/3/', None), # 'sphinx': ('https://www.sphinx-doc.org/en/master/', None), # } # intersphinx_disabled_domains = ['std'] templates_path = ['_templates'] # -- Options for HTML output html_theme = 'sphinx_rtd_theme' libpqxx-7.10.0/doc/source/index.rst000066400000000000000000000004341473205454700172100ustar00rootroot00000000000000libpqxx documentation ===================== This documentation is for libpqxx_, the C++ client library for PostgreSQL. This is the library you call in order to work with a postgres database from your C++ code. .. _libpqxx: https://pqxx.org/libpqxx/ Contents -------- .. toctree:: libpqxx-7.10.0/include/000077500000000000000000000000001473205454700147245ustar00rootroot00000000000000libpqxx-7.10.0/include/CMakeLists.txt000066400000000000000000000035261473205454700174720ustar00rootroot00000000000000# ############################################################################## # 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 ) libpqxx-7.10.0/include/CMakeLists.txt.template000066400000000000000000000011511473205454700212740ustar00rootroot00000000000000install( 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 ) libpqxx-7.10.0/include/Makefile.am000066400000000000000000000057421473205454700167700ustar00rootroot00000000000000SUBDIRS = 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/stream_query.hxx \ pqxx/internal/stream_query_impl.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-stream_from.hxx \ pqxx/internal/gates/connection-stream_to.hxx \ pqxx/internal/gates/connection-transaction.hxx \ pqxx/internal/gates/errorhandler-connection.hxx \ pqxx/internal/gates/icursor_iterator-icursorstream.hxx \ pqxx/internal/gates/icursorstream-icursor_iterator.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 libpqxx-7.10.0/include/Makefile.in000066400000000000000000000626111473205454700167770ustar00rootroot00000000000000# Makefile.in generated by automake 1.16.5 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)/pqxx_cxx_feature_checks.ac \ $(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@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ 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/stream_query.hxx \ pqxx/internal/stream_query_impl.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-stream_from.hxx \ pqxx/internal/gates/connection-stream_to.hxx \ pqxx/internal/gates/connection-transaction.hxx \ pqxx/internal/gates/errorhandler-connection.hxx \ pqxx/internal/gates/icursor_iterator-icursorstream.hxx \ pqxx/internal/gates/icursorstream-icursor_iterator.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: libpqxx-7.10.0/include/pqxx/000077500000000000000000000000001473205454700157245ustar00rootroot00000000000000libpqxx-7.10.0/include/pqxx/Makefile.am000066400000000000000000000004131473205454700177560ustar00rootroot00000000000000MAINTAINERCLEANFILES=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 libpqxx-7.10.0/include/pqxx/Makefile.in000066400000000000000000000364151473205454700200020ustar00rootroot00000000000000# Makefile.in generated by automake 1.16.5 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)/pqxx_cxx_feature_checks.ac \ $(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@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ 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: libpqxx-7.10.0/include/pqxx/array000066400000000000000000000003271473205454700167670ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/array.hxx000066400000000000000000000560131473205454700176000ustar00rootroot00000000000000/* Handling of SQL arrays. * * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 #include #include #include #include "pqxx/connection.hxx" #include "pqxx/internal/array-composite.hxx" #include "pqxx/internal/encoding_group.hxx" #include "pqxx/internal/encodings.hxx" namespace pqxx { // TODO: Specialise for string_view/zview, allocate all strings in one buffer. /// An SQL array received from the database. /** Parses an SQL array from its text format, making it available as a * container of C++-side values. * * The array can have one or more dimensions. You must specify the number of * dimensions at compile time. In each dimension, the array has a size which * the `array` constructor determines at run time based on the SQL array's * textual representation. The sizes of a given SQL array are consistent: if * your array has two dimensions, for example, then it will have one * "horizontal" size which determines the number of elements in each row; and * it will have one "vertical" size which determines the number of rows. * * Physical memory storage is "row-major." This means that the last of the * dimensions represents a row. So in memory, element `a[m][n]` comes right * before `a[m][n+1]`. */ template< typename ELEMENT, std::size_t DIMENSIONS = 1u, char SEPARATOR = array_separator> class array final { public: /// Parse an SQL array, read as text from a pqxx::result or stream. /** Uses `cx` only during construction, to find out the text encoding in * which it should interpret `data`. * * Once the `array` constructor completes, destroying or moving the * `connection` will not affect the `array` object in any way. * * @throws pqxx::unexpected_null if the array contains a null value, and the * `ELEMENT` type does not support null values. */ array(std::string_view data, connection const &cx) : array{data, pqxx::internal::enc_group(cx.encoding_id())} {} /// How many dimensions does this array have? /** This value is known at compile time. */ constexpr std::size_t dimensions() noexcept { return DIMENSIONS; } /// Return the sizes of this array in each of its dimensions. /** The last of the sizes is the number of elements in a single row. The * size before that is the number of rows of elements, and so on. The first * is the "outer" size. */ std::array const &sizes() noexcept { return m_extents; } template ELEMENT const &at(INDEX... index) const { static_assert(sizeof...(index) == DIMENSIONS); check_bounds(index...); return m_elts.at(locate(index...)); } /// Access element (without bounds check). /** Return element at given index. Blindly assumes that the index lies * within the bounds of the array. This is likely to be slightly faster than * `at()`. * * Multi-dimensional indexing using `operator[]` only works in C++23 or * better. In older versions of C++ it will work only with * single-dimensional arrays. */ template ELEMENT const &operator[](INDEX... index) const { static_assert(sizeof...(index) == DIMENSIONS); return m_elts[locate(index...)]; } /// Begin iteration of individual elements. /** If this is a multi-dimensional array, iteration proceeds in row-major * order. So for example, a two-dimensional array `a` would start at * `a[0, 0]`, then `a[0, 1]`, and so on. Once it reaches the end of that * first row, it moves on to element `a[1, 0]`, and continues from there. */ constexpr auto cbegin() const noexcept { return m_elts.cbegin(); } /// Return end point of iteration. constexpr auto cend() const noexcept { return m_elts.cend(); } /// Begin reverse iteration. constexpr auto crbegin() const noexcept { return m_elts.crbegin(); } /// Return end point of reverse iteration. constexpr auto crend() const noexcept { return m_elts.crend(); } /// Number of elements in the array. /** This includes all elements, in all dimensions. Therefore it is the * product of all values in `sizes()`. */ constexpr std::size_t size() const noexcept { return m_elts.size(); } /// Number of elements in the array (as a signed number). /** This includes all elements, in all dimensions. Therefore it is the * product of all values in `sizes()`. * * In principle, the size could get so large that it had no signed * equivalent. If that can ever happen, this is your own problem and * behaviour is undefined. * * In practice however, I don't think `ssize()` could ever overflow. You'd * need an array where each element takes up just one byte, such as Booleans, * filling up more than half your address space. But the input string for * that array would need at least two bytes per value: one for the value, one * for the separating comma between elements. So even then you wouldn't have * enough address space to create the array, even if your system allowed you * to use your full address space. */ constexpr auto ssize() const noexcept { return static_cast(size()); } /// Refer to the first element, if any. /** If the array is empty, dereferencing this results in undefined behaviour. */ constexpr auto front() const noexcept { return m_elts.front(); } /// Refer to the last element, if any. /** If the array is empty, dereferencing this results in undefined behaviour. */ constexpr auto back() const noexcept { return m_elts.back(); } private: /// Throw an error if `data` is not a `DIMENSIONS`-dimensional SQL array. /** Sanity-checks two aspects of the array syntax: the opening braces at the * beginning, and the closing braces at the end. * * One syntax error this does not detect, for efficiency reasons, is for too * many closing braces at the end. That's a tough one to detect without * walking through the entire array sequentially, and identifying all the * character boundaries. The main parsing routine detects that one. */ void check_dims(std::string_view data) { auto sz{std::size(data)}; if (sz < DIMENSIONS * 2) throw conversion_error{pqxx::internal::concat( "Trying to parse a ", DIMENSIONS, "-dimensional array out of '", data, "'.")}; // Making some assumptions here: // * The array holds no extraneous whitespace. // * None of the sub-arrays can be null. // * Only ASCII characters start off with a byte in the 0-127 range. // // Given those, the input must start with a sequence of DIMENSIONS bytes // with the ASCII value for '{'; and likewise it must end with a sequence // of DIMENSIONS bytes with the ASCII value for '}'. if (data[0] != '{') throw conversion_error{"Malformed array: does not start with '{'."}; for (std::size_t i{0}; i < DIMENSIONS; ++i) if (data[i] != '{') throw conversion_error{pqxx::internal::concat( "Expecting ", DIMENSIONS, "-dimensional array, but found ", i, ".")}; if (data[DIMENSIONS] == '{') throw conversion_error{pqxx::internal::concat( "Tried to parse ", DIMENSIONS, "-dimensional array from array data that has more dimensions.")}; for (std::size_t i{0}; i < DIMENSIONS; ++i) if (data[sz - 1 - i] != '}') throw conversion_error{ "Malformed array: does not end in the right number of '}'."}; } // Allow fields to construct arrays passing the encoding group. // Couldn't make this work through a call gate, thanks to the templating. friend class ::pqxx::field; array(std::string_view data, pqxx::internal::encoding_group enc) { using group = pqxx::internal::encoding_group; switch (enc) { case group::MONOBYTE: parse(data); break; case group::BIG5: parse(data); break; case group::EUC_CN: parse(data); break; case group::EUC_JP: parse(data); break; case group::EUC_KR: parse(data); break; case group::EUC_TW: parse(data); break; case group::GB18030: parse(data); break; case group::GBK: parse(data); break; case group::JOHAB: parse(data); break; case group::MULE_INTERNAL: parse(data); break; case group::SJIS: parse(data); break; case group::UHC: parse(data); break; case group::UTF8: parse(data); break; default: PQXX_UNREACHABLE; break; } } /// Handle the end of a field. /** Check for a trailing separator, detect any syntax errors at this somewhat * complicated point, and return the offset where parsing should continue. */ std::size_t parse_field_end(std::string_view data, std::size_t here) const { auto const sz{std::size(data)}; if (here < sz) switch (data[here]) { case SEPARATOR: ++here; if (here >= sz) throw conversion_error{"Array looks truncated."}; switch (data[here]) { case SEPARATOR: throw conversion_error{"Array contains double separator."}; case '}': throw conversion_error{"Array contains trailing separator."}; default: break; } break; case '}': break; default: throw conversion_error{pqxx::internal::concat( "Unexpected character in array: ", static_cast(static_cast(data[here])), " where separator or closing brace expected.")}; } return here; } /// Estimate the number of elements in this array. /** We use this to pre-allocate internal storage, so that we don't need to * keep extending it on the fly. It doesn't need to be too precise, so long * as it's fast; doesn't usually underestimate; and never overestimates by * orders of magnitude. */ constexpr std::size_t estimate_elements(std::string_view data) const noexcept { // Dirty trick: just count the number of bytes that look as if they may be // separators. At the very worst we may overestimate by a factor of two or // so, in exceedingly rare cases, on some encodings. auto const separators{ std::count(std::begin(data), std::end(data), SEPARATOR)}; // The number of dimensions makes no difference here. It's still one // separator between consecutive elements, just possibly with some extra // braces as well. return static_cast(separators + 1); } template void parse(std::string_view data) { static_assert(DIMENSIONS > 0u, "Can't create a zero-dimensional array."); auto const sz{std::size(data)}; check_dims(data); m_elts.reserve(estimate_elements(data)); // We discover the array's extents along each of the dimensions, starting // with the final dimension and working our way towards the first. At any // given point during parsing, we know the extents starting at this // dimension. std::size_t know_extents_from{DIMENSIONS}; // Currently parsing this dimension. We start off at -1, relying on C++'s // well-defined rollover for unsigned numbers. // The actual outermost dimension of the array is 0, and the innermost is // at the end. But, the array as a whole is enclosed in braces just like // each row. So we act like there's an anomalous "outer" dimension holding // the entire array. constexpr std::size_t outer{std::size_t{0u} - std::size_t{1u}}; // We start parsing at the fictional outer dimension. The input begins // with opening braces, one for each dimension, so we'll start off by // bumping all the way to the innermost dimension. std::size_t dim{outer}; // Extent counters, one per "real" dimension. // Note initialiser syntax; this zero-initialises all elements. std::array extents{}; // Current parsing position. std::size_t here{0}; PQXX_ASSUME(here <= sz); while (here < sz) { if (data[here] == '{') { if (dim == outer) { // This must be the initial opening brace. if (know_extents_from != DIMENSIONS) throw conversion_error{ "Array text representation closed and reopened its outside " "brace pair."}; assert(here == 0); PQXX_ASSUME(here == 0); } else { if (dim >= (DIMENSIONS - 1)) throw conversion_error{ "Array seems to have inconsistent number of dimensions."}; ++extents[dim]; } // (Rolls over to zero if we're coming from the outer dimension.) ++dim; extents[dim] = 0u; ++here; } else if (data[here] == '}') { if (dim == outer) throw conversion_error{"Array has spurious '}'."}; if (dim < know_extents_from) { // We just finished parsing our first row in this dimension. // Now we know the array dimension's extent. m_extents[dim] = extents[dim]; know_extents_from = dim; } else { if (extents[dim] != m_extents[dim]) throw conversion_error{"Rows in array have inconsistent sizes."}; } // Bump back down to the next-lower dimension. Which may be the outer // dimension, through underflow. --dim; ++here; here = parse_field_end(data, here); } else { // Found an array element. The actual elements always live in the // "inner" dimension. if (dim != DIMENSIONS - 1) throw conversion_error{ "Malformed array: found element where sub-array was expected."}; assert(dim != outer); ++extents[dim]; std::size_t end; switch (data[here]) { case '\0': throw conversion_error{"Unexpected zero byte in array."}; case ',': throw conversion_error{"Array contains empty field."}; case '"': { // Double-quoted string. We parse it into a buffer before parsing // the resulting string as an element. This seems wasteful: the // string might not contain any special characters. So it's // tempting to check, and try to use a string_view and avoid a // useless copy step. But. Even besides the branch prediction // risk, the very fact that the back-end chose to quote the string // indicates that there is some kind of special character in there. // So in practice, this optimisation would only apply if the only // special characters in the string were commas. end = pqxx::internal::scan_double_quoted_string( std::data(data), std::size(data), here); // TODO: scan_double_quoted_string() with reusable buffer. std::string const buf{ pqxx::internal::parse_double_quoted_string( std::data(data), end, here)}; m_elts.emplace_back(from_string(buf)); } break; default: { // Unquoted string. An unquoted string is always literal, no // escaping or encoding, so we don't need to parse it into a // buffer. We can just read it as a string_view. end = pqxx::internal::scan_unquoted_string( std::data(data), std::size(data), here); std::string_view const field{ std::string_view{std::data(data) + here, end - here}}; if (field == "NULL") { if constexpr (nullness::has_null) m_elts.emplace_back(nullness::null()); else throw unexpected_null{pqxx::internal::concat( "Array contains a null ", type_name, ". Consider making it an array of std::optional<", type_name, "> instead.")}; } else m_elts.emplace_back(from_string(field)); } } here = end; PQXX_ASSUME(here <= sz); here = parse_field_end(data, here); } } if (dim != outer) throw conversion_error{"Malformed array; may be truncated."}; assert(know_extents_from == 0); PQXX_ASSUME(know_extents_from == 0); init_factors(); } /// Pre-compute indexing factors. void init_factors() noexcept { std::size_t factor{1}; for (std::size_t dim{DIMENSIONS - 1}; dim > 0; --dim) { factor *= m_extents[dim]; m_factors[dim - 1] = factor; } } /// Map a multidimensional index to an entry in our linear storage. template std::size_t locate(INDEX... index) const noexcept { static_assert( sizeof...(index) == DIMENSIONS, "Indexing array with wrong number of dimensions."); return add_index(index...); } template constexpr std::size_t add_index(OUTER outer, INDEX... indexes) const noexcept { std::size_t const first{check_cast(outer, "array index"sv)}; if constexpr (sizeof...(indexes) == 0) { return first; } else { static_assert(sizeof...(indexes) < DIMENSIONS); // (Offset by 1 here because the outer dimension is not in there.) constexpr auto dimension{DIMENSIONS - (sizeof...(indexes) + 1)}; static_assert(dimension < DIMENSIONS); return first * m_factors[dimension] + add_index(indexes...); } } /// Check that indexes are within bounds. /** @throw pqxx::range_error if not. */ template constexpr void check_bounds(OUTER outer, INDEX... indexes) const { std::size_t const first{check_cast(outer, "array index"sv)}; static_assert(sizeof...(indexes) < DIMENSIONS); // (Offset by 1 here because the outer dimension is not in there.) constexpr auto dimension{DIMENSIONS - (sizeof...(indexes) + 1)}; static_assert(dimension < DIMENSIONS); if (first >= m_extents[dimension]) throw range_error{pqxx::internal::concat( "Array index for dimension ", dimension, " is out of bounds: ", first, " >= ", m_extents[dimension])}; // Now check the rest of the indexes, if any. if constexpr (sizeof...(indexes) > 0) check_bounds(indexes...); } /// Linear storage for the array's elements. std::vector m_elts; /// Size along each dimension. std::array m_extents; /// Multiplication factors for indexing in each dimension. /** This wouldn't make any sense if `locate()` could recurse from the "inner" * dimension towards the "outer" one. Unfortunately we've got to recurse in * the opposite direction, so it helps to pre-compute the factors. * * We don't need to cache a factor for the outer dimension, since we never * multiply by that number. */ std::array m_factors; }; /// Low-level parser for C++ arrays. @deprecated Use @ref pqxx::array instead. /** Clunky old API for parsing SQL arrays. * * @warning This parser will only work reliably if your client encoding is * UTF-8, ASCII, or a "safe ASCII superset" (such as the EUC encodings) where * a byte value in the ASCII range can only occur as an actual ASCII character, * never as one byte in a multi-byte character. * * @warning The parser only supports array element types which use a comma * (`','`) as the separator between array elements. All built-in SQL types use * comma, except for `box` which uses semicolon. However 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, }; /// 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() { return (this->*m_impl)(); } private: std::string_view m_input; /// Current parsing position in the input. std::size_t m_pos = 0u; /// A function implementing the guts of `get_next`. /** Internally this class uses a template to specialise the implementation of * `get_next` for each of the various encoding groups. This allows the * compiler to inline the parsing of each text encoding, which happens in * very hot loops. */ using implementation = std::pair (array_parser::*)(); /// Pick the `implementation` for `enc`. static implementation specialize_for_encoding(pqxx::internal::encoding_group enc); /// Our implementation of `parse_array_step`, specialised for our encoding. implementation m_impl; /// Perform one step of array parsing. template std::pair parse_array_step(); template std::string::size_type scan_double_quoted_string() const; template std::string parse_double_quoted_string(std::string::size_type end) const; template std::string::size_type scan_unquoted_string() const; template std::string_view parse_unquoted_string(std::string::size_type end) const; template std::string::size_type scan_glyph(std::string::size_type pos) const; template std::string::size_type scan_glyph(std::string::size_type pos, std::string::size_type end) const; }; } // namespace pqxx #endif libpqxx-7.10.0/include/pqxx/binarystring000066400000000000000000000003511473205454700203610ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/binarystring.hxx000066400000000000000000000175431473205454700212020ustar00rootroot00000000000000/* Deprecated representation for raw, binary data. * * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/binarystring instead. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 bytes and @c bytes_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 = 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 bytes_view. [[nodiscard]] pqxx::bytes_view bytes_view() const { return pqxx::bytes_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 libpqxx-7.10.0/include/pqxx/blob000066400000000000000000000003361473205454700165670ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/blob.hxx000066400000000000000000000315061473205454700174000ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 // C++20: Assume support. #if __has_include() # include #endif // C++20: Assume support. #if __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(bytes &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 bytes_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, bytes_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, bytes_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, bytes &, 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, bytes &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 &cx, int fd) noexcept : m_conn{&cx}, 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 libpqxx-7.10.0/include/pqxx/composite000066400000000000000000000003461473205454700176540ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/composite.hxx000066400000000000000000000111651473205454700204630ustar00rootroot00000000000000#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; // TODO: Reuse parse_composite_field specialisation across calls. constexpr auto num_fields{sizeof...(fields)}; std::size_t index{0}; (pqxx::internal::specialize_parse_composite_field(enc)( index, text, here, fields, 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 libpqxx-7.10.0/include/pqxx/config.h.in000066400000000000000000000063761473205454700177630ustar00rootroot00000000000000/* 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_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_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 this feature is available. */ #undef PQXX_HAVE_ASSUME /* Define if this feature is available. */ #undef PQXX_HAVE_CHARCONV_FLOAT /* Define if this feature is available. */ #undef PQXX_HAVE_CHARCONV_INT /* Define if this feature is available. */ #undef PQXX_HAVE_CMP /* Define if this feature is available. */ #undef PQXX_HAVE_CONCEPTS /* Define if this feature is available. */ #undef PQXX_HAVE_CXA_DEMANGLE /* Define if this feature is available. */ #undef PQXX_HAVE_GCC_PURE /* Define if this feature is available. */ #undef PQXX_HAVE_GCC_VISIBILITY /* Define if this feature is available. */ #undef PQXX_HAVE_LIKELY /* Define if this feature is available. */ #undef PQXX_HAVE_MULTIDIM /* Define if this feature is available. */ #undef PQXX_HAVE_PATH /* Define if this feature is available. */ #undef PQXX_HAVE_POLL /* Define if this feature is available. */ #undef PQXX_HAVE_SLEEP_FOR /* Define if this feature is available. */ #undef PQXX_HAVE_SOURCE_LOCATION /* Define if this feature is available. */ #undef PQXX_HAVE_SPAN /* Define if this feature is available. */ #undef PQXX_HAVE_SSIZE /* Define if this feature is available. */ #undef PQXX_HAVE_STRERROR_R /* Define if this feature is available. */ #undef PQXX_HAVE_STRERROR_S /* Define if this feature is available. */ #undef PQXX_HAVE_THREAD_LOCAL /* Define if this feature is available. */ #undef PQXX_HAVE_YEAR_MONTH_DAY /* Define to 1 if all of the C90 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Define if this feature is available. */ #undef no_need_fslib libpqxx-7.10.0/include/pqxx/connection000066400000000000000000000004341473205454700200070ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/connection.hxx000066400000000000000000001637021473205454700206250ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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. For example, if you want custom * handling of error andwarning messages, you control that in the context of a * connection. You also define prepared statements here. For actually * executing SQL, however, you'll also need a transaction object which operates * "on top of" the connection. (See @ref transactions for more about these.) * * 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 /// Control OpenSSL/crypto library initialisation. /** This is an internal helper. Unless you're working on libpqxx itself, use * @ref pqxx::skip_init_ssl instead. * * @param flags a bitmask of `1 << flag` for each of the `skip_init` flags. * * Ignores the `skip_init::nothing` flag. */ void PQXX_COLD PQXX_LIBEXPORT skip_init_ssl(int skips) noexcept; } // 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; struct connection_stream_from; class connection_stream_to; class connection_transaction; class const_connection_largeobject; } // namespace pqxx::internal::gate namespace pqxx { /// An incoming notification. /** PostgreSQL extends SQL with a "message bus" using the `LISTEN` and `NOTIFY` * commands. In libpqxx you use @ref connection::listen() and (optionally) * @ref transaction_base::notify(). * * When you receive a notification for which you have been listening, your * handler receives it in the form of a `notification` object. * * @warning These structs are meant for extremely short lifespans: the fields * reference memory that may become invalid as soon as your handler has been * called. */ struct notification { /// The connection which received the notification. /** There will be no _backend_ transaction active on the connection when your * handler gets called, but there may be a @ref nontransaction. (This is a * special transaction type in libpqxx which does not start a transaction on * the backend.) */ connection &conn; /// Channel name. /** The notification logic will only pass the notification to a handler which * was registered to listen on this exact name. */ zview channel; /// Optional payload text. /** If the notification did not carry a payload, the string will be empty. */ zview payload; /// Process ID of the backend that sent the notification. /** This can be useful in situations where a multiple clients are listening * on the same channel, and also send notifications on it. * * In those situations, it often makes sense for a client to ignore its own * incoming notifications, but handle all others on the same channel in some * way. * * To check for that, compare this process ID to the return value of the * connection's `backendpid()`. */ int backend_pid; }; /// Flags for skipping initialisation of SSL-related libraries. /** When a running process makes its first SSL connection to a database through * libpqxx, libpq automatically initialises the OpenSSL and libcrypto * libraries. But there are scenarios in which you may want to suppress that. * * This enum is a way to express this. Pass values of this enum to * @ref pqxx::skip_init_ssl as template arguments. */ enum skip_init : int { /// A do-nothing flag that does not affect anything. nothing, /// Skip initialisation of OpenSSL library. openssl, /// Skip initialisation of libcrypto. crypto, }; /// Control initialisation of OpenSSL and libcrypto libraries. /** By default, libpq initialises the openssl and libcrypto libraries when your * process first opens an SSL connection to a database. But this may not be * what you want: perhaps your application (or some other library it uses) * already initialises one or both of these libraries. * * Call this function to stop libpq from initialising one or the other of * these. Pass as arguments each of the `skip_init` flags for which of the * libraries whose initialisation you want to prevent. * * @warning Each call to this function _overwrites_ the effects of any previous * call. So if you make one call to skip OpenSSL initialisation, and then * another to skip libcrypto initialisation, the first call will do nothing. * * Examples: * * To let libpq initialise libcrypto but not OpenSSL: * `skip_init_ssl();` * * To let libpq know that it should not initialise either: * ```cxx * skip_init_ssl(); * ``` * * To say explicitly that you want libpq to initialise both: * `skip_init_ssl();` */ template inline void skip_init_ssl() noexcept { // (Normalise skip flags to one per.) pqxx::internal::skip_init_ssl(((1 << SKIP) | ...)); } /// 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; /// 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. As per RAII principles, the connection opens during * construction, and closes upon destruction. If the connection attempt fails, * you will not get a @ref connection object; the constructor will fail with a * @ref pqxx::broken_connection exception. * * 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, or fails to establish itself in the first place, * 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 is listening for notifications. 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 &) {} } // TODO: Once we drop notification_receiver/errorhandler, move is easier. /// Move assignment. /** Neither connection can have an open transaction, `errorhandler`, or * `notification_receiver`. */ connection &operator=(connection &&rhs); connection(connection const &) = delete; connection &operator=(connection const &) = delete; /// Is this connection open at the moment? /** @warning Most code does **not** need this function. Resist the * temptation to check your connection after opening it: if the connection * attempt failed, the constructor will never even return, throwing a * @ref broken_connection exception instead. */ [[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 the database to which we're connected, if any. /** Returns nullptr when not connected. */ [[nodiscard]] char const *dbname() const; /// Database user ID under which we are connected, if any. /** Returns nullptr when not connected. */ [[nodiscard]] char const *username() const; /// Database server address, if given. /** This may be an IP address, or a hostname, or (for a Unix domain socket) * a socket path. Returns nullptr when not connected. */ [[nodiscard]] char const *hostname() const; /// Server port number on which we are connected to the database. [[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. /** 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 encoding_id() const; //@} /// 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 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 * * This is PostgreSQL-specific extension that goes beyond standard SQL. It's * a communications mechanism between clients on a database, akin to a * transactional message bus. * * A notification happens on a _channel,_ identified by a name. You can set * a connection to _listen_ for notifications on the channel, using the * connection's @ref listen() function. (Internally this will issue a * `LISTEN` SQL command). Any client on the database can send a * notification on that channel by executing a `NOTIFY` SQL command. The * transaction classes implement a convenience function for this, called * @ref transaction_base::notify(). * * Notifications can carry an optional _payload_ string. This is free-form * text which carries additional information to the receiver. * * @warning There are a few pitfalls with the channel names: case sensitivity * and encodings. They are not too hard to avoid, but the safest thing to do * is use only lower-case ASCII names. * * * ### Case sensitivity * * Channel names are _case-sensitive._ By default, however, PostgreSQL does * convert the channel name in a `NOTIFY` or `LISTEN` command to lower-case, * to give the impression that it is _not_ case-sensitive while keeping the * performance cost low. * * Thus, a `LISTEN Hello` will pick up a notification from `NOTIFY Hello` but * also one from `NOTIFY hello`, because the database converts `Hello` into * `hello` going in either direction. * * You can prevent this conversion by putting the name in double quotes, as * @ref quote_name() does. This is what libpqxx's notification functions do. * If you use libpqxx to lisen on `Hello` but raw SQL to notify `Hello`, the * notification will not arrive because the notification actually uses the * string `hello` instead. * * Confused? Safest thing to do is to use only lower-case letters in the * channel names! * * * ### Transactions * * Both listening and notifying are _transactional_ in the backend: they * only take effect once the back-end transaction in which you do them is * committed. * * For an outgoing notification, this means that the transaction holds on to * the outgoing message until you commit. (A @ref nontransaction does not * start a backend transaction, so if that's the transaction type you're * using, the message does go out immediately.) * * For listening to incoming notifications, it gets a bit more complicated. * To avoid complicating its internal bookkeeping, libpqxx only lets you * start listening while no transaction is open. * * No notifications will come in while you're in a transaction... again * unless it's a @ref nontransaction of course, because that does not open a * transaction on the backend. * * * ### Exceptions * * If your handler throws an exception, that will simply propagate up the * call chain to wherever you were when you received it. * * This is differnt from the old `notification_receiver` mechanism which * logged exceptions but did not propagate them. * * * ### Encoding * * When a client sends a notification, it does so in its client encoding. If * necessary, the back-end converts them to its internal encoding. And then * when a client receives the notification, the database converts it to the * receiver's client encoding. * * Simple enough, right? * * However if you should _change_ your connection's client encoding after you * start listening on a channel, then any notifications you receive may have * different channel names than the ones for which you are listening. * * If this could be a problem in your scenario, stick to names in pure * ASCII. Those will look the same in all the encodings postgres supports. */ //@{ /// Check for pending notifications and take appropriate action. /** This does not block. To wait for incoming notifications, either call * @ref 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, or move on and do * other work. * * If any notifications are pending when you call this function, it * processes them by checking for a matching notification handler, and if it * finds one, invoking it. If there is no matching handler, nothing happens. * * If your notifcation handler throws an exception, `get_notifs()` will just * propagate it back to you. (This is different from the old * `notification_receiver` mechanism, which would merely log them.) * * @return Number of notifications processed. */ int get_notifs(); /// Wait for a notification to come in. /** There are other events that will also cancel the wait, such as the * backend failing. Also, _the function will wake up by itself from time to * time._ Your code must be ready to handle this; don't assume after waking * up that there will always be a pending notifiation. * * If a notification comes in, the call to this function 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 cancel the wait, such as the * backend failing, some kinds of signal coming in, 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. * * If your notifcation handler throws an exception, `get_notifs()` will just * propagate it back to you. (This is different from the old * `notification_receiver` mechanism, which would merely log them.) * * @return Number of notifications processed. */ int await_notification(std::time_t seconds, long microseconds = 0); /// A handler callback for incoming notifications on a given channel. /** Your callback must accept a @ref notification object. This object can * and will exist only for the duration of the handling of that one incoming * notification. * * The handler can be "empty," i.e. contain no code. Setting an empty * handler on a channel disables listening on that channel. */ using notification_handler = std::function; /// Attach a handler to a notification channel. /** Issues a `LISTEN` SQL command for channel `channel`, and stores `handler` * as the callback for when a notification comes in on that channel. * * The handler is a `std::function` (see @ref notification_handler), but you * can simply pass in a lambda with the right parameters, or a function, or * an object of a type you define that happens to implemnt the right function * call operator. * * Your handler probably needs to interact with your application's data; the * simple way to get that working is to pass a lambda with a closure * referencing the data items you need. * * If the handler is empty (the default), then that stops the connection * listening on the channel. It cancels your subscription, so to speak. * You can do that as many times as you like, even when you never started * listening to that channel in the first place. * * A connection can only have one handler per channel, so if you register two * different handlers on the same channel, then the second overwrites the * first. */ void listen(std::string_view channel, notification_handler handler = {}); //@} /** * @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. [[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, ".")}; bytes_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(bytes_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(bytes_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(bytes_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 // TODO: Make "into buffer" variant to eliminate a string allocation. /// Unescape binary data, e.g. from a `bytea` field. /** 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]] bytes unesc_bin(std::string_view text) const { bytes 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. std::string quote_raw(bytes_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(bytes_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(bytes_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; /// 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}); } /// Unescape binary data, e.g. from a `bytea` field. /** 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 `bytea` field. /** 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; /// Escape and quote a string of binary data. [[deprecated("Use quote(bytes_view).")]] std::string quote_raw(unsigned char const bin[], std::size_t len) 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." * * This affects the notices that the `connection` and its `result` objects * will pass to your notice handler. * * 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; // C++20: Use std::callable. /// Set a notice handler to the connection. /** When a notice comes in (a warning or error message), the connection or * result object on which it happens will call the notice handler, passing * the message as its argument. * * The handler must not throw any exceptions. If it does, the program will * terminate. * * @warning It's not just the `connection` that can call a notice handler, * but any of the `result` objects that it produces as well. So, be prepared * for the possibility that the handler may still receive a call after the * connection has been closed. */ void set_notice_handler(std::function handler) { m_notice_waiters->notice_handler = std::move(handler); } /// @deprecated Return pointers to the active errorhandlers. /** The entries are ordered from oldest to newest handler. * * 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, deprecated("Use a notice handler instead.")]] 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); } /// 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) &; /// 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); 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); /// 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 set_up_notice_handlers(); 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; 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 const &, std::string_view = ""sv); void PQXX_PRIVATE register_transaction(transaction_base *); void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept; friend struct internal::gate::connection_stream_from; /// Read a line of COPY output. /** If the output indicates that the COPY has ended, the buffer pointer * will be null and the size will be zero. Otherwise, the pointer will hold * a buffer containing the line, and size will be its length not including * the newline at the end. */ std::pair, std::size_t> 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; /// 9.0: Replace with just notice handler. std::shared_ptr m_notice_waiters; // TODO: Remove these when we retire notification_receiver. // TODO: Can we make these movable? using receiver_list = std::multimap; /// Notification receivers. receiver_list m_receivers; /// Notification handlers. /** These are the functions we call when notifications come in. Each * corresponds to a `LISTEN` we have executed. * * The map does not contain any `std::function` which are empty. If the * caller registers an empty function, that simply cancels any subscription * to that channel. */ std::map m_notification_handlers; /// 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 cx = std::move(cg).produce(); * * // At this point, cx 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 /// 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" } } // namespace pqxx #endif libpqxx-7.10.0/include/pqxx/cursor000066400000000000000000000004441473205454700171660ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/cursor.hxx000066400000000000000000000414131473205454700177750ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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. */ //@{ /// 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 constexpr difference_type all() noexcept { return (std::numeric_limits::max)() - 1; } /// 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; } /// Special value: read backwards from current position back to origin. /** @return Minimum value for result::difference_type. */ [[nodiscard]] static constexpr difference_type backward_all() noexcept { return (std::numeric_limits::min)() + 1; } //@} /// 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 libpqxx-7.10.0/include/pqxx/dbtransaction000066400000000000000000000004651473205454700205070ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/dbtransaction.hxx000066400000000000000000000052341473205454700213140ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 &cx) : transaction_base{cx} {} /// Begin transaction. dbtransaction(connection &cx, std::string_view tname) : transaction_base{cx, tname} {} /// Begin transaction. dbtransaction( connection &cx, std::string_view tname, std::shared_ptr rollback_cmd) : transaction_base{cx, tname, rollback_cmd} {} }; } // namespace pqxx #endif libpqxx-7.10.0/include/pqxx/doc/000077500000000000000000000000001473205454700164715ustar00rootroot00000000000000libpqxx-7.10.0/include/pqxx/doc/accessing-results.md000066400000000000000000000167751473205454700224710ustar00rootroot00000000000000Accessing results and result rows {#accessing-results} ================================= A query produces a result set consisting of rows, and each row consists of fields. There are several ways to receive this data. The fields are "untyped." That is to say, libpqxx has no opinion on what their types are. The database sends the data in a very flexible textual format. When you read a field, you specify what type you want it to be, and libpqxx converts the text format to that type for you. If a value does not conform to the format for the type you specify, the conversion fails. For example, if you have strings that all happen to contain numbers, you can read them as `int`. But if any of the values is empty, or it's null (for a type that doesn't support null), or it's some string that does not look like an integer, or it's too large, you can't convert it to `int`. So usually, reading result data from the database means not just retrieving the data; it also means converting it to some target type. Querying rows of data --------------------- The simplest way to query rows of data is to call one of a transaction's "query" functions, passing as template arguments the types of columns you want to get back (e.g. `int`, `std::string`, `double`, and so on) and as a regular argument the query itself. You can then iterate over the result to go over the rows of data: ```cxx for (auto [id, value] : tx.query("SELECT id, name FROM item")) { std::cout << id << '\t' << value << '\n'; } ``` The "query" functions execute your query, load the complete result data from the database, and then as you iterate, convert each row it received to a tuple of C++ types that you indicated. There are different query functions for querying any number of rows (`query()`); querying just one row of data as a `std::tuple` and throwing an error if there's more than one row (`query1()`); or querying Streaming rows -------------- There's another way to go through the rows coming out of a query. It's usually easier and faster if there are a lot of rows, 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 ](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 `pqxx::bytes_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, and often faster than with the "query" or "exec" functions: ```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. Results with metadata --------------------- Sometimes you want more from a query result than just rows of data. You may need to know right away how many rows of result data you received, or how many rows your `UPDATE` statement has affected, or the names of the columns, etc. For that, use the transaction's "exec" query execution functions. Apart from a few exceptions, these return a `pqxx::result` object. A `result` is a container of `pqxx::row` objects, so you can iterate them as normal, or index them like you would index an array. Each `row` in turn is a container of `pqxx::field`, Each `field` holds a value, but doesn't know its type. You specify the type when you read the value. For example, your code might do: ```cxx pqxx::result r = tx.exec("SELECT * FROM mytable"); 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]`. libpqxx-7.10.0/include/pqxx/doc/binary-data.md000066400000000000000000000044411473205454700212110ustar00rootroot00000000000000Binary 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 `pqxx::bytes` or `pqxx::bytes_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 `pqxx::bytes_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 `pqxx::bytes_view` from it. There are two forms of `binary_cast`. One takes a single argument that must support `std::data()` and `std::size()`: ```cxx std::string hi{"Hello binary world"}; my_blob.write(pqxx::binary_cast(hi); ``` The other takes a pointer and a size: ```cxx 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. libpqxx-7.10.0/include/pqxx/doc/datatypes.md000066400000000000000000000437471473205454700210300ustar00rootroot00000000000000Supporting additional data types {#datatypes} ================================ Communication with the database mostly happens in a text format. When you include an integer value in a query, either you use `to_string` to convert it to that text format, or under the bonnet, libpqxx does it for you. When you get a query result field "as a float," libpqxx converts from the text format to a floating-point type. These conversions are everywhere in libpqxx. The conversion system 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.** If that happens, your code may fail to compile with the newer libpqxx version, and you'll have to go through the `NEWS` file to find the API changes. Usually it'll be a small change, like an additional function you need to implement, or a constant you need to define. Converting types ---------------- In your application, a conversion is driven entirely by a C++ type you specify. The value's SQL type on the database side has nothing to do with it. Nor is there anything in the string that would identify its type. Your code says "convert to this type" and libpqxx does it. 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. Similarly, if you try to read a 32-bit SQL `int` as a C++ 32-bit `unsigned int`, that'll work fine, unless the value happens to be negative. In such cases the conversion will throw a `conversion_error`. 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 your code specifies. In some cases the templates for these conversions can tell the type from the arguments you pass them: ```cxx auto x = to_string(99); ``` In other cases you may need to instantiate template explicitly: ```cxx 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. You write out the conversion 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. First thing to do is specialise the `pqxx::type_name` variable to give the type a human-readable name. That allows libpqxx error messages and such to talk about the type. If you don't define a name, libpqxx will try to figure one out with some help from the compiler, but it may not always be easy to read. Then, does your type have a built-in null value? For example, a `char *` can be null on the C++ side. Or some types are _always_ null, such as `nullptr`. 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 the type itself. That's also why libpqxx can convert 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 automatically 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: ```cxx // T is your type. namespace pqxx { template<> std::string const type_name{"My T type's name"}; } ``` (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. There is no "null `int`" in C++. In that kind of case, just derive your nullness traits from `pqxx::no_null` as a shorthand: ```cxx // T is your type. 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: ```cxx namespace pqxx { // T is your type. template<> struct nullness { // Does T have a value that should translate to an SQL null? static constexpr bool has_null{true}; // Does this C++ type always denote an SQL null, like with nullptr_t? 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 (like in SQL, where `NULL <> NULL`). Or `T` may have multiple different null values. Or `T` may override the comparison operator to behave in some unusual way. 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 the most work. You can skip it for types that are _always_ null, but those will be rare. The APIs for doing this are designed so that you don't need to allocate memory on the free store, also known as "the heap": `new`/`delete`. Memory allocation can be hidden inside `std::string`, `std::vector`, etc. The conversion API allows you to use `std::string` for convenience, or memory buffers for speed. Start by specialising the `pqxx::string_traits` template. You don't absolutely have to implement all parts of this API. Generally, if it compilers, you're OK for the time being. Just bear in mind that future libpqxx versions may change the API — or how it uses the API internally. ```cxx namespace pqxx { // T is your type. template<> struct string_traits { // Do you support converting T to PostgreSQL string format? static constexpr bool converts_to_string{true}; // Do you support converting PostgreSQL string format to T? static constexpr bool converts_from_string{true}; // If converts_to_string is true: // Write string version into buffer, or return a constant string. static zview to_buf(char *begin, char *end, T const &value); // Write string version into buffer. static char *into_buf(char *begin, char *end, T const &value); // Converting value to string may require this much buffer space at most. static std::size_t size_buffer(T const &value) noexcept; // If converts_from_string is true: // Parse text as a T value. static T from_string(std::string_view text); }; } ``` 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 or may not be zero-terminated; it's just the `string_view` from beginning to end (with `end` being exclusive). In your tests, be sure to cover cases where the string does not end in a zero byte! It's perfectly possible that the string doesn't actually represent a `T` value. Mistakes happen. There can be corner cases. When you run into this, 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 completely 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 may work from right to left, if that's easier: they can start by writing the _least_ significant digit to the _end_ of the buffer, divide the remainder by 10, and repeat for the next digit. Return a `pqxx::zview`. This is basically a `std::string_view`, but with one difference: when you create a `zview` you _guarantee_ that there is a valid zero byte right after the `string_view`. The zero byte does not count as part of its size, but it has to be there. Expressed in code, this rule must hold: ```cxx void invariant(zview z) { assert(z[std::size(z)] == 0); } ``` The trailing zero should not go inside the `zview`, but if you convert into the buffer, do make sure you that trailing stays inside the buffer, i.e. before the `end`. (If there's no room for that zero inside the buffer, throw `pqxx::conversion_error`). Beware of locales when converting. If you use standard library features like `sprintf`, they may obey whatever locale is currently set on the system where the code runs. 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". Don't let that happen, or it will confuse things. Use only non-locale-sensitive library functions. Values coming from or going to the database should be in fixed, non-localised formats. If your conversions need to deal with fields in types that libpqxx already supports, you can use the conversion functions for those: `pqxx::from_string`, `pqxx::to_string`, `pqxx::to_buf`. They in turn will call the `string_traits` specialisations for those types. Or, you can call their `string_traits` directly. ### `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 given buffer,_ 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 another value into the rest of the buffer, they can continue writing 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 bytes of space 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 SQL arrays or composite types. If your type is like that, you can tell libpqxx about this by defining: ```cxx namespace pqxx { // T is your type. 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 pass 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 in the PostgreSQL text format, and the server then converts them into its own internal binary representation. That's what those string conversions above 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 across postgres releases, and there's no really solid way to detect when we might get the format wrong. On top of all that, 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. libpqxx-7.10.0/include/pqxx/doc/escaping.md000066400000000000000000000066711473205454700206160ustar00rootroot00000000000000String 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". Or... Well, I was born in a place called _'s-Gravenhage..._ There are two ways of dealing with this. One is statement @ref parameters — many SQL execution functions in libpqxx let you write _placeholders_ for variable values in your SQL, like `$1`, `$2`, etc. When you then pass your variables as the parameter values, they get substituted into the query, but in a safe form. The other is to _escape_ the values yourself, before inserting them into your SQL. This isn't as safe as using parameters, since you need to be really conscientious about it. Use @ref parameters if you can... and libpqxx will do the escaping for you. In escaping, quotes and other problematic characters are marked as "this is just a character inside 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: ```cxx tx.exec( "SELECT number, amount " "FROM account " "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 getting the following password: ```text 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: ```sql SELECT number, amount FROM account 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: ```cxx tx.exec( "SELECT number, amount " "FROM account " "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: ```sql SELECT number, amount FROM account 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. In practice, of course, it would be better to use parameters: ```cxx tx.exec( " SELECT number, amount " "FROM account " "WHERE allowed_to_see($1, $2)", pqxx::params{userid, password}); ``` libpqxx-7.10.0/include/pqxx/doc/getting-started.md000066400000000000000000000127701473205454700221270ustar00rootroot00000000000000Getting 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. ```cxx #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 cx; // Start a transaction. In libpqxx, you always work in one. pqxx::work tx(cx); // 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 = tx.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. tx.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: ```cxx pqxx::connection cx; pqxx::work tx(cx); pqxx::row r = tx.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. ```cxx #include #include #include int main(int argc, char *argv[]) { try { if (!argv[1]) throw std::runtime_error("Give me a string!"); pqxx::connection cx; pqxx::work tx(cx); // work::exec() returns a full result set, which can consist of any // number of rows. pqxx::result r = tx.exec("SELECT $1", pqxx::params{argv[1]}); // End our transaction here. We can still use the result afterwards. tx.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. libpqxx-7.10.0/include/pqxx/doc/mainpage.md000066400000000000000000000015511473205454700205760ustar00rootroot00000000000000libpqxx {#mainpage} ======= @version 7.10.0 @author Jeroen T. Vermeulen @see https://pqxx.org/libpqxx/ @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/](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 libpqxx-7.10.0/include/pqxx/doc/mainpage.md.template000066400000000000000000000015601473205454700224100ustar00rootroot00000000000000libpqxx {#mainpage} ======= @version @PQXXVERSION@ @author Jeroen T. Vermeulen @see https://pqxx.org/libpqxx/ @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/](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 libpqxx-7.10.0/include/pqxx/doc/parameters.md000066400000000000000000000101271473205454700211570ustar00rootroot00000000000000Statement parameters {#parameters} ==================== In an SQL statement (including a prepared statemen), you may write special _placeholders_ in the query text. They look like `$1`, `$2`, and so on. When executing the query later, you pass parameter values. The call will respectively substitute the first parameter value where it finds `$1` in the query, the second where it finds `$2`, _et cetera._ For example, let's say you have a transaction called `tx`. Here's how you execute a plain statement: ```cxx pqxx::result r = tx.exec("SELECT name FROM employee where id=101"); ``` Inserting the `101` in there is awkward and even dangerous. We'll get to that in a moment. Here's how you do it better, using parameters: ```cxx pqxx::result r = tx.exec("SELECT name FROM employee WHERE id=$1", {101}); ``` That second argument to `exec()`, the `{101}`, constructs a `pqxx::params` object. The `exec()` call will fill this value in where the query says `$1`. 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! With parameters you can pass your values as they are, 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 than the standard textual format in which the data normally gets sent to the database. 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; and the data will take up more bytes, which take time to transmit. Multiple parameters ------------------- The `pqxx::params` class is quite fleixble. It can contain any number of parameter values, of many different types. You can pass them in while constructing the `params` object: ```cxx pqxx::params{23, "acceptance", 3.14159} ``` Or you can add them one by one: ```cxx pqxx::params p; p.append(23); p.append("acceptance"); p.append(3.14159); ``` You can also combine the two, passing some values int the constructor and adding the rest later. You can even insert a `params` into a `params`: ```cxx pqxx::params p{23}; p.append(params{"acceptance", 3.14159}); ``` Each of these examples will produce the same list of parameters. 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`: ```cxx 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: ```cxx 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` ". libpqxx-7.10.0/include/pqxx/doc/performance.md000066400000000000000000000023541473205454700213200ustar00rootroot00000000000000Performance 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! libpqxx-7.10.0/include/pqxx/doc/prepared-statement.md000066400000000000000000000124551473205454700226260ustar00rootroot00000000000000Prepared 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 a lot like a function that you can define ad hoc, within the scope of one connection. If you have an SQL statement that you're going to execute many times in quick succession, it _may_ (but see below!) be more efficient to prepare it once and reuse it. This saves the database backend the effort of parsing the SQL and figuring out an efficient execution plan. Preparing a statement --------------------- You create a prepared statement by preparing it on the connection (using the `pqxx::connection::prepare` functions), passing an identifying name for the statement, and its SQL text. The statement's name 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 &cx) { cx.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, call `pqxx::transaction_base::exec()` and pass a `pqxx::prepped` object instead of an SQL statement string. The `pqxx::prepped` type is just a wrapper that tells the library "this is not SQL text, it's the name of a prepared statement." ```cxx pqxx::result execute_my_statement(pqxx::transaction_base &t) { return t.exec(pqxx::prepped{"my_statement"}); } ``` Parameters ---------- You can pass parameters to a prepared statemet, just like you can with a regular statement. 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 &cx) { // Prepare a statement called "find" that looks for employees with a // given name (parameter 1) whose salary exceeds a given number // (parameter 2). cx.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 &tx, std::string name, int min_salary) { return tx.exec(pqxx::prepped{"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. So, as with any optimisation... measure where your real performance problems are before you start making changes, and then afterwards, measure whether your changes actually helped. Don't complicate your code unless it solves a real problem. Knuth's Law applies. Zero bytes ---------- @warning Beware of zero ("nul") bytes! Since libpqxx is a wrapper around libpq, the C-level client library, most strings you pass to the library should be compatible with C-style strings. So they must end with a single byte with value 0, and the text within them cannot contain any such zero bytes. (The `pqxx::zview` type exists specifically to tell libpqxx: "this is a C-compatible string, containing no zero bytes but ending in a zero byte.") One example is prepared statement names. But the same also goes for the parameters values. 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 `pqxx::bytes`, or `pqxx::bytes_view`, or `std::vector`. libpqxx-7.10.0/include/pqxx/doc/streams.md000066400000000000000000000202461473205454700204750ustar00rootroot00000000000000Streams {#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 _data streaming_ mechanisms to help you do this more efficiently: "streaming queries," for reading query results from the database; and the @ref pqxx::stream_to class, for writing data from the client into a table. These are less flexible than SQL queries. Also, depending on your needs, it may be a problem to lose your connection while you're in mid-stream, not knowing that the query may not complete. But, you get some scalability and memory efficiencies in return. Just like regular querying, these streaming mechanisms do data conversion for you. You deal with the C++ data types, and the database deals with the SQL data types. Interlude: 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. Streaming data _from a query_ ----------------------------- Use @ref transaction_base::stream to read large amounts of data directly from the database. In terms of API it works just like @ref transaction_base::query, but it's faster than the `exec` and `query` functions For larger data sets. Also, you won't need to keep your full result set in memory. That can really matter with larger data sets. Another performance advantage is that with a streaming query, you can start processing your data right after the first row of data comes in from the server. With `exec()` or `query()` you need to wait to receive all data, and only then can you begin processing. With streaming queries you can be processing data on the client side while the server is still sending you the rest. 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 will just work, but fancier constructs may not. As you read a row, the stream converts its fields to a tuple type containing the value types you ask for: ```cxx for (auto [name, score] : tx.stream("SELECT name, points FROM score") ) process(name, score); ``` On each iteration, the stream gives you a `std::tuple` of the column types you specify. It converts the row's fields (which internally arrive at the client in text format) to your chosen types. The `auto [name, score]` in the example is a _structured binding_ which unpacks the tuple's fields into separate variables. If you prefer, you can choose to receive the tuple instead: `for (std::tuple :`. ### Is streaming right for my query? Here are the things you need to be aware of when deciding whether to stream a query, or just execute it normally. First, when you stream a query, there is no metadata describing how many rows it returned, what the columns are called, and so on. With a regular query you get a @ref result object which contains this metadata as well as the data itself. If you absolutely need this metadata for a particular query, then that means you can't stream the query. Second, under the bonnet, streaming from a query uses a PostgreSQL-specific SQL command `COPY (...) TO STDOUT`. There are some limitations on what kinds of queries this command can handle. These limitations may change over time, so I won't describe them here. Instead, see PostgreSQL's [COPY documentation](https://www.postgresql.org/docs/current/sql-copy.html) for the details. (Look for the `TO` variant, with a query as the data source.) Third: when you stream a query, you start receiving and processing data before you even know whether you will receive all of the data. If you lose your connection to the database halfway through, you will have processed half your data, unaware that the query may never execute to completion. If this is a problem for your application, don't stream that query! The fourth and final factor is performance. If you're interested in streaming, obviously you care about this one. I can't tell you _a priori_ whether streaming will make your query faster. It depends on how many rows you're retrieving, how much data there is in those rows, the speed of your network connection to the database, your client encoding, how much processing you do per row, and the details of the client-side system: hardware speed, CPU load, and available memory. Ultimately, no amount of theory beats real-world measurement for your specific situation so... if it really matters, measure. (And as per Knuth's Law: if it doesn't really matter, don't optimise.) That said, here are a few data points from some toy benchmarks: If your query returns e.g. a hundred small rows, it's not likely to make up a significant portion of your application's run time. Streaming is likely to be _slower_ than regular querying, but most likely the difference just won't amtter. If your query returns _a thousand_ small rows, streaming is probably still going to be a bit slower than regular querying, though "your mileage may vary." If you're querying _ten thousand_ small rows, however, it becomes more likely that streaming will speed it up. The advantage increases as the number of rows increases. That's for small rows, based on a test where each row consisted of just one integer number. If your query returns larger rows, with more columns, I find that streaming seems to become more attractive. In a simple test with 4 columns (two integers and two strings), streaming even just a thousand rows was considerably faster than a regular query. If your network connection to the database is slow, however, that may make streaming a bit _less_ effcient. There is a bit more communication back and forth between the client and the database to set up a stream. This overhead takes a more or less constant amount of time, so for larger data sets it will tend to become insignificant compared to the other performance costs. Streaming data _into a table_ ----------------------------- 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: ```cxx 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! libpqxx-7.10.0/include/pqxx/doc/thread-safety.md000066400000000000000000000025531473205454700215600ustar00rootroot00000000000000Thread 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. libpqxx-7.10.0/include/pqxx/errorhandler000066400000000000000000000004221473205454700203340ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/errorhandler.hxx000066400000000000000000000045451473205454700211540ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 */ //@{ /// @deprecated Base class for obsolete error-handler callbacks. /** This method of handling errors is obsolete. Use a "notice handler" * instead. * * @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: [[deprecated("Use a notice handler instead.")]] 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; }; /// @deprecated Use a notice handler instead. class quiet_errorhandler : public errorhandler { public: #include "pqxx/internal/ignore-deprecated-pre.hxx" /// Suppress error notices. [[deprecated("Use notice handlers instead.")]] quiet_errorhandler(connection &cx) : errorhandler{cx} {} #include "pqxx/internal/ignore-deprecated-post.hxx" /// Revert to previous handling of error notices. virtual bool operator()(char const[]) noexcept override { return false; } }; //@} } // namespace pqxx #endif libpqxx-7.10.0/include/pqxx/except000066400000000000000000000004451473205454700171420ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/except.hxx000066400000000000000000000550571473205454700177610ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 #if defined(PQXX_HAVE_SOURCE_LOCATION) # include #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 { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit failure( std::string const &, std::source_location = std::source_location::current()); std::source_location location; #else explicit failure(std::string const &); #endif }; /// 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() * { * std::signal(SIGPIPE, SIG_IGN); * // ... * } * ``` */ struct PQXX_LIBEXPORT broken_connection : failure { broken_connection(); explicit broken_connection( std::string const & #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); }; /// Exception class for micommunication with the server. /** This happens when the conversation between libpq and the server gets messed * up. There aren't many situations where this happens, but one known instance * is when you call a parameterised or prepared statement with th ewrong number * of parameters. * * So even though this is a `broken_connection`, it signals that retrying is * _not_ likely to make the problem go away. */ struct PQXX_LIBEXPORT protocol_violation : broken_connection { explicit protocol_violation( std::string const & #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); }; /// The caller attempted to set a variable to null, which is not allowed. struct PQXX_LIBEXPORT variable_set_to_null : failure { explicit variable_set_to_null( std::string const & #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); }; /// 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 Q = "", char const *sqlstate = nullptr #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); 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 & #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); }; /// 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 #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); }; /// 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 #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); }; /// 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 #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); }; /// 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 #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); }; /// 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 & #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); #if defined(PQXX_HAVE_SOURCE_LOCATION) std::source_location location; #endif }; /// Invalid argument passed to libpqxx, similar to std::invalid_argument struct PQXX_LIBEXPORT argument_error : std::invalid_argument { explicit argument_error( std::string const & #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); #if defined(PQXX_HAVE_SOURCE_LOCATION) std::source_location location; #endif }; /// Value conversion failed, e.g. when converting "Hello" to int. struct PQXX_LIBEXPORT conversion_error : std::domain_error { explicit conversion_error( std::string const & #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); #if defined(PQXX_HAVE_SOURCE_LOCATION) std::source_location location; #endif }; /// Could not convert null value: target type does not support null. struct PQXX_LIBEXPORT unexpected_null : conversion_error { explicit unexpected_null( std::string const & #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); }; /// Could not convert value to string: not enough buffer space. struct PQXX_LIBEXPORT conversion_overrun : conversion_error { explicit conversion_overrun( std::string const & #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); }; /// 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 & #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location = std::source_location::current() #endif ); #if defined(PQXX_HAVE_SOURCE_LOCATION) std::source_location location; #endif }; /// Query returned an unexpected number of rows. struct PQXX_LIBEXPORT unexpected_rows : public range_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit unexpected_rows( std::string const &msg, std::source_location loc = std::source_location::current()) : range_error{msg, loc} {} #else explicit unexpected_rows(std::string const &msg) : range_error{msg} {} #endif }; /// Database feature not supported in current setup. struct PQXX_LIBEXPORT feature_not_supported : sql_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit feature_not_supported( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : sql_error{err, Q, sqlstate, loc} {} #else explicit feature_not_supported( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : sql_error{err, Q, sqlstate} {} #endif }; /// Error in data provided to SQL statement. struct PQXX_LIBEXPORT data_exception : sql_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit data_exception( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : sql_error{err, Q, sqlstate, loc} {} #else explicit data_exception( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : sql_error{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT integrity_constraint_violation : sql_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit integrity_constraint_violation( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : sql_error{err, Q, sqlstate, loc} {} #else explicit integrity_constraint_violation( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : sql_error{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT restrict_violation : integrity_constraint_violation { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit restrict_violation( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : integrity_constraint_violation{err, Q, sqlstate, loc} {} #else explicit restrict_violation( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : integrity_constraint_violation{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT not_null_violation : integrity_constraint_violation { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit not_null_violation( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : integrity_constraint_violation{err, Q, sqlstate, loc} {} #else explicit not_null_violation( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : integrity_constraint_violation{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT foreign_key_violation : integrity_constraint_violation { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit foreign_key_violation( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : integrity_constraint_violation{err, Q, sqlstate, loc} {} #else explicit foreign_key_violation( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : integrity_constraint_violation{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT unique_violation : integrity_constraint_violation { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit unique_violation( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : integrity_constraint_violation{err, Q, sqlstate, loc} {} #else explicit unique_violation( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : integrity_constraint_violation{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT check_violation : integrity_constraint_violation { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit check_violation( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : integrity_constraint_violation{err, Q, sqlstate, loc} {} #else explicit check_violation( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : integrity_constraint_violation{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT invalid_cursor_state : sql_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit invalid_cursor_state( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : sql_error{err, Q, sqlstate, loc} {} #else explicit invalid_cursor_state( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : sql_error{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT invalid_sql_statement_name : sql_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit invalid_sql_statement_name( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : sql_error{err, Q, sqlstate, loc} {} #else explicit invalid_sql_statement_name( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : sql_error{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT invalid_cursor_name : sql_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit invalid_cursor_name( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : sql_error{err, Q, sqlstate, loc} {} #else explicit invalid_cursor_name( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : sql_error{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT syntax_error : sql_error { /// Approximate position in string where error occurred, or -1 if unknown. int const error_position; #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit syntax_error( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, int pos = -1, std::source_location loc = std::source_location::current()) : sql_error{err, Q, sqlstate, loc}, error_position{pos} {} #else 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} {} #endif }; struct PQXX_LIBEXPORT undefined_column : syntax_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit undefined_column( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : // TODO: Can we get the column? syntax_error{err, Q, sqlstate, -1, loc} {} #else explicit undefined_column( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : syntax_error{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT undefined_function : syntax_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit undefined_function( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : // TODO: Can we get the column? syntax_error{err, Q, sqlstate, -1, loc} {} #else explicit undefined_function( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : syntax_error{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT undefined_table : syntax_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit undefined_table( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : // TODO: Can we get the column? syntax_error{err, Q, sqlstate, -1, loc} {} #else explicit undefined_table( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : syntax_error{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT insufficient_privilege : sql_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit insufficient_privilege( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : sql_error{err, Q, sqlstate, loc} {} #else explicit insufficient_privilege( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : sql_error{err, Q, sqlstate} {} #endif }; /// Resource shortage on the server struct PQXX_LIBEXPORT insufficient_resources : sql_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit insufficient_resources( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : sql_error{err, Q, sqlstate, loc} {} #else explicit insufficient_resources( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : sql_error{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT disk_full : insufficient_resources { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit disk_full( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : insufficient_resources{err, Q, sqlstate, loc} {} #else explicit disk_full( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : insufficient_resources{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT out_of_memory : insufficient_resources { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit out_of_memory( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : insufficient_resources{err, Q, sqlstate, loc} {} #else explicit out_of_memory( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : insufficient_resources{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT too_many_connections : broken_connection { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit too_many_connections( std::string const &err, std::source_location loc = std::source_location::current()) : broken_connection{err, loc} {} #else explicit too_many_connections(std::string const &err) : broken_connection{err} {} #endif }; /// PL/pgSQL error /** Exceptions derived from this class are errors from PL/pgSQL procedures. */ struct PQXX_LIBEXPORT plpgsql_error : sql_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit plpgsql_error( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : sql_error{err, Q, sqlstate, loc} {} #else explicit plpgsql_error( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : sql_error{err, Q, sqlstate} {} #endif }; /// Exception raised in PL/pgSQL procedure struct PQXX_LIBEXPORT plpgsql_raise : plpgsql_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit plpgsql_raise( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : plpgsql_error{err, Q, sqlstate, loc} {} #else explicit plpgsql_raise( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : plpgsql_error{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT plpgsql_no_data_found : plpgsql_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit plpgsql_no_data_found( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : plpgsql_error{err, Q, sqlstate, loc} {} #else explicit plpgsql_no_data_found( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : plpgsql_error{err, Q, sqlstate} {} #endif }; struct PQXX_LIBEXPORT plpgsql_too_many_rows : plpgsql_error { #if defined(PQXX_HAVE_SOURCE_LOCATION) explicit plpgsql_too_many_rows( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr, std::source_location loc = std::source_location::current()) : plpgsql_error{err, Q, sqlstate, loc} {} #else explicit plpgsql_too_many_rows( std::string const &err, std::string const &Q = "", char const sqlstate[] = nullptr) : plpgsql_error{err, Q, sqlstate} {} #endif }; /** * @} */ } // namespace pqxx #endif libpqxx-7.10.0/include/pqxx/field000066400000000000000000000004111473205454700167260ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/field.hxx000066400000000000000000000416411473205454700175460ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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; /** * @name Comparison */ //@{ /// 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 noexcept; /// 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 * * You can read a field as any C++ type for which a conversion from * PostgreSQL's text format is defined. See @ref datatypes for how this * works. This mechanism is _weakly typed:_ the conversions do not care * what SQL type a field had in the database, only that its actual contents * convert to the target type without problems. So for instance, you can * read a `text` field as an `int`, so long as the string in the field spells * out a valid `int` number. * * Many built-in types come with conversions predefined. To find out how to * add your own, see @ref datatypes. */ //@{ /// 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 data{c_str()}; from_string(data, 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>(); } /// Read SQL array contents as a @ref pqxx::array. template array as_sql_array() const { using array_type = array; // There's no such thing as a null SQL array. if (is_null()) internal::throw_null_conversion(type_name); else return array_type{this->view(), this->m_home.m_encoding}; } /// 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. */ [[deprecated( "Avoid pqxx::array_parser. " "Instead, use as_sql_array() to convert to pqxx::array.")]] array_parser as_array() const & noexcept { return array_parser{c_str(), m_home.m_encoding}; } //@} /// 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; 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 /** @deprecated To convert a field's value string to some other type, e.g. to * an `int`, use the field's `as<...>()` member function. To read a field * efficiently just as a string, use its `c_str()` or its * `as()`. * * Works like any other istream to read data from a field. It supports all * formatting and streaming operations of `std::istream`. For convenience * there is a 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; [[deprecated("Use field::as<...>() or field::c_str().")]] basic_fieldstream( field const &f) : super{nullptr}, m_buf{f} { super::init(&m_buf); } private: field_streambuf m_buf; }; /// @deprecated Read a field using `field::as<...>()` or `field::c_str()`. using fieldstream = basic_fieldstream; /// Write a result field to any type of stream. /** @deprecated The C++ streams library is not great to work with. In * particular, error handling is easy to get wrong. So you're probably better * off doing this by hand. * * 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 [[deprecated( "Do this by hand, probably with better error checking.")]] 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 libpqxx-7.10.0/include/pqxx/internal/000077500000000000000000000000001473205454700175405ustar00rootroot00000000000000libpqxx-7.10.0/include/pqxx/internal/array-composite.hxx000066400000000000000000000263411473205454700234150ustar00rootroot00000000000000#if !defined(PQXX_ARRAY_COMPOSITE_HXX) # define PQXX_ARRAY_COMPOSITE_HXX # include # include "pqxx/internal/encodings.hxx" # include "pqxx/strconv.hxx" namespace pqxx::internal { // Find the end of a double-quoted string. /** `input[pos]` must be the opening double quote. * * The backend double-quotes strings in composites or arrays, when needed. * Special characters are escaped using backslashes. * * Returns the offset of the first position after the closing quote. */ template inline std::size_t scan_double_quoted_string( char const input[], std::size_t size, std::size_t pos) { // TODO: find_char<'"', '\\'>(). using scanner = glyph_scanner; auto next{scanner::call(input, size, pos)}; PQXX_ASSUME(next > pos); bool at_quote{false}; pos = next; next = scanner::call(input, size, pos); PQXX_ASSUME(next > pos); while (pos < size) { 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 = scanner::call(input, size, pos); PQXX_ASSUME(next > 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. } pos = next; next = scanner::call(input, size, pos); PQXX_ASSUME(next > pos); } if (not at_quote) throw argument_error{ "Missing closing double-quote: " + std::string{input}}; return pos; } // TODO: Needs version with caller-supplied buffer. /// Un-quote and un-escape a double-quoted SQL string. template inline std::string parse_double_quoted_string( char const input[], std::size_t end, std::size_t pos) { 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)); // TODO: Use find_char<...>(). using scanner = glyph_scanner; auto here{scanner::call(input, end, pos)}, next{scanner::call(input, end, here)}; PQXX_ASSUME(here > pos); PQXX_ASSUME(next > here); while (here < end - 1) { // 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 = scanner::call(input, end, here); PQXX_ASSUME(next > here); } output.append(input + here, input + next); here = next; next = scanner::call(input, end, here); PQXX_ASSUME(next > here); } 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 an array element separator (typically comma, or * 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) { using scanner = glyph_scanner; auto next{scanner::call(input, size, pos)}; PQXX_ASSUME(next > pos); while ((pos < size) and ((next - pos) > 1 or ((input[pos] != STOP) and ...))) { pos = next; next = scanner::call(input, size, pos); PQXX_ASSUME(next > pos); } return pos; } /// Parse an unquoted array entry or cfield of a composite-type field. template inline std::string_view parse_unquoted_string(char const input[], std::size_t end, std::size_t pos) { return {&input[pos], end - pos}; } /// 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, std::size_t last_field) { assert(index <= last_field); auto next{glyph_scanner::call(std::data(input), std::size(input), pos)}; PQXX_ASSUME(next > 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)}; PQXX_ASSUME(stop > pos); auto const text{ parse_double_quoted_string(std::data(input), stop, pos)}; field = from_string(text); pos = stop; } break; default: { auto const stop{scan_unquoted_string( std::data(input), std::size(input), pos)}; PQXX_ASSUME(stop >= pos); field = from_string(std::string_view{std::data(input) + pos, stop - pos}); pos = stop; } break; } // Expect a comma or a closing parenthesis. next = glyph_scanner::call(std::data(input), std::size(input), pos); PQXX_ASSUME(next > 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; } /// Pointer to an encoding-specific specialisation of parse_composite_field. template using composite_field_parser = void (*)( std::size_t &index, std::string_view input, std::size_t &pos, T &field, std::size_t last_field); /// Look up implementation of parse_composite_field for ENC. template composite_field_parser specialize_parse_composite_field(encoding_group enc) { switch (enc) { case encoding_group::MONOBYTE: return parse_composite_field; case encoding_group::BIG5: return parse_composite_field; case encoding_group::EUC_CN: return parse_composite_field; case encoding_group::EUC_JP: return parse_composite_field; case encoding_group::EUC_KR: return parse_composite_field; case encoding_group::EUC_TW: return parse_composite_field; case encoding_group::GB18030: return parse_composite_field; case encoding_group::GBK: return parse_composite_field; case encoding_group::JOHAB: return parse_composite_field; case encoding_group::MULE_INTERNAL: return parse_composite_field; case encoding_group::SJIS: return parse_composite_field; case encoding_group::UHC: return parse_composite_field; case encoding_group::UTF8: return parse_composite_field; } throw internal_error{concat("Unexpected encoding group code: ", enc, ".")}; } /// 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 libpqxx-7.10.0/include/pqxx/internal/callgate.hxx000066400000000000000000000042451473205454700220520ustar00rootroot00000000000000#ifndef PQXX_H_CALLGATE #define PQXX_H_CALLGATE /* Here's what a typical gate class definition looks like: ```cxx #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 libpqxx-7.10.0/include/pqxx/internal/concat.hxx000066400000000000000000000024741473205454700215470ustar00rootroot00000000000000#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) { auto const next = string_traits::into_buf(here, end, item) - 1; PQXX_ASSUME(next >= here); here = next; } // 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 libpqxx-7.10.0/include/pqxx/internal/conversions.hxx000066400000000000000000001122151473205454700226430ustar00rootroot00000000000000#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 SQL NULL to given type. [[noreturn]] PQXX_LIBEXPORT PQXX_COLD void throw_null_conversion(std::string const &type); /// Throw exception for attempt to convert SQL NULL to given type. [[noreturn]] PQXX_LIBEXPORT PQXX_COLD void throw_null_conversion(std::string_view 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 constexpr bool converts_to_string{false}; static constexpr bool converts_from_string{false}; 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; } // C++20: Guard with concept? /// String traits for builtin integral types (though not bool). template struct integral_traits { static constexpr bool converts_to_string{true}; static constexpr bool converts_from_string{true}; 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; } }; // C++20: Guard with concept? /// String traits for builtin floating-point types. template struct float_traits { static constexpr bool converts_to_string{true}; static constexpr bool converts_from_string{true}; 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. /** Not-a-Number values (or NaNs for short) behave a lot like an SQL null, but * they are not nulls. A non-null SQL float can be NaN. */ 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 constexpr bool converts_to_string{true}; static constexpr bool converts_from_string{true}; 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; } }; 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 constexpr bool converts_to_string{ string_traits::converts_to_string}; static constexpr bool converts_from_string{ string_traits::converts_from_string}; 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 (pqxx::is_null(value)) return {}; else return string_traits::to_buf(begin, end, *value); } 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 { if (pqxx::is_null(value)) return 0; else 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 value.valueless_by_exception() or 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 constexpr bool converts_to_string{ (string_traits::converts_to_string and ...)}; 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 { if (pqxx::is_null(value)) return 0; else 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 constexpr bool converts_to_string{false}; static constexpr bool converts_from_string{false}; static char *into_buf(char *, char *, std::nullptr_t) = delete; [[deprecated("Do not convert nulls.")]] static constexpr zview to_buf(char *, char *, std::nullptr_t const &) noexcept { return {}; } [[deprecated("Do not convert nulls.")]] 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 constexpr bool converts_to_string{false}; static constexpr bool converts_from_string{false}; static char *into_buf(char *, char *, std::nullopt_t) = delete; [[deprecated("Do not convert nulls.")]] static constexpr zview to_buf(char *, char *, std::nullopt_t const &) noexcept { return {}; } [[deprecated("Do not convert nulls.")]] 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 constexpr bool converts_to_string{false}; static constexpr bool converts_from_string{false}; static char *into_buf(char *, char *, std::monostate) = delete; [[deprecated("Do not convert nulls.")]] static constexpr zview to_buf(char *, char *, std::monostate const &) noexcept { return {}; } [[deprecated("Do not convert nulls.")]] static constexpr std::size_t size_buffer(std::monostate) noexcept { return 0; } [[deprecated("Do not convert nulls.")]] 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 constexpr bool converts_to_string{true}; static constexpr bool converts_from_string{true}; 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 { if (pqxx::is_null(value)) return 0; else 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 constexpr bool converts_to_string{true}; static constexpr bool converts_from_string{false}; 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 { if (pqxx::is_null(value)) return 0; else 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 ("pointer to 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 bool converts_to_string{true}; static constexpr bool converts_from_string{false}; 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 constexpr bool converts_to_string{true}; static constexpr bool converts_from_string{true}; 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 bool converts_to_string{true}; static constexpr bool converts_from_string{false}; 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; } static zview to_buf(char *begin, char *end, std::string_view const &value) { // You'd think we could just return the same view but alas, there's no // zero-termination on a string_view. return generic_to_buf(begin, end, value); } /// 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 bool converts_to_string{true}; static constexpr bool converts_from_string{false}; 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) { char *const stop{into_buf(begin, end, value)}; return {begin, static_cast(stop - begin - 1)}; } /// 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 constexpr bool converts_to_string{false}; static constexpr bool converts_from_string{true}; 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 constexpr bool converts_to_string{ string_traits::converts_to_string}; static constexpr bool converts_from_string{ string_traits::converts_from_string}; 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 { if (pqxx::is_null(value)) return 0; else 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 constexpr bool converts_to_string{ string_traits::converts_to_string}; static constexpr bool converts_from_string{ string_traits::converts_from_string}; 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 { if (pqxx::is_null(value)) return 0; else 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 constexpr bool converts_to_string{true}; static constexpr bool converts_from_string{true}; 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))}; bytes buf; buf.resize(size); pqxx::internal::unesc_bin(text, reinterpret_cast(buf.data())); return buf; } }; #endif // PQXX_HAVE_CONCEPTS template<> struct string_traits { static constexpr bool converts_to_string{true}; static constexpr bool converts_from_string{true}; static std::size_t size_buffer(bytes const &value) noexcept { return internal::size_esc_bin(std::size(value)); } static zview to_buf(char *begin, char *end, bytes const &value) { return generic_to_buf(begin, end, value); } static char *into_buf(char *begin, char *end, bytes 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 bytes from_string(std::string_view text) { auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; bytes buf; buf.resize(size); pqxx::internal::unesc_bin(text, reinterpret_cast(buf.data())); return buf; } }; template<> inline constexpr format param_format(bytes const &) { return format::binary; } template<> struct nullness : no_null {}; template<> struct string_traits { static constexpr bool converts_to_string{true}; static constexpr bool converts_from_string{false}; static std::size_t size_buffer(bytes_view const &value) noexcept { return internal::size_esc_bin(std::size(value)); } static zview to_buf(char *begin, char *end, bytes_view const &value) { return generic_to_buf(begin, end, value); } static char *into_buf(char *begin, char *end, bytes_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(bytes_view const &) { return format::binary; } } // namespace pqxx namespace pqxx::internal { // C++20: Use concepts to identify arrays. /// 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 constexpr bool converts_to_string{true}; static constexpr bool converts_from_string{false}; 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) { assert(begin <= end); 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)}; assert(elt_budget < static_cast(end - here)); for (char const c : elt_traits::to_buf(end - elt_budget, end, elt)) { // We copy the intermediate buffer into the final buffer, char by // char, with escaping where necessary. // TODO: This will not work for all encodings. UTF8 & ASCII are OK. 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) { // Budget for each element includes a terminating zero. // We won't actually be wanting those, but don't subtract // that one byte: we want room for a separator instead. return acc + (pqxx::is_null(elt) ? std::size(s_null) : elt_traits::size_buffer(elt)); }); 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, // and the one byte for the trailing zero becomes room // for a separator. std::size_t const elt_size{ pqxx::is_null(elt) ? std::size(s_null) : elt_traits::size_buffer(elt)}; 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}; #if defined(PQXX_HAVE_SPAN) && __has_include() template struct nullness> : no_null> {}; template struct string_traits> : internal::array_string_traits> {}; template inline constexpr format param_format(std::span const &) { return format::text; } template inline constexpr format param_format(std::span const &) { return format::binary; } template inline constexpr bool is_sql_array>{true}; #endif 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 " + std::string{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 libpqxx-7.10.0/include/pqxx/internal/encoding_group.hxx000066400000000000000000000042271473205454700233000ustar00rootroot00000000000000/** Enum type for supporting encodings in libpqxx * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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, EUC_JP, EUC_KR, EUC_TW, GB18030, GBK, JOHAB, MULE_INTERNAL, SJIS, UHC, UTF8, }; // TODO: Get rid of these. Specialise at higher level. /// 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); /// Function type: "find first occurrence of specific any of ASCII characters." /** This type of function takes a text buffer, and a location in that buffer, * and returns the location of the first occurrence within that string of any * of a specific set of ASCII characters. * * For efficiency, it's up to the function to know which those special ASCII * characters are. * * The start offset marks the beginning of the current glyph. It must fall * within the buffer. * * Returns the offset of the first matching character, or if there is none, the * end of `haystack`. */ using char_finder_func = std::size_t(std::string_view haystack, std::size_t start); } // namespace pqxx::internal #endif libpqxx-7.10.0/include/pqxx/internal/encodings.hxx000066400000000000000000000646161473205454700222570ustar00rootroot00000000000000/** Internal string encodings support for libpqxx * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 #include #include #include "pqxx/internal/concat.hxx" #include "pqxx/internal/encoding_group.hxx" namespace pqxx { PQXX_DECLARE_ENUM_CONVERSION(pqxx::internal::encoding_group); } // namespace pqxx namespace pqxx::internal { /// Return PostgreSQL's name for encoding enum value. PQXX_PURE char const *name_encoding(int encoding_id); /// Convert libpq encoding enum value to its libpqxx group. PQXX_LIBEXPORT encoding_group enc_group(int /* libpq encoding ID */); /// 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: Get rid of this one. Use compile-time-specialised version instead. /// 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)}; PQXX_ASSUME(next > 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; } // TODO: Get rid of this one. Use compile-time-specialised loop instead. /// 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); PQXX_ASSUME(next > here); callback(buffer + here, buffer + next); } } 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]] PQXX_COLD 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; } } // namespace /// Wrapper struct template for "find next glyph" functions. /** When we use this, all we really want is a function pointer. But that * won't work, because the template specialisation we use will only work (under * current C++ rules) for a struct or class, not for a function. */ template struct glyph_scanner { // TODO: Convert to use string_view? /// Find the next glyph in `buffer` after position `start`. PQXX_PURE static std::size_t call(char const buffer[], std::size_t buffer_len, std::size_t start); }; namespace { /// Find any of the ASCII characters in `NEEDLE` in `haystack`. /** Scans through `haystack` until it finds a single-byte character that * matches any of the values in `NEEDLE`. * * Returns the offset of the character it finds, or the end of the `haystack` * otherwise. */ template PQXX_PURE inline std::size_t find_ascii_char(std::string_view haystack, std::size_t here) { // We only know how to search for ASCII characters. It's an optimisation // assumption in the code below. static_assert((... and ((NEEDLE & 0x80) == 0))); auto const sz{std::size(haystack)}; auto const data{std::data(haystack)}; while (here < sz) { // Look up the next character boundary. This can be quite costly, so we // desperately want the call inlined. auto next{glyph_scanner::call(data, sz, here)}; PQXX_ASSUME(next > here); // (For some reason gcc had a problem with a right-fold here. But clang // was fine.) // // In all supported encodings, if a character's first byte is in the ASCII // range, that means it's a single-byte character. It follows that when we // find a match, we do not need to check that we're in a single-byte // character: // // If this is an "ASCII-unsafe" encoding, e.g. SJIS, we're only checking // each character's first byte. That first byte can only match NEEDLE if // it's a single-byte character. // // In an "ASCII-safe" encoding, e.g. UTF-8 or the ISO-8859 ones, we check // for a match at each byte in the text, because it's faster than finding // character boundaries first. But in these encodings, a multichar byte // never contains any bytes in the ASCII range at all. if ((... or (data[here] == NEEDLE))) return here; // Nope, no hit. Move on. here = next; } return sz; } } // namespace /// Find first of `NEEDLE` ASCII chars in `haystack`. /** @warning This assumes that one of the `NEEDLE` characters is actually * present. It does not check for buffer overruns, so make sure that there's * a sentinel. */ template PQXX_PURE std::size_t find_s_ascii_char(std::string_view haystack, std::size_t here) { // We only know how to search for ASCII characters. It's an optimisation // assumption in the code below. static_assert((... and ((NEEDLE >> 7) == 0))); auto const sz{std::size(haystack)}; auto const data{std::data(haystack)}; // No supported encoding has multibyte characters that start with an // ASCII-range byte. while ((... and (data[here] != NEEDLE))) { auto const next = glyph_scanner::call(data, sz, here); PQXX_ASSUME(next > here); here = next; } return here; } template<> struct glyph_scanner { static PQXX_PURE constexpr std::size_t call(char const /* buffer */[], std::size_t buffer_len, std::size_t start) { // TODO: Don't bother with npos. Let the caller check. if (start >= buffer_len) PQXX_UNLIKELY return std::string::npos; else return start + 1; } }; // https://en.wikipedia.org/wiki/Big5#Organization template<> struct glyph_scanner { static PQXX_PURE std::size_t 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 (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<> struct glyph_scanner { static PQXX_PURE std::size_t 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; } }; // 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 template<> struct glyph_scanner { static PQXX_PURE std::size_t 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("EUC_JP", 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("EUC_JP", 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("EUC_JP", 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("EUC_JP", buffer, start, 3); return start + 3; } throw_for_encoding_error("EUC_JP", buffer, start, 1); } }; // https://en.wikipedia.org/wiki/Extended_Unix_Code#EUC-KR template<> struct glyph_scanner { static PQXX_PURE std::size_t 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 (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<> struct glyph_scanner { static PQXX_PURE std::size_t 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<> struct glyph_scanner { static PQXX_PURE std::size_t 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 (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<> struct glyph_scanner { static PQXX_PURE std::size_t 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("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<> struct glyph_scanner { static PQXX_PURE std::size_t 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("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<> struct glyph_scanner { static PQXX_PURE std::size_t 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("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); } }; // 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 template<> struct glyph_scanner { static PQXX_PURE std::size_t 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 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("SJIS", buffer, start, 1); if (start + 2 > buffer_len) PQXX_UNLIKELY throw_for_encoding_error("SJIS", buffer, start, buffer_len - start); auto const byte2{get_byte(buffer, start + 1)}; if (byte2 == 0x7f) PQXX_UNLIKELY throw_for_encoding_error("SJIS", buffer, start, 2); if (between_inc(byte2, 0x40, 0x9e) or between_inc(byte2, 0x9f, 0xfc)) return start + 2; PQXX_UNLIKELY throw_for_encoding_error("SJIS", buffer, start, 2); } }; // https://en.wikipedia.org/wiki/Unified_Hangul_Code template<> struct glyph_scanner { static PQXX_PURE std::size_t 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("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<> struct glyph_scanner { static PQXX_PURE std::size_t 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("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); } }; /// Just for searching an ASCII character, what encoding can we use here? /** Maps an encoding group to an encoding group that we can apply for the * specific purpose of looking for a given ASCII character. * * The "difficult" encoding groups will map to themselves. But the ones that * work like "ASCII supersets" have the wonderful property that even a * multibyte character cannot contain a byte that happens to be in the ASCII * range. This holds for the single-byte encodings, for example, but also for * UTF-8. * * For those encodings, we can just pretend that we're dealing with a * single-byte encoding and scan byte-by-byte until we find a byte with the * value we're looking for. We don't actually need to know where the * boundaries between the characters are. */ constexpr inline encoding_group map_ascii_search_group(encoding_group enc) noexcept { switch (enc) { case encoding_group::MONOBYTE: case encoding_group::EUC_CN: case encoding_group::EUC_JP: case encoding_group::EUC_KR: case encoding_group::EUC_TW: case encoding_group::MULE_INTERNAL: case encoding_group::UTF8: // All these encodings are "ASCII-safe," meaning that if we're looking // for a particular ASCII character, we can safely just go through the // string byte for byte. Multibyte characters have the high bit set. return encoding_group::MONOBYTE; default: PQXX_UNLIKELY return enc; } } /// Look up a character search function for an encoding group. /** We only define a few individual instantiations of this function, as needed. * * Returns a pointer to a function which looks for the first instance of any of * the ASCII characters in `NEEDLE`. Returns its offset, or the end of the * `haystack` if it found none. */ template PQXX_PURE constexpr inline char_finder_func * get_char_finder(encoding_group enc) { auto const as_if{map_ascii_search_group(enc)}; switch (as_if) { case encoding_group::MONOBYTE: return pqxx::internal::find_ascii_char< encoding_group::MONOBYTE, NEEDLE...>; case encoding_group::BIG5: return pqxx::internal::find_ascii_char; case encoding_group::GB18030: return pqxx::internal::find_ascii_char; case encoding_group::GBK: return pqxx::internal::find_ascii_char; case encoding_group::JOHAB: return pqxx::internal::find_ascii_char; case encoding_group::SJIS: return pqxx::internal::find_ascii_char; case encoding_group::UHC: return pqxx::internal::find_ascii_char; default: throw pqxx::internal_error{concat( "Unexpected encoding group: ", as_if, " (mapped from ", enc, ").")}; } } /// Look up a "sentry" character search function for an encoding group. /** This version returns a finder function that does not check buffer bounds. * It just assumes that one of the `NEEDLE` characters will be there. */ template PQXX_PURE constexpr inline char_finder_func * get_s_char_finder(encoding_group enc) { auto const as_if{map_ascii_search_group(enc)}; switch (as_if) { case encoding_group::MONOBYTE: return pqxx::internal::find_s_ascii_char< encoding_group::MONOBYTE, NEEDLE...>; case encoding_group::BIG5: return pqxx::internal::find_s_ascii_char; case encoding_group::GB18030: return pqxx::internal::find_s_ascii_char< encoding_group::GB18030, NEEDLE...>; case encoding_group::GBK: return pqxx::internal::find_s_ascii_char; case encoding_group::JOHAB: return pqxx::internal::find_s_ascii_char; case encoding_group::SJIS: return pqxx::internal::find_s_ascii_char; case encoding_group::UHC: return pqxx::internal::find_s_ascii_char; default: throw pqxx::internal_error{concat( "Unexpected encoding group: ", as_if, " (mapped from ", enc, ").")}; } } } // namespace pqxx::internal #endif libpqxx-7.10.0/include/pqxx/internal/gates/000077500000000000000000000000001473205454700206435ustar00rootroot00000000000000libpqxx-7.10.0/include/pqxx/internal/gates/connection-errorhandler.hxx000066400000000000000000000010231473205454700262140ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/internal/gates/connection-largeobject.hxx000066400000000000000000000014001473205454700260050ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/internal/gates/connection-notification_receiver.hxx000066400000000000000000000011121473205454700300760ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/internal/gates/connection-pipeline.hxx000066400000000000000000000014121473205454700253340ustar00rootroot00000000000000#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(); } auto get_notice_waiters() const { return home().m_notice_waiters; } }; } // namespace pqxx::internal::gate libpqxx-7.10.0/include/pqxx/internal/gates/connection-sql_cursor.hxx000066400000000000000000000006031473205454700257240ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/internal/gates/connection-stream_from.hxx000066400000000000000000000010241473205454700260440ustar00rootroot00000000000000#if !defined(PQXX_H_CONNECTION_STREAM_FROM) # define PQXX_H_CONNECTION_STREAM_FROM # include # include "pqxx/connection.hxx" namespace pqxx::internal::gate { // Not publicising this call gate to specific classes. We also use it in // stream_query, which is a template. struct PQXX_PRIVATE connection_stream_from : callgate { connection_stream_from(reference x) : super{x} {} auto read_copy_line() { return home().read_copy_line(); } }; } // namespace pqxx::internal::gate #endif libpqxx-7.10.0/include/pqxx/internal/gates/connection-stream_to.hxx000066400000000000000000000006511473205454700255300ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/internal/gates/connection-transaction.hxx000066400000000000000000000021131473205454700260530ustar00rootroot00000000000000#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(std::string_view statement, internal::c_params const &args) { return home().exec_prepared(statement, args); } result exec_params(std::string_view query, internal::c_params const &args) { return home().exec_params(query, args); } }; } // namespace pqxx::internal::gate libpqxx-7.10.0/include/pqxx/internal/gates/errorhandler-connection.hxx000066400000000000000000000005031473205454700262160ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx000066400000000000000000000012321473205454700276710ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx000066400000000000000000000013561473205454700277000ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/internal/gates/result-connection.hxx000066400000000000000000000005421473205454700250500ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/internal/gates/result-creation.hxx000066400000000000000000000012241473205454700245130ustar00rootroot00000000000000#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( std::shared_ptr rhs, std::shared_ptr const &query, std::shared_ptr ¬ice_waiters, encoding_group enc) { return result(rhs, query, notice_waiters, enc); } void check_status(std::string_view desc = ""sv) const { return home().check_status(desc); } }; } // namespace pqxx::internal::gate libpqxx-7.10.0/include/pqxx/internal/gates/result-pipeline.hxx000066400000000000000000000005311473205454700245140ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/internal/gates/result-sql_cursor.hxx000066400000000000000000000005251473205454700251060ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/internal/gates/transaction-sql_cursor.hxx000066400000000000000000000004271473205454700261160ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/internal/gates/transaction-transaction_focus.hxx000066400000000000000000000013301473205454700274400ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/internal/header-post.hxx000066400000000000000000000013031473205454700225010ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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 libpqxx-7.10.0/include/pqxx/internal/header-pre.hxx000066400000000000000000000130661473205454700223130ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did not receive a file called * COPYING with this source code, please notify the distributor of this * mistake, or contact the author. */ #if __has_include() # include #endif // 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" // MSVC has a nonstandard definition of __cplusplus. #if defined(_MSC_VER) # define PQXX_CPLUSPLUS _MSVC_LANG #else # define PQXX_CPLUSPLUS __cplusplus #endif // C++20: No longer needed. // Enable ISO-646 alternative operaotr representations: "and" instead of "&&" // etc. on older compilers. C++20 removes this header. #if PQXX_CPLUSPLUS <= 201703L && __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 // C++23: Assume support. #if defined(PQXX_HAVE_ASSUME) # define PQXX_ASSUME(condition) [[assume(condition)]] #else # define PQXX_ASSUME(condition) while (false) #endif libpqxx-7.10.0/include/pqxx/internal/ignore-deprecated-post.hxx000066400000000000000000000005101473205454700246310ustar00rootroot00000000000000/// 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 libpqxx-7.10.0/include/pqxx/internal/ignore-deprecated-pre.hxx000066400000000000000000000016351473205454700244430ustar00rootroot00000000000000/** 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 libpqxx-7.10.0/include/pqxx/internal/libpq-forward.hxx000066400000000000000000000016061473205454700230450ustar00rootroot00000000000000/** Minimal forward declarations of libpq types needed in libpqxx headers. * * DO NOT INCLUDE THIS FILE when building client programs. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did not receive a file called * COPYING with this source code, please notify the distributor of this * mistake, or contact the author. */ #if !defined(PQXX_H_LIBPQ_FORWARD) # define PQXX_H_LIBPQ_FORWARD 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 #endif libpqxx-7.10.0/include/pqxx/internal/result_iter.hxx000066400000000000000000000053411473205454700226350ustar00rootroot00000000000000/** Result loops. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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} { m_home.expect_columns(sizeof...(TYPE)); } 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 libpqxx-7.10.0/include/pqxx/internal/result_iterator.hxx000066400000000000000000000244511473205454700235260ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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: // TODO: Change operator[] so this becomes a proper random_access_iterator. using iterator_category = std::bidirectional_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 pqxx::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; // TODO: Replace with standard operator[]: i[n] == *(i + n). 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; // TODO: Replace with standard operator[]: i[n] == *(i + n). 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 libpqxx-7.10.0/include/pqxx/internal/sql_cursor.hxx000066400000000000000000000073031473205454700224700ustar00rootroot00000000000000/** 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 stateless_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; /// 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 libpqxx-7.10.0/include/pqxx/internal/statement_parameters.hxx000066400000000000000000000071141473205454700245230ustar00rootroot00000000000000/** 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 "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; }}; /// @deprecated Use @ref params instead. 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 libpqxx-7.10.0/include/pqxx/internal/stream_iterator.hxx000066400000000000000000000042411473205454700234760ustar00rootroot00000000000000/** Stream iterators. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 { template class stream_query; } namespace pqxx::internal { // C++20: Replace with generator? /// Input iterator for stream_from. /** Just barely enough to support range-based "for" loops on stream_from. * Don't assume that any of the usual behaviour works beyond that. */ template class stream_from_input_iterator { using stream_t = stream_from; public: using value_type = std::tuple; /// Construct an "end" iterator. stream_from_input_iterator() = default; explicit stream_from_input_iterator(stream_t &home) : m_home(&home) { advance(); } stream_from_input_iterator(stream_from_input_iterator const &) = default; stream_from_input_iterator &operator++() { advance(); return *this; } value_type const &operator*() const { return m_value; } /// Comparison only works for comparing to end(). bool operator==(stream_from_input_iterator const &rhs) const { return m_home == rhs.m_home; } /// Comparison only works for comparing to end(). bool operator!=(stream_from_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_t *m_home{nullptr}; value_type m_value; }; // C++20: Replace with generator? /// Iteration over a @ref stream_query. template class stream_input_iteration { public: using stream_t = stream_from; using iterator = stream_from_input_iterator; explicit stream_input_iteration(stream_t &home) : m_home{home} {} iterator begin() const { return iterator{m_home}; } iterator end() const { return {}; } private: stream_t &m_home; }; } // namespace pqxx::internal #endif libpqxx-7.10.0/include/pqxx/internal/stream_query.hxx000066400000000000000000000253001473205454700230110ustar00rootroot00000000000000/* Definition of the pqxx::internal::stream_query class. * * Enables optimized batch reads from a database table. * * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_query instead. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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_QUERY #define PQXX_H_STREAM_QUERY #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/encodings.hxx" #include "pqxx/internal/gates/connection-stream_from.hxx" #include "pqxx/internal/stream_iterator.hxx" #include "pqxx/separated_list.hxx" #include "pqxx/transaction_base.hxx" #include "pqxx/transaction_focus.hxx" #include "pqxx/util.hxx" namespace pqxx { class transaction_base; } // namespace pqxx namespace pqxx::internal { /// The `end()` iterator for a `stream_query`. class stream_query_end_iterator {}; // C++20: Can we use generators, and maybe get speedup from HALO? /// Stream query results from the database. Used by transaction_base::stream. /** 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. * (For smaller result sets though, a stream is likely to be a bit slower.) * * A `stream_query` stream is strongly typed. You specify the columns' types * while instantiating the stream_query template. * * Not all kinds of query will work in a stream. But straightforward `SELECT` * and `UPDATE ... RETURNING` queries should work. The class uses PostgreSQL's * `COPY` command, so see the documentation for that command to get the full * details. * * There are other downsides. If the 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. * * 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. */ template class stream_query : transaction_focus { public: using line_handle = std::unique_ptr; /// Execute `query` on `tx`, stream results. inline stream_query(transaction_base &tx, std::string_view query); /// Execute `query` on `tx`, stream results. inline stream_query( transaction_base &tx, std::string_view query, params const &); stream_query(stream_query &&) = delete; stream_query &operator=(stream_query &&) = delete; ~stream_query() noexcept { try { close(); } catch (std::exception const &e) { reg_pending_error(e.what()); } } /// Has this stream reached the end of its data? bool done() const & noexcept { return m_char_finder == nullptr; } /// Begin iterator. Only for use by "range for." inline auto begin() &; /// End iterator. Only for use by "range for." /** The end iterator is a different type than the regular iterator. It * simplifies the comparisons: we know at compile time that we're comparing * to the end pointer. */ auto end() const & { return stream_query_end_iterator{}; } /// Parse and convert the latest line of data we received. std::tuple parse_line(zview line) & { assert(not done()); auto const line_size{std::size(line)}; // This function uses m_row as a buffer, across calls. The only reason for // it to carry over across calls is to avoid reallocation. // 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); std::size_t offset{0u}; char *write{m_row.data()}; // DO NOT shrink m_row to fit. We're carrying views pointing into the // buffer. (Also, how useful would shrinking really be?) // Folding expression: scan and unescape each field, and convert it to its // requested type. std::tuple data{parse_field(line, offset, write)...}; assert(offset == line_size + 1u); return data; } /// Read a COPY line from the server. std::pair read_line() &; private: /// Look up a char_finder_func. /** This is the only encoding-dependent code in the class. All we need to * store after that is this function pointer. */ static inline char_finder_func *get_finder(transaction_base const &tx); /// Scan and unescape a field into the row buffer. /** The row buffer is `m_row`. * * @param line The line of COPY output. * @param offset The current scanning position inside `line`. * @param write The current writing position in the row buffer. * * @return new `offset`; new `write`; and a zview on the unescaped * field text in the row buffer. * * The zview's data pointer will be nullptr for a null field. * * After reading the final field in a row, if all goes well, offset should be * one greater than the size of the line, pointing at the terminating zero. */ std::tuple read_field(zview line, std::size_t offset, char *write) { #if !defined(NDEBUG) auto const line_size{std::size(line)}; #endif assert(offset <= line_size); char const *lp{std::data(line)}; // The COPY line now ends in a tab. (We replace the trailing newline with // that to simplify the loop here.) assert(lp[line_size] == '\t'); assert(lp[line_size + 1] == '\0'); if ((lp[offset] == '\\') and (lp[offset + 1] == 'N')) { // Null field. Consume the "\N" and the field separator. offset += 3; assert(offset <= (line_size + 1)); assert(lp[offset - 1] == '\t'); // Return a null value. There's nothing to write into m_row. return {offset, write, {}}; } // Beginning of the field text in the row buffer. char const *const field_begin{write}; // We're relying on several assumptions just for making the main loop // condition work: // * The COPY line ends in a newline. // * Multibyte characters never start with an ASCII-range byte. // * We can index a view beyond its bounds (but within its address space). // // Effectively, the newline acts as a final field separator. while (lp[offset] != '\t') { assert(lp[offset] != '\0'); // Beginning of the next character of interest (or the end of the line). auto const stop_char{m_char_finder(line, offset)}; PQXX_ASSUME(stop_char > offset); assert(stop_char < (line_size + 1)); // Copy the text we have so far. It's got no special characters in it. std::memcpy(write, &lp[offset], stop_char - offset); write += (stop_char - offset); offset = stop_char; // We're still within the line. char const special{lp[offset]}; if (special == '\\') { // Escape sequence. // Consume the backslash. ++offset; assert(offset < line_size); // The database will only escape ASCII characters, so we assume that // we're dealing with a single-byte character. char const escaped{lp[offset]}; assert((escaped >> 7) == 0); ++offset; *write++ = unescape_char(escaped); } else { // Field separator. Fall out of the loop. assert(special == '\t'); } } // Hit the end of the field. assert(lp[offset] == '\t'); *write = '\0'; ++write; ++offset; return {offset, write, {field_begin, write - field_begin - 1}}; } /// Parse the next field. /** Unescapes the field into the row buffer (m_row), and converts it to its * TARGET type. * * Using non-const reference parameters here, so we can propagate side * effects across a fold expression. * * @param line The latest COPY line. * @param offset The current parsing offset in `line`. The function will * update this value. * @param write The current writing position in the row buffer. The * function will update this value. * @return Field value converted to TARGET type. */ template TARGET parse_field(zview line, std::size_t &offset, char *&write) { using field_type = strip_t; using nullity = nullness; assert(offset <= std::size(line)); auto [new_offset, new_write, text]{read_field(line, offset, write)}; PQXX_ASSUME(new_offset > offset); PQXX_ASSUME(new_write >= write); offset = new_offset; write = new_write; if constexpr (nullity::always_null) { if (std::data(text) != nullptr) throw conversion_error{concat( "Streaming a non-null value into a ", type_name, ", which must always be null.")}; } else if (std::data(text) == nullptr) { if constexpr (nullity::has_null) return nullity::null(); else internal::throw_null_conversion(type_name); } else { // Don't ever try to convert a non-null value to nullptr_t! return from_string(text); } } /// If this stream isn't already closed, close it now. void close() noexcept { if (not done()) { m_char_finder = nullptr; unregister_me(); } } /// Callback for finding next special character (or end of line). /** This pointer doubles as an indication that we're done. We set it to * nullptr when the iteration is finished, and that's how we can know that * there are no more rows to be iterated. */ char_finder_func *m_char_finder; /// Current row's fields' text, combined into one reusable string. /** We carry this buffer over from one invocation to the next, not because we * need the data, but just so we can re-use the space. It saves us having to * re-allocate it every time. */ std::string m_row; }; } // namespace pqxx::internal #endif libpqxx-7.10.0/include/pqxx/internal/stream_query_impl.hxx000066400000000000000000000121271473205454700240350ustar00rootroot00000000000000/* Code for parts of pqxx::internal::stream_query. * * These definitions needs to be in a separate file in order to iron out * circular dependencies between headers. */ #if !defined(PQXX_H_STREAM_QUERY_IMPL) # define PQXX_H_STREAM_QUERY_IMPL namespace pqxx::internal { template inline stream_query::stream_query( transaction_base &tx, std::string_view query) : transaction_focus{tx, "stream_query"}, m_char_finder{get_finder(tx)} { auto const r{tx.exec(internal::concat("COPY (", query, ") TO STDOUT"))}; r.expect_columns(sizeof...(TYPE)); r.expect_rows(0); register_me(); } template inline stream_query::stream_query( transaction_base &tx, std::string_view query, params const &parms) : transaction_focus{tx, "stream_query"}, m_char_finder{get_finder(tx)} { auto const r{tx.exec(internal::concat("COPY (", query, ") TO STDOUT"), parms) .no_rows()}; if (r.columns() != sizeof...(TYPE)) throw usage_error{concat( "Parsing query stream with wrong number of columns: " "code expects ", sizeof...(TYPE), " but query returns ", r.columns(), ".")}; register_me(); } template inline char_finder_func * stream_query::get_finder(transaction_base const &tx) { auto const group{enc_group(tx.conn().encoding_id())}; return get_s_char_finder<'\t', '\\'>(group); } // C++20: Replace with generator? Could be faster (local vars vs. members). /// Input iterator for stream_query. /** Just barely enough to support range-based "for" loops on stream_from. * Don't assume that any of the usual behaviour works beyond that. */ template class stream_query_input_iterator { using stream_t = stream_query; public: using value_type = std::tuple; using difference_type = long; explicit stream_query_input_iterator(stream_t &home) : m_home(&home), m_line{typename stream_query::line_handle( nullptr, pqxx::internal::pq::pqfreemem)} { consume_line(); } stream_query_input_iterator(stream_query_input_iterator const &) = default; stream_query_input_iterator(stream_query_input_iterator &&) = default; /// Pre-increment. This is what you'd normally want to use. stream_query_input_iterator &operator++() & { assert(not done()); consume_line(); return *this; } /// Post-increment. Only here to satisfy input_iterator concept. /** The iterator that this returns is in an unusable state. */ stream_query_input_iterator operator++(int) { ++*this; return {}; } /// Dereference. There's no caching in here, so don't repeat calls. value_type operator*() const { return m_home->parse_line(zview{m_line.get(), m_line_size}); } /// Are we at the end? bool operator==(stream_query_end_iterator) const noexcept { return done(); } /// Comparison only works for comparing to end(). bool operator!=(stream_query_end_iterator) const noexcept { return not done(); } stream_query_input_iterator & operator=(stream_query_input_iterator &&rhs) noexcept { if (&rhs != this) { m_line = std::move(rhs.m_line); m_home = rhs.m_home; m_line_size = rhs.m_line_size; } return *this; } private: stream_query_input_iterator() {} /// Have we finished? bool done() const noexcept { return m_home->done(); } /// Read a line from the stream, store it in the iterator. /** Replaces the newline at the end with a tab, as a sentinel to simplify * (and thus hopefully speed up) the field parsing loop. */ void consume_line() & { auto [line, size]{m_home->read_line()}; m_line = std::move(line); m_line_size = size; if (m_line) { // We know how many fields to expect. Replace the newline at the end // with the field separator, so the parsing loop only needs to scan for a // tab, not a tab or a newline. char *const ptr{m_line.get()}; assert(ptr[size] == '\n'); ptr[size] = '\t'; } } stream_t *m_home; /// Last COPY line we read, allocated by libpq. typename stream_t::line_handle m_line; /// Length of the last COPY line we read. std::size_t m_line_size; }; template inline bool operator==( stream_query_end_iterator, stream_query_input_iterator const &i) { return i.done(); } template inline bool operator!=( stream_query_end_iterator, stream_query_input_iterator const &i) { return not i.done(); } template inline auto stream_query::begin() & { return stream_query_input_iterator{*this}; } template inline std::pair::line_handle, std::size_t> stream_query::read_line() & { assert(not done()); internal::gate::connection_stream_from gate{m_trans->conn()}; try { auto line{gate.read_copy_line()}; // Check for completion. if (not line.first) PQXX_UNLIKELY close(); return line; } catch (std::exception const &) { close(); throw; } } } // namespace pqxx::internal #endif libpqxx-7.10.0/include/pqxx/internal/wait.hxx000066400000000000000000000010111473205454700212260ustar00rootroot00000000000000#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 libpqxx-7.10.0/include/pqxx/isolation000066400000000000000000000004471473205454700176550ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/isolation.hxx000066400000000000000000000052651473205454700204660ustar00rootroot00000000000000/* Definitions for transaction isolation levels, and such. * * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/isolation instead. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 libpqxx-7.10.0/include/pqxx/largeobject000066400000000000000000000004541473205454700201330ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/largeobject.hxx000066400000000000000000000565041473205454700207500ustar00rootroot00000000000000/* Large Objects interface. Deprecated; use blob instead. * * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 libpqxx-7.10.0/include/pqxx/nontransaction000066400000000000000000000004521473205454700207100ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/nontransaction.hxx000066400000000000000000000060471473205454700215240ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 as far as the database is concerned. * Just like other transaction types, however, the nontransaction remains * attached to the @ref pqxx::connection until you commit, abort, or destroy * it. Just like a regular transaction, it is a @ref transaction_focus, of * which no more than one can be active for any given connection at any given * time. * * 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 cx 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 &cx, std::string_view tname = ""sv) : transaction_base{cx, tname, std::shared_ptr{}} { register_transaction(); } virtual ~nontransaction() override { close(); } private: virtual void do_commit() override {} }; } // namespace pqxx #endif libpqxx-7.10.0/include/pqxx/notification000066400000000000000000000004671473205454700203440ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/notification.hxx000066400000000000000000000073351473205454700211530ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 cx Connnection to operate on. * @param channel Name of the notification to listen for. */ [[deprecated("Use pqxx::connection::listen() instead.")]] notification_receiver(connection &cx, std::string_view channel); /// Register the receiver with a connection. [[deprecated("Use pqxx::connection::listen() instead.")]] notification_receiver(notification_receiver const &) = delete; /// Register the receiver with a connection. [[deprecated("Use pqxx::connection::listen() instead.")]] 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; } /// 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 libpqxx-7.10.0/include/pqxx/params000066400000000000000000000004671473205454700171410ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/params.hxx000066400000000000000000000246351473205454700177520ustar00rootroot00000000000000/* Helpers for prepared statements and parameterised statements. * * See @ref connection and @ref transaction_base for more. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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" namespace pqxx { /// Build a parameter list for a parameterised or prepared statement. /** When calling a parameterised statement or a prepared statement, in many * cases you can pass parameters into the statement in the form of a * `pqxx::params` object. */ 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(bytes_view) &; /// Append a non-null binary parameter. /** Copies the underlying data into internal storage. For best efficiency, * use the `pqxx::bytes_view` variant if you can, or `std::move()`. */ void append(bytes 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(bytes_view{std::data(data), std::size(data)}); } #endif // PQXX_HAVE_CONCEPTS /// Append a non-null binary parameter. void append(bytes &&) &; /// @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::vector m_params; static constexpr std::string_view s_overflow{ "Statement parameter length overflow."sv}; }; /// 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, ".")}; PQXX_ASSUME(m_current > 0); ++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; }; } // namespace pqxx /// @deprecated The new @ref params class replaces all of this. namespace pqxx::prepare { /// @deprecated Use @ref params instead. template [[deprecated("Use the params class instead.")]] constexpr inline auto make_dynamic_params(IT begin, IT end) { return pqxx::internal::dynamic_params(begin, end); } /// @deprecated Use @ref params instead. 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" } /// @deprecated Use @ref params instead. 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 #endif libpqxx-7.10.0/include/pqxx/pipeline000066400000000000000000000004041473205454700174520ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/pipeline.hxx000066400000000000000000000174551473205454700202760ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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; pipeline(pipeline &&) = delete; pipeline &operator=(pipeline &&) = 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 libpqxx-7.10.0/include/pqxx/pqxx000066400000000000000000000016331473205454700166520ustar00rootroot00000000000000/// 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/range.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/time.hxx" #include "pqxx/transaction.hxx" #include "pqxx/transactor.hxx" #include "pqxx/internal/header-post.hxx" libpqxx-7.10.0/include/pqxx/prepared_statement000066400000000000000000000004651473205454700215420ustar00rootroot00000000000000/// Marker type to indicate that a string is the name of a prepared statement. #include "pqxx/internal/header-pre.hxx" // This include is deprecated. It will go away. // Include if you need it. #include "params.hxx" #include "pqxx/prepared_statement.hxx" #include "pqxx/internal/header-post.hxx" libpqxx-7.10.0/include/pqxx/prepared_statement.hxx000066400000000000000000000064131473205454700223470ustar00rootroot00000000000000/* Definition of the pqxx::prepped. * * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/prepared_statement instead. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did not receive a file called * COPYING with this source code, please notify the distributor of this * mistake, or contact the author. */ #ifndef PQXX_H_PREPARED_STATEMENT #define PQXX_H_PREPARED_STATEMENT namespace pqxx { /** * @name Prepared statements * * These are very similar to parameterised statements. The difference is * that you prepare a statement in advance, before you execute it, giving it an * identifying name. You can then call it by this name, as many times as you * like, passing in separate sets of argument values appropriate for each call. * * You prepare a statement on the connection, using * @ref pqxx::connection::prepare(). But you then call the statement in a * transaction, by calling * @ref pqxx::transaction_base::exec(pqxx::prepped, pqxx::params). * * The @ref pqxx::prepped type is really just a zero-terminated string, but * wrapped in its own type. This type only exists for one reason: it indicates * that the string is not an SQL statement itself, but the _name_ of a prepared * statement. * * 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 `pqxx::bytes` or * `pqxx::bytes_view` or (in C++20) `std::vector`. Also, consider * large objects on the SQL side and @ref blob on the C++ side. * * @warning Passing the wrong number of parameters to a prepared or * parameterised statement will _break the connection._ The usual exception * that occurs in this situation is @ref pqxx::protocol_violation. It's a * subclass of @ref pqxx::broken_connection, but where `broken_connection` * usually indicates a networking problem, `protocol_violation` indicates * that the communication with the server has deviated from protocol. Once * something like that happens, communication is broken and there is nothing * for it but to discard the connection. A networking problem is usually * worth retrying, but a protocol violation is not. Once the two ends of the * connection disagree about where they are in their conversation, they can't * get back on track. This is beyond libpqxx's control. */ //@{ /// A string that is the name of a prepared statement. /** * When calling on libpqxx to execute a prepared statement, wrap its name in * a `prepped` object to indicate to libpqxx that it is a statement name, not * SQL. * * The string must be like a C-style string: it should contain no bytes with * value zero, but it must have a single byte with value zero directly behind * it in memory. */ class PQXX_LIBEXPORT prepped : public zview { public: // TODO: May not have to be a zview! Because exec() draws a copy anyway. prepped(zview name) : zview{name} {} }; } // namespace pqxx #endif libpqxx-7.10.0/include/pqxx/range000066400000000000000000000003501473205454700167410ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/range.hxx000066400000000000000000000415331473205454700175570ustar00rootroot00000000000000#ifndef PQXX_H_RANGE #define PQXX_H_RANGE #if !defined(PQXX_HEADER_PRE) # error "Include libpqxx headers as , not ." #endif #include #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 noexcept { return true; } template constexpr bool extends_up_to(TYPE const &) const noexcept { 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 { // (Putting private section first to work around bug in gcc < 10: see #665.) private: TYPE m_value; public: inclusive_bound() = delete; constexpr 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; } /// Would this bound, as a lower bound, include value? [[nodiscard]] constexpr bool extends_down_to(TYPE const &value) const noexcept(noexcept(value < m_value)) { return not(value < m_value); } /// Would this bound, as an upper bound, include value? [[nodiscard]] constexpr bool extends_up_to(TYPE const &value) const noexcept(noexcept(value < m_value)) { return not(m_value < 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 { // (Putting private section first to work around bug in gcc < 10: see #665.) private: TYPE m_value; public: exclusive_bound() = delete; constexpr 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; } /// Would this bound, as a lower bound, include value? [[nodiscard]] constexpr bool extends_down_to(TYPE const &value) const noexcept(noexcept(m_value < value)) { return m_value < value; } /// Would this bound, as an upper bound, include value? [[nodiscard]] constexpr bool extends_up_to(TYPE const &value) const noexcept(noexcept(value < m_value)) { return value < 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 { // (Putting private section first to work around bug in gcc < 10: see #665.) private: std::variant, exclusive_bound> m_bound; public: range_bound() = delete; constexpr range_bound(no_bound) noexcept : m_bound{} {} constexpr range_bound(inclusive_bound const &bound) noexcept( noexcept(inclusive_bound{bound})) : m_bound{bound} {} constexpr range_bound(exclusive_bound const &bound) noexcept( noexcept(exclusive_bound{bound})) : m_bound{bound} {} constexpr range_bound(range_bound const &) noexcept( noexcept(inclusive_bound{ std::declval const &>()}) and noexcept(exclusive_bound{ std::declval const &>()})) = default; constexpr range_bound(range_bound &&) = default; constexpr bool operator==(range_bound const &rhs) const noexcept(noexcept(*this->value() == *rhs.value())) { 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(); } constexpr bool operator!=(range_bound const &rhs) const noexcept(noexcept(*this == rhs)) { 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); } /// Would this bound, as a lower bound, include `value`? constexpr bool extends_down_to(TYPE const &value) const { return std::visit( [&value](auto const &bound) noexcept(noexcept(bound.extends_down_to( value))) { return bound.extends_down_to(value); }, m_bound); } /// Would this bound, as an upper bound, include `value`? constexpr bool extends_up_to(TYPE const &value) const { return std::visit( [&value](auto const &bound) noexcept(noexcept( bound.extends_up_to(value))) { 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); } }; // 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 { // (Putting private section first to work around bug in gcc < 10: see #665.) private: range_bound m_lower, m_upper; public: /// Create a range. /** For each of the two bounds, pass a @ref no_bound, @ref inclusive_bound, * or * @ref exclusive_bound. */ constexpr 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(), ").")}; } /// 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. */ constexpr range() noexcept(noexcept(exclusive_bound{TYPE{}})) : m_lower{exclusive_bound{TYPE{}}}, m_upper{exclusive_bound{TYPE{}}} {} constexpr bool operator==(range const &rhs) const noexcept( noexcept(this->lower_bound() == rhs.lower_bound()) and noexcept(this->upper_bound() == rhs.upper_bound()) and noexcept(this->empty())) { return (this->lower_bound() == rhs.lower_bound() and this->upper_bound() == rhs.upper_bound()) or (this->empty() and rhs.empty()); } constexpr bool operator!=(range const &rhs) const noexcept(noexcept(*this == rhs)) { return not(*this == rhs); } range(range const &) = default; range(range &&) = default; range &operator=(range const &) = default; range &operator=(range &&) = default; /// 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. */ constexpr bool empty() const noexcept( noexcept(m_lower.is_exclusive()) and noexcept(m_lower.is_limited()) and noexcept(*m_lower.value() < *m_upper.value())) { 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()); } /// Does this range encompass `value`? constexpr bool contains(TYPE value) const noexcept( noexcept(m_lower.extends_down_to(value)) and noexcept(m_upper.extends_up_to(value))) { return m_lower.extends_down_to(value) and m_upper.extends_up_to(value); } /// 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. */ constexpr bool contains(range const &other) const noexcept(noexcept((*this & other) == other)) { 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; } /// Intersection of two ranges. /** Returns a range describing those values which are in both ranges. */ constexpr 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}; } }; /// 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)}; } // 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. auto const field_parser{ pqxx::internal::specialize_parse_composite_field>( pqxx::internal::encoding_group::UTF8)}; field_parser(index, text, pos, lower, last); field_parser(index, text, pos, upper, 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 libpqxx-7.10.0/include/pqxx/result000066400000000000000000000010471473205454700171670ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/result.hxx000066400000000000000000000360341473205454700200010ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 #include "pqxx/except.hxx" #include "pqxx/types.hxx" #include "pqxx/util.hxx" #include "pqxx/zview.hxx" #include "pqxx/internal/encodings.hxx" namespace pqxx::internal { PQXX_LIBEXPORT void clear_result(pq::PGresult const *) noexcept; } // 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::internal { // 9.0: Remove this, just use the notice handler in connection/result. /// Various callbacks waiting for a notice to come in. struct notice_waiters { std::function notice_handler; std::list errorhandlers; notice_waiters() = default; notice_waiters(notice_waiters const &) = delete; notice_waiters(notice_waiters &&) = delete; notice_waiters &operator=(notice_waiters const &) = delete; notice_waiters &operator=(notice_waiters &&) = delete; }; } // namespace pqxx::internal 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: * * ```cxx * 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{}, 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_MULTIDIM) [[nodiscard]] field operator[](size_type row_num, row_size_type col_num) const noexcept; #endif // PQXX_HAVE_MULTIDIM /// 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 &; /// Server-side storage size for field of column's type, in bytes. /** Returns the size of the server's internal representation of the column's * data type. A negative value indicates the data type is variable-length. */ [[nodiscard]] int column_storage(row_size_type number) const; /// Type modifier of the column with this number. /** The meaning of modifier values is type-specific; they typically indicate * precision or size limits. * * _Use this only if you know what you're doing._ Most applications do not * need it, and most types do not use modifiers. * * The value -1 indicates "no information available." * * @warning There is no check for errors, such as an invalid column number. */ [[nodiscard]] int column_type_modifier(row_size_type number) const noexcept; /// 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 pqxx::usage_error if `func`'s number of parameters does not match * the number of columns in this result. * * The parameter types must have conversions from PostgreSQL's string format * defined; see @ref datatypes. */ template inline void for_each(CALLABLE &&func) const; /// Check that result contains exactly `n` rows. /** @return The result itself, for convenience. * @throw @ref unexpected_rows if the actual count is not equal to `n`. */ result expect_rows(size_type n) const { auto const sz{size()}; if (sz != n) { // TODO: See whether result contains a generated statement. if (not m_query or m_query->empty()) throw unexpected_rows{pqxx::internal::concat( "Expected ", n, " row(s) from query, got ", sz, ".")}; else throw unexpected_rows{pqxx::internal::concat( "Expected ", n, " row(s) from query '", *m_query, "', got ", sz, ".")}; } return *this; } /// Check that result contains exactly 1 row, and return that row. /** @return @ref pqxx::row * @throw @ref unexpected_rows if the actual count is not equal to `n`. */ row one_row() const; /// Expect that result contains at moost one row, and return as optional. /** Returns an empty `std::optional` if the result is empty, or if it has * exactly one row, a `std::optional` containing the row. * * @throw @ref unexpected_rows is the row count is not 0 or 1. */ std::optional opt_row() const; /// Expect that result contains no rows. Return result for convenience. result no_rows() const { expect_rows(0); return *this; } /// Expect that result consists of exactly `cols` columns. /** @return The result itself, for convenience. * @throw @ref usage_error otherwise. */ result expect_columns(row_size_type cols) const { auto const actual{columns()}; if (actual != cols) { // TODO: See whether result contains a generated statement. if (not m_query or m_query->empty()) throw usage_error{pqxx::internal::concat( "Expected 1 column from query, got ", actual, ".")}; else throw usage_error{pqxx::internal::concat( "Expected 1 column from query '", *m_query, "', got ", actual, ".")}; } return *this; } /// Expect that result consists of exactly 1 row and 1 column. /** @return The one @ref pqxx::field in the result. * @throw @ref usage_error otherwise. */ field one_field() const; private: using data_pointer = std::shared_ptr; /// Underlying libpq result set. data_pointer m_data; 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; /// The connection's notice handler. /** We're not actually using this, but we need a copy here so that the * actual function does not get deallocated if the connection is destroyed * while this result still exists. */ std::shared_ptr m_notice_waiters; internal::encoding_group m_encoding; static std::string const s_empty_string; friend class pqxx::field; PQXX_PURE char const * get_value(size_type row, row_size_type col) const noexcept; PQXX_PURE bool get_is_null(size_type row, row_size_type col) const noexcept; PQXX_PURE field_size_type get_length(size_type, row_size_type) const noexcept; friend class pqxx::internal::gate::result_creation; result( std::shared_ptr const &rhs, std::shared_ptr const &query, std::shared_ptr const &waiters, 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 PQXX_COLD 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 libpqxx-7.10.0/include/pqxx/robusttransaction000066400000000000000000000004611473205454700214340ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/robusttransaction.hxx000066400000000000000000000075421473205454700222510ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 &cx, zview begin_command, std::string_view tname); basic_robusttransaction(connection &cx, 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 cx Connection inside which this robusttransaction should live. * @param tname optional human-readable name for this transaction. */ robusttransaction(connection &cx, std::string_view tname) : internal::basic_robusttransaction{ cx, pqxx::internal::begin_cmd, tname} {} /** Create robusttransaction of given name. * @param cx Connection inside which this robusttransaction should live. * @param tname optional human-readable name for this transaction. */ robusttransaction(connection &cx, std::string &&tname) : internal::basic_robusttransaction{ cx, pqxx::internal::begin_cmd, std::move(tname)} {} /** Create robusttransaction of given name. * @param cx Connection inside which this robusttransaction should live. */ explicit robusttransaction(connection &cx) : internal::basic_robusttransaction{ cx, pqxx::internal::begin_cmd} {} virtual ~robusttransaction() noexcept override { close(); } }; /** * @} */ } // namespace pqxx #endif libpqxx-7.10.0/include/pqxx/row000066400000000000000000000004301473205454700164530ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/row.hxx000066400000000000000000000404121473205454700172650ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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: // TODO: Some of these types conflict: class is both iterator and container. // TODO: Set iterator nested types using std::iterator_traits. 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; [[nodiscard]] const_reverse_row_iterator rbegin() const noexcept; [[nodiscard]] const_reverse_row_iterator crbegin() const noexcept; [[nodiscard]] const_reverse_row_iterator rend() const noexcept; [[nodiscard]] const_reverse_row_iterator crend() const noexcept; [[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; } /// 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(); } /// Extract entire row's values into a tuple. /** Converts to the types of the tuple's respective fields. * * The types in the tuple must have conversions from PostgreSQL's text format * defined; see @ref datatypes. * * @throw usage_error If the number of columns in the `row` does not match * the number of fields in `t`. */ template void to(Tuple &t) const { check_size(std::tuple_size_v); convert(t); } /// Extract entire row's values into a tuple. /** Converts to the types of the tuple's respective fields. * * The types must have conversions from PostgreSQL's text format defined; * see @ref datatypes. * * @throw usage_error If the number of columns in the `row` does not match * the number of fields in `t`. */ template std::tuple as() const { check_size(sizeof...(TYPE)); using seq = std::make_index_sequence; return get_tuple>(seq{}); } [[deprecated("Swap iterators, not rows.")]] void swap(row &) noexcept; /** 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; protected: friend class const_row_iterator; friend class result; row(result 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() noexcept = 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; const_row_iterator operator++(int) & noexcept; const_row_iterator &operator++() noexcept { ++m_col; return *this; } const_row_iterator operator--(int) & noexcept; 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; [[nodiscard]] inline field operator[](difference_type offset) const noexcept { return *(*this + offset); } //@} }; /// 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; } const_reverse_row_iterator operator++(int) & noexcept; const_reverse_row_iterator &operator--() noexcept { iterator_type::operator++(); return *this; } const_reverse_row_iterator operator--(int) &; 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); } [[nodiscard]] inline field operator[](difference_type offset) const noexcept { return *(*this + offset); } //@} /** * @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 libpqxx-7.10.0/include/pqxx/separated_list000066400000000000000000000003621473205454700206530ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/separated_list.hxx000066400000000000000000000104701473205454700214620ustar00rootroot00000000000000/* Helper similar to Python's `str.join()`. * * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/separated_list instead. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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. // C++23: Use std::join_with(). // TODO: Or just use std formatting? // TODO: Can we pass separators at compile time? 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; }); } // C++20: Use a concept. /// 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 libpqxx-7.10.0/include/pqxx/strconv000066400000000000000000000003401473205454700173420ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/strconv.hxx000066400000000000000000000542601473205454700201620ustar00rootroot00000000000000/* String conversion definitions. * * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 #include // C++20: Assume support. #if __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, and handle them * separately. */ template struct string_traits { /// Is conversion from `TYPE` to strings supported? /** When defining your own conversions, specialise this as `true` to indicate * that your string traits support the conversions to strings. */ static constexpr bool converts_to_string{false}; /// Is conversion from `string_view` to `TYPE` supported? /** When defining your own conversions, specialise this as `true` to indicate * that your string traits support `from_string`. */ static constexpr bool converts_from_string{false}; /// Return a @c string_view representing value, plus terminating zero. /** Produces a @c string_view containing the PostgreSQL string representation * for @c value. * * @warning A null value has no string representation. Do not pass a null. * * 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. /* @warning A null value has no string representation. Do not pass a 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. * * @warning A null value has no string representation. Do not parse a null. */ [[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; // TODO: Move is_unquoted_safe into the traits after all? }; /// Nonexistent function to indicate a disallowed type conversion. /** There is no implementation for this function, so any reference to it will * fail to link. The error message will mention the function name and its * template argument, as a deliberate message to an application developer that * their code is attempting to use a deliberately unsupported conversion. * * There are some C++ types that you may want to convert to or from SQL values, * but which libpqxx deliberately does not support. Take `char` for example: * we define no conversions for that type because it is not inherently clear * whether whether the corresponding SQL type should be a single-character * string, a small integer, a raw byte value, etc. The intention could differ * from one call site to the next. * * If an application attempts to convert these types, we try to make sure that * the compiler will issue an error involving this function name, and mention * the type, as a hint as to the reason. */ template [[noreturn]] void oops_forbidden_conversion() noexcept; /// String traits for a forbidden type conversion. /** If you have a C++ type for which you explicitly wish to forbid SQL * conversion, you can derive a @ref pqxx::string_traits specialisation for * that type from this struct. Any attempt to convert the type will then fail * to build, and produce an error mentioning @ref oops_forbidden_conversion. */ template struct forbidden_conversion { static constexpr bool converts_to_string{false}; static constexpr bool converts_from_string{false}; [[noreturn]] static zview to_buf(char *, char *, TYPE const &) { oops_forbidden_conversion(); } [[noreturn]] static char *into_buf(char *, char *, TYPE const &) { oops_forbidden_conversion(); } [[noreturn]] static TYPE from_string(std::string_view) { oops_forbidden_conversion(); } [[noreturn]] static std::size_t size_buffer(TYPE const &) noexcept { oops_forbidden_conversion(); } }; /// You cannot convert a `char` to/from SQL. /** Converting this type may seem simple enough, but it's ambiguous: Did you * mean the `char` value as a small integer? If so, did you mean it to be * signed or unsigned? (The C++ Standard allows the system to implement `char` * as either a signed type or an unsigned type.) Or were you thinking of a * single-character string (and if so, using what encoding)? Or perhaps it's * just a raw byte value? * * If you meant it as an integer, use an appropriate integral type such as * `int` or `short` or `unsigned int` etc. * * If you wanted a single-character string, use `std::string_view` (or a * similar type such as `std::string`). * * Or if you had a raw byte in mind, try `pqxx::bytes_view` instead. */ template<> struct string_traits : forbidden_conversion {}; /// You cannot convert an `unsigned char` to/from SQL. /** Converting this type may seem simple enough, but it's ambiguous: Did you * mean the `char` value as a small integer? Or were you thinking of a * single-character string (and if so, using what encoding)? Or perhaps it's * just a raw byte value? * * If you meant it as an integer, use an appropriate integral type such as * `int` or `short` or `unsigned int` etc. * * If you wanted a single-character string, use `std::string_view` (or a * similar type such as `std::string`). * * Or if you had a raw byte in mind, try `pqxx::bytes_view` instead. */ template<> struct string_traits : forbidden_conversion {}; /// You cannot convert a `signed char` to/from SQL. /** Converting this type may seem simple enough, but it's ambiguous: Did you * mean the value as a small integer? Or were you thinking of a * single-character string (and if so, in what encoding)? Or perhaps it's just * a raw byte value? * * If you meant it as an integer, use an appropriate integral type such as * `int` or `short` etc. * * If you wanted a single-character string, use `std::string_view` (or a * similar type such as `std::string`). * * Or if you had a raw byte in mind, try `pqxx::bytes_view` instead. */ template<> struct string_traits : forbidden_conversion {}; /// You cannot convert a `std::byte` to/from SQL. /** To convert a raw byte value, use a `bytes_view`. * * For example, to convert a byte `b` from C++ to SQL, convert the value * `pqxx::bytes_view{&b, 1}` instead. */ template<> struct string_traits : forbidden_conversion {}; /// Nullness: Enums do not have an inherent null value. template struct nullness>> : no_null {}; // C++20: Concepts for "converts from string" & "converts to string." } // 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; static constexpr bool converts_to_string{true}; static constexpr bool converts_from_string{true}; [[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 // We used to inline type_name, but this triggered a "double free" error // on program exit, when libpqxx was built as a shared library on Debian with // gcc 12. /// 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_view 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) { PQXX_ASSUME(here <= end); 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 libpqxx-7.10.0/include/pqxx/stream_from000066400000000000000000000004531473205454700201670ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/stream_from.hxx000066400000000000000000000322701473205454700207770ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 "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 transaction_base::stream instead of stream_from. */ constexpr from_table_t from_table; /// Pass this to a `stream_from` constructor to stream query results. /** @deprecated Use transaction_base::stream instead of stream_from. */ constexpr from_query_t from_query; /// Stream data from the database. /** @deprecated Use @ref transaction_base::stream. * * 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>; stream_from(stream_from &&) = delete; stream_from &operator=(stream_from &&) = delete; /// 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 */ [[deprecated("Use transaction_base::stream instead.")]] 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. */ [[deprecated("Use transaction_base::stream instead.")]] 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. */ [[deprecated("Use transaction_base::stream instead.")]] 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 transaction_base::stream 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 transaction_base::stream 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 transaction_base::stream 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 transaction_base::stream() 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 transaction_base::stream 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 transaction_base::stream 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 transaction_base::stream 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::char_finder_func *m_char_finder; /// 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) PQXX_UNLIKELY return *this; static constexpr auto tup_size{std::tuple_size_v}; m_fields.reserve(tup_size); parse_line(); if (m_finished) PQXX_UNLIKELY 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 libpqxx-7.10.0/include/pqxx/stream_to000066400000000000000000000004451473205454700176470ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/stream_to.hxx000066400000000000000000000435431473205454700204630ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 &cx{tx.conn()}; return raw_table(tx, cx.quote_table(path), cx.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 &cx{tx.conn()}; return stream_to::raw_table( tx, cx.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 explicit stream_to(stream_to &&other) : // (This first step only moves the transaction_focus base-class // object.) transaction_focus{std::move(other)}, m_finished{other.m_finished}, m_buffer{std::move(other.m_buffer)}, m_field_buf{std::move(other.m_field_buf)}, m_finder{other.m_finder} { other.m_finished = true; } ~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(); } /// 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); 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; /// Callback to find the special characters we need to watch out for. internal::char_finder_func *m_finder; /// 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 if constexpr ( std::is_same_v> or std::is_same_v> or std::is_same_v>) { // Optional string. It's not null (we checked for that above), so... // Treat like a string. m_field_buf.resize(budget); escape_field_to_buffer(f.value()); } // TODO: Support deleter template argument on unique_ptr. else if constexpr ( std::is_same_v> or std::is_same_v> or std::is_same_v> or std::is_same_v> or std::is_same_v> or std::is_same_v>) { // TODO: Can we generalise this elegantly without Concepts? // Effectively also an optional string. It's not null (we checked // for that above). 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)} {} } // namespace pqxx #endif libpqxx-7.10.0/include/pqxx/subtransaction000066400000000000000000000004671473205454700207150ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/subtransaction.hxx000066400000000000000000000061061473205454700215170ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 &cx) * { * string const temptable = "fleetingtable"; * * work tx(cx, "do_job"); * do_firstpart(tx); * * // Attempt to delete our temporary table if it already existed. * try * { * subtransaction S(tx, "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 tx is still fine. We can continue to use it. * tx.exec0("CREATE TEMP TABLE " + temptable + "(bar integer, splat * varchar)"); * * do_lastpart(tx); * } * ``` * * (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 libpqxx-7.10.0/include/pqxx/time000066400000000000000000000003341473205454700166050ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/time.hxx000066400000000000000000000056341473205454700174230ustar00rootroot00000000000000/** 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 libpqxx-7.10.0/include/pqxx/transaction000066400000000000000000000004421473205454700201740ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/transaction.hxx000066400000000000000000000055411473205454700210070ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 &cx, zview begin_command, std::string_view tname); basic_transaction(connection &cx, zview begin_command, std::string &&tname); basic_transaction(connection &cx, 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 cx; * work tx(cx); * try * { * tx.exec("UPDATE employees SET wage=wage*2").no_rows(); * tx.commit(); // NOTE: do this inside try block * } * catch (exception const &e) * { * cerr << e.what() << endl; * tx.abort(); // Usually not needed; same happens when tx'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 cx 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 &cx, std::string_view tname) : internal::basic_transaction{ cx, internal::begin_cmd, tname} {} /// Begin a transaction. /** * @param cx Connection for this transaction to operate on. * may contain letters and digits only. */ explicit transaction(connection &cx) : internal::basic_transaction{ cx, 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 libpqxx-7.10.0/include/pqxx/transaction_base000066400000000000000000000005411473205454700211660ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/transaction_base.hxx000066400000000000000000001352231473205454700220020ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 /* 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/internal/stream_query.hxx" #include "pqxx/isolation.hxx" #include "pqxx/prepared_statement.hxx" #include "pqxx/result.hxx" #include "pqxx/row.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. In libpqxx * you can't execute SQL directly on the connection object; that all happens * only on a transaction object. If you don't actually want to start a * transaction on the server, there's a @ref nontransaction class which * operates in _autocommit,_ i.e. without a transaction. * * (Why do you always need a transaction object? It ended up being the cleaner * choice in terms of interface design. It avoids a bunch of API maladies: * duplicating API between classes, messy inheritance, inviting mistakes by * making the transaction afterthought, and so on.) * * Like most other things in libpqxx, transactions follow RAII principles. * Creating a transaction object starts the transaction on the backend (if * appropriate), and to destroying one ends the transaction. But there's one * extra step: if you want to make the transaction's changes permanent, you * need to _commit_ it before you destroy it. If you destroy the transaction * object without committing, or if you call its `abort()` member function, * then any transaction type (other than @ref nontransaction) will roll back * its changes to the database instead. * * There is a choice of transaction types. To start with you'll probably want * to use @ref work, represents a regular, vanilla transaction with the default * isolation level. * * All the actual transaction functionality, including all the functions for * executing SQL statements, lives in the abstract @ref transaction_base class. * It defines the API for each type of transaction. You create a transaction, * you use it by calling @ref transaction_base member functions, and then you * either commit or (in the case of failure) abort. If you destroy your * transaction object without doing either, it automatically aborts. * * Once you're done with your transaction, you can start a new one using the * same connection. But there can be only one main transaction going on on a * connection at any given time. (You _can_ have more "nested" transactions, * but I'm not counting those as "main" transactions here. See below.) * * The concrete transaction types, all derived from @ref transaction_base, are: * * First and foremost, the plain @ref transaction template. Template * parameters let you select isolation level, and whether it should be * read-only. Two aliases are usually more convenient: @ref work is a * regular, run-of-the-mill default transaction. @ref read_transaction is a * read-only transaction that will not let you modify the database. * * Then there's @ref nontransaction. This one runs in autocommit, meaning * that we don't start any transaction at all. (Technically in this mode each * SQL command runs in its own little transaction, hence the term * "autocommit." There is no way to "undo" an SQL statement in this kind of * transaction.) Autocommit is sometimes a bit faster, and sometimes a bit * slower. Mainly you'll use it for specific operations that cannot be done *inside a database transaction, such as some kinds of schema changes. * * And then ther's @ref robusttransaction to help you deal with those painful * situations where you don't know for sure whether a transaction actually * succeeded. This can happen if you lose your network connection to the * database _just_ while you're trying to commit your transaction, before you * receive word about the outcome. You can re-connect and find out, but what * if the server is still executing the commit? * * You could say that @ref robusttransaction is not more robust, exactly, but * it goes to some extra effort to try and figure these situations out and give * you clarity. Extra effort does actually mean more things that can go wrong, * and it may be a litte slower, so investigate carefully before using this * transaction class. * * All of the transaction types that actually begin and commit/abort on the * database itself are derived from @ref dbtransaction, which can be a useful * type if your code needs a reference to such a transaction but doesn't need * to enforce a particular one. These types are @ref transaction, @ref work, * @ref read_transaction, and @ref robusttransaction. * * Finally, there's @ref subtransaction. This one is not at all like the * others: it can only exist inside a @ref dbtransaction. (Which includes * @ref subtransaction itself: you can nest them freely.) You can only * operate on the "innermost" active subtransaction at any given time, until * you either commit or abort it. Subtransactions are built on _savepoints_ * in the database; these are efficient to a point but do consume some server * resources. So use them when they make sense, e.g. to try an SQL statement * but continue your main transation if it fails. But don't create them in * enormous numbers, or performance may start to suffer. */ /// 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 `bytea` field. /** 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 `bytea` field. /** Takes a binary string as escaped by PostgreSQL, and returns a restored * copy of the original binary data. */ [[nodiscard]] bytes unesc_bin(zview text) { return conn().unesc_bin(text); } /// Unescape binary data, e.g. from a `bytea` field. /** 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 `bytea` field. /** Takes a binary string as escaped by PostgreSQL, and returns a restored * copy of the original binary data. */ [[nodiscard]] bytes 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 bytes 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(pqxx::bytes_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(pqxx::bytes_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 in libpqxx, and * it always starts at 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. * * Most of the differences between the query execution functions are in how * they return the query's results. * * * The "query" functions run your query, wait for it to complete, and load * all of the results into memory on the client side. You can then access * rows of result data, converted to C++ types that you request. * * The "stream" functions execute your query in a completely different way. * Called _streaming queries,_ these don't support quite the full range of * SQL queries, and they're a bit slower to start. But they are * significantly _faster_ for queries that return larger numbers of rows. * They don't load the entire result set, so you can start processing data * as soon as the first row of data comes in from the database. This can * This can save you a lot of time. Processing itself may also be faster. * And of course, it also means you don't need enough memory to hold the * entire result set, just the row you're working on. * * The "exec" functions are a more low-level interface. Most of them * return a pqxx::result object. This is an object that contains all * information abouut the query's result: the data itself, but also the * number of rows in the result, the column names, the number of rows that * your query may have modified, and so on. */ //@{ /// 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); // TODO: Wrap PQdescribePrepared(). result exec(std::string_view query, params parms) { return internal_exec_params(query, parms.make_c_params()); } /// 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("Use exec(string_view) and call no_rows() on the result.")]] result exec0(zview query, std::string_view desc) { #include "pqxx/internal/ignore-deprecated-pre.hxx" return exec(query, desc).no_rows(); #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("Use exec() and call no_rows() on the result.")]] result exec0(zview query) { return exec(query).no_rows(); } /// 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("Use exec(string_view), and call one_row() on the result.")]] row exec1(zview query, std::string_view desc) { #include "pqxx/internal/ignore-deprecated-pre.hxx" return exec(query, desc).one_row(); #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. */ [[deprecated("Use exec() instead, and call one_row() on the result.")]] row exec1(zview query) { return exec(query).one_row(); } /// 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("Use exec() instead, and call expect_rows() on the result.")]] 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. */ [[deprecated("Use exec() instead, and call expect_rows() on the result.")]] result exec_n(result::size_type rows, zview query) { #include "pqxx/internal/ignore-deprecated-pre.hxx" return exec(query, std::string_view{}).expect_rows(rows); #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" return exec(query, desc).one_field().as(); #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. * * @throw unexpected_rows If the query did not return exactly 1 row. * @throw usage_error If the row did not contain exactly 1 field. */ template TYPE query_value(zview query) { return exec(query).one_field().as(); } /// Perform query returning exactly one row, and convert its fields. /** This is a convenient way of querying one row's worth of data, and * converting its fields to a tuple of the C++-side types you specify. * * @throw unexpected_rows If the query did not return exactly 1 row. * @throw usage_error If the number of columns in the result does not match * the number of fields in the tuple. */ template [[nodiscard]] std::tuple query1(zview query) { return exec(query).expect_columns(sizeof...(TYPE)).one_row().as(); } /// Query at most one row of data, and if there is one, convert it. /** If the query produced a row of data, this converts it to a tuple of the * C++ types you specify. Otherwise, this returns no tuple. * * @throw unexpected_rows If the query returned more than 1 row. * @throw usage_error If the number of columns in the result does not match * the number of fields in the tuple. */ template [[nodiscard]] std::optional> query01(zview query) { std::optional const r{exec(query).opt_row()}; if (r) return {r->as()}; else return {}; } /// Execute a query, in streaming fashion; 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. Unlike with the "exec" functions, processing can start before * all the data from the server is in. * * Streaming is also documented in @ref streams. * * The column types must all be types that have conversions from PostgreSQL's * text format defined. Many built-in types such as `int` or `std::string` * have pre-defined conversions; if you want to define your own conversions * for additional types, see @ref datatypes. * * 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 you're * translating it does not have a null value, wrap the type in a * `std::optional<>` (or if you prefer, a `std::shared_ptr<>` or a * `std::unique_ptr`). These templates do support null values, and libpqxx * will know how to convert to them. * * The stream lives entirely within the lifetime of the transaction. Make * sure you complete the stream before you destroy the transaction. Until * the stream has finished, the transaction and the connection are in a * special state where they cannot be used for anything else. * * @warning If the stream fails, you will have to destroy the transaction * and the connection. If this is a problem, use the "exec" functions * instead. * * Streaming your query is likely to be faster than the `exec()` methods for * larger results (but slower for small results), and start useful processing * sooner. Also, `stream()` scales better in terms of memory usage: it only * needs to keep the current row in memory. The "exec" functions read the * entire result into memory at once. * * 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](https://www.postgresql.org/docs/current/sql-copy.html) for * the exact restrictions. * * Iterating in this way does require each of the field types you pass to be * default-constructible, copy-constructible, and assignable. These * requirements may loosen a bit once libpqxx moves on to C++20. */ template [[nodiscard]] auto stream(std::string_view query) & { return pqxx::internal::stream_query{*this, query}; } /// Execute a query, in streaming fashion; loop over the results row by row. /** Like @ref stream(std::string_view), but with parameters. */ template [[nodiscard]] auto stream(std::string_view query, params parms) & { return pqxx::internal::stream_query{*this, query, parms}; } // 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_stream` function executes `query` in a stream similar to * @ref stream. 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::internal::stream_query 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 larger result sets. So if * performance matters, you'll want to use `for_stream` if you query large * amounts of data, but not if you do lots of queries with small outputs. * * However, the transaction and the connection are in a special state while * the iteration is ongoing. If `func` throws an exception, or the iteration * fails in some way, the only way out is to destroy the transaction and the * connection. * * Each of the parameter types must have a conversion from PostgreSQL's text * format defined. To define conversions for additional types, see * @ref datatypes. */ template auto for_stream(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); } template [[deprecated( "pqxx::transaction_base::for_each is now called for_stream.")]] auto for_each(std::string_view query, CALLABLE &&func) { return for_stream(query, std::forward(func)); } /// Execute query, read full results, then iterate rows of data. /** Converts each row of the result to a `std::tuple` of the types you pass * as template arguments. (The number of template arguments must match the * number of columns in the query's result.) * * Example: * * ```cxx * for ( * auto [name, salary] : * tx.query( * "SELECT name, salary FROM employee" ) * ) * std::cout << name << " earns " << salary << ".\n"; * ``` * * You can't normally convert a field value to `std::string_view`, but this * is one of the places where you can. The underlying string to which the * `string_view` points exists only for the duration of the one iteration. * After that, the buffer that holds the actual string may have disappeared, * or it may contain a new string value. * * If you expect a lot of rows from your query, it's probably faster to use * transaction_base::stream() instead. Or if you need to access metadata of * the result, such as the number of rows in the result, or the number of * rows that your query updates, then you'll need to use * transaction_base::exec() instead. * * @return Something you can iterate using "range `for`" syntax. The actual * type details may change. */ template auto query(zview query) { return exec(query).iter(); } /// Perform query, expect given number of rows, iterate results. template [[deprecated("Use query() instead, and call expect_rows() on the result.")]] auto query_n(result::size_type rows, zview query) { return exec(query).expect_rows(rows).iter(); } // C++20: Concept like std::invocable, but without specifying param types. /// Execute a query, load the full result, and perform `func` for each row. /** Converts each row to data types matching `func`'s parameter types. The * number of columns in the result set must match the number of parameters. * * This is a lot like for_stream(). The differences are: * 1. It can execute some unusual queries that for_stream() can't. * 2. The `exec` functions are faster for small results, but slower for large * results. */ template void for_query(zview query, CALLABLE &&func) { exec(query).for_each(std::forward(func)); } /** * @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 such as "," 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. /** This is like calling `exec()`, except it will substitute the first * parameter after `query` (the first in `args`) for a `$1` in the query, the * next one for `$2`, etc. */ template [[deprecated("Use exec(zview, params) instead.")]] result exec_params(std::string_view query, Args &&...args) { return exec(query, params{args...}); } // Execute parameterised statement, expect a single-row result. /** @throw unexpected_rows if the result does not consist of exactly one row. */ template [[deprecated("Use exec() instead, and call one_row() on the result.")]] row exec_params1(zview query, Args &&...args) { return exec(query, params{args...}).one_row(); } // Execute parameterised statement, expect a result with zero rows. /** @throw unexpected_rows if the result contains rows. */ template [[deprecated( "Use exec(string_view, params) and call no_rows() on the result.")]] result exec_params0(zview query, Args &&...args) { return exec(query, params{args...}).no_rows(); } // Execute parameterised statement, expect exactly a given number of rows. /** @throw unexpected_rows if the result contains the wrong number of rows. */ template [[deprecated("Use exec(), and call expect_rows() on the result.")]] result exec_params_n(std::size_t rows, zview query, Args &&...args) { return exec(query, params{args...}) .expect_rows(check_cast(rows, "number of rows")); } // Execute parameterised statement, expect exactly a given number of rows. /** @throw unexpected_rows if the result contains the wrong number of rows. */ template [[deprecated("Use exec(), and call expect_rows() on the result.")]] result exec_params_n(result::size_type rows, zview query, Args &&...args) { return exec(query, params{args...}).expect_rows(rows); } /// Execute parameterised query, read full results, iterate rows of data. /** Like @ref query, but the query can contain parameters. * * Converts each row of the result to a `std::tuple` of the types you pass * as template arguments. (The number of template arguments must match the * number of columns in the query's result.) * * Example: * * ```cxx * for ( * auto [name, salary] : * tx.query( * "SELECT name, salary FROM employee" ) * ) * std::cout << name << " earns " << salary << ".\n"; * ``` * * You can't normally convert a field value to `std::string_view`, but this * is one of the places where you can. The underlying string to which the * `string_view` points exists only for the duration of the one iteration. * After that, the buffer that holds the actual string may have disappeared, * or it may contain a new string value. * * If you expect a lot of rows from your query, it's probably faster to use * transaction_base::stream() instead. Or if you need to access metadata of * the result, such as the number of rows in the result, or the number of * rows that your query updates, then you'll need to use * transaction_base::exec() instead. * * @return Something you can iterate using "range `for`" syntax. The actual * type details may change. */ template auto query(zview query, params const &parms) { return exec(query, parms).iter(); } /// Perform query parameterised, expect given number of rows, iterate /// results. /** Works like @ref query, but checks that the result has exactly the * expected number of rows. * * @throw unexpected_rows If the query returned the wrong number of rows. * * @return Something you can iterate using "range `for`" syntax. The actual * type details may change. */ template [[deprecated("Use exec(), and call check_rows() & iter() on the result.")]] auto query_n(result::size_type rows, zview query, params const &parms) { return exec(query, parms).expect_rows(rows).iter(); } /// 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. * * @throw unexpected_rows If the query did not return exactly 1 row. * @throw usage_error If the row did not contain exactly 1 field. */ template TYPE query_value(zview query, params const &parms) { return exec(query, parms).expect_columns(1).one_field().as(); } /// Perform query returning exactly one row, and convert its fields. /** This is a convenient way of querying one row's worth of data, and * converting its fields to a tuple of the C++-side types you specify. * * @throw unexpected_rows If the query did not return exactly 1 row. * @throw usage_error If the number of columns in the result does not match * the number of fields in the tuple. */ template [[nodiscard]] std::tuple query1(zview query, params const &parms) { return exec(query, parms).one_row().as(); } /// Query at most one row of data, and if there is one, convert it. /** If the query produced a row of data, this converts it to a tuple of the * C++ types you specify. Otherwise, this returns no tuple. * * @throw unexpected_rows If the query returned more than 1 row. * @throw usage_error If the number of columns in the result does not match * the number of fields in the tuple. */ template [[nodiscard]] std::optional> query01(zview query, params const &parms) { std::optional r{exec(query, parms).opt_row()}; if (r) return {r->as()}; else return {}; } // C++20: Concept like std::invocable, but without specifying param types. /// Execute a query, load the full result, and perform `func` for each row. /** The query may use parameters. So for example, the query may contain `$1` * to denote the first parameter value in `parms`, and so on. * * Converts each row to data types matching `func`'s parameter types. The * number of columns in the result set must match the number of parameters. * * This is a lot like for_stream(). The differences are: * 1. It can execute some unusual queries that for_stream() can't. * 2. The `exec` functions are faster for small results, but slower for large * results. */ template void for_query(zview query, CALLABLE &&func, params const &parms) { exec(query, parms).for_each(std::forward(func)); } /// Send a notification. /** Convenience shorthand for executing a "NOTIFY" command. Most of the * logic for handling _incoming_ notifications is in @ref pqxx::connection * (particularly @ref pqxx::connection::listen), but _outgoing_ * notifications happen here. * * Unless this transaction is a nontransaction, the actual notification only * goes out once the outer transaction is committed. * * @param channel Name of the "channel" on which clients will need to be * listening in order to receive this notification. * * @param payload Optional argument string which any listeners will also * receive. If you leave this out, they will receive an empty string as the * payload. */ void notify(std::string_view channel, std::string_view payload = {}); //@} /// Execute a prepared statement, with optional arguments. template [[deprecated("Use exec(prepped, params) instead.")]] result exec_prepared(zview statement, Args &&...args) { return exec(prepped{statement}, params{args...}); } /// Execute a prepared statement taking no parameters. result exec(prepped statement) { params pp; return internal_exec_prepared(statement, pp.make_c_params()); } /// Execute prepared statement, read full results, iterate rows of data. /** Like @ref query(zview), but using a prepared statement. * * @return Something you can iterate using "range `for`" syntax. The actual * type details may change. */ template auto query(prepped statement, params const &parms = {}) { return exec(statement, parms).iter(); } /// Perform prepared statement returning exactly 1 value. /** This is just like @ref query_value(zview), but using a prepared * statement. */ template TYPE query_value(prepped statement, params const &parms = {}) { return exec(statement, parms).expect_columns(1).one_field().as(); } // C++20: Concept like std::invocable, but without specifying param types. /// Execute prepared statement, load result, perform `func` for each row. /** This is just like @ref for_query(zview), but using a prepared statement. */ template void for_query(prepped statement, CALLABLE &&func, params const &parms = {}) { exec(statement, parms).for_each(std::forward(func)); } // TODO: stream() with prepped. // TODO: stream_like() with prepped. /// Execute a prepared statement with parameters. result exec(prepped statement, params const &parms) { return internal_exec_prepared(statement, parms.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 [[deprecated( "Use exec(string_view, params) and call one_row() on the result.")]] row exec_prepared1(zview statement, Args &&...args) { return exec(prepped{statement}, params{args...}).one_row(); } /// Execute a prepared statement, and expect a result with zero rows. /** @throw pqxx::unexpected_rows if the result contained rows. */ template [[deprecated( "Use exec(prepped, params), and call no_rows() on the result.")]] result exec_prepared0(zview statement, Args &&...args) { return exec(prepped{statement}, params{args...}).no_rows(); } /// 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 [[deprecated( "Use exec(prepped, params), and call expect_rows() on the result.")]] result exec_prepared_n(result::size_type rows, zview statement, Args &&...args) { return exec(pqxx::prepped{statement}, params{args...}).expect_rows(rows); } /** * @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 &cx, std::string_view tname, std::shared_ptr rollback_cmd) : m_conn{cx}, 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 &cx, std::string_view tname); /// Create a transaction (to be called by implementation classes only). explicit transaction_base(connection &cx); /// 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( std::string_view statement, internal::c_params const &args); result internal_exec_params(std::string_view query, internal::c_params const &args); /// 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 #include "pqxx/internal/stream_query_impl.hxx" #endif libpqxx-7.10.0/include/pqxx/transaction_focus000066400000000000000000000004071473205454700213740ustar00rootroot00000000000000/** * 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" libpqxx-7.10.0/include/pqxx/transaction_focus.hxx000066400000000000000000000066751473205454700222170ustar00rootroot00000000000000/** Transaction focus: types which monopolise a transaction's attention. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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`. In 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); } transaction_focus(transaction_focus &&other) : m_trans{other.m_trans}, m_registered{other.m_registered}, m_classname{other.m_classname}, // We can't move the name until later. m_name{} { // This is a bit more complicated than you might expect. The transaction // has a backpointer to the focus, and we need to transfer that to the new // focus. move_name_and_registration(other); } transaction_focus &operator=(transaction_focus &&other) { if (&other != this) { if (m_registered) unregister_me(); m_trans = other.m_trans; m_classname = other.m_classname; move_name_and_registration(other); } return *this; } 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; /// Perform part of a move operation. void move_name_and_registration(transaction_focus &other) { bool const reg{other.m_registered}; // Unregister the original while it still owns its name. if (reg) other.unregister_me(); // Now! Quick! Steal that name. m_name = std::move(other.m_name); // Now that we own the name, register ourselves instead. if (reg) this->register_me(); } }; } // namespace pqxx #endif libpqxx-7.10.0/include/pqxx/transactor000066400000000000000000000004471473205454700200340ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/transactor.hxx000066400000000000000000000135411473205454700206410ustar00rootroot00000000000000/* Transactor framework, a wrapper for safely retryable transactions. * * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transactor instead. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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. * * 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 (protocol_violation const &) { // This is a subclass of broken_connection, but it's not one where // retrying is likely to do us any good. 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 libpqxx-7.10.0/include/pqxx/types000066400000000000000000000003531473205454700170140ustar00rootroot00000000000000/** * 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" libpqxx-7.10.0/include/pqxx/types.hxx000066400000000000000000000117361473205454700176310ustar00rootroot00000000000000/* Basic type aliases and forward declarations. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen * * See COPYING for copyright license. If you did 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; // 9.0: Remove this. class errorhandler; class field; class largeobjectaccess; class notification_receiver; struct range_error; class result; class row; class stream_from; class transaction_base; /// 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>, 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 /// 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 {}; } // namespace pqxx #endif libpqxx-7.10.0/include/pqxx/util000066400000000000000000000003461473205454700166270ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/util.hxx000066400000000000000000000544131473205454700174410ustar00rootroot00000000000000/* Various utility definitions for libpqxx. * * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/util instead. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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 #include #include #include #include "pqxx/except.hxx" #include "pqxx/types.hxx" #include "pqxx/version.hxx" /// The home of all libpqxx classes, functions, templates, etc. namespace pqxx {} #include // C++23: Retire wrapper. // PQXX_UNREACHABLE: equivalent to `std::unreachable()` if available. #if !defined(__cpp_lib_unreachable) # define PQXX_UNREACHABLE while (false) #elif !__cpp_lib_unreachable # define PQXX_UNREACHABLE while (false) #else # define PQXX_UNREACHABLE std::unreachable() #endif /// 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 /// Custom `std::char_trast` if the compiler does not provide one. /** Needed if the standard library lacks a generic implementation or a * specialisation for std::byte. They aren't strictly required to provide * either, and libc++ 19 removed its generic implementation. */ struct byte_char_traits : std::char_traits { using char_type = std::byte; static void assign(std::byte &a, const std::byte &b) noexcept { a = b; } static bool eq(std::byte a, std::byte b) { return a == b; } static bool lt(std::byte a, std::byte b) { return a < b; } static int compare(const std::byte *a, const std::byte *b, std::size_t size) { return std::memcmp(a, b, size); } /// Deliberately undefined: "guess" the length of an array of bytes. /* This is nonsense: we can't determine the length of a random sequence of * bytes. There is no terminating zero like there is for C strings. * * But `std::char_traits` requires us to provide this function, so we * declare it without defining it. */ static size_t length(const std::byte *data); static const std::byte * find(const std::byte *data, std::size_t size, const std::byte &value) { return static_cast( std::memchr(data, static_cast(value), size)); } static std::byte * move(std::byte *dest, const std::byte *src, std::size_t size) { return static_cast(std::memmove(dest, src, size)); } static std::byte * copy(std::byte *dest, const std::byte *src, std::size_t size) { return static_cast(std::memcpy(dest, src, size)); } static std::byte *assign(std::byte *dest, std::size_t size, std::byte value) { return static_cast( std::memset(dest, static_cast(value), size)); } /// Declared but not defined: makes no sense for binary data. static int_type not_eof(int_type value); static std::byte to_char_type(int_type value) { return std::byte(value); } static int_type to_int_type(std::byte value) { return int_type(value); } static bool eq_int_type(int_type a, int_type b) { return a == b; } /// Declared but not defined: makes no sense for binary data. static int_type eof(); }; template struct has_generic_char_traits : std::false_type {}; template struct has_generic_char_traits< TYPE, std::void_t::eof)>> : std::true_type {}; inline constexpr bool has_generic_bytes_char_traits = has_generic_char_traits::value; // Supress warnings from potentially using a deprecated generic // std::char_traits. // Necessary for libc++ 18. #include "pqxx/internal/ignore-deprecated-pre.hxx" // C++20: Change this type. /// Type alias for a container containing bytes. /* Required to support standard libraries without a generic implementation for * `std::char_traits`. * @warn Will change to `std::vector` in the next major release. */ using bytes = std::conditional< has_generic_bytes_char_traits, std::basic_string, std::basic_string>::type; // C++20: Change this type. /// Type alias for a view of bytes. /* Required to support standard libraries without a generic implementation for * `std::char_traits`. * @warn Will change to `std::span` in the next major release. */ using bytes_view = std::conditional< has_generic_bytes_char_traits, std::basic_string_view, std::basic_string_view>::type; #include "pqxx/internal/ignore-deprecated-post.hxx" /// 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 * `pqxx::bytes`, or a `pqxx::bytes_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 * `pqxx::bytes_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 bytes_view binary_cast(TYPE const &data) { static_assert(sizeof(value_type) == 1); // C++20: Use std::as_bytes. 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 `pqxx::bytes_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 bytes_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(bytes_view binary_data, char buffer[]) noexcept; /// Hex-escape binary data into a std::string. std::string PQXX_LIBEXPORT esc_bin(bytes_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. bytes 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(PQXX_HAVE_SSIZE) return std::ssize(c); #else using signed_t = std::make_signed_t; return static_cast(std::size(c)); #endif // PQXX_HAVE_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())); /// Return original byte for escaped character. inline constexpr char unescape_char(char escaped) noexcept { switch (escaped) { case 'b': // Backspace. PQXX_UNLIKELY return '\b'; case 'f': // Form feed PQXX_UNLIKELY return '\f'; case 'n': // Line feed. return '\n'; case 'r': // Carriage return. return '\r'; case 't': // Horizontal tab. return '\t'; case 'v': // Vertical tab. return '\v'; default: break; } // Regular character ("self-escaped"). return escaped; } // 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 pqxx::internal namespace pqxx::internal::pq { /// Wrapper for `PQfreemem()`, with C++ linkage. PQXX_LIBEXPORT void pqfreemem(void const *) noexcept; } // namespace pqxx::internal::pq #endif libpqxx-7.10.0/include/pqxx/version000066400000000000000000000003301473205454700173300ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/version.hxx000066400000000000000000000040761473205454700201510ustar00rootroot00000000000000/* Version info for libpqxx. * * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/version instead. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did not receive a file called * COPYING with this source code, please notify the distributor of this * mistake, or contact the author. */ #if !defined(PQXX_H_VERSION) # define PQXX_H_VERSION # if !defined(PQXX_HEADER_PRE) # error "Include libpqxx headers as , not ." # endif /// Full libpqxx version string. # define PQXX_VERSION "7.10.0" /// Library ABI version. # define PQXX_ABI "7.10" /// Major version number. # define PQXX_VERSION_MAJOR 7 /// Minor version number. # define PQXX_VERSION_MINOR 10 # define PQXX_VERSION_CHECK check_pqxx_version_7_10 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 libpqxx-7.10.0/include/pqxx/version.hxx.template000066400000000000000000000041651473205454700217620ustar00rootroot00000000000000/* Version info for libpqxx. * * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/version instead. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did not receive a file called * COPYING with this source code, please notify the distributor of this * mistake, or contact the author. */ #if !defined(PQXX_H_VERSION) # define 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 libpqxx-7.10.0/include/pqxx/zview000066400000000000000000000003421473205454700170120ustar00rootroot00000000000000/** 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" libpqxx-7.10.0/include/pqxx/zview.hxx000066400000000000000000000121301473205454700176160ustar00rootroot00000000000000/* Zero-terminated string view. * * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/zview instead. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. If you did 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) noexcept( noexcept(std::string_view{text, static_cast(len)})) : std::string_view{text, static_cast(len)} {} /// Convenience overload: construct using pointer and signed length. constexpr zview(char text[], std::ptrdiff_t len) noexcept( noexcept(std::string_view{text, static_cast(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[]) noexcept(noexcept(std::string_view{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, 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 libpqxx-7.10.0/libpqxx.pc.in000066400000000000000000000003601473205454700157200ustar00rootroot00000000000000prefix=@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} libpqxx-7.10.0/pqxx_cxx_feature_checks.ac000066400000000000000000000141121473205454700205220ustar00rootroot00000000000000# Configuration for feature checks. Generated by generate_check_config.py. AC_MSG_CHECKING([PQXX_HAVE_ASSUME]) PQXX_HAVE_ASSUME=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_ASSUME.cxx)], AC_DEFINE( [PQXX_HAVE_ASSUME], 1, [Define if this feature is available.]), PQXX_HAVE_ASSUME=no) AC_MSG_RESULT($PQXX_HAVE_ASSUME) AC_MSG_CHECKING([PQXX_HAVE_CHARCONV_FLOAT]) PQXX_HAVE_CHARCONV_FLOAT=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_CHARCONV_FLOAT.cxx)], AC_DEFINE( [PQXX_HAVE_CHARCONV_FLOAT], 1, [Define if this feature is available.]), PQXX_HAVE_CHARCONV_FLOAT=no) AC_MSG_RESULT($PQXX_HAVE_CHARCONV_FLOAT) AC_MSG_CHECKING([PQXX_HAVE_CHARCONV_INT]) PQXX_HAVE_CHARCONV_INT=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_CHARCONV_INT.cxx)], AC_DEFINE( [PQXX_HAVE_CHARCONV_INT], 1, [Define if this feature is available.]), PQXX_HAVE_CHARCONV_INT=no) AC_MSG_RESULT($PQXX_HAVE_CHARCONV_INT) AC_MSG_CHECKING([PQXX_HAVE_CMP]) PQXX_HAVE_CMP=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_CMP.cxx)], AC_DEFINE( [PQXX_HAVE_CMP], 1, [Define if this feature is available.]), PQXX_HAVE_CMP=no) AC_MSG_RESULT($PQXX_HAVE_CMP) AC_MSG_CHECKING([PQXX_HAVE_CONCEPTS]) PQXX_HAVE_CONCEPTS=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_CONCEPTS.cxx)], AC_DEFINE( [PQXX_HAVE_CONCEPTS], 1, [Define if this feature is available.]), PQXX_HAVE_CONCEPTS=no) AC_MSG_RESULT($PQXX_HAVE_CONCEPTS) AC_MSG_CHECKING([PQXX_HAVE_CXA_DEMANGLE]) PQXX_HAVE_CXA_DEMANGLE=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_CXA_DEMANGLE.cxx)], AC_DEFINE( [PQXX_HAVE_CXA_DEMANGLE], 1, [Define if this feature is available.]), PQXX_HAVE_CXA_DEMANGLE=no) AC_MSG_RESULT($PQXX_HAVE_CXA_DEMANGLE) AC_MSG_CHECKING([PQXX_HAVE_GCC_PURE]) PQXX_HAVE_GCC_PURE=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_GCC_PURE.cxx)], AC_DEFINE( [PQXX_HAVE_GCC_PURE], 1, [Define if this feature is available.]), PQXX_HAVE_GCC_PURE=no) AC_MSG_RESULT($PQXX_HAVE_GCC_PURE) AC_MSG_CHECKING([PQXX_HAVE_GCC_VISIBILITY]) PQXX_HAVE_GCC_VISIBILITY=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_GCC_VISIBILITY.cxx)], AC_DEFINE( [PQXX_HAVE_GCC_VISIBILITY], 1, [Define if this feature is available.]), PQXX_HAVE_GCC_VISIBILITY=no) AC_MSG_RESULT($PQXX_HAVE_GCC_VISIBILITY) AC_MSG_CHECKING([PQXX_HAVE_LIKELY]) PQXX_HAVE_LIKELY=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_LIKELY.cxx)], AC_DEFINE( [PQXX_HAVE_LIKELY], 1, [Define if this feature is available.]), PQXX_HAVE_LIKELY=no) AC_MSG_RESULT($PQXX_HAVE_LIKELY) AC_MSG_CHECKING([PQXX_HAVE_MULTIDIM]) PQXX_HAVE_MULTIDIM=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_MULTIDIM.cxx)], AC_DEFINE( [PQXX_HAVE_MULTIDIM], 1, [Define if this feature is available.]), PQXX_HAVE_MULTIDIM=no) AC_MSG_RESULT($PQXX_HAVE_MULTIDIM) AC_MSG_CHECKING([PQXX_HAVE_PATH]) PQXX_HAVE_PATH=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_PATH.cxx)], AC_DEFINE( [PQXX_HAVE_PATH], 1, [Define if this feature is available.]), PQXX_HAVE_PATH=no) AC_MSG_RESULT($PQXX_HAVE_PATH) AC_MSG_CHECKING([PQXX_HAVE_POLL]) PQXX_HAVE_POLL=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_POLL.cxx)], AC_DEFINE( [PQXX_HAVE_POLL], 1, [Define if this feature is available.]), PQXX_HAVE_POLL=no) AC_MSG_RESULT($PQXX_HAVE_POLL) AC_MSG_CHECKING([PQXX_HAVE_SLEEP_FOR]) PQXX_HAVE_SLEEP_FOR=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_SLEEP_FOR.cxx)], AC_DEFINE( [PQXX_HAVE_SLEEP_FOR], 1, [Define if this feature is available.]), PQXX_HAVE_SLEEP_FOR=no) AC_MSG_RESULT($PQXX_HAVE_SLEEP_FOR) AC_MSG_CHECKING([PQXX_HAVE_SOURCE_LOCATION]) PQXX_HAVE_SOURCE_LOCATION=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_SOURCE_LOCATION.cxx)], AC_DEFINE( [PQXX_HAVE_SOURCE_LOCATION], 1, [Define if this feature is available.]), PQXX_HAVE_SOURCE_LOCATION=no) AC_MSG_RESULT($PQXX_HAVE_SOURCE_LOCATION) AC_MSG_CHECKING([PQXX_HAVE_SPAN]) PQXX_HAVE_SPAN=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_SPAN.cxx)], AC_DEFINE( [PQXX_HAVE_SPAN], 1, [Define if this feature is available.]), PQXX_HAVE_SPAN=no) AC_MSG_RESULT($PQXX_HAVE_SPAN) AC_MSG_CHECKING([PQXX_HAVE_SSIZE]) PQXX_HAVE_SSIZE=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_SSIZE.cxx)], AC_DEFINE( [PQXX_HAVE_SSIZE], 1, [Define if this feature is available.]), PQXX_HAVE_SSIZE=no) AC_MSG_RESULT($PQXX_HAVE_SSIZE) AC_MSG_CHECKING([PQXX_HAVE_STRERROR_R]) PQXX_HAVE_STRERROR_R=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_STRERROR_R.cxx)], AC_DEFINE( [PQXX_HAVE_STRERROR_R], 1, [Define if this feature is available.]), PQXX_HAVE_STRERROR_R=no) AC_MSG_RESULT($PQXX_HAVE_STRERROR_R) AC_MSG_CHECKING([PQXX_HAVE_STRERROR_S]) PQXX_HAVE_STRERROR_S=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_STRERROR_S.cxx)], AC_DEFINE( [PQXX_HAVE_STRERROR_S], 1, [Define if this feature is available.]), PQXX_HAVE_STRERROR_S=no) AC_MSG_RESULT($PQXX_HAVE_STRERROR_S) AC_MSG_CHECKING([PQXX_HAVE_THREAD_LOCAL]) PQXX_HAVE_THREAD_LOCAL=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_THREAD_LOCAL.cxx)], AC_DEFINE( [PQXX_HAVE_THREAD_LOCAL], 1, [Define if this feature is available.]), PQXX_HAVE_THREAD_LOCAL=no) AC_MSG_RESULT($PQXX_HAVE_THREAD_LOCAL) AC_MSG_CHECKING([PQXX_HAVE_YEAR_MONTH_DAY]) PQXX_HAVE_YEAR_MONTH_DAY=yes AC_COMPILE_IFELSE( [read_test(PQXX_HAVE_YEAR_MONTH_DAY.cxx)], AC_DEFINE( [PQXX_HAVE_YEAR_MONTH_DAY], 1, [Define if this feature is available.]), PQXX_HAVE_YEAR_MONTH_DAY=no) AC_MSG_RESULT($PQXX_HAVE_YEAR_MONTH_DAY) AC_MSG_CHECKING([no_need_fslib]) no_need_fslib=yes AC_COMPILE_IFELSE( [read_test(no_need_fslib.cxx)], AC_DEFINE( [no_need_fslib], 1, [Define if this feature is available.]), no_need_fslib=no) AC_MSG_RESULT($no_need_fslib) # End of config. libpqxx-7.10.0/requirements.json000066400000000000000000000002731473205454700167210ustar00rootroot00000000000000{ "description": "Minimum versions needed of various things.", "c++": "17", "libpq": "12.0", "postgresql": "12.0", "gcc": "9", "clang": "12", "msvc": "2019" } libpqxx-7.10.0/src/000077500000000000000000000000001473205454700140705ustar00rootroot00000000000000libpqxx-7.10.0/src/CMakeLists.txt000066400000000000000000000066721473205454700166430ustar00rootroot00000000000000if(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}) add_library(libpqxx::pqxx ALIAS pqxx) 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 ) libpqxx-7.10.0/src/Makefile.am000066400000000000000000000016151473205454700161270ustar00rootroot00000000000000lib_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 libpqxx-7.10.0/src/Makefile.in000066400000000000000000000652371473205454700161520ustar00rootroot00000000000000# Makefile.in generated by automake 1.16.5 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)/pqxx_cxx_feature_checks.ac \ $(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@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ 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: libpqxx-7.10.0/src/array.cxx000066400000000000000000000130251473205454700157330ustar00rootroot00000000000000/** Handling of SQL arrays. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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/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. template [[nodiscard]] std::string::size_type array_parser::scan_glyph(std::string::size_type pos) const { return pqxx::internal::glyph_scanner::call( std::data(m_input), std::size(m_input), pos); } /// Scan to next glyph in a substring. Assumes there is one. template std::string::size_type array_parser::scan_glyph( std::string::size_type pos, std::string::size_type end) const { return pqxx::internal::glyph_scanner::call( std::data(m_input), end, pos); } /// Find the end of a double-quoted SQL string in an SQL array. template 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); } /// Parse a double-quoted SQL string: un-quote it and un-escape it. template 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); } /// Find the end of an unquoted string in an SQL array. /** Assumes UTF-8 or an ASCII-superset single-byte encoding. */ template 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); } /// Parse an unquoted SQL string. /** Here, the special unquoted value NULL means a null value, not a string * that happens to spell "NULL". */ template std::string_view array_parser::parse_unquoted_string(std::string::size_type end) const { return pqxx::internal::parse_unquoted_string( std::data(m_input), end, m_pos); } array_parser::array_parser( std::string_view input, internal::encoding_group enc) : m_input{input}, m_impl{specialize_for_encoding(enc)} {} template std::pair array_parser::parse_array_step() { std::string value{}; if (m_pos >= std::size(m_input)) return std::make_pair(juncture::done, value); auto [found, end] = [this, &value] { if (scan_glyph(m_pos) - m_pos > 1) { // Non-ASCII unquoted string. auto const endpoint = scan_unquoted_string(); value = parse_unquoted_string(endpoint); return std::tuple{juncture::string_value, endpoint}; } else switch (m_input[m_pos]) { case '\0': throw failure{"Unexpected zero byte in array."}; case '{': return std::tuple{juncture::row_start, scan_glyph(m_pos)}; case '}': return std::tuple{juncture::row_end, scan_glyph(m_pos)}; case '"': { auto const endpoint = scan_double_quoted_string(); value = parse_double_quoted_string(endpoint); return std::tuple{juncture::string_value, endpoint}; } default: { auto const endpoint = scan_unquoted_string(); value = parse_unquoted_string(endpoint); 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(); return std::tuple{juncture::null_value, endpoint}; } else { // The normal case: we just parsed an unquoted string. The value // is what we need. PQXX_LIKELY return std::tuple{juncture::string_value, endpoint}; } } } }(); // 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] == ',')) PQXX_UNLIKELY end = next; } m_pos = end; return std::make_pair(found, value); } array_parser::implementation array_parser::specialize_for_encoding(pqxx::internal::encoding_group enc) { using encoding_group = pqxx::internal::encoding_group; #define PQXX_ENCODING_CASE(GROUP) \ case encoding_group::GROUP: \ return &array_parser::parse_array_step switch (enc) { PQXX_ENCODING_CASE(MONOBYTE); PQXX_ENCODING_CASE(BIG5); PQXX_ENCODING_CASE(EUC_CN); PQXX_ENCODING_CASE(EUC_JP); PQXX_ENCODING_CASE(EUC_KR); PQXX_ENCODING_CASE(EUC_TW); PQXX_ENCODING_CASE(GB18030); PQXX_ENCODING_CASE(GBK); PQXX_ENCODING_CASE(JOHAB); PQXX_ENCODING_CASE(MULE_INTERNAL); PQXX_ENCODING_CASE(SJIS); PQXX_ENCODING_CASE(UHC); PQXX_ENCODING_CASE(UTF8); } PQXX_UNLIKELY throw pqxx::internal_error{ pqxx::internal::concat("Unsupported encoding code: ", enc, ".")}; #undef PQXX_ENCODING_CASE } } // namespace pqxx libpqxx-7.10.0/src/binarystring.cxx000066400000000000000000000050201473205454700173240ustar00rootroot00000000000000/** Implementation of bytea (binary string) conversions. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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) { std::shared_ptr ptr{ static_cast(malloc(len + 1)), std::free}; if (not ptr) throw std::bad_alloc{}; ptr.get()[len] = '\0'; std::memcpy(ptr.get(), data, len); return ptr; } } // 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), pqxx::internal::pq::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}; } libpqxx-7.10.0/src/blob.cxx000066400000000000000000000175571473205454700155510ustar00rootroot00000000000000#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 *cx) noexcept { pqxx::internal::gate::connection_largeobject const gate{*cx}; 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 *cx) { pqxx::internal::gate::const_connection_largeobject const gate{*cx}; return gate.error_message(); } pqxx::blob pqxx::blob::open_internal(dbtransaction &tx, oid id, int mode) { auto &cx{tx.conn()}; int const fd{lo_open(raw_conn(&cx), id, mode)}; if (fd == -1) throw pqxx::failure{internal::concat( "Could not open binary large object ", id, ": ", errmsg(&cx))}; return {cx, fd}; } pqxx::oid pqxx::blob::create(dbtransaction &tx, oid id) { oid const 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) { m_conn->process_notice("Failure while closing binary large object:\n"); // TODO: Make at least an attempt to append a newline. m_conn->process_notice(e.what()); } } } 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 const 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(bytes &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 const 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 const 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 const 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, bytes_view data, oid id) { oid const 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(), "\n")); } catch (std::exception const &) {} } throw; } return actual_id; } void pqxx::blob::append_from_buf(dbtransaction &tx, bytes_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, bytes &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, bytes &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(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))}; } libpqxx-7.10.0/src/connection.cxx000066400000000000000000000775411473205454700167710ustar00rootroot00000000000000/** Implementation of the pqxx::connection class. * * pqxx::connection encapsulates a connection to a database. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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" // For ioctlsocket(). // We would normally include this after the standard headers, but MinGW warns // that we can't include windows.h before winsock2.h, and some of the standard // headers probably include windows.h. #if defined(_WIN32) && __has_include() # include #endif #include #include #include #include #include #include #include #include #include #include #include #include // For fcntl(). #if __has_include() # include #endif #if __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" namespace { void process_notice_raw( pqxx::internal::notice_waiters *waiters, pqxx::zview msg) noexcept { if ((waiters != nullptr) and not msg.empty()) { auto const rbegin = std::crbegin(waiters->errorhandlers), rend = std::crend(waiters->errorhandlers); for (auto i{rbegin}; (i != rend) and (**i)(msg.data()); ++i); if (waiters->notice_handler) waiters->notice_handler(msg); } } } // namespace 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 *cx, char const *msg) noexcept { process_notice_raw( reinterpret_cast(cx), pqxx::zview{msg}); } } // extern "C" using namespace std::literals; void PQXX_COLD PQXX_LIBEXPORT pqxx::internal::skip_init_ssl(int skips) noexcept { // We got "skip flags," but we pass to libpq which libraries we *do* want it // to initialise. PQinitOpenSSL( (skips & (1 << skip_init::openssl)) == 0, (skips & (1 << skip_init::crypto)) == 0); } std::string PQXX_COLD pqxx::encrypt_password(char const user[], char const password[]) { std::unique_ptr const p{ PQencryptPassword(password, user), pqxx::internal::pq::pqfreemem}; return {p.get()}; } pqxx::connection::connection(connection &&rhs) : m_conn{rhs.m_conn}, m_notice_waiters{std::move(rhs.m_notice_waiters)}, m_notification_handlers{std::move(rhs.m_notification_handlers)}, 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{}; set_up_notice_handlers(); if (status() == CONNECTION_BAD) { std::string const msg{PQerrorMessage(m_conn)}; PQfinish(m_conn); m_conn = nullptr; throw pqxx::broken_connection{msg}; } } pqxx::connection::connection(internal::pq::PGconn *raw_conn) : m_conn{raw_conn} { set_up_notice_handlers(); } 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)}; PQXX_LIKELY 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::set_up_notice_handlers() { if (not m_notice_waiters) m_notice_waiters = std::make_shared(); // Our notice processor gets a pointer to our notice_waiters. We can't // just pass "this" to it, because it may get called at a time when the // pqxx::connection has already been destroyed and only a pqxx::result // remains. if (m_conn != nullptr) PQsetNoticeProcessor( m_conn, pqxx_notice_processor, m_notice_waiters.get()); } 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); set_up_notice_handlers(); complete_init(); } void pqxx::connection::init(char const *params[], char const *values[]) { m_conn = PQconnectdbParams(params, values, 0); set_up_notice_handlers(); 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_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_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 our old connection, if any. close(); m_conn = std::exchange(rhs.m_conn, nullptr); m_unique_id = rhs.m_unique_id; m_notice_waiters = std::move(rhs.m_notice_waiters); m_notification_handlers = std::move(rhs.m_notification_handlers); return *this; } pqxx::result pqxx::connection::make_result( internal::pq::PGresult *pgr, std::shared_ptr const &query, std::string_view desc) { std::shared_ptr const smart{ pgr, internal::clear_result}; if (not smart) { if (is_open()) throw failure(err_msg()); else throw broken_connection{"Lost connection to the database server."}; } auto const enc{internal::enc_group(encoding_id())}; auto r{pqxx::internal::gate::result_creation::create( smart, query, m_notice_waiters, 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))) .one_field() .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."}; } constexpr int oldest_server{90000}; if (server_version() <= oldest_server) throw feature_not_supported{ "Unsupported server version; 9.0 is the minimum."}; } bool pqxx::connection::is_open() const noexcept { return status() == CONNECTION_OK; } void pqxx::connection::process_notice(char const msg[]) noexcept { process_notice(zview{msg}); } void pqxx::connection::process_notice(zview msg) noexcept { if (not msg.empty()) process_notice_raw(m_notice_waiters.get(), msg); } 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::connection::listen( std::string_view channel, notification_handler handler) { if (m_trans != nullptr) throw usage_error{pqxx::internal::concat( "Attempting to listen for notifications on '", channel, "' while transaction is active.")}; std::string str_name{channel}; auto const pos{m_notification_handlers.lower_bound(str_name)}, handlers_end{std::end(m_notification_handlers)}; if (handler) { // Setting a handler. if ((pos != handlers_end) and (pos->first == channel)) { // Overwrite existing handler. m_notification_handlers.insert_or_assign( pos, std::move(str_name), std::move(handler)); } else { // We had no handler installed for this name. Start listening. exec(pqxx::internal::concat("LISTEN ", quote_name(channel))).no_rows(); m_notification_handlers.emplace_hint(pos, channel, std::move(handler)); } } else { // Installing an empty handler. That's equivalent to removing whatever // handler may have been installed previously. if (pos != handlers_end) { // Yes, we had a handler for this name. Remove it. exec(pqxx::internal::concat("UNLISTEN ", quote_name(channel))).no_rows(); m_notification_handlers.erase(pos); } } } 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, "'\n")); } 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))); } } catch (std::exception const &e) { // TODO: Make at least an attempt to append a newline. 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; } namespace { /// Wrapper for `PQfreeCancel`, with C++ linkage. void wrap_pgfreecancel(PGcancel *ptr) { PQfreeCancel(ptr); } /// A fairly arbitrary buffer size for error strings and such. constexpr int buf_size{500u}; } // namespace void PQXX_COLD pqxx::connection::cancel_query() { std::unique_ptr const cancel{ PQgetCancel(m_conn), wrap_pgfreecancel}; if (cancel == nullptr) PQXX_UNLIKELY throw std::bad_alloc{}; std::array errbuf{}; auto const err{errbuf.data()}; auto const c{PQcancel(cancel.get(), err, buf_size)}; if (c == 0) PQXX_UNLIKELY throw pqxx::sql_error{std::string{err, std::size(errbuf)}, "[cancel]"}; } #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{pqxx::internal::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{pqxx::internal::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{pqxx::internal::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 *cx) { return {PQnotifies(cx), pqxx::internal::pq::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 != nullptr) PQXX_UNLIKELY return 0; int notifs = 0; // Old mechanism. This is going away. for (auto N{get_notif(m_conn)}; N.get(); N = get_notif(m_conn)) { notifs++; std::string const channel{N->relname}; auto const Hit{m_receivers.equal_range(channel)}; if (Hit.second != Hit.first) { std::string const 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"); } } } auto const handler{m_notification_handlers.find(N->relname)}; // C++20: Use "dot notation" to initialise struct fields. if (handler != std::end(m_notification_handlers)) (handler->second)(notification{*this, channel, N->extra, N->be_pid}); 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) { m_notice_waiters->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_notice_waiters->errorhandlers.remove(handler); } std::vector PQXX_COLD pqxx::connection::get_errorhandlers() const { return { std::begin(m_notice_waiters->errorhandlers), std::end(m_notice_waiters->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 const &query, std::string_view desc) { auto 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) { auto const buf{PQencryptPasswordConn(m_conn, password, user, algorithm)}; std::unique_ptr const ptr{ buf, pqxx::internal::pq::pqfreemem}; return (ptr.get()); } 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 r{make_result(pq_result, q, statement)}; get_notifs(); return r; } void pqxx::connection::close() { // Just in case PQfinish() doesn't handle nullptr nicely. if (m_conn == nullptr) return; try { if (m_trans) PQXX_UNLIKELY process_notice(internal::concat( "Closing connection while ", internal::describe_object("transaction"sv, m_trans->name()), " is still open.\n")); if (not std::empty(m_receivers)) { PQXX_UNLIKELY process_notice("Closing connection with outstanding receivers.\n"); m_receivers.clear(); } if (m_notice_waiters) { // It's a bit iffy to unregister these in this destructor. There may // still be result objects that want to process notices. But it's an // improvement over the 7.9-and-older situation where you'd simply get a // stale pointer. Better yet, this whole mechanism is going away. #include "pqxx/internal/ignore-deprecated-pre.hxx" auto old_handlers{get_errorhandlers()}; #include "pqxx/internal/ignore-deprecated-post.hxx" 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) { // TODO: Make at least an attempt to append a newline. 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 std::make_pair( std::unique_ptr{ nullptr, pqxx::internal::pq::pqfreemem}, 0u); case 0: // "Come back later." throw internal_error{"table read inexplicably went asynchronous"}; default: // Success, got buffer size. PQXX_LIKELY { // 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, pqxx::internal::pq::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 const 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(bytes_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{reinterpret_cast(text)}; std::unique_ptr const ptr{ PQunescapeBytea(bytes, &len), pqxx::internal::pq::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(bytes_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(bytes_view b) const { return internal::concat("'", esc_raw(b), "'::bytea"); } std::string pqxx::connection::quote_name(std::string_view identifier) const { std::unique_ptr const buf{ PQescapeIdentifier(m_conn, identifier.data(), std::size(identifier)), pqxx::internal::pq::pqfreemem}; if (buf == 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)); // TODO: Rewrite using a char_finder. 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 == '%')) 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 const 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 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; } /// Wrapper for `PQconninfoFree()`, with C++ linkage. void pqconninfofree(PQconninfoOption *ptr) { PQconninfoFree(ptr); } } // 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 const params{ PQconninfo(m_conn), pqconninfofree}; if (params == 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( libpqxx-7.10.0/src/cursor.cxx000066400000000000000000000200121473205454700161240ustar00rootroot00000000000000/** Implementation of libpqxx STL-style cursor classes. * * These classes wrap SQL cursors in STL-like interfaces. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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::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 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 const 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 == this) {} else 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; } libpqxx-7.10.0/src/encodings.cxx000066400000000000000000000143211473205454700165660ustar00rootroot00000000000000/** Implementation of string encodings support * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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/internal/encodings.hxx" #include "pqxx/strconv.hxx" #include "pqxx/internal/header-post.hxx" using namespace std::literals; namespace pqxx::internal { /// Convert libpq encoding name to its libpqxx encoding group. pqxx::internal::encoding_group enc_group(std::string_view encoding_name) { struct mapping { private: std::string_view m_name; pqxx::internal::encoding_group m_group; public: constexpr mapping(std::string_view n, pqxx::internal::encoding_group g) : m_name{n}, m_group{g} {} constexpr bool operator<(mapping const &rhs) const { return m_name < rhs.m_name; } [[nodiscard]] std::string_view get_name() const { return m_name; } [[nodiscard]] pqxx::internal::encoding_group get_group() const { return m_group; } }; // 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 pqxx::internal::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, pqxx::internal::encoding_group::EUC_CN}, // We support EUC_JIS_2004 and EUC_JP as identical encodings. mapping{"JIS_2004"sv, pqxx::internal::encoding_group::EUC_JP}, mapping{"JP"sv, pqxx::internal::encoding_group::EUC_JP}, mapping{"KR"sv, pqxx::internal::encoding_group::EUC_KR}, mapping{"TW"sv, pqxx::internal::encoding_group::EUC_TW}, }; for (auto const &m : subtypes) if (m.get_name() == subtype) return m.get_group(); } PQXX_UNLIKELY break; case 'G': if (encoding_name == "GB18030"sv) return pqxx::internal::encoding_group::GB18030; else if (encoding_name == "GBK"sv) return pqxx::internal::encoding_group::GBK; PQXX_UNLIKELY break; case 'I': // We know iso-8859-X, where 5 <= X < 9. They're all monobyte encodings. // C++20: Use string_view::starts_with(). 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 pqxx::internal::encoding_group::MONOBYTE; } PQXX_UNLIKELY break; case 'J': if (encoding_name == "JOHAB"sv) return pqxx::internal::encoding_group::JOHAB; PQXX_UNLIKELY break; case 'K': if ((encoding_name == "KOI8R"sv) or (encoding_name == "KOI8U"sv)) return pqxx::internal::encoding_group::MONOBYTE; PQXX_UNLIKELY break; case 'L': // We know LATIN1 through LATIN10. // C++20: Use string_view::starts_with(). 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 pqxx::internal::encoding_group::MONOBYTE; } else if (subtype == "10"sv) { return pqxx::internal::encoding_group::MONOBYTE; } } PQXX_UNLIKELY break; case 'M': if (encoding_name == "MULE_INTERNAL"sv) return pqxx::internal::encoding_group::MULE_INTERNAL; PQXX_UNLIKELY break; case 'S': if (encoding_name == "SHIFT_JIS_2004"sv) return pqxx::internal::encoding_group::SJIS; else if (encoding_name == "SJIS"sv) return pqxx::internal::encoding_group::SJIS; else if (encoding_name == "SQL_ASCII"sv) return pqxx::internal::encoding_group::MONOBYTE; PQXX_UNLIKELY break; case 'U': if (encoding_name == "UHC"sv) return pqxx::internal::encoding_group::UHC; else if (encoding_name == "UTF8"sv) return pqxx::internal::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 pqxx::internal::encoding_group::MONOBYTE; } PQXX_UNLIKELY break; default: PQXX_UNLIKELY break; } PQXX_UNLIKELY throw std::invalid_argument{ pqxx::internal::concat("Unrecognized encoding: '", encoding_name, "'.")}; } PQXX_PURE char const *name_encoding(int encoding_id) { return pg_encoding_to_char(encoding_id); } encoding_group enc_group(int libpq_enc_id) { // TODO: Can we safely do this without using string representation? return enc_group(name_encoding(libpq_enc_id)); } PQXX_PURE glyph_scanner_func *get_glyph_scanner(encoding_group enc) { #define CASE_GROUP(ENC) \ case encoding_group::ENC: return glyph_scanner::call switch (enc) { PQXX_LIKELY CASE_GROUP(MONOBYTE); CASE_GROUP(BIG5); CASE_GROUP(EUC_CN); CASE_GROUP(EUC_JP); 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(UHC); PQXX_LIKELY CASE_GROUP(UTF8); } PQXX_UNLIKELY throw usage_error{ internal::concat("Unsupported encoding group code ", enc, ".")}; #undef CASE_GROUP } } // namespace pqxx::internal libpqxx-7.10.0/src/errorhandler.cxx000066400000000000000000000020401473205454700172770ustar00rootroot00000000000000/** Implementation of pqxx::errorhandler and helpers. * * pqxx::errorhandler allows programs to receive errors and warnings. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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 &cx) : m_home{&cx} { 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); } } libpqxx-7.10.0/src/except.cxx000066400000000000000000000132321473205454700161050ustar00rootroot00000000000000/** Implementation of libpqxx exception classes. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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" #if defined(PQXX_HAVE_SOURCE_LOCATION) pqxx::failure::failure(std::string const &whatarg, std::source_location loc) : std::runtime_error{whatarg}, location{loc} {} #else pqxx::failure::failure(std::string const &whatarg) : std::runtime_error{whatarg} {} #endif pqxx::broken_connection::broken_connection() : failure{"Connection to database failed."} {} pqxx::broken_connection::broken_connection( std::string const &whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : failure{ whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif } {} pqxx::protocol_violation::protocol_violation( std::string const &whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : broken_connection{ whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif } {} pqxx::variable_set_to_null::variable_set_to_null( std::string const &whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : failure{ whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif } {} pqxx::sql_error::sql_error( std::string const &whatarg, std::string Q, char const *sqlstate #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : failure{ whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif }, m_query{std::move(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 #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : failure{ whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif } {} pqxx::transaction_rollback::transaction_rollback( std::string const &whatarg, std::string const &q, char const sqlstate[] #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : sql_error{ whatarg, q, sqlstate #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif } {} pqxx::serialization_failure::serialization_failure( std::string const &whatarg, std::string const &q, char const sqlstate[] #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : transaction_rollback{ whatarg, q, sqlstate #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif } {} pqxx::statement_completion_unknown::statement_completion_unknown( std::string const &whatarg, std::string const &q, char const sqlstate[] #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : transaction_rollback{ whatarg, q, sqlstate #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif } {} pqxx::deadlock_detected::deadlock_detected( std::string const &whatarg, std::string const &q, char const sqlstate[] #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : transaction_rollback{ whatarg, q, sqlstate #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif } {} 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 #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : std::logic_error{whatarg} #if defined(PQXX_HAVE_SOURCE_LOCATION) , location{loc} #endif {} pqxx::argument_error::argument_error( std::string const &whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : invalid_argument{whatarg} #if defined(PQXX_HAVE_SOURCE_LOCATION) , location{loc} #endif {} pqxx::conversion_error::conversion_error( std::string const &whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : domain_error{whatarg} #if defined(PQXX_HAVE_SOURCE_LOCATION) , location{loc} #endif {} pqxx::unexpected_null::unexpected_null( std::string const &whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : conversion_error{ whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif } {} pqxx::conversion_overrun::conversion_overrun( std::string const &whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : conversion_error{ whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif } {} pqxx::range_error::range_error( std::string const &whatarg #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) : out_of_range{whatarg} #if defined(PQXX_HAVE_SOURCE_LOCATION) , location{loc} #endif {} libpqxx-7.10.0/src/field.cxx000066400000000000000000000031451473205454700157020ustar00rootroot00000000000000/** Implementation of the pqxx::field class. * * pqxx::field refers to a field in a query result. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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 noexcept { 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()); } libpqxx-7.10.0/src/largeobject.cxx000066400000000000000000000173571473205454700171120ustar00rootroot00000000000000/** Implementation of the Large Objects interface. * * Allows direct access to large objects, as well as though I/O streams. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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) : m_id{lo_creat(raw_connection(t), 0)} { // (Mode is ignored as of postgres 8.1.) 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 &cx, int err) const { if (err == ENOMEM) return "Out of memory"; return pqxx::internal::gate::const_connection_largeobject{cx} .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" libpqxx-7.10.0/src/notification.cxx000066400000000000000000000017261473205454700173100ustar00rootroot00000000000000/** Implementation of the pqxx::notification_receiever class. * * pqxx::notification_receiver processes notifications. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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 &cx, std::string_view channel) : m_conn{cx}, m_channel{channel} { pqxx::internal::gate::connection_notification_receiver{cx}.add_receiver( this); } pqxx::notification_receiver::~notification_receiver() { pqxx::internal::gate::connection_notification_receiver{this->conn()} .remove_receiver(this); } libpqxx-7.10.0/src/params.cxx000066400000000000000000000046771473205454700161150ustar00rootroot00000000000000/* Implementations related to prepared and parameterised statements. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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(bytes_view value) & { m_params.emplace_back(value); } void pqxx::params::append(bytes const &value) & { m_params.emplace_back(value); } void pqxx::params::append(bytes &&value) & { m_params.emplace_back(std::move(value)); } void PQXX_COLD pqxx::params::append(binarystring const &value) & { m_params.emplace_back(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(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; } libpqxx-7.10.0/src/pipeline.cxx000066400000000000000000000266321473205454700164320ustar00rootroot00000000000000/** Implementation of the pqxx::pipeline class. * * Throughput-optimized query interface. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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" using namespace std::literals::string_view_literals; namespace { constexpr std::string_view theSeparator{"; "sv}, theDummyValue{"1"sv}, theDummyQuery{"SELECT 1; "sv}; } // 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 = pqxx::internal::concat(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()}; std::shared_ptr const r{ gate.get_result(), pqxx::internal::clear_result}; if (not r) { if (have_pending() and not expect_none) { PQXX_UNLIKELY set_error_at(m_issuedrange.first->first); m_issuedrange.second = m_issuedrange.first; } return false; } pqxx::internal::gate::connection_pipeline const pgate{m_trans->conn()}; auto handler{pgate.get_notice_waiters()}; result const res{pqxx::internal::gate::result_creation::create( r, std::begin(m_queries)->second.query, handler, 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()}; std::shared_ptr const r{ gate.get_result(), pqxx::internal::clear_result}; m_dummy_pending = false; if (not r) PQXX_UNLIKELY internal_error("Pipeline got no result from backend when it expected one."); pqxx::internal::gate::connection_pipeline const pgate{m_trans->conn()}; auto handler{pgate.get_notice_waiters()}; result const R{pqxx::internal::gate::result_creation::create( r, text, handler, 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 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(); } libpqxx-7.10.0/src/pqxx-source.hxx000066400000000000000000000016511473205454700171220ustar00rootroot00000000000000/* 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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 libpqxx-7.10.0/src/result.cxx000066400000000000000000000372561473205454700161470ustar00rootroot00000000000000/** Implementation of the pqxx::result class and support classes. * * pqxx::result represents the set of result rows from a database query * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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); } // namespace pqxx std::string const pqxx::result::s_empty_string; /// C++ wrapper for libpq's PQclear. void pqxx::internal::clear_result(pq::PGresult const *data) noexcept { // This acts as a destructor, though implemented as a regular function so we // can pass it into a smart pointer. That's why I think it's kind of fair // to treat the PGresult as const. PQclear(const_cast(data)); } pqxx::result::result( std::shared_ptr const &rhs, std::shared_ptr const &query, std::shared_ptr const ¬ice_waiters, internal::encoding_group enc) : m_data{rhs}, m_query{query}, m_notice_waiters{notice_waiters}, 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_MULTIDIM) pqxx::field pqxx::result::operator[]( result_size_type row_num, row_size_type col_num) const noexcept { return {*this, row_num, col_num}; } #endif // PQXX_HAVE_MULTIDIM 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': if (equal(code, "08P01")) throw protocol_violation{Err}; 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. case PGRES_COPY_OUT: // Copy Out (from server) data transfer started. case PGRES_COPY_IN: // Copy In (to server) data transfer started. case PGRES_COPY_BOTH: // Copy In/Out. Used for streaming replication. break; #if defined(LIBPQ_HAS_PIPELINING) case PGRES_PIPELINE_SYNC: // Pipeline mode synchronisation point. case PGRES_PIPELINE_ABORTED: // Previous command in pipeline failed. throw feature_not_supported{"Not supported yet: libpq pipelines."}; #endif case PGRES_BAD_RESPONSE: // The server's response was not understood. case PGRES_NONFATAL_ERROR: case PGRES_FATAL_ERROR: PQXX_UNLIKELY err = PQresultErrorMessage(m_data.get()); break; case PGRES_SINGLE_TUPLE: throw feature_not_supported{"Not supported: single-row mode."}; default: throw internal_error{internal::concat( "pqxx::result: Unrecognized result status code ", PQresultStatus(m_data.get()))}; } return err; } char const *pqxx::result::cmd_status() const noexcept { // PQcmdStatus() can't take a PGresult const * because it returns a non-const // pointer into the PGresult's data, and that can't be changed without // breaking compatibility. return PQcmdStatus(const_cast(m_data.get())); } std::string const &pqxx::result::query() const & noexcept { return (m_query == 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(m_data.get()); } pqxx::result::size_type pqxx::result::affected_rows() const { // PQcmdTuples() can't take a PGresult const * because it returns a non-const // pointer into the PGresult's data, and that can't be changed without // breaking compatibility. 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 noexcept { return PQgetvalue(m_data.get(), row, col); } bool pqxx::result::get_is_null( pqxx::result::size_type row, pqxx::row::size_type col) const noexcept { 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(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(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 { return m_data ? row::size_type(PQnfields(m_data.get())) : 0; } int pqxx::result::column_storage(pqxx::row::size_type number) const { int const out{PQfsize(m_data.get(), number)}; if (out == 0) { auto const sz{this->size()}; if ((number < 0) or (number >= sz)) throw argument_error{pqxx::internal::concat( "Column number out of range: ", number, " (have 0 - ", sz, ")")}; throw failure{pqxx::internal::concat( "Error getting column_storage for column ", number)}; } return out; } int pqxx::result::column_type_modifier( pqxx::row::size_type number) const noexcept { return PQfmod(m_data.get(), number); } pqxx::row pqxx::result::one_row() const { auto const sz{size()}; if (sz != 1) { // TODO: See whether result contains a generated statement. if (not m_query or m_query->empty()) throw unexpected_rows{ pqxx::internal::concat("Expected 1 row from query, got ", sz, ".")}; else throw unexpected_rows{pqxx::internal::concat( "Expected 1 row from query '", *m_query, "', got ", sz, ".")}; } return front(); } pqxx::field pqxx::result::one_field() const { expect_columns(1); return one_row()[0]; } std::optional pqxx::result::opt_row() const { auto const sz{size()}; if (sz > 1) { // TODO: See whether result contains a generated statement. if (not m_query or m_query->empty()) throw unexpected_rows{pqxx::internal::concat( "Expected at most 1 row from query, got ", sz, ".")}; else throw unexpected_rows{pqxx::internal::concat( "Expected at most 1 row from query '", *m_query, "', got ", sz, ".")}; } else if (sz == 1) { return {front()}; } else { return {}; } } // 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 const tmp{*this}; iterator_type::operator--(); return tmp; } pqxx::const_reverse_result_iterator pqxx::const_reverse_result_iterator::operator--(int) & { const_reverse_result_iterator const tmp{*this}; iterator_type::operator++(); return tmp; } template<> std::string pqxx::to_string(field const &value) { return {value.c_str(), std::size(value)}; } libpqxx-7.10.0/src/robusttransaction.cxx000066400000000000000000000140311473205454700203770ustar00rootroot00000000000000/** Implementation of the pqxx::robusttransaction class. * * pqxx::robusttransaction is a slower but safer transaction class. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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 cx{conn_str}; pqxx::nontransaction tx{cx, name}; auto const status_row{tx.exec(query).one_row()}; 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).one_field().to(m_xid); } pqxx::internal::basic_robusttransaction::basic_robusttransaction( connection &cx, zview begin_command, std::string_view tname) : dbtransaction(cx, tname), m_conn_string{cx.connection_string()} { init(begin_command); } pqxx::internal::basic_robusttransaction::basic_robusttransaction( connection &cx, zview begin_command) : dbtransaction(cx), m_conn_string{cx.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. constexpr int max_attempts{500}; constexpr unsigned int wait_micros{300u}; static_assert(max_attempts > 0); for (int attempts{0}; attempts < max_attempts; ++attempts, pqxx::internal::wait_for(wait_micros)) { try { switch (query_status(m_xid, m_conn_string)) { 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; default: PQXX_UNREACHABLE; } } catch (pqxx::broken_connection const &) { // We can expect this to happen before we can get a working // connection. Swallow the error and retry. } } // 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.")}; } libpqxx-7.10.0/src/row.cxx000066400000000000000000000116541473205454700154320ustar00rootroot00000000000000/** Implementation of the pqxx::result class and support classes. * * pqxx::result represents the set of result rows from a database query. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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 r, result::size_type index, size_type cols) noexcept : m_result{std::move(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 noexcept { return const_reverse_row_iterator{end()}; } pqxx::row::const_reverse_iterator pqxx::row::crbegin() const noexcept { return rbegin(); } pqxx::row::const_reverse_iterator pqxx::row::rend() const noexcept { return const_reverse_row_iterator{begin()}; } pqxx::row::const_reverse_iterator pqxx::row::crend() const noexcept { 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) & noexcept { auto old{*this}; m_col++; return old; } pqxx::const_row_iterator pqxx::const_row_iterator::operator--(int) & noexcept { auto 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) & noexcept { auto tmp{*this}; operator++(); return tmp; } pqxx::const_reverse_row_iterator pqxx::const_reverse_row_iterator::operator--(int) & { auto tmp{*this}; operator--(); return tmp; } libpqxx-7.10.0/src/sql_cursor.cxx000066400000000000000000000205311473205454700170110ustar00rootroot00000000000000/** Implementation of libpqxx STL-style cursor classes. * * These classes wrap SQL cursors in STL-like interfaces. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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/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 std::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{size}; if (enc == pqxx::internal::encoding_group::MONOBYTE) { // This is an encoding where we can scan backwards from the end. // C++20: Use string_view::ends_with() and sub-view. while (end > 0 and useless_trail(query[end - 1])) --end; } else { // Complex encoding. We only know how to iterate forwards, so start from // the beginning. end = 0; // TODO: Rewrite using find_char. 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_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_ownership{op}, m_at_end{0}, m_pos{-1} {} 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 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); } libpqxx-7.10.0/src/strconv.cxx000066400000000000000000000542531473205454700163230ustar00rootroot00000000000000/** Implementation of string conversions. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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/internal/concat.hxx" #include "pqxx/strconv.hxx" #include "pqxx/internal/header-post.hxx" using namespace std::literals; 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 /// 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) { constexpr int ten{10}; char *pos = end; *--pos = '\0'; do { *--pos = pqxx::internal::number_to_digit(int(value % ten)); value = T(value / ten); } 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 *const pos{[end, &value]() { if constexpr (std::is_unsigned_v) return nonneg_to_buf(end, value); else if (value >= 0) return nonneg_to_buf(end, value); else if (value > bottom) return neg_to_buf(end, -value); else return 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. std::unique_ptr const demangled{ abi::__cxa_demangle(raw, nullptr, nullptr, &status), [](char *x) { std::free(x); }}; #else std::unique_ptr demangled{}; #endif return std::string{demangled ? demangled.get() : raw}; } // TODO: Equivalents for converting a null in the other direction. void PQXX_COLD throw_null_conversion(std::string const &type) { throw conversion_error{concat("Attempt to convert SQL null to ", type, ".")}; } void PQXX_COLD throw_null_conversion(std::string_view type) { throw conversion_error{concat("Attempt to convert SQL 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. // C++20: Use formatting library. 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{std::data(in)}; 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. while (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 #if !defined(PQXX_HAVE_CHARCONV_FLOAT) namespace { constexpr bool valid_infinity_string(std::string_view text) noexcept { return text == "inf" or text == "infinity" or text == "INFINITY" or text == "Infinity"; } /// 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; // TODO: Don't really need to handle all these formats. 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 std::size("true"sv): if (text == "true" or text == "TRUE") result = true; break; case std::size("false"sv): if (text == "false" or text == "FALSE") result = false; break; default: break; } if (result) return *result; else throw conversion_error{ "Failed conversion to bool: '" + std::string{text} + "'."}; } libpqxx-7.10.0/src/stream_from.cxx000066400000000000000000000171201473205454700171330ustar00rootroot00000000000000/** Implementation of the pqxx::stream_from class. * * pqxx::stream_from enables optimized batch reads from a database table. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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 "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::char_finder_func *get_finder(pqxx::transaction_base const &tx) { auto const group{pqxx::internal::enc_group(tx.conn().encoding_id())}; return pqxx::internal::get_char_finder<'\t', '\\'>(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_char_finder{get_finder(tx)} { tx.exec(internal::concat("COPY ("sv, query, ") TO STDOUT"sv)).no_rows(); register_me(); } pqxx::stream_from::stream_from( transaction_base &tx, from_table_t, std::string_view table) : transaction_focus{tx, class_name, table}, m_char_finder{get_finder(tx)} { tx.exec(internal::concat("COPY "sv, tx.quote_name(table), " TO STDOUT"sv)) .no_rows(); 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_char_finder{get_finder(tx)} { if (std::empty(columns)) PQXX_UNLIKELY tx.exec(internal::concat("COPY "sv, table, " TO STDOUT"sv)).no_rows(); else PQXX_LIKELY tx .exec(internal::concat("COPY "sv, table, "("sv, columns, ") TO STDOUT"sv)) .no_rows(); 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 &cx{tx.conn()}; #include "pqxx/internal/ignore-deprecated-pre.hxx" return raw_table(tx, cx.quote_table(path), cx.quote_columns(columns)); #include "pqxx/internal/ignore-deprecated-post.hxx" } 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 == nullptr) close(); return line; } catch (std::exception const &) { close(); throw; } } else { return std::make_pair( std::unique_ptr{nullptr, nullptr}, 0u); } } 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; // TODO: Any way to keep current size in a local var, for speed? 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()}; std::string_view const line_view{line_begin, line_size}; // 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}; std::size_t offset{0}; while (offset < line_size) { auto const stop_char{m_char_finder(line_view, offset)}; // Copy the text we have so far. It's got no special characters in it. std::memcpy(write, &line_begin[offset], stop_char - offset); write += (stop_char - offset); if (stop_char >= line_size) break; offset = stop_char; char const special{line_begin[stop_char]}; ++offset; if (special == '\t') { // Field separator. End the field. // 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.emplace_back(field_begin, write - field_begin); *write++ = '\0'; } // Set up for the next field. field_begin = write; } else { // Escape sequence. assert(special == '\\'); if ((offset) >= line_size) throw failure{"Row ends in backslash"}; // The database will only escape ASCII characters, so no need to use // the glyph scanner. char const escaped{line_begin[offset++]}; if (escaped == '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.) } *write++ = pqxx::internal::unescape_char(escaped); } } // End the last field here. if (field_begin == nullptr) { m_fields.emplace_back(); } else { m_fields.emplace_back(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; } libpqxx-7.10.0/src/stream_to.cxx000066400000000000000000000067241473205454700166220ustar00rootroot00000000000000/** Implementation of the pqxx::stream_to class. * * pqxx::stream_to enables optimized batch updates to a database table. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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.exec( std::empty(columns) ? pqxx::internal::concat("COPY "sv, table, " FROM STDIN"sv) : pqxx::internal::concat( "COPY "sv, table, "("sv, columns, ") FROM STDIN"sv)) .no_rows(); } /// Return the escape character for escaping the given special character. char escape_char(char special) { switch (special) { 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 '\\'; default: break; } PQXX_UNLIKELY throw pqxx::internal_error{pqxx::internal::concat( "Stream escaping unexpectedly stopped at '", static_cast(static_cast(special)), "'.")}; } } // 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_finder{pqxx::internal::get_char_finder< '\b', '\f', '\n', '\r', '\t', '\v', '\\'>( 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(); } } void pqxx::stream_to::escape_field_to_buffer(std::string_view data) { std::size_t const end{std::size(data)}; std::size_t here{0}; while (here < end) { auto const stop_char{m_finder(data, here)}; // Append any unremarkable we just skipped over. m_buffer.append(std::data(data) + here, stop_char - here); if (stop_char < end) { m_buffer.push_back('\\'); m_buffer.push_back(escape_char(data[stop_char])); } here = stop_char + 1; } // Terminate the field. m_buffer.push_back('\t'); } libpqxx-7.10.0/src/subtransaction.cxx000066400000000000000000000033451473205454700176600ustar00rootroot00000000000000/** Implementation of the pqxx::subtransaction class. * * pqxx::transaction is a nested transaction, i.e. one within a transaction * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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 &; } // namespace 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()))); } libpqxx-7.10.0/src/time.cxx000066400000000000000000000165221473205454700155600ustar00rootroot00000000000000/** 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; /// Because the C++ Core Guidelines don't like numeric constants... constexpr int ten{10}; /// 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? constexpr int oldest{-32767}; static_assert(int{(std::chrono::year::min)()} == oldest); 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})}; // Keep C++ Code Guidelines happy. constexpr int hundred{100}, thousand{1000}; // 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 < thousand) { PQXX_UNLIKELY *begin++ = '0'; if (absy < hundred) *begin++ = '0'; if (absy < ten) *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 char *month_into_buf(char *begin, std::chrono::month const &value) { unsigned const m{value}; if (m >= ten) *begin = '1'; else *begin = '0'; ++begin; *begin++ = pqxx::internal::number_to_digit(static_cast(m % ten)); 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( (ten * 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 const d{value}; *begin++ = pqxx::internal::number_to_digit(static_cast(d / ten)); *begin++ = pqxx::internal::number_to_digit(static_cast(d % ten)); 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( (ten * 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{0}; while (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 libpqxx-7.10.0/src/transaction.cxx000066400000000000000000000064351473205454700171510ustar00rootroot00000000000000/** Implementation of the pqxx::transaction class. * * pqxx::transaction represents a regular database transaction. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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 &cx, zview begin_command, std::string_view tname) : dbtransaction(cx, tname) { register_transaction(); direct_exec(begin_command); } pqxx::internal::basic_transaction::basic_transaction( connection &cx, zview begin_command, std::string &&tname) : dbtransaction(cx, std::move(tname)) { register_transaction(); direct_exec(begin_command); } pqxx::internal::basic_transaction::basic_transaction( connection &cx, zview begin_command) : dbtransaction(cx) { 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 status 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{ msg #if defined(PQXX_HAVE_SOURCE_LOCATION) , e.location #endif }; } 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{msg}; } else { // Commit failed--probably due to a constraint violation or something // similar. throw; } } } libpqxx-7.10.0/src/transaction_base.cxx000066400000000000000000000320131473205454700201320ustar00rootroot00000000000000/** 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-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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 "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 &cx) : m_conn{cx}, m_rollback_cmd{make_rollback_cmd()} {} pqxx::transaction_base::transaction_base( connection &cx, std::string_view tname) : m_conn{cx}, 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 &) { // TODO: Make at least an attempt to append a newline. 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: PQXX_UNREACHABLE; } // 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: PQXX_UNREACHABLE; } 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() noexcept { unregister_me(); } command() = delete; command(command const &) = delete; command(command &&) = delete; command &operator=(command const &) = delete; command &operator=(command &&) = delete; }; } // namespace pqxx::result pqxx::transaction_base::exec(std::string_view query, std::string_view desc) { check_pending_error(); command const 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: PQXX_UNREACHABLE; } 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 r{exec(query, desc)}; #include "pqxx/internal/ignore-deprecated-post.hxx" r.expect_rows(rows); return r; } pqxx::result pqxx::transaction_base::internal_exec_prepared( std::string_view statement, internal::c_params const &args) { command const cmd{*this, statement}; return pqxx::internal::gate::connection_transaction{conn()}.exec_prepared( statement, args); } pqxx::result pqxx::transaction_base::internal_exec_params( std::string_view query, internal::c_params const &args) { command const cmd{*this, query}; return pqxx::internal::gate::connection_transaction{conn()}.exec_params( query, args); } void pqxx::transaction_base::notify( std::string_view channel, std::string_view payload) { // For some reason, NOTIFY does not work as a parameterised statement, // even just for the payload (which is supposed to be a normal string). // Luckily, pg_notify() does. exec("SELECT pg_notify($1, $2)", params{channel, payload}).one_row(); } 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) { // TODO: Make at least an attempt to append a newline. 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) { // TODO: Make at least an attempt to append a newline. m_conn.process_notice(e.what()); } } catch (std::exception const &e) { try { // TODO: Make at least an attempt to append a newline. 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) { // TODO: Make at least an attempt to append a newline. m_conn.process_notice(e.what()); } } 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( std::move(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"); // TODO: Make at least an attempt to append a newline. process_notice(e.what()); process_notice("ERROR WAS:\n"); 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"); // TODO: Make at least an attempt to append a newline. process_notice(e.what()); process_notice("ERROR WAS:\n"); 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); } libpqxx-7.10.0/src/util.cxx000066400000000000000000000131711473205454700155740ustar00rootroot00000000000000/** Various utility functions. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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 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(old_class, old_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 std::array 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 { assert(c >= 0 and c < pqxx::internal::ssize(hex_digits)); return hex_digits[static_cast(c)]; } constexpr int ten{10}; /// 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 ten + (c - 'a'); else if (c >= 'A' and c <= 'F') return ten + (c - 'A'); else return -1; } } // namespace void pqxx::internal::esc_bin(bytes_view binary_data, char buffer[]) noexcept { auto here{buffer}; *here++ = '\\'; *here++ = 'x'; constexpr int nibble_bits{4}; constexpr int nibble_mask{0x0f}; for (auto const byte : binary_data) { auto uc{static_cast(byte)}; *here++ = hex_digit(uc >> nibble_bits); *here++ = hex_digit(uc & nibble_mask); } // (No need to increment further. Facebook's "infer" complains if we do.) *here = '\0'; } std::string pqxx::internal::esc_bin(bytes_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 const hi{nibble(*in++)}; if (hi < 0) throw pqxx::failure{"Invalid hex-escaped data."}; int const lo{nibble(*in++)}; if (lo < 0) throw pqxx::failure{"Invalid hex-escaped data."}; *out++ = static_cast((hi << 4) | lo); } } pqxx::bytes pqxx::internal::unesc_bin(std::string_view escaped_data) { auto const bytes{size_unesc_bin(std::size(escaped_data))}; pqxx::bytes buf; buf.resize(bytes); unesc_bin(escaped_data, buf.data()); return buf; } namespace pqxx::internal::pq { void pqfreemem(void const *ptr) noexcept { // Why is it OK to const_cast here? Because this is the C equivalent to a // destructor. Those apply to const objects as well as non-const ones. PQfreemem(const_cast(ptr)); } } // namespace pqxx::internal::pq libpqxx-7.10.0/src/version.cxx000066400000000000000000000013561473205454700163060ustar00rootroot00000000000000/** Version check. * * Copyright (c) 2000-2024, Jeroen T. Vermeulen. * * See COPYING for copyright license. 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 libpqxx-7.10.0/src/wait.cxx000066400000000000000000000076431473205454700155720ustar00rootroot00000000000000/** Functions that wait. */ #include "pqxx-source.hxx" #include // For WSAPoll(). // Normally we'd do this *after* including , but MinGW complains: it // issues a warning telling us to include winsock2.h before windows.h. // We don't actually include windows.h ourselves, but it looks as if MinGW's // does. #if __has_include() # include # define PQXX_HAVE_SELECT #endif // The header is still broken on MinGW. :-( #if defined(PQXX_HAVE_SLEEP_FOR) # include #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) static_assert(SOCKET_ERROR == -1); short const events{static_cast( (for_read ? POLLRDNORM : 0) | (for_write ? POLLWRNORM : 0))}; WSAPOLLFD fdarray{SOCKET(fd), events, 0}; int const code{ WSAPoll(&fdarray, 1u, to_milli(seconds, microseconds))}; #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}; int const code{poll(&pfd, 1, to_milli(seconds, microseconds))}; #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}; int const code{select(fd + 1, &read_fds, &write_fds, &except_fds, &tv)}; #endif if (code == -1) { constexpr std::size_t buf_size{200u}; std::array errbuf{}; int const err_code{ #if defined(_WIN32) && (_WIN32_WINNT >= 0x0600) WSAGetLastError() #else errno #endif }; throw std::runtime_error{pqxx::internal::error_string(err_code, errbuf)}; } } 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 } libpqxx-7.10.0/test/000077500000000000000000000000001473205454700142605ustar00rootroot00000000000000libpqxx-7.10.0/test/CMakeLists.txt000066400000000000000000000010171473205454700170170ustar00rootroot00000000000000enable_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() libpqxx-7.10.0/test/Makefile.am000066400000000000000000000065611473205454700163240ustar00rootroot00000000000000# ############################################################################## # 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_notice_handler.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_query.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} libpqxx-7.10.0/test/Makefile.am.template000066400000000000000000000020761473205454700201330ustar00rootroot00000000000000# 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} libpqxx-7.10.0/test/Makefile.in000066400000000000000000001405501473205454700163320ustar00rootroot00000000000000# Makefile.in generated by automake 1.16.5 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)/pqxx_cxx_feature_checks.ac \ $(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_notice_handler.$(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_query.$(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_notice_handler.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_query.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@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ 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_notice_handler.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_query.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_notice_handler.$(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_query.$(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_notice_handler.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_query.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_notice_handler.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_query.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_notice_handler.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_query.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: libpqxx-7.10.0/test/runner.cxx000066400000000000000000000142151473205454700163200ustar00rootroot00000000000000/* 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 { #if defined(PQXX_HAVE_SOURCE_LOCATION) test_failure::test_failure(std::string const &desc, std::source_location loc) : std::logic_error{desc}, m_loc{loc} {} #else test_failure::test_failure( std::string const &ffile, int fline, std::string const &desc) : std::logic_error(desc), m_file(ffile), m_line(fline) {} #endif 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( #if !defined(PQXX_HAVE_SOURCE_LOCATION) char const file[], int line, #endif std::string desc #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) { throw test_failure{ #if !defined(PQXX_HAVE_SOURCE_LOCATION) file, line, #endif desc #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif }; } void check( #if !defined(PQXX_HAVE_SOURCE_LOCATION) char const file[], int line, #endif bool condition, char const text[], std::string const &desc #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc #endif ) { if (not condition) throw test_failure{ #if !defined(PQXX_HAVE_SOURCE_LOCATION) file, line, #endif desc + " (failed expression: " + text + ")" #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif }; } 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() << '\n'; #if defined(PQXX_HAVE_SOURCE_LOCATION) std::string func{e.location.function_name()}; std::cerr << "("; std::cerr << e.location.file_name() << ':' << e.location.line(); if (not func.empty()) std::cerr << " in " << e.location.function_name(); std::cerr << ")\n"; #endif success = true; --test_count; } catch (pqxx::sql_error const &e) { std::cerr << "SQL error: " << e.what() << '\n'; #if defined(PQXX_HAVE_SOURCE_LOCATION) std::string func{e.location.function_name()}; std::cerr << "("; std::cerr << e.location.file_name() << ':' << e.location.line(); if (not func.empty()) std::cerr << " in " << e.location.function_name(); std::cerr << ")\n"; #endif std::cerr << "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)); } libpqxx-7.10.0/test/test00.cxx000066400000000000000000000056111473205454700161260ustar00rootroot00000000000000#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()}; void test_000() { PQXX_CHECK_EQUAL( oid_none, 0u, "InvalidId 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 libpqxx-7.10.0/test/test01.cxx000066400000000000000000000013151473205454700161240ustar00rootroot00000000000000#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 cx; // 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{cx, "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 libpqxx-7.10.0/test/test02.cxx000066400000000000000000000043121473205454700161250ustar00rootroot00000000000000#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 cx{"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 cx{ConnectString}; // Start transaction within context of connection. work tx{cx, "test2"}; // Perform query within transaction. result R(tx.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. tx.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 libpqxx-7.10.0/test/test04.cxx000066400000000000000000000024021473205454700161250ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include "test_helpers.hxx" // Example program for libpqxx. Send notification to self. namespace { void test_004() { auto const channel{"pqxx_test_notif"}; pqxx::connection cx; int backend_pid{0}; cx.listen(channel, [&backend_pid](pqxx::notification n) noexcept { backend_pid = n.backend_pid; }); // Trigger our notification receiver. pqxx::perform([&cx, &channel] { pqxx::work tx(cx); tx.notify(channel); tx.commit(); }); int notifs{0}; for (int i{0}; (i < 20) and (backend_pid == 0); ++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(1000u); notifs = cx.get_notifs(); } PQXX_CHECK_EQUAL( backend_pid, cx.backendpid(), "Did not get our notification from our own backend."); PQXX_CHECK_EQUAL(notifs, 1, "Got too many notifications."); } PQXX_REGISTER_TEST(test_004); } // namespace libpqxx-7.10.0/test/test07.cxx000066400000000000000000000072021473205454700161330ustar00rootroot00000000000000#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 cx; cx.set_client_encoding("SQL_ASCII"); { work tx{cx}; 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, &cx] { work tx{cx}; // 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.exec(query).no_rows(); } }); } PQXX_REGISTER_TEST(test_007); } // namespace libpqxx-7.10.0/test/test10.cxx000066400000000000000000000057011473205454700161270ustar00rootroot00000000000000#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 .exec( "INSERT INTO " + Table + "(year, event) " "VALUES (" + to_string(BoringYear) + ", 'yawn')") .no_rows(); 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 cx; nontransaction tx{cx}; test::create_pqxxevents(tx); connection &c(tx.conn()); tx.commit(); Test(c, true); Test(c, false); } PQXX_REGISTER_TEST(test_abort); } // namespace libpqxx-7.10.0/test/test11.cxx000066400000000000000000000042301473205454700161240ustar00rootroot00000000000000#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 cx; work tx{cx}; 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 libpqxx-7.10.0/test/test13.cxx000066400000000000000000000045401473205454700161320ustar00rootroot00000000000000#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 &cx, std::string const &table) { work tx{cx}; 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 &cx, std::string const &table) { work tx(cx); result R = tx.exec( "INSERT INTO " + table + " VALUES (" + to_string(BoringYear) + ", " "'yawn')") .no_rows(); PQXX_CHECK_EQUAL(R.affected_rows(), 1, "Bad affected_rows()."); throw deliberate_error(); } void test_013() { connection cx; { work tx{cx}; test::create_pqxxevents(tx); tx.commit(); } std::string const Table{"pqxxevents"}; auto const Before{ perform([&cx, &Table] { return count_events(cx, Table); })}; PQXX_CHECK_EQUAL( Before.second, 0, "Already have event for " + to_string(BoringYear) + "--can't test."); #include "pqxx/internal/ignore-deprecated-pre.hxx" quiet_errorhandler d(cx); #include "pqxx/internal/ignore-deprecated-post.hxx" PQXX_CHECK_THROWS( perform([&cx, &Table] { failed_insert(cx, Table); }), deliberate_error, "Failing transactor failed to throw correct exception."); auto const After{perform([&cx, &Table] { return count_events(cx, 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 libpqxx-7.10.0/test/test14.cxx000066400000000000000000000016561473205454700161400ustar00rootroot00000000000000#include #include #include "test_helpers.hxx" using namespace pqxx; // Test nontransaction. namespace { void test_014() { connection cx; // 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{cx, "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 libpqxx-7.10.0/test/test16.cxx000066400000000000000000000017451473205454700161410ustar00rootroot00000000000000#include #include #include #include "test_helpers.hxx" using namespace pqxx; // Test robusttransaction. namespace { void test_016() { connection cx; robusttransaction<> tx{cx}; 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 libpqxx-7.10.0/test/test17.cxx000066400000000000000000000011311473205454700161270ustar00rootroot00000000000000#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 cx; perform([&cx] { nontransaction tx{cx}; 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 libpqxx-7.10.0/test/test18.cxx000066400000000000000000000042771473205454700161460ustar00rootroot00000000000000#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 &cx, std::string const &table) { nontransaction tx{cx}; 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 cx; { work tx{cx}; test::create_pqxxevents(tx); tx.commit(); } std::string const Table{"pqxxevents"}; auto const Before{ perform([&cx, &Table] { return count_events(cx, Table); })}; PQXX_CHECK_EQUAL( Before.second, 0, "Already have event for " + to_string(BoringYear) + ", cannot run."); { #include "pqxx/internal/ignore-deprecated-pre.hxx" quiet_errorhandler d{cx}; #include "pqxx/internal/ignore-deprecated-post.hxx" PQXX_CHECK_THROWS( perform([&cx, Table] { robusttransaction tx{cx}; tx.exec( "INSERT INTO " + Table + " VALUES (" + to_string(BoringYear) + ", '" + tx.esc("yawn") + "')") .no_rows(); throw deliberate_error(); }), deliberate_error, "Not getting expected exception from failing transactor."); } auto const After{perform([&cx, &Table] { return count_events(cx, 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 libpqxx-7.10.0/test/test20.cxx000066400000000000000000000045201473205454700161260ustar00rootroot00000000000000#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 cx; nontransaction t1{cx}; 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.exec( "INSERT INTO " + Table + " VALUES" "(" + to_string(BoringYear) + "," "'Yawn'" ")") .no_rows(); // 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{cx, "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.exec( "DELETE FROM " + Table + " " "WHERE year=" + to_string(BoringYear)) .no_rows(); t2.commit(); // And again, verify results nontransaction t3{cx, "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 libpqxx-7.10.0/test/test21.cxx000066400000000000000000000030111473205454700161210ustar00rootroot00000000000000#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 cx; std::string const HostName{ ((cx.hostname() == nullptr) ? "" : cx.hostname())}; cx.process_notice( std::string{} + "database=" + cx.dbname() + ", " "username=" + cx.username() + ", " "hostname=" + HostName + ", " "port=" + to_string(cx.port()) + ", " "backendpid=" + to_string(cx.backendpid()) + "\n"); work tx{cx, "test_021"}; // By now our connection should really have been created cx.process_notice("Printing details on actual connection\n"); cx.process_notice( std::string{} + "database=" + cx.dbname() + ", " "username=" + cx.username() + ", " "hostname=" + HostName + ", " "port=" + to_string(cx.port()) + ", " "backendpid=" + to_string(cx.backendpid()) + "\n"); std::string P; from_string(cx.port(), P); PQXX_CHECK_EQUAL( P, to_string(cx.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 libpqxx-7.10.0/test/test26.cxx000066400000000000000000000040001473205454700161250ustar00rootroot00000000000000#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.exec( "UPDATE pqxxevents " "SET year=" + to_string(c.second) + " " "WHERE year=" + to_string(c.first)) .no_rows(); tx.commit(); return conversions; } void test_026() { connection cx; { nontransaction tx{cx}; 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([&cx] { return update_years(cx); })}; PQXX_CHECK(not std::empty(conversions), "No conversions done!"); } PQXX_REGISTER_TEST(test_026); } // namespace libpqxx-7.10.0/test/test29.cxx000066400000000000000000000057741473205454700161530ustar00rootroot00000000000000#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 &cx, 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(cx, "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 .exec( "INSERT INTO " + Table + "(year, event) " "VALUES (" + to_string(BoringYear) + ", 'yawn')") .no_rows(); 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(cx, "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 cx; { nontransaction tx{cx}; test::create_pqxxevents(tx); } // Test abort semantics, both with explicit and implicit abort Test(cx, true); Test(cx, false); } PQXX_REGISTER_TEST(test_029); } // namespace libpqxx-7.10.0/test/test30.cxx000066400000000000000000000033741473205454700161350ustar00rootroot00000000000000#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 cx; work tx{cx, "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 libpqxx-7.10.0/test/test32.cxx000066400000000000000000000041121473205454700161260ustar00rootroot00000000000000#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 &cx, std::string const &table) { std::string const count_query{"SELECT count(*) FROM " + table}; work tx{cx}; 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 cx; { nontransaction tx{cx}; test::create_pqxxevents(tx); } std::string const Table{"pqxxevents"}; std::pair const Before{ perform([&cx, &Table] { return count_events(cx, Table); })}; PQXX_CHECK_EQUAL( Before.second, 0, "Already have event for " + to_string(BoringYear) + ", cannot test."); { #include "pqxx/internal/ignore-deprecated-pre.hxx" quiet_errorhandler d(cx); #include "pqxx/internal/ignore-deprecated-post.hxx" PQXX_CHECK_THROWS( perform([&cx, &Table] { work{cx} .exec( "INSERT INTO " + Table + " VALUES (" + to_string(BoringYear) + ", " "'yawn')") .no_rows(); throw deliberate_error(); }), deliberate_error, "Did not get expected exception from failing transactor."); } std::pair const After{ perform([&cx, &Table] { return count_events(cx, 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 libpqxx-7.10.0/test/test37.cxx000066400000000000000000000042301473205454700161340ustar00rootroot00000000000000#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 &cx, std::string const &table) { std::string const count_query{"SELECT count(*) FROM " + table}; nontransaction tx{cx}; 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 cx; { nontransaction tx{cx}; test::create_pqxxevents(tx); } std::string const Table{"pqxxevents"}; auto const Before{ perform([&cx, &Table] { return count_events(cx, Table); })}; PQXX_CHECK_EQUAL( Before.second, 0, "Already have event for " + to_string(BoringYear) + ", cannot test."); { #include "pqxx/internal/ignore-deprecated-pre.hxx" quiet_errorhandler d(cx); #include "pqxx/internal/ignore-deprecated-post.hxx" PQXX_CHECK_THROWS( perform([&cx, &Table] { robusttransaction<> tx{cx}; tx.exec( "INSERT INTO " + Table + " VALUES (" + to_string(BoringYear) + ", " "'yawn')") .no_rows(); throw deliberate_error(); }), deliberate_error, "Did not get expected exception from failing transactor."); } auto const After{perform([&cx, &Table] { return count_events(cx, 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 libpqxx-7.10.0/test/test39.cxx000066400000000000000000000040741473205454700161440ustar00rootroot00000000000000#include #include "test_helpers.hxx" using namespace pqxx; // Test: nontransaction changes are committed immediately. namespace { int BoringYear{1977}; void test_039() { connection cx; nontransaction tx1{cx}; 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 .exec( "INSERT INTO " + Table + " VALUES" "(" + to_string(BoringYear) + "," "'Yawn'" ")") .no_rows(); // 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(cx, "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 .exec( "DELETE FROM " + Table + " " "WHERE year=" + to_string(BoringYear)) .no_rows(); tx2.commit(); // And again, verify results nontransaction tx3(cx, "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 libpqxx-7.10.0/test/test46.cxx000066400000000000000000000037651473205454700161500ustar00rootroot00000000000000#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 cx; work tx{cx}; pqxx::field R{tx.exec("SELECT count(*) FROM pg_tables").one_field()}; // Read the value into a stringstream. std::stringstream I; #include "pqxx/internal/ignore-deprecated-pre.hxx" I << R; #include "pqxx/internal/ignore-deprecated-post.hxx" // Now convert the stringstream into a numeric type long L{}, L2{}; I >> L; R.to(L2); PQXX_CHECK_EQUAL(L, L2, "Inconsistency between conversion methods."); float F{}, F2{}; std::stringstream I2; #include "pqxx/internal/ignore-deprecated-pre.hxx" I2 << R; #include "pqxx/internal/ignore-deprecated-post.hxx" I2 >> F; R.to(F2); PQXX_CHECK_BOUNDS(F2, F - 0.01, F + 0.01, "Bad floating-point result."); auto F3{from_string(R.c_str())}; PQXX_CHECK_BOUNDS(F3, F - 0.01, F + 0.01, "Bad float from from_string."); auto D{from_string(R.c_str())}; PQXX_CHECK_BOUNDS(D, F - 0.01, F + 0.01, "Bad double from from_string."); auto LD{from_string(R.c_str())}; PQXX_CHECK_BOUNDS( LD, F - 0.01, F + 0.01, "Bad long double from from_string."); auto S{from_string(R.c_str())}, S2{from_string(std::string{R.c_str()})}, S3{from_string(R)}; 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 libpqxx-7.10.0/test/test56.cxx000066400000000000000000000010361473205454700161360ustar00rootroot00000000000000#include #include "test_helpers.hxx" using namespace pqxx; // Simple test program for libpqxx. Issue invalid query and handle error. namespace { void test_056() { connection cx; work tx{cx}; #include "pqxx/internal/ignore-deprecated-pre.hxx" quiet_errorhandler d(cx); #include "pqxx/internal/ignore-deprecated-post.hxx" 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 libpqxx-7.10.0/test/test60.cxx000066400000000000000000000040621473205454700161330ustar00rootroot00000000000000#include #include #include #include #include "test_helpers.hxx" using namespace pqxx; // Example program for libpqxx. Test session variable functionality. namespace { std::string GetDatestyle(connection &cx) { return cx.get_var("DATESTYLE"); } std::string SetDatestyle(connection &cx, std::string style) { cx.set_session_var("DATESTYLE", style); std::string const fullname{GetDatestyle(cx)}; PQXX_CHECK( not std::empty(fullname), "Setting datestyle to " + style + " makes it an empty string."); return fullname; } void CheckDatestyle(connection &cx, std::string expected) { PQXX_CHECK_EQUAL(GetDatestyle(cx), expected, "Got wrong datestyle."); } void RedoDatestyle( connection &cx, std::string const &style, std::string const &expected) { PQXX_CHECK_EQUAL(SetDatestyle(cx, style), expected, "Set wrong datestyle."); } void ActivationTest( connection &cx, std::string const &style, std::string const &expected) { RedoDatestyle(cx, style, expected); CheckDatestyle(cx, expected); } void test_060() { connection cx; PQXX_CHECK(not std::empty(GetDatestyle(cx)), "Initial datestyle not set."); std::string const ISOname{SetDatestyle(cx, "ISO")}; std::string const SQLname{SetDatestyle(cx, "SQL")}; PQXX_CHECK_NOT_EQUAL(ISOname, SQLname, "Same datestyle in SQL and ISO."); RedoDatestyle(cx, "SQL", SQLname); ActivationTest(cx, "ISO", ISOname); ActivationTest(cx, "SQL", SQLname); PQXX_CHECK_THROWS( cx.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 #include "pqxx/internal/ignore-deprecated-pre.hxx" quiet_errorhandler d{cx}; #include "pqxx/internal/ignore-deprecated-post.hxx" PQXX_CHECK_THROWS( cx.set_session_var("NONEXISTENT_VARIABLE_I_HOPE", 1), sql_error, "Setting unknown variable failed to fail."); } PQXX_REGISTER_TEST(test_060); } // namespace libpqxx-7.10.0/test/test61.cxx000066400000000000000000000027451473205454700161420ustar00rootroot00000000000000#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 cx; work tx{cx}; 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 #include "pqxx/internal/ignore-deprecated-pre.hxx" quiet_errorhandler d(tx.conn()); #include "pqxx/internal/ignore-deprecated-post.hxx" PQXX_CHECK_THROWS( cx.set_session_var("NONEXISTENT_VARIABLE_I_HOPE", 1), sql_error, "Setting unknown variable failed to fail."); } PQXX_REGISTER_TEST(test_061); } // namespace libpqxx-7.10.0/test/test62.cxx000066400000000000000000000027211473205454700161350ustar00rootroot00000000000000#include #include #include #include "test_helpers.hxx" using namespace pqxx; // Example program for libpqxx. Test binary string functionality. namespace { void test_062() { connection cx; work tx{cx}; std::string const TestStr{ "Nasty\n\030Test\n\t String with \200\277 weird bytes " "\r\0 and Trailer\\\\\0"}; tx.exec("CREATE TEMP TABLE pqxxbin (binfield bytea)").no_rows(); std::string const Esc{tx.esc_raw(bytes{ reinterpret_cast(std::data(TestStr)), std::size(TestStr)})}; tx.exec("INSERT INTO pqxxbin VALUES ('" + Esc + "')").no_rows(); result R{tx.exec("SELECT * from pqxxbin")}; tx.exec("DELETE FROM pqxxbin").no_rows(); 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."); bytes::const_iterator c; bytes::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 libpqxx-7.10.0/test/test69.cxx000066400000000000000000000021521473205454700161420ustar00rootroot00000000000000#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.one_field().as(), res, "Got unexpected result out of pipeline."); res = R.second.one_field().as(); } PQXX_CHECK(std::empty(P), "Pipeline not empty after retrieval."); } void test_069() { connection cx; work tx{cx}; 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 libpqxx-7.10.0/test/test70.cxx000066400000000000000000000055171473205454700161420ustar00rootroot00000000000000#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 cx; work tx{cx}; 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 #include "pqxx/internal/ignore-deprecated-pre.hxx" quiet_errorhandler d(cx); #include "pqxx/internal/ignore-deprecated-post.hxx" PQXX_CHECK_THROWS_EXCEPTION( P.retrieve(), "Empty pipeline allows retrieve()."); } } // namespace PQXX_REGISTER_TEST(test_070); libpqxx-7.10.0/test/test71.cxx000066400000000000000000000034361473205454700161410ustar00rootroot00000000000000#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 cx; work tx{cx}; 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); libpqxx-7.10.0/test/test72.cxx000066400000000000000000000030471473205454700161400ustar00rootroot00000000000000#include #include #include #include "test_helpers.hxx" using namespace pqxx; // Test program for libpqxx. Test error handling for pipeline. namespace { void test_072() { connection cx; work tx{cx}; 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 { #include "pqxx/internal/ignore-deprecated-pre.hxx" quiet_errorhandler d{cx}; #include "pqxx/internal/ignore-deprecated-post.hxx" 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 { #include "pqxx/internal/ignore-deprecated-pre.hxx" quiet_errorhandler d{cx}; #include "pqxx/internal/ignore-deprecated-post.hxx" PQXX_CHECK_THROWS( P.retrieve(id_f), sql_error, "Pipeline failed to register SQL error."); } } } // namespace PQXX_REGISTER_TEST(test_072); libpqxx-7.10.0/test/test74.cxx000066400000000000000000000037441473205454700161460ustar00rootroot00000000000000#include #include #include "test_helpers.hxx" using namespace pqxx; // Test program for libpqxx. Test fieldstream. namespace { void test_074() { #include "pqxx/internal/ignore-deprecated-pre.hxx" connection cx; work tx{cx}; 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."); #include "pqxx/internal/ignore-deprecated-post.hxx" } } // namespace PQXX_REGISTER_TEST(test_074); libpqxx-7.10.0/test/test75.cxx000066400000000000000000000076151473205454700161500ustar00rootroot00000000000000#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 cx; pqxx::work tx{cx}; 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); libpqxx-7.10.0/test/test76.cxx000066400000000000000000000034331473205454700161430ustar00rootroot00000000000000#include #include "test_helpers.hxx" // Simple test program for libpqxx. Test string conversion routines. namespace { void test_076() { pqxx::connection cx; pqxx::nontransaction tx{cx}; auto RFalse{tx.exec("SELECT 1=0").one_field()}, RTrue{tx.exec("SELECT 1=1").one_field()}; auto False{pqxx::from_string(RFalse)}, True{pqxx::from_string(RTrue)}; PQXX_CHECK(not False, "False bool converted to true."); PQXX_CHECK(True, "True bool converted to false."); RFalse = tx.exec("SELECT " + pqxx::to_string(False)).one_field(); RTrue = tx.exec("SELECT " + pqxx::to_string(True)).one_field(); False = pqxx::from_string(RFalse); True = pqxx::from_string(RTrue); 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.exec("SELECT " + pqxx::to_string(svals[i])).one_field().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.exec("SELECT " + pqxx::to_string(uvals[i])).one_field().c_str()); PQXX_CHECK_EQUAL( u, uvals[i], "Roundtrip through backend changed unsigned short."); } } } // namespace PQXX_REGISTER_TEST(test_076); libpqxx-7.10.0/test/test77.cxx000066400000000000000000000012351473205454700161420ustar00rootroot00000000000000#include #include "test_helpers.hxx" // Test program for libpqxx. Test result::swap() namespace { void test_077() { pqxx::connection cx; pqxx::nontransaction tx{cx}; 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); libpqxx-7.10.0/test/test78.cxx000066400000000000000000000017331473205454700161460ustar00rootroot00000000000000#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 { void test_078() { pqxx::connection cx; bool done{false}; std::string const channel{"my listener"}; cx.listen(channel, [&done](pqxx::notification) noexcept { done = true; }); pqxx::perform([&cx, &channel] { pqxx::nontransaction tx{cx}; tx.notify(channel); tx.commit(); }); int notifs{0}; for (int i{0}; (i < 20) and not done; ++i) { PQXX_CHECK_EQUAL(notifs, 0, "Got unexpected notifications."); std::cout << "."; notifs = cx.await_notification(); } std::cout << std::endl; PQXX_CHECK(done, "No notification received."); PQXX_CHECK_EQUAL(notifs, 1, "Got unexpected number of notifications."); } } // namespace PQXX_REGISTER_TEST(test_078); libpqxx-7.10.0/test/test79.cxx000066400000000000000000000021761473205454700161510ustar00rootroot00000000000000#include #include #include #include #include #include "test_helpers.hxx" // Example program for libpqxx. Test waiting for notification with timeout. namespace { void test_079() { pqxx::connection cx; std::string const channel{"mylistener"}; int backend_pid{0}; cx.listen(channel, [&backend_pid](pqxx::notification n) noexcept { backend_pid = n.backend_pid; }); // First see if the timeout really works: we're not expecting any notifs int notifs{cx.await_notification(0, 1)}; PQXX_CHECK_EQUAL(notifs, 0, "Got unexpected notification."); pqxx::perform([&cx, &channel] { pqxx::work tx{cx}; tx.notify(channel); tx.commit(); }); for (int i{0}; (i < 20) and (backend_pid == 0); ++i) { PQXX_CHECK_EQUAL(notifs, 0, "Got notifications, but no handler called."); std::cout << "."; notifs = cx.await_notification(1, 0); } std::cout << std::endl; PQXX_CHECK_EQUAL(backend_pid, cx.backendpid(), "Wrong backend."); PQXX_CHECK_EQUAL(notifs, 1, "Got unexpected notifications."); } } // namespace PQXX_REGISTER_TEST(test_079); libpqxx-7.10.0/test/test82.cxx000066400000000000000000000120041473205454700161320ustar00rootroot00000000000000#include #include #include "test_helpers.hxx" // Test program for libpqxx. Read and print table using row iterators. namespace { void test_082() { pqxx::connection cx; pqxx::nontransaction tx{cx}; 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); libpqxx-7.10.0/test/test84.cxx000066400000000000000000000061661473205454700161500ustar00rootroot00000000000000#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 cx; pqxx::transaction tx{cx}; 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.exec("DECLARE " + tx.quote_name(CurName) + " CURSOR FOR " + Query) .no_rows(); tx.exec( "MOVE " + pqxx::to_string(InitialSkip * GetRows) + " " "IN " + tx.quote_name(CurName)) .no_rows(); // 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 $1", pqxx::params{CurName}).one_field(), 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); libpqxx-7.10.0/test/test87.cxx000066400000000000000000000026171473205454700161500ustar00rootroot00000000000000#include "pqxx/config-public-compiler.h" #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 { void test_087() { pqxx::connection cx; std::string const channel{"my notification"}; int backend_pid{0}; cx.listen(channel, [&backend_pid](pqxx::notification n) noexcept { backend_pid = n.backend_pid; }); pqxx::perform([&cx, &channel] { pqxx::work tx{cx}; tx.notify(channel); tx.commit(); }); int notifs{0}; for (int i{0}; (i < 20) and (backend_pid == 0); ++i) { PQXX_CHECK_EQUAL(notifs, 0, "Got unexpected notifications."); std::cout << "."; pqxx::internal::wait_fd(cx.sock(), true, false); notifs = cx.get_notifs(); } std::cout << std::endl; PQXX_CHECK_EQUAL( backend_pid, cx.backendpid(), "Notification came from wrong backend."); PQXX_CHECK_EQUAL(notifs, 1, "Got unexpected number of notifications."); } } // namespace PQXX_REGISTER_TEST(test_087); libpqxx-7.10.0/test/test88.cxx000066400000000000000000000060571473205454700161530ustar00rootroot00000000000000#include #include #include #include "test_helpers.hxx" // Test program for libpqxx. Attempt to perform nested transactions. namespace { void test_088() { pqxx::connection cx; pqxx::work tx0{cx}; pqxx::test::create_pqxxevents(tx0); // Trivial test: create subtransactions, and commit/abort std::cout << tx0.query_value("SELECT 'tx0 starts'") << std::endl; pqxx::subtransaction T0a(static_cast(tx0), "T0a"); T0a.commit(); pqxx::subtransaction T0b(static_cast(tx0), "T0b"); T0b.abort(); std::cout << tx0.query_value("SELECT 'tx0 ends'") << std::endl; tx0.commit(); // Basic functionality: perform query in subtransaction; abort, continue pqxx::work tx1{cx, "tx1"}; std::cout << tx1.query_value("SELECT 'tx1 starts'") << std::endl; pqxx::subtransaction tx1a{tx1, "tx1a"}; std::cout << tx1a.query_value("SELECT ' a'") << std::endl; tx1a.commit(); pqxx::subtransaction tx1b{tx1, "tx1b"}; std::cout << tx1b.query_value("SELECT ' b'") << std::endl; tx1b.abort(); pqxx::subtransaction tx1c{tx1, "tx1c"}; std::cout << tx1c.query_value("SELECT ' c'") << std::endl; tx1c.commit(); std::cout << tx1.query_value("SELECT 'tx1 ends'") << std::endl; tx1.commit(); // Commit/rollback functionality pqxx::work tx2{cx, "tx2"}; std::string const Table{"test088"}; tx2.exec("CREATE TEMP TABLE " + Table + "(no INTEGER, text VARCHAR)") .no_rows(); tx2.exec("INSERT INTO " + Table + " VALUES(1,'tx2')").no_rows(); pqxx::subtransaction tx2a{tx2, "tx2a"}; tx2a.exec("INSERT INTO " + Table + " VALUES(2,'tx2a')").no_rows(); tx2a.commit(); pqxx::subtransaction tx2b{tx2, "tx2b"}; tx2b.exec("INSERT INTO " + Table + " VALUES(3,'tx2b')").no_rows(); tx2b.abort(); pqxx::subtransaction tx2c{tx2, "tx2c"}; tx2c.exec("INSERT INTO " + Table + " VALUES(4,'tx2c')").no_rows(); 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{cx, "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.exec("SELECT count(*) FROM pqxxevents").one_row(); // Make sure we can commit exactly one more level of transaction. tx3.commit(); } } // namespace PQXX_REGISTER_TEST(test_088); libpqxx-7.10.0/test/test89.cxx000066400000000000000000000021451473205454700161460ustar00rootroot00000000000000#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 cx; // Trivial test: create subtransactions, and commit/abort pqxx::work tx0(cx, "tx0"); tx0.exec("SELECT 'tx0 starts'").one_row(); pqxx::subtransaction tx0a(tx0, "tx0a"); tx0a.commit(); pqxx::subtransaction tx0b(tx0, "tx0b"); tx0b.abort(); tx0.exec("SELECT 'tx0 ends'").one_row(); tx0.commit(); // Basic functionality: perform query in subtransaction; abort, continue pqxx::work tx1(cx, "tx1"); tx1.exec("SELECT 'tx1 starts'").one_row(); pqxx::subtransaction tx1a(tx1, "tx1a"); tx1a.exec("SELECT ' a'").one_row(); tx1a.commit(); pqxx::subtransaction tx1b(tx1, "tx1b"); tx1b.exec("SELECT ' b'").one_row(); tx1b.abort(); pqxx::subtransaction tx1c(tx1, "tx1c"); tx1c.exec("SELECT ' c'").one_row(); tx1c.commit(); tx1.exec("SELECT 'tx1 ends'").one_row(); tx1.commit(); } } // namespace PQXX_REGISTER_TEST(test_089); libpqxx-7.10.0/test/test90.cxx000066400000000000000000000006561473205454700161430ustar00rootroot00000000000000#include #include "test_helpers.hxx" // Test program for libpqxx. Test adorn_name. namespace { void test_090() { pqxx::connection cx; // Test connection's adorn_name() function for uniqueness std::string const nametest{"basename"}; PQXX_CHECK_NOT_EQUAL( cx.adorn_name(nametest), cx.adorn_name(nametest), "\"Unique\" names are not unique."); } } // namespace PQXX_REGISTER_TEST(test_090); libpqxx-7.10.0/test/test_helpers.hxx000066400000000000000000000431661473205454700175240ustar00rootroot00000000000000#include #include #include #include namespace pqxx { namespace test { class test_failure : public std::logic_error { public: #if defined(PQXX_HAVE_SOURCE_LOCATION) test_failure( std::string const &desc, std::source_location loc = std::source_location::current()); #else test_failure(std::string const &ffile, int fline, std::string const &desc); #endif ~test_failure() noexcept override; #if defined(PQXX_HAVE_SOURCE_LOCATION) constexpr char const *file() const noexcept { return m_loc.file_name(); } constexpr auto line() const noexcept { return m_loc.line(); } #else std::string const &file() const noexcept { return m_file; } int line() const noexcept { return m_line; } #endif private: #if defined(PQXX_HAVE_SOURCE_LOCATION) std::source_location m_loc; #else std::string const m_file; int m_line; #endif }; /// 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. #if defined(PQXX_HAVE_SOURCE_LOCATION) # define PQXX_CHECK_NOTREACHED(desc) pqxx::test::check_notreached((desc)) #else # define PQXX_CHECK_NOTREACHED(desc) \ pqxx::test::check_notreached(__FILE__, __LINE__, (desc)) #endif [[noreturn]] void check_notreached( #if !defined(PQXX_HAVE_SOURCE_LOCATION) char const file[], int line, #endif std::string desc #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc = std::source_location::current() #endif ); // Verify that a condition is met, similar to assert() #if defined(PQXX_HAVE_SOURCE_LOCATION) # define PQXX_CHECK(condition, desc) \ pqxx::test::check((condition), #condition, (desc)) #else # define PQXX_CHECK(condition, desc) \ pqxx::test::check(__FILE__, __LINE__, (condition), #condition, (desc)) #endif void check( #if !defined(PQXX_HAVE_SOURCE_LOCATION) char const file[], int line, #endif bool condition, char const text[], std::string const &desc #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc = std::source_location::current() #endif ); // Verify that variable has the expected value. #if defined(PQXX_HAVE_SOURCE_LOCATION) # define PQXX_CHECK_EQUAL(actual, expected, desc) \ pqxx::test::check_equal((actual), #actual, (expected), #expected, (desc)) #else # define PQXX_CHECK_EQUAL(actual, expected, desc) \ pqxx::test::check_equal( \ __FILE__, __LINE__, (actual), #actual, (expected), #expected, (desc)) #endif template inline void check_equal( #if !defined(PQXX_HAVE_SOURCE_LOCATION) char const file[], int line, #endif ACTUAL actual, char const actual_text[], EXPECTED expected, char const expected_text[], std::string const &desc #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc = std::source_location::current() #endif ) { if (expected == actual) return; std::string const fulldesc = desc + " (" + actual_text + " <> " + expected_text + ": " "actual=" + to_string(actual) + ", " "expected=" + to_string(expected) + ")"; #if defined(PQXX_HAVE_SOURCE_LOCATION) throw test_failure{fulldesc, loc}; #else throw test_failure(file, line, fulldesc); #endif } // Verify that two values are not equal. #if defined(PQXX_HAVE_SOURCE_LOCATION) # define PQXX_CHECK_NOT_EQUAL(value1, value2, desc) \ pqxx::test::check_not_equal((value1), #value1, (value2), #value2, (desc)) #else # define PQXX_CHECK_NOT_EQUAL(value1, value2, desc) \ pqxx::test::check_not_equal( \ __FILE__, __LINE__, (value1), #value1, (value2), #value2, (desc)) #endif template inline void check_not_equal( #if !defined(PQXX_HAVE_SOURCE_LOCATION) char const file[], int line, #endif VALUE1 value1, char const text1[], VALUE2 value2, char const text2[], std::string const &desc #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc = std::source_location::current() #endif ) { if (value1 != value2) return; std::string const fulldesc = desc + " (" + text1 + " == " + text2 + ": " "both are " + to_string(value2) + ")"; #if defined(PQXX_HAVE_SOURCE_LOCATION) throw test_failure{fulldesc, loc}; #else throw test_failure{file, line, fulldesc}; #endif } #if defined(PQXX_HAVE_SOURCE_LOCATION) // Verify that value1 is less than value2. # define PQXX_CHECK_LESS(value1, value2, desc) \ pqxx::test::check_less((value1), #value1, (value2), #value2, (desc)) // Verify that value1 is greater than value2. # define PQXX_CHECK_GREATER(value2, value1, desc) \ pqxx::test::check_less((value1), #value1, (value2), #value2, (desc)) #else // 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)) #endif template inline void check_less( #if !defined(PQXX_HAVE_SOURCE_LOCATION) char const file[], int line, #endif VALUE1 value1, char const text1[], VALUE2 value2, char const text2[], std::string const &desc #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc = std::source_location::current() #endif ) { if (value1 < value2) return; std::string const fulldesc = desc + " (" + text1 + " >= " + text2 + ": " "\"lower\"=" + to_string(value1) + ", " "\"upper\"=" + to_string(value2) + ")"; #if defined(PQXX_HAVE_SOURCE_LOCATION) throw test_failure{fulldesc, loc}; #else throw test_failure(file, line, fulldesc); #endif } #if defined(PQXX_HAVE_SOURCE_LOCATION) // Verify that value1 is less than or equal to value2. # define PQXX_CHECK_LESS_EQUAL(value1, value2, desc) \ pqxx::test::check_less_equal((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((value1), #value1, (value2), #value2, (desc)) #else // 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)) #endif template inline void check_less_equal( #if !defined(PQXX_HAVE_SOURCE_LOCATION) char const file[], int line, #endif VALUE1 value1, char const text1[], VALUE2 value2, char const text2[], std::string const &desc #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc = std::source_location::current() #endif ) { if (value1 <= value2) return; std::string const fulldesc = desc + " (" + text1 + " > " + text2 + ": " "\"lower\"=" + to_string(value1) + ", " "\"upper\"=" + to_string(value2) + ")"; #if defined(PQXX_HAVE_SOURCE_LOCATION) throw test_failure{fulldesc, loc}; #else throw test_failure(file, line, fulldesc); #endif } 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() #if defined(PQXX_HAVE_SOURCE_LOCATION) # define PQXX_CHECK_BOUNDS(value, lower, upper, desc) \ pqxx::test::check_bounds( \ (value), #value, (lower), #lower, (upper), #upper, (desc)) #else # define PQXX_CHECK_BOUNDS(value, lower, upper, desc) \ pqxx::test::check_bounds( \ __FILE__, __LINE__, (value), #value, (lower), #lower, (upper), #upper, \ (desc)) #endif template inline void check_bounds( #if !defined(PQXX_HAVE_SOURCE_LOCATION) char const file[], int line, #endif VALUE value, char const text[], LOWER lower, char const lower_text[], UPPER upper, char const upper_text[], std::string const &desc #if defined(PQXX_HAVE_SOURCE_LOCATION) , std::source_location loc = std::source_location::current() #endif ) { 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( #if !defined(PQXX_HAVE_SOURCE_LOCATION) file, line, #endif lower < upper, range_check.c_str(), desc + " (acceptable range is empty; value was " + text + ")" #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif ); pqxx::test::check( #if !defined(PQXX_HAVE_SOURCE_LOCATION) file, line, #endif not(value < lower), lower_check.c_str(), desc + " (" + text + " is below lower bound " + lower_text + ")" #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif ); pqxx::test::check( #if !defined(PQXX_HAVE_SOURCE_LOCATION) file, line, #endif value < upper, upper_check.c_str(), desc + " (" + text + " is not below upper bound " + upper_text + ")" #if defined(PQXX_HAVE_SOURCE_LOCATION) , loc #endif ); } // 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 libpqxx-7.10.0/test/test_types.hxx000066400000000000000000000126061473205454700172210ustar00rootroot00000000000000/* * Custom types for testing & libpqxx support those types */ #if !defined(PQXX_H_TEST_TYPES) # define PQXX_H_TEST_TYPES # include # include # include # include # include # include # include # include # include # include namespace pqxx { template<> struct nullness : no_null {}; } // 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 constexpr bool converts_to_string{true}; static constexpr bool converts_from_string{true}; static ipv4 from_string(std::string_view text) { ipv4 ts; if (std::data(text) == nullptr) internal::throw_null_conversion(type_name); std::vector ends; for (std::size_t i{0}; i < std::size(text); ++i) if (text[i] == '.') ends.push_back(i); ends.push_back(std::size(text)); if (std::size(ends) != 4) throw conversion_error{pqxx::internal::concat( "Can't parse '", text, "' as ipv4: expected 4 octets, " "found ", std::size(ends), ".")}; std::size_t start{0}; for (int i{0}; i < 4; ++i) { auto idx{static_cast(i)}; std::string_view digits{&text[start], ends[idx] - start}; auto value{pqxx::from_string(digits)}; ts.set_byte(i, value); start = ends[idx] + 1; } 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 constexpr bool converts_to_string{true}; static constexpr bool converts_from_string{true}; 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 #endif libpqxx-7.10.0/test/unit/000077500000000000000000000000001473205454700152375ustar00rootroot00000000000000libpqxx-7.10.0/test/unit/CMakeLists.txt000066400000000000000000000006101473205454700177740ustar00rootroot00000000000000if(NOT PostgreSQL_FOUND) find_package(PostgreSQL REQUIRED) 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 ) libpqxx-7.10.0/test/unit/test_array.cxx000066400000000000000000000575311473205454700201530ustar00rootroot00000000000000#include #include "../test_helpers.hxx" // Test program for libpqxx array parsing. using namespace std::literals; 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_array_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_array_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_array_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_array_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_array_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_array_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_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_empty_strings() { // Reproduce #816: Under-budgeted conversion of empty strings in arrays. PQXX_CHECK_EQUAL( pqxx::to_string(std::vector({""})), "{\"\"}", "Array of one empty string came out wrong."); PQXX_CHECK_EQUAL( pqxx::to_string(std::vector({"", "", "", ""})), "{\"\",\"\",\"\",\"\"}", "Array of 4 empty strings came out wrong."); PQXX_CHECK_EQUAL( pqxx::to_string(std::vector( {"", "", "", "", "", "", "", "", "", "", "", ""})), "{\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"}", "Array of 12 empty strings came out wrong."); } 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 cx; pqxx::work tx{cx}; std::vector const in{0, 1, 2, 3, 5}; auto const text{ tx.query_value("SELECT $1::integer[]", pqxx::params{in})}; pqxx::array_parser parser{text}; 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."); } void test_array_strings() { std::vector inputs{ "", "null", "NULL", "\\N", "'", "''", "\\", "\n\t", "\\n", "\"", "\"\"", "a b", "a<>b", "{", "}", "{}", }; pqxx::connection cx; pqxx::work tx{cx}; for (auto const &input : inputs) { auto const f{tx.exec("SELECT ARRAY[$1]", pqxx::params{input}).one_field()}; pqxx::array_parser parser{f.as()}; auto [start_juncture, start_value]{parser.get_next()}; pqxx::ignore_unused(start_value); PQXX_CHECK_EQUAL( start_juncture, pqxx::array_parser::juncture::row_start, "Bad start."); auto [value_juncture, value]{parser.get_next()}; PQXX_CHECK_EQUAL( value_juncture, pqxx::array_parser::juncture::string_value, "Bad value juncture."); PQXX_CHECK_EQUAL(value, input, "Bad array value roundtrip."); } } void test_array_parses_real_arrays() { pqxx::connection cx; pqxx::work tx{cx}; auto const empty_s{tx.query_value("SELECT ARRAY[]::integer[]")}; pqxx::array empty_a{empty_s, cx}; PQXX_CHECK_EQUAL( empty_a.dimensions(), 1u, "Unexpected dimension count for empty array."); PQXX_CHECK_EQUAL( empty_a.sizes(), (std::array{0u}), "Unexpected sizes for empty array."); auto const onedim_s{tx.query_value("SELECT ARRAY[0, 1, 2]")}; pqxx::array onedim_a{onedim_s, cx}; PQXX_CHECK_EQUAL( onedim_a.dimensions(), 1u, "Unexpected dimension count for one-dimensional array."); PQXX_CHECK_EQUAL( onedim_a.sizes(), (std::array{3u}), "Unexpected sizes for one-dimensional array."); PQXX_CHECK_EQUAL(onedim_a[0], 0, "Bad data in one-dimensional array."); PQXX_CHECK_EQUAL( onedim_a[2], 2, "Array started off OK but later data was bad."); auto const null_s{ tx.query_value("SELECT ARRAY[NULL]::integer[]")}; PQXX_CHECK_THROWS( (pqxx::array{null_s, cx}), pqxx::unexpected_null, "Not getting unexpected_null from array parser."); auto const twodim_s{tx.query_value("SELECT ARRAY[[1], [2]]")}; pqxx::array twodim_a{twodim_s, cx}; PQXX_CHECK_EQUAL( twodim_a.dimensions(), 2u, "Wrong number of dimensions on multi-dimensional array."); PQXX_CHECK_EQUAL( twodim_a.sizes(), (std::array{2u, 1u}), "Wrong sizes on multidim array."); auto const string_s{tx.query_value("SELECT ARRAY['Hello']")}; pqxx::array string_a{string_s, cx}; PQXX_CHECK_EQUAL(string_a[0], "Hello", "String field came out wrong."); auto const fake_null_s{tx.query_value("SELECT ARRAY['NULL']")}; pqxx::array fake_null_a{string_s, cx}; PQXX_CHECK_EQUAL( fake_null_a[0], "Hello", "String field 'NULL' came out wrong."); auto const nulls_s{ tx.query_value("SELECT ARRAY[NULL, 'NULL']")}; pqxx::array> nulls_a{nulls_s, cx}; PQXX_CHECK(not nulls_a[0].has_value(), "Null string cvame out with value."); PQXX_CHECK(nulls_a[1].has_value(), "String 'NULL' came out as null."); PQXX_CHECK_EQUAL( nulls_a[1].value(), "NULL", "String 'NULL' came out wrong."); } void test_array_rejects_malformed_simple_int_arrays() { pqxx::connection cx; std::string_view const bad_arrays[]{ ""sv, "null"sv, ","sv, "1"sv, "{"sv, "}"sv, "}{"sv, "{}{"sv, "{{}"sv, "{}}"sv, "{{}}"sv, "{1"sv, "{1,"sv, "{,}"sv, "{1,}"sv, "{,1}"sv, "{1,{}}"sv, "{x}"sv, "{1,{2,3}}"sv, }; for (auto bad : bad_arrays) PQXX_CHECK_THROWS( (pqxx::array{bad, cx}), pqxx::conversion_error, "No conversion_error for '" + std::string{bad} + "'."); } void test_array_rejects_malformed_simple_string_arrays() { pqxx::connection cx; std::string_view const bad_arrays[]{ ""sv, "null"sv, "1"sv, ","sv, "{"sv, "}"sv, "}{"sv, "{}{"sv, "{{}"sv, "{}}"sv, "{{}}"sv, "{1"sv, "{1,"sv, "{,}"sv, "{1,}"sv, "{,1}"sv, "{1,{}}"sv, }; for (auto bad : bad_arrays) PQXX_CHECK_THROWS( (pqxx::array{bad, cx}), pqxx::conversion_error, "No conversion_error for '" + std::string{bad} + "'."); } void test_array_rejects_malformed_twodimensional_arrays() { pqxx::connection cx; std::string_view const bad_arrays[]{ ""sv, "{}"sv, "{null}"sv, "{{1},{2,3}}"sv, }; for (auto bad : bad_arrays) PQXX_CHECK_THROWS( (pqxx::array{bad, cx}), pqxx::conversion_error, "No conversion_error for '" + std::string{bad} + "'."); } void test_array_parses_quoted_strings() { pqxx::connection cx; pqxx::array const a{R"x({"\"'"})x", cx}; PQXX_CHECK_EQUAL(a[0], R"x("')x", "String in array did not unescape right."); } void test_array_parses_multidim_arrays() { pqxx::connection cx; pqxx::array const a{"{{0,1},{2,3}}", cx}; PQXX_CHECK_EQUAL(a.at(0u, 0u), 0, "Indexing is wrong."); PQXX_CHECK_EQUAL(a.at(1u, 0u), 2, "Indexing seems to confuse dimensions."); PQXX_CHECK_EQUAL(a.at(1u, 1u), 3, "Indexing at higher indexes goes wrong."); } void test_array_at_checks_bounds() { pqxx::connection cx; pqxx::array const simple{"{0, 1, 2}", cx}; PQXX_CHECK_EQUAL(simple.at(0), 0, "Array indexing does not work."); PQXX_CHECK_EQUAL(simple.at(2), 2, "Nonzero array indexing goes wrong."); PQXX_CHECK_THROWS( simple.at(3), pqxx::range_error, "No bounds checking on array::at()."); PQXX_CHECK_THROWS( simple.at(-1), pqxx::range_error, "Negative index does not throw range_error."); pqxx::array const multi{"{{0,1},{2,3},{4,5}}", cx}; PQXX_CHECK_EQUAL( multi.at(0, 0), 0, "Multidim array indexing does not work."); PQXX_CHECK_EQUAL(multi.at(1, 1), 3, "Nonzero multidim indexing goes wrong."); PQXX_CHECK_EQUAL(multi.at(2, 1), 5, "Multidim top element went wrong."); PQXX_CHECK_THROWS( multi.at(3, 0), pqxx::range_error, "Out-of-bounds on outer dimension was not detected."); PQXX_CHECK_THROWS( multi.at(0, 2), pqxx::range_error, "Out-of-bounds on inner dimension was not detected."); PQXX_CHECK_THROWS( multi.at(0, -1), pqxx::range_error, "Negative inner index was not detected."); PQXX_CHECK_THROWS( multi.at(-1, 0), pqxx::range_error, "Negative outer index was not detected."); } void test_array_iterates_in_row_major_order() { pqxx::connection cx; pqxx::work tx{cx}; auto const array_s{tx.query_value( "SELECT ARRAY[[1, 2, 3], [4, 5, 6], [7, 8, 9]]")}; pqxx::array array{array_s, cx}; auto it{array.cbegin()}; PQXX_CHECK_EQUAL(*it, 1, "Iteration started off wrong."); ++it; ++it; PQXX_CHECK_EQUAL(*it, 3, "Iteration seems to have taken the wrong order."); ++it; PQXX_CHECK_EQUAL(*it, 4, "Iteration did not jump to the next dimension."); it += 6; PQXX_CHECK(it == array.cend(), "Array cend() not where I expected."); PQXX_CHECK_EQUAL(*(array.cend() - 1), 9, "Iteration did not end well."); PQXX_CHECK_EQUAL(*array.crbegin(), 9, "Bad crbegin()."); PQXX_CHECK_EQUAL(*(array.crend() - 1), 1, "Bad crend()."); PQXX_CHECK_EQUAL(std::size(array), 9u, "Bad array size."); // C++20: Use std::ssize() instead. PQXX_CHECK_EQUAL(array.ssize(), 9, "Bad array ssize()."); PQXX_CHECK_EQUAL(array.front(), 1, "Bad front()."); PQXX_CHECK_EQUAL(array.back(), 9, "Bad back()."); } void test_as_sql_array() { pqxx::connection cx; pqxx::row r; { pqxx::work tx{cx}; r = tx.exec("SELECT ARRAY [5, 4, 3, 2]").one_row(); // Connection closes, but we should still be able to parse the array. } auto const array{r[0].as_sql_array()}; PQXX_CHECK_EQUAL(array[1], 4, "Got wrong value out of array."); } PQXX_REGISTER_TEST(test_empty_arrays); PQXX_REGISTER_TEST(test_array_null_value); PQXX_REGISTER_TEST(test_array_double_quoted_string); PQXX_REGISTER_TEST(test_array_double_quoted_escaping); PQXX_REGISTER_TEST(test_array_double_double_quoted_string); PQXX_REGISTER_TEST(test_array_unquoted_string); PQXX_REGISTER_TEST(test_array_multiple_values); PQXX_REGISTER_TEST(test_nested_array); PQXX_REGISTER_TEST(test_nested_array_with_multiple_entries); PQXX_REGISTER_TEST(test_array_generate); PQXX_REGISTER_TEST(test_array_roundtrip); PQXX_REGISTER_TEST(test_array_strings); PQXX_REGISTER_TEST(test_array_parses_real_arrays); PQXX_REGISTER_TEST(test_array_rejects_malformed_simple_int_arrays); PQXX_REGISTER_TEST(test_array_rejects_malformed_simple_string_arrays); PQXX_REGISTER_TEST(test_array_rejects_malformed_twodimensional_arrays); PQXX_REGISTER_TEST(test_array_parses_quoted_strings); PQXX_REGISTER_TEST(test_array_parses_multidim_arrays); PQXX_REGISTER_TEST(test_array_at_checks_bounds); PQXX_REGISTER_TEST(test_array_iterates_in_row_major_order); PQXX_REGISTER_TEST(test_array_generate_empty_strings); PQXX_REGISTER_TEST(test_as_sql_array); } // namespace libpqxx-7.10.0/test/unit/test_binarystring.cxx000066400000000000000000000200331473205454700215330ustar00rootroot00000000000000#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.exec("SELECT " + T.quote_raw(content)).one_field()); #include "pqxx/internal/ignore-deprecated-post.hxx" } void test_binarystring() { pqxx::connection cx; pqxx::work tx{cx}; 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(pqxx::bytes_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.query_value("SELECT $1", pqxx::params{b})) .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 cx; pqxx::transaction tx{cx}; tx.exec("CREATE TEMP TABLE pqxxbinstream(id integer, bin bytea)").no_rows(); 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(pqxx::bytes_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() { // This test won't compile on clang in maintainer mode. For some reason, // clang seems to ignore the ignore-deprecated headers in just this one // function, where we create the vector of binarystring. #if !defined(__clang__) pqxx::connection cx; pqxx::transaction tx{cx}; tx.exec("CREATE TEMP TABLE pqxxbinstream(id integer, vec bytea[])") .no_rows(); 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(pqxx::bytes_view{ptr1, std::size(data1)})}, expect2{tx.quote(pqxx::bytes_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."); #endif // __clang__ } 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 libpqxx-7.10.0/test/unit/test_blob.cxx000066400000000000000000000421261473205454700177450ustar00rootroot00000000000000#include #include #include #include "../test_helpers.hxx" #include "../test_types.hxx" namespace { void test_blob_is_useless_by_default() { pqxx::blob b{}; pqxx::bytes 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 cx; pqxx::work tx{cx}; 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 cx; pqxx::work tx{cx}; 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 cx; pqxx::work tx{cx}; 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 cx; pqxx::work tx{cx}; pqxx::oid id{pqxx::blob::create(tx)}; tx.abort(); pqxx::work tx2{cx}; 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 cx; pqxx::work tx{cx}; 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 cx; pqxx::work tx{cx}; 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 cx; pqxx::work tx{cx}; 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)}; pqxx::bytes 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() { pqxx::bytes buf; buf.push_back(std::byte{'x'}); pqxx::connection cx; pqxx::work tx{cx}; 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() { pqxx::bytes const data{std::byte{'a'}, std::byte{'b'}, std::byte{'c'}}; pqxx::connection cx; pqxx::work tx{cx}; pqxx::oid id{pqxx::blob::from_buf(tx, data)}; pqxx::bytes 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, (pqxx::bytes{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, (pqxx::bytes{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, (pqxx::bytes{}), "Read past end produced data."); } /// Cast a `char` or `std::byte` to `unsigned int`. template inline unsigned byte_val(BYTE val) { return unsigned(static_cast(val)); } void test_blob_read_span() { #if defined(PQXX_HAVE_SPAN) pqxx::bytes const data{std::byte{'u'}, std::byte{'v'}, std::byte{'w'}, std::byte{'x'}, std::byte{'y'}, std::byte{'z'}}; pqxx::connection cx; pqxx::work tx{cx}; pqxx::oid id{pqxx::blob::from_buf(tx, data)}; auto b{pqxx::blob::open_r(tx, id)}; pqxx::bytes 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( byte_val(output[0]), byte_val('u'), "Unexpected byte from blob::read()."); PQXX_CHECK_EQUAL( byte_val(output[1]), byte_val('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( byte_val(output[0]), byte_val('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( byte_val(output2[0]), byte_val('x'), "Unexpected byte from blob::read()."); PQXX_CHECK_EQUAL( byte_val(output2[1]), byte_val('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(byte_val(output2[0]), byte_val('z'), "Bad data at EOF."); #endif // PQXX_HAVE_SPAN } void test_blob_reads_vector() { char const content[]{"abcd"}; pqxx::connection cx; pqxx::work tx{cx}; auto id{pqxx::blob::from_buf( tx, pqxx::bytes_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( byte_val(out[0]), byte_val('a'), "Got bad data when reading as vector."); } void test_blob_write_appends_at_insertion_point() { pqxx::connection cx; pqxx::work tx{cx}; auto id{pqxx::blob::create(tx)}; auto b{pqxx::blob::open_rw(tx, id)}; b.write(pqxx::bytes{std::byte{'z'}}); b.write(pqxx::bytes{std::byte{'a'}}); pqxx::bytes buf; b.read(buf, 5); PQXX_CHECK_EQUAL(buf, (pqxx::bytes{}), "Found data at the end."); b.seek_abs(0); b.read(buf, 5); PQXX_CHECK_EQUAL( buf, (pqxx::bytes{std::byte{'z'}, std::byte{'a'}}), "Consecutive writes did not append correctly."); b.write(pqxx::bytes{std::byte{'x'}}); // Blob now contains "zax". That's not we wanted... Rewind and rewrite. b.seek_abs(1); b.write(pqxx::bytes{std::byte{'y'}}); b.seek_abs(0); b.read(buf, 5); PQXX_CHECK_EQUAL( buf, (pqxx::bytes{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 cx; pqxx::work tx{cx}; constexpr char content[]{"gfbltk"}; pqxx::bytes 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( byte_val(out[0]), byte_val('f'), "Data did not come back right."); PQXX_CHECK_EQUAL( byte_val(out[2]), byte_val('l'), "Data started right, ended wrong!"); #endif // PQXX_HAVE_SPAN } void test_blob_resize_shortens_to_desired_length() { pqxx::bytes const data{ std::byte{'w'}, std::byte{'o'}, std::byte{'r'}, std::byte{'k'}}; pqxx::connection cx; pqxx::work tx{cx}; auto id{pqxx::blob::from_buf(tx, data)}; pqxx::blob::open_w(tx, id).resize(2); pqxx::bytes buf; pqxx::blob::to_buf(tx, id, buf, 10); PQXX_CHECK_EQUAL( buf, (pqxx::bytes{std::byte{'w'}, std::byte{'o'}}), "Truncate did not shorten correctly."); } void test_blob_resize_extends_to_desired_length() { pqxx::connection cx; pqxx::work tx{cx}; auto id{pqxx::blob::from_buf(tx, pqxx::bytes{std::byte{100}})}; pqxx::blob::open_w(tx, id).resize(3); pqxx::bytes buf; pqxx::blob::to_buf(tx, id, buf, 10); PQXX_CHECK_EQUAL( buf, (pqxx::bytes{std::byte{100}, std::byte{0}, std::byte{0}}), "Resize did not zero-extend correctly."); } void test_blob_tell_tracks_position() { pqxx::connection cx; pqxx::work tx{cx}; 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(pqxx::bytes{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() { pqxx::bytes 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 cx; pqxx::work tx{cx}; auto id{pqxx::blob::from_buf(tx, data)}; auto b{pqxx::blob::open_r(tx, id)}; pqxx::bytes buf; b.seek_rel(3); b.read(buf, 1u); PQXX_CHECK_EQUAL( byte_val(buf[0]), byte_val(3), "seek_rel() from beginning did not take us to the right position."); b.seek_abs(2); b.read(buf, 1u); PQXX_CHECK_EQUAL( byte_val(buf[0]), byte_val(2), "seek_abs() did not take us to the right position."); b.seek_end(-2); b.read(buf, 1u); PQXX_CHECK_EQUAL( byte_val(buf[0]), byte_val(8), "seek_end() did not take us to the right position."); } void test_blob_from_buf_interoperates_with_to_buf() { pqxx::bytes const data{std::byte{'h'}, std::byte{'i'}}; pqxx::bytes buf; pqxx::connection cx; pqxx::work tx{cx}; 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() { pqxx::bytes const data{std::byte{'h'}, std::byte{'o'}}; pqxx::connection cx; pqxx::work tx{cx}; auto id{pqxx::blob::create(tx)}; pqxx::blob::append_from_buf(tx, data, id); pqxx::blob::append_from_buf(tx, data, id); pqxx::bytes 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, pqxx::bytes &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[], pqxx::bytes_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)) throw 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[], pqxx::bytes_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"; pqxx::bytes const data{std::byte{'4'}, std::byte{'2'}}; pqxx::connection cx; pqxx::work tx{cx}; pqxx::bytes 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() { pqxx::bytes const data{std::byte{'6'}, std::byte{'9'}}; char const temp_file[] = "blob-test-from_file-oid.tmp"; pqxx::bytes buf; pqxx::connection cx; pqxx::work tx{cx}; // 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() { pqxx::bytes const data{ std::byte{'b'}, std::byte{'l'}, std::byte{'u'}, std::byte{'b'}}; pqxx::connection cx; pqxx::work tx{cx}; auto id{pqxx::blob::from_buf(tx, data)}; pqxx::bytes 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() { pqxx::bytes const data{std::byte{'C'}, std::byte{'+'}, std::byte{'+'}}; char const temp_file[] = "blob-test-to_file.tmp"; pqxx::connection cx; pqxx::work tx{cx}; auto id{pqxx::blob::from_buf(tx, data)}; pqxx::bytes 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 cx; pqxx::work tx{cx}; auto id{pqxx::blob::from_buf(tx, pqxx::bytes{std::byte{1}})}; auto b{pqxx::blob::open_rw(tx, id)}; b.close(); pqxx::bytes 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"; pqxx::bytes const data{std::byte{'4'}, std::byte{'2'}}; pqxx::connection cx; pqxx::work tx{cx}; pqxx::bytes 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 libpqxx-7.10.0/test/unit/test_cancel_query.cxx000066400000000000000000000010411473205454700214700ustar00rootroot00000000000000#include #include #include "../test_helpers.hxx" namespace { void test_cancel_query() { pqxx::connection cx; pqxx::work tx{cx}; // Calling cancel_query() while none is in progress has no effect. cx.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)"); cx.cancel_query(); } PQXX_REGISTER_TEST(test_cancel_query); } // namespace libpqxx-7.10.0/test/unit/test_column.cxx000066400000000000000000000036431473205454700203250ustar00rootroot00000000000000#include #include "../test_helpers.hxx" namespace { void test_table_column() { pqxx::connection cx; pqxx::work tx{cx}; tx.exec("CREATE TEMP TABLE pqxxfoo (x varchar, y integer, z integer)") .no_rows(); tx.exec("INSERT INTO pqxxfoo VALUES ('xx', 1, 2)").no_rows(); 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); libpqxx-7.10.0/test/unit/test_composite.cxx000066400000000000000000000056301473205454700210300ustar00rootroot00000000000000#include "../test_helpers.hxx" #include "pqxx/composite" #include "pqxx/transaction" namespace { void test_composite() { pqxx::connection cx; pqxx::work tx{cx}; tx.exec("CREATE TYPE pqxxfoo AS (a integer, b text)").no_rows(); auto const f{tx.exec("SELECT '(5,hello)'::pqxxfoo").one_field()}; int a; std::string b; pqxx::parse_composite(f.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 cx; pqxx::work tx{cx}; tx.exec("CREATE TYPE pqxxsingle AS (x text)").no_rows(); std::string s; pqxx::row r; r = tx.exec(R"--(SELECT '("a""b")'::pqxxsingle)--").one_row(); pqxx::parse_composite(r[0].view(), s); PQXX_CHECK_EQUAL( s, "a\"b", "Double-double-quotes escaping did not parse correctly."); r = tx.exec(R"--(SELECT '("a\"b")'::pqxxsingle)--").one_row(); 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 cx; pqxx::work tx{cx}; pqxx::row r; tx.exec("CREATE TYPE pqxxnull AS (a integer)").no_rows(); int nonnull; r = tx.exec("SELECT '()'::pqxxnull").one_row(); 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.exec("CREATE TYPE pqxxnulls AS (a integer, b integer)").no_rows(); std::optional a{2}, b{4}; r = tx.exec("SELECT '(,)'::pqxxnulls").one_row(); 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 cx; pqxx::work tx{cx}; 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.exec("CREATE TYPE pqxxcomp AS (a integer, b text, c text)").no_rows(); auto const f{ tx.exec("SELECT '" + std::string{buf} + "'::pqxxcomp").one_field()}; int a; std::string b, c; bool const nonnull{f.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 libpqxx-7.10.0/test/unit/test_connection.cxx000066400000000000000000000153001473205454700211600ustar00rootroot00000000000000#include #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::nontransaction 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::nontransaction tx2{conn2}; PQXX_CHECK_EQUAL( tx2.query_value("SELECT 9"), 9, "Raw connection did not produce a working new connection."); } void test_closed_connection() { pqxx::connection cx; cx.close(); PQXX_CHECK(not cx.dbname(), "Closed connection had a dbname."); PQXX_CHECK(not cx.username(), "Closed connection had a username."); PQXX_CHECK(not cx.hostname(), "Closed connection had a hostname."); PQXX_CHECK(not cx.port(), "Closed connection had a port."); } void test_skip_init_ssl() { pqxx::skip_init_ssl(); pqxx::skip_init_ssl(); } 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); PQXX_REGISTER_TEST(test_closed_connection); PQXX_REGISTER_TEST(test_skip_init_ssl); } // namespace libpqxx-7.10.0/test/unit/test_cursor.cxx000066400000000000000000000026721473205454700203460ustar00rootroot00000000000000#include #include #include "../test_helpers.hxx" namespace { void test_stateless_cursor_provides_random_access(pqxx::connection &cx) { pqxx::work tx{cx}; 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 &cx) { pqxx::work tx{cx}; 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 cx; test_stateless_cursor_provides_random_access(cx); test_stateless_cursor_ignores_trailing_semicolon(cx); } PQXX_REGISTER_TEST(test_cursor); } // namespace libpqxx-7.10.0/test/unit/test_encodings.cxx000066400000000000000000000061521473205454700207770ustar00rootroot00000000000000#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 libpqxx-7.10.0/test/unit/test_error_verbosity.cxx000066400000000000000000000016251473205454700222650ustar00rootroot00000000000000#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 cx; pqxx::work tx{cx}; cx.set_verbosity(pqxx::error_verbosity::terse); tx.exec("SELECT 1").one_row(); cx.set_verbosity(pqxx::error_verbosity::verbose); tx.exec("SELECT 2").one_row(); } PQXX_REGISTER_TEST(test_error_verbosity); } // namespace libpqxx-7.10.0/test/unit/test_errorhandler.cxx000066400000000000000000000174541473205454700215240ustar00rootroot00000000000000#include #include #include #include "../test_helpers.hxx" namespace { class TestErrorHandler final : public pqxx::errorhandler { public: #include "pqxx/internal/ignore-deprecated-pre.hxx" TestErrorHandler( pqxx::connection &cx, std::vector &activated_handlers, bool retval = true) : pqxx::errorhandler(cx), return_value(retval), message(), handler_list(activated_handlers) {} #include "pqxx/internal/ignore-deprecated-post.hxx" 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 &cx) { std::vector dummy; TestErrorHandler handler(cx, dummy); cx.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 &cx) { std::vector handlers; TestErrorHandler h1(cx, handlers); TestErrorHandler h2(cx, handlers); TestErrorHandler h3(cx, handlers); cx.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 &cx) { std::vector handlers; TestErrorHandler starved(cx, handlers); TestErrorHandler blocker(cx, handlers, false); cx.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 &cx) { std::vector handlers; { TestErrorHandler doomed(cx, handlers); } cx.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 cx; survivor = new TestErrorHandler(cx, 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: #include "pqxx/internal/ignore-deprecated-pre.hxx" explicit MinimalErrorHandler(pqxx::connection &cx) : pqxx::errorhandler(cx) {} #include "pqxx/internal/ignore-deprecated-post.hxx" bool operator()(char const[]) noexcept override { return true; } }; void test_get_errorhandlers(pqxx::connection &cx) { std::unique_ptr eh3; #include "pqxx/internal/ignore-deprecated-pre.hxx" auto const handlers_before{cx.get_errorhandlers()}; #include "pqxx/internal/ignore-deprecated-post.hxx" std::size_t const base_handlers{std::size(handlers_before)}; { MinimalErrorHandler eh1(cx); #include "pqxx/internal/ignore-deprecated-pre.hxx" auto const handlers_with_eh1{cx.get_errorhandlers()}; #include "pqxx/internal/ignore-deprecated-post.hxx" 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(cx); #include "pqxx/internal/ignore-deprecated-pre.hxx" auto const handlers_with_eh2{cx.get_errorhandlers()}; #include "pqxx/internal/ignore-deprecated-post.hxx" 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."); } #include "pqxx/internal/ignore-deprecated-pre.hxx" auto const handlers_without_eh2{cx.get_errorhandlers()}; #include "pqxx/internal/ignore-deprecated-post.hxx" 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(cx); #include "pqxx/internal/ignore-deprecated-pre.hxx" auto const handlers_with_eh3{cx.get_errorhandlers()}; #include "pqxx/internal/ignore-deprecated-post.hxx" 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."); } #include "pqxx/internal/ignore-deprecated-pre.hxx" auto const handlers_without_eh1{cx.get_errorhandlers()}; #include "pqxx/internal/ignore-deprecated-post.hxx" 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(); #include "pqxx/internal/ignore-deprecated-pre.hxx" auto const handlers_without_all{cx.get_errorhandlers()}; #include "pqxx/internal/ignore-deprecated-post.hxx" PQXX_CHECK_EQUAL( std::size(handlers_without_all), base_handlers, "Destroying all custom handlers didn't work as expected."); } void test_errorhandler() { pqxx::connection cx; test_process_notice_calls_errorhandler(cx); test_error_handlers_get_called_newest_to_oldest(cx); test_returning_false_stops_error_handling(cx); test_destroyed_error_handlers_are_not_called(cx); test_destroying_connection_unregisters_handlers(); test_get_errorhandlers(cx); } PQXX_REGISTER_TEST(test_errorhandler); } // namespace libpqxx-7.10.0/test/unit/test_escape.cxx000066400000000000000000000152621473205454700202700ustar00rootroot00000000000000#include #include #include "../test_helpers.hxx" namespace { using namespace std::literals; void compare_esc( pqxx::connection &cx, pqxx::transaction_base &t, char const text[]) { std::size_t const len{std::size(std::string{text})}; PQXX_CHECK_EQUAL( cx.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 &cx, 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(cx, t, escstrings[i]); } void test_quote(pqxx::connection &cx, 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"), cx.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"}; pqxx::bytes const data( reinterpret_cast(binary), std::size(binary)); std::string const escaped{ t.esc_raw(pqxx::bytes_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 cx; pqxx::work tx{cx}; test_esc(cx, tx); test_quote(cx, 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 cx; pqxx::work tx{cx}; 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."); pqxx::bytes 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 cx; pqxx::work tx{cx}; 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 cx; pqxx::work tx{cx}; std::string buf; pqxx::bytes 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 libpqxx-7.10.0/test/unit/test_exceptions.cxx000066400000000000000000000017361473205454700212120ustar00rootroot00000000000000#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 cx; pqxx::work tx{cx}; 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 libpqxx-7.10.0/test/unit/test_field.cxx000066400000000000000000000034441473205454700201120ustar00rootroot00000000000000#include #include "../test_helpers.hxx" namespace { void test_field() { pqxx::connection cx; pqxx::work tx{cx}; auto const r1{tx.exec("SELECT 9").one_row()}; 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.exec("SELECT NULL").one_row()}; 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_MULTIDIM) PQXX_CHECK_EQUAL((r3[3, 0].as()), 4, "Two-argument [] went wrong."); #endif // PQXX_HAVE_MULTIDIM } PQXX_REGISTER_TEST(test_field); } // namespace libpqxx-7.10.0/test/unit/test_float.cxx000066400000000000000000000134461473205454700201370ustar00rootroot00000000000000#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 cx; cx.prepare("stmt", "select cast($1 as float)"); pqxx::work tr{cx}; // 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.exec("SELECT 1.0").one_row(); // 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.exec("SELECT 2.0").one_row(); // 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.exec("SELECT 3.0").one_row(); 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 libpqxx-7.10.0/test/unit/test_largeobject.cxx000066400000000000000000000034731473205454700213120ustar00rootroot00000000000000#include #include #include #include #include "../test_helpers.hxx" namespace { void test_stream_large_object() { pqxx::connection cx; // 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{cx}; #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 libpqxx-7.10.0/test/unit/test_nonblocking_connect.cxx000066400000000000000000000010051473205454700230320ustar00rootroot00000000000000#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 cx{std::move(nbc).produce()}; pqxx::work tx{cx}; PQXX_CHECK_EQUAL(tx.query_value("SELECT 10"), 10, "Bad value!?"); } PQXX_REGISTER_TEST(test_nonblocking_connect); } // namespace libpqxx-7.10.0/test/unit/test_notice_handler.cxx000066400000000000000000000077751473205454700220200ustar00rootroot00000000000000#include #include "../test_helpers.hxx" namespace { void test_notice_handler_receives_notice() { pqxx::connection cx; int notices{0}; cx.set_notice_handler([¬ices](pqxx::zview) noexcept { ++notices; }); pqxx::work tx{cx}; // Start a transaction while already in a transaction, to trigger a notice. tx.exec("BEGIN").no_rows(); PQXX_CHECK_EQUAL(notices, 1, "Did not get expected single notice."); } void test_notice_handler_works_after_connection_closes() { pqxx::result r; int notices{0}; { pqxx::connection cx; cx.set_notice_handler([¬ices](pqxx::zview) noexcept { ++notices; }); pqxx::work tx{cx}; r = tx.exec("SELECT 1"); } PQXX_CHECK_EQUAL(notices, 0, "Got premature notice."); // Trigger a notice by asking libpq about a nonexistent column. PQXX_CHECK_THROWS_EXCEPTION( pqxx::ignore_unused(r.table_column(99)), "Expected an out-of-bounds table_column() to throw an error."); PQXX_CHECK_EQUAL( notices, 1, "Did not get expected single post-connection notice."); } void test_process_notice_calls_notice_handler() { int calls{0}; std::string received; const std::string msg{"Hello there\n"}; pqxx::connection cx; cx.set_notice_handler([&calls, &received](auto x) noexcept { ++calls; received = x; }); cx.process_notice(msg); PQXX_CHECK_EQUAL(calls, 1, "Expected exactly 1 call to notice handler."); PQXX_CHECK_EQUAL(received, msg, "Got wrong message."); } // Global counter so we can count calls to a global function. int notice_handler_test_func_counter{0}; void notice_handler_test_func(pqxx::zview) { ++notice_handler_test_func_counter; } void test_notice_handler_accepts_function() { pqxx::connection cx; cx.set_notice_handler(notice_handler_test_func); cx.process_notice("Hello"); PQXX_CHECK_EQUAL(notice_handler_test_func_counter, 1, "Expected 1 call."); } int notice_handler_test_lambda_counter{0}; void test_notice_handler_accepts_stateless_lambda() { pqxx::connection cx; cx.set_notice_handler( [](pqxx::zview) noexcept { ++notice_handler_test_lambda_counter; }); cx.process_notice("Hello"); PQXX_CHECK_EQUAL(notice_handler_test_lambda_counter, 1, "Expected 1 call."); } struct notice_handler_test_functor { int &count; std::string &received; notice_handler_test_functor(int &c, std::string &r) : count{c}, received{r} {} void operator()(pqxx::zview msg) noexcept { ++count; received = msg; } }; void test_notice_handler_accepts_functor() { std::string const hello{"Hello world"}; // We're going to create a functor that stores its call count and message // her. We can't store it inside the functor, because that gets passed by // value to the connection as a std::function. int count{0}; std::string received; notice_handler_test_functor f(count, received); pqxx::connection cx; cx.set_notice_handler(f); cx.process_notice(hello); PQXX_CHECK_EQUAL(count, 1, "Expected 1 call."); PQXX_CHECK_EQUAL(received, hello, "Wrong message."); } void test_notice_handler_works_after_moving_connection() { bool got_message{false}; pqxx::connection cx; cx.set_notice_handler( [&got_message](pqxx::zview) noexcept { got_message = true; }); auto cx2{std::move(cx)}; pqxx::connection cx3; cx3 = std::move(cx2); pqxx::work tx{cx3}; // Trigger a notice. Just calling process_notice() isn't hard enough for a // good strong test, because that function bypasses the libpq logic for // receiving a notice. tx.exec("BEGIN").no_rows(); PQXX_CHECK(got_message, "Did not receive notice after moving."); } PQXX_REGISTER_TEST(test_notice_handler_receives_notice); PQXX_REGISTER_TEST(test_notice_handler_works_after_connection_closes); PQXX_REGISTER_TEST(test_process_notice_calls_notice_handler); PQXX_REGISTER_TEST(test_notice_handler_accepts_function); PQXX_REGISTER_TEST(test_notice_handler_accepts_stateless_lambda); PQXX_REGISTER_TEST(test_notice_handler_accepts_functor); PQXX_REGISTER_TEST(test_notice_handler_works_after_moving_connection); } // namespace libpqxx-7.10.0/test/unit/test_notification.cxx000066400000000000000000000301261473205454700215120ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "../test_helpers.hxx" namespace { #include class TestReceiver final : public pqxx::notification_receiver { public: std::string payload; int backend_pid; TestReceiver(pqxx::connection &cx, std::string const &channel_name) : pqxx::notification_receiver(cx, 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_classic( pqxx::transaction_base &tx, std::string const &channel, char const payload[] = nullptr) { pqxx::connection &cx(tx.conn()); std::string SQL{"NOTIFY " + tx.quote_name(channel)}; if (payload != nullptr) SQL += ", " + tx.quote(payload); TestReceiver receiver{cx, channel}; // Clear out any previously pending notifications that might otherwise // confuse the test. cx.get_notifs(); // Notify, and receive. tx.exec(SQL); tx.commit(); int notifs{0}; for (int i{0}; (i < 10) and (notifs == 0); ++i, pqxx::internal::wait_for(1000u)) notifs = cx.get_notifs(); PQXX_CHECK_EQUAL(notifs, 1, "Got wrong number of notifications."); PQXX_CHECK_EQUAL(receiver.backend_pid, cx.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_classic() { pqxx::connection cx; TestReceiver receiver(cx, "mychannel"); PQXX_CHECK_EQUAL(receiver.channel(), "mychannel", "Bad channel."); pqxx::work tx{cx}; test_receive_classic(tx, "channel1"); pqxx::nontransaction u(cx); test_receive_classic(u, "channel2", "payload"); } #include void test_notification_to_self_arrives_after_commit() { pqxx::connection cx; auto const channel{"pqxx_test_channel"}; int notifications{0}; pqxx::connection *conn; std::string incoming, payload; int pid{0}; cx.listen( channel, [¬ifications, &conn, &incoming, &payload, &pid](pqxx::notification n) { ++notifications; conn = &n.conn; incoming = n.channel; pid = n.backend_pid; payload = n.payload; }); cx.get_notifs(); // No notifications so far. PQXX_CHECK_EQUAL(notifications, 0, "Unexpected notification."); pqxx::work tx{cx}; tx.notify(channel); int received{cx.await_notification(0, 300)}; // Notification has not been delivered yet, since transaction has not yet // been committed. PQXX_CHECK_EQUAL(received, 0, "Notification went out before commit."); PQXX_CHECK_EQUAL(notifications, 0, "Received uncounted notification."); tx.commit(); received = cx.await_notification(3); PQXX_CHECK_EQUAL(received, 1, "Did not receive 1 notification from self."); PQXX_CHECK_EQUAL(notifications, 1, "Miscounted notifcations."); PQXX_CHECK(conn == &cx, "Wrong connection on notification from self."); PQXX_CHECK_EQUAL( pid, cx.backendpid(), "Notification from self came from wrong connection."); PQXX_CHECK_EQUAL(incoming, channel, "Notification is on wrong channel."); PQXX_CHECK_EQUAL(payload, "", "Unexpected payload."); } void test_notification_has_payload() { pqxx::connection cx; auto const channel{"pqxx-ichan"}, payload{"two dozen eggs"}; int notifications{0}; std::string received; cx.listen(channel, [¬ifications, &received](pqxx::notification n) { ++notifications; received = n.payload; }); pqxx::work tx{cx}; tx.notify(channel, payload); tx.commit(); cx.await_notification(3); PQXX_CHECK_EQUAL(notifications, 1, "Expeccted 1 self-notification."); PQXX_CHECK_EQUAL(received, payload, "Unexpected payload."); } // Functor-shaped notification handler. struct notify_test_listener { int &received; notify_test_listener(int &r) : received{r} {} void operator()(pqxx::notification) { ++received; } }; void test_listen_supports_different_types_of_callable() { auto const chan{"pqxx-test-listen"}; pqxx::connection cx; int received; // Using a functor as a handler. received = 0; notify_test_listener l(received); cx.listen(chan, l); pqxx::work tx1{cx}; tx1.notify(chan); tx1.commit(); cx.await_notification(3); PQXX_CHECK_EQUAL(received, 1, "Notification did not arrive."); // Using a handler that takes a const reference to the notification. received = 0; cx.listen(chan, [&received](pqxx::notification const &) { ++received; }); pqxx::work tx2{cx}; tx2.notify(chan); tx2.commit(); cx.await_notification(3); PQXX_CHECK_EQUAL(received, 1, "Const ref did not receive notification."); // Using a handler that takes an rvalue reference. received = 0; cx.listen(chan, [&received](pqxx::notification &&) { ++received; }); pqxx::work tx3{cx}; tx3.notify(chan); tx3.commit(); cx.await_notification(3); PQXX_CHECK_EQUAL(received, 1, "Revalue ref did not receive notification."); } void test_abort_cancels_notification() { auto const chan{"pqxx-test-channel"}; pqxx::connection cx; bool received{false}; cx.listen(chan, [&received](pqxx::notification) { received = true; }); pqxx::work tx{cx}; tx.notify(chan); tx.abort(); cx.await_notification(3); PQXX_CHECK(not received, "Abort did not cancel notification."); } void test_notification_channels_are_case_sensitive() { pqxx::connection cx; std::string in; cx.listen("pqxx-AbC", [&in](pqxx::notification n) { in = n.channel; }); pqxx::work tx{cx}; tx.notify("pqxx-AbC"); tx.notify("pqxx-ABC"); tx.notify("pqxx-abc"); tx.commit(); cx.await_notification(3); PQXX_CHECK_EQUAL(in, "pqxx-AbC", "Channel is not case-insensitive."); } void test_notification_channels_may_contain_weird_chars() { auto const chan{"pqxx-A_#&*!"}; pqxx::connection cx; std::string got; cx.listen(chan, [&got](pqxx::notification n) { got = n.channel; }); pqxx::work tx{cx}; tx.notify(chan); tx.commit(); cx.await_notification(3); PQXX_CHECK_EQUAL( got, chan, "Channel name with weird characters got distorted."); } /// In a nontransaction, a notification goes out even if you abort. void test_nontransaction_sends_notification() { auto const chan{"pqxx-test-chan"}; pqxx::connection cx; bool got{false}; cx.listen(chan, [&got](pqxx::notification) { got = true; }); pqxx::nontransaction tx{cx}; tx.notify(chan); tx.abort(); cx.await_notification(3); PQXX_CHECK(got, "Notification from nontransaction did not arrive."); } void test_subtransaction_sends_notification() { auto const chan{"pqxx-test-chan6301"}; pqxx::connection cx; bool got{false}; cx.listen(chan, [&got](pqxx::notification) { got = true; }); pqxx::work tx{cx}; pqxx::subtransaction sx{tx}; sx.notify(chan); sx.commit(); tx.commit(); cx.await_notification(3); PQXX_CHECK(got, "Notification from subtransaction did not arrive."); } void test_subtransaction_abort_cancels_notification() { auto const chan{"pqxx-test-chan123278w"}; pqxx::connection cx; bool got{false}; cx.listen(chan, [&got](pqxx::notification) { got = true; }); pqxx::work tx{cx}; pqxx::subtransaction sx{tx}; sx.notify(chan); sx.abort(); tx.commit(); cx.await_notification(3); PQXX_CHECK(not got, "Subtransaction rollback did not cancel notification."); } void test_cannot_listen_during_transaction() { pqxx::connection cx; // Listening while a transaction is active is an error, even when it's just // a nontransaction. pqxx::nontransaction tx{cx}; PQXX_CHECK_THROWS( cx.listen("pqxx-test-chan02756", [](pqxx::notification) {}), pqxx::usage_error, "Expected usage_error when listening during transaction."); } void test_notifications_cross_connections() { auto const chan{"pqxx-chan7529"}; pqxx::connection cx_listen, cx_notify; int sender_pid{0}; cx_listen.listen( chan, [&sender_pid](pqxx::notification n) { sender_pid = n.backend_pid; }); pqxx::work tx{cx_notify}; tx.notify(chan); tx.commit(); cx_listen.await_notification(3); PQXX_CHECK_EQUAL(sender_pid, cx_notify.backendpid(), "Sender pid mismatch."); } void test_notification_goes_to_right_handler() { pqxx::connection cx; std::string got; int count{0}; cx.listen("pqxx-chanX", [&got, &count](pqxx::notification) { got = "chanX"; ++count; }); cx.listen("pqxx-chanY", [&got, &count](pqxx::notification) { got = "chanY"; ++count; }); cx.listen("pqxx-chanZ", [&got, &count](pqxx::notification) { got = "chanZ"; ++count; }); pqxx::work tx{cx}; tx.notify("pqxx-chanY"); tx.commit(); cx.await_notification(3); PQXX_CHECK_EQUAL(got, "chanY", "Wrong handler got called."); PQXX_CHECK_EQUAL(count, 1, "Wrong number of handler calls."); } void test_listen_on_same_channel_overwrites() { auto const chan{"pqxx-chan84710"}; pqxx::connection cx; std::string got; int count{0}; cx.listen(chan, [&got, &count](pqxx::notification) { got = "first"; ++count; }); cx.listen(chan, [&got, &count](pqxx::notification) { got = "second"; ++count; }); cx.listen(chan, [&got, &count](pqxx::notification) { got = "third"; ++count; }); pqxx::work tx{cx}; tx.notify(chan); tx.commit(); cx.await_notification(3); PQXX_CHECK_EQUAL(count, 1, "Expected 1 notification despite overwrite."); PQXX_CHECK_EQUAL(got, "third", "Wrong handler called."); } void test_empty_notification_handler_disables() { auto const chan{"pqxx-chan812710"}; pqxx::connection cx; bool got{false}; cx.listen(chan, [&got](pqxx::notification) { got = true; }); cx.listen(chan); pqxx::work tx{cx}; tx.notify(chan); tx.commit(); PQXX_CHECK(not got, "Disabling a notification handler did not work."); } void test_notifications_do_not_come_in_until_commit() { auto const chan{"pqxx-chan95017834"}; pqxx::connection cx; bool got{false}; cx.listen(chan, [&got](pqxx::notification) { got = true; }); // This applies even during a nontransaction. Another test verifies that // a notification goes _out_ even if we abort the nontransaction, because // it goes out immediately, not at commit time. What we're establishing // here is that the notification does not come _in_ during a transaction, // even if it's a nontransaction. pqxx::nontransaction tx{cx}; tx.notify(chan); cx.await_notification(3); PQXX_CHECK(not got, "Notification came in during nontransaction."); } void test_notification_handlers_follow_connection_move() { auto const chan{"pqxx-chan3782"}; pqxx::connection cx1; pqxx::connection *got{nullptr}; cx1.listen(chan, [&got](pqxx::notification n) { got = &n.conn; }); pqxx::connection cx2{std::move(cx1)}; pqxx::connection cx3; cx3 = std::move(cx2); pqxx::work tx{cx3}; tx.notify(chan); tx.commit(); cx3.await_notification(3); PQXX_CHECK(got != nullptr, "Did not get notified."); PQXX_CHECK(got == &cx3, "Notification got the wrong connection."); } PQXX_REGISTER_TEST(test_notification_classic); PQXX_REGISTER_TEST(test_notification_to_self_arrives_after_commit); PQXX_REGISTER_TEST(test_notification_has_payload); PQXX_REGISTER_TEST(test_listen_supports_different_types_of_callable); PQXX_REGISTER_TEST(test_abort_cancels_notification); PQXX_REGISTER_TEST(test_notification_channels_are_case_sensitive); PQXX_REGISTER_TEST(test_notification_channels_may_contain_weird_chars); PQXX_REGISTER_TEST(test_nontransaction_sends_notification); PQXX_REGISTER_TEST(test_subtransaction_sends_notification); PQXX_REGISTER_TEST(test_subtransaction_abort_cancels_notification); PQXX_REGISTER_TEST(test_cannot_listen_during_transaction); PQXX_REGISTER_TEST(test_notifications_cross_connections); PQXX_REGISTER_TEST(test_notification_goes_to_right_handler); PQXX_REGISTER_TEST(test_listen_on_same_channel_overwrites); PQXX_REGISTER_TEST(test_empty_notification_handler_disables); PQXX_REGISTER_TEST(test_notifications_do_not_come_in_until_commit); PQXX_REGISTER_TEST(test_notification_handlers_follow_connection_move); } // namespace libpqxx-7.10.0/test/unit/test_pipeline.cxx000066400000000000000000000040471473205454700206340ustar00rootroot00000000000000#include #include #include #include "../test_helpers.hxx" namespace { void test_pipeline() { pqxx::connection cx; pqxx::work tx{cx}; // 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.one_field().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.one_field().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.one_field().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); libpqxx-7.10.0/test/unit/test_prepared_statement.cxx000066400000000000000000000316371473205454700227220ustar00rootroot00000000000000#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 cx; pqxx::work tx1{cx}; // Prepare a simple statement. tx1.conn().prepare("CountToFive", count_to_5); // The statement returns exactly what you'd expect. COMPARE_RESULTS( "CountToFive", tx1.exec(pqxx::prepped{"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{cx}; // Executing a nonexistent prepared statement is also an error. PQXX_CHECK_THROWS( tx2.exec(pqxx::prepped{"NonexistentStatement"}), pqxx::sql_error, "Did not report invocation of nonexistent prepared statement."); } void test_basic_args() { pqxx::connection cx; cx.prepare("EchoNum", "SELECT $1::int"); pqxx::work tx{cx}; auto r{tx.exec(pqxx::prepped{"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.one_field().as(), 7, "Got wrong result."); auto rw{tx.exec(pqxx::prepped{"EchoNum"}, 8).one_row()}; 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 cx; cx.prepare("CountSeries", "SELECT * FROM generate_series($1::int, $2::int)"); pqxx::work tx{cx}; auto r{ tx.exec(pqxx::prepped{"CountSeries"}, pqxx::params{7, 10}).expect_rows(4)}; 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."); cx.prepare("Reversed", "SELECT * FROM generate_series($2::int, $1::int)"); r = tx.exec(pqxx::prepped{"Reversed"}, pqxx::params{8, 6}).expect_rows(3); 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 cx; pqxx::work tx{cx}; cx.prepare("EchoStr", "SELECT $1::varchar"); auto rw{tx.exec(pqxx::prepped{"EchoStr"}, pqxx::params{nullptr}).one_row()}; PQXX_CHECK(rw.front().is_null(), "nullptr did not translate to null."); char const *n{nullptr}; rw = tx.exec(pqxx::prepped{"EchoStr"}, pqxx::params{n}).one_row(); PQXX_CHECK(rw.front().is_null(), "Null pointer did not translate to null."); } void test_strings() { pqxx::connection cx; pqxx::work tx{cx}; cx.prepare("EchoStr", "SELECT $1::varchar"); auto rw{tx.exec(pqxx::prepped{"EchoStr"}, pqxx::params{"foo"}).one_row()}; PQXX_CHECK_EQUAL( rw.front().as(), "foo", "Wrong string result."); char const nasty_string[]{R"--('\"\)--"}; rw = tx.exec(pqxx::prepped{"EchoStr"}, pqxx::params{nasty_string}).one_row(); PQXX_CHECK_EQUAL( rw.front().as(), std::string(nasty_string), "Prepared statement did not quote/escape correctly."); rw = tx.exec(pqxx::prepped{"EchoStr"}, pqxx::params{std::string{nasty_string}}) .one_row(); 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(pqxx::prepped{"EchoStr"}, pqxx::params{nonconst}).one_row(); PQXX_CHECK_EQUAL( rw.front().as(), std::string(nonconst), "Non-const C string passed incorrectly."); } void test_binary() { pqxx::connection cx; pqxx::work tx{cx}; cx.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(pqxx::prepped{"EchoBin"}, pqxx::params{bin}).one_row()}; PQXX_CHECK_EQUAL( pqxx::binarystring(rw[0]).str(), input, "Binary string came out damaged."); } #include "pqxx/internal/ignore-deprecated-post.hxx" { pqxx::bytes bytes{ reinterpret_cast(raw_bytes), std::size(raw_bytes)}; auto bp{tx.exec(pqxx::prepped{"EchoBin"}, pqxx::params{bytes}).one_row()}; 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 // pqx::bytes, 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(pqxx::prepped{"EchoBin"}, pqxx::params{ptr}).one_row()}; 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(pqxx::prepped{"EchoBin"}, pqxx::params{opt}).one_row()}; 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 pqxx::bytes. Any contiguous range // will do. { std::vector data{std::byte{'x'}, std::byte{'v'}}; auto op{tx.exec(pqxx::prepped{"EchoBin"}, pqxx::params{data}).one_row()}; 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 cx; pqxx::work tx{cx}; cx.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(pqxx::prepped{"Concat2Numbers"}, pqxx::params{params}).one_row()}; PQXX_CHECK_EQUAL( rw39.front().as(), 39, "Dynamic prepared-statement parameters went wrong."); cx.prepare("Concat4Numbers", "SELECT 1000*$1 + 100*$2 + 10*$3 + $4"); auto const rw1396{ tx.exec(pqxx::prepped{"Concat4Numbers"}, pqxx::params{1, params, 6}) .one_row()}; PQXX_CHECK_EQUAL( rw1396.front().as(), 1396, "Dynamic params did not interleave with static ones properly."); } void test_optional() { pqxx::connection cx; pqxx::work tx{cx}; cx.prepare("EchoNum", "SELECT $1::int"); pqxx::row rw{tx.exec( pqxx::prepped{"EchoNum"}, pqxx::params{std::optional{std::in_place, 10}}) .one_row()}; PQXX_CHECK_EQUAL( rw.front().as(), 10, "optional (with value) did not return the right value."); rw = tx.exec(pqxx::prepped{"EchoNum"}, pqxx::params{std::optional{}}) .one_row(); 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."); } void test_wrong_number_of_params() { { pqxx::connection conn1; pqxx::transaction tx1{conn1}; conn1.prepare("broken1", "SELECT $1::int + $2::int"); PQXX_CHECK_THROWS( tx1.exec(pqxx::prepped{"broken1"}, pqxx::params{10}), pqxx::protocol_violation, "Incomplete params no longer thrws protocol violation."); } { pqxx::connection conn2; pqxx::transaction tx2{conn2}; conn2.prepare("broken2", "SELECT $1::int + $2::int"); PQXX_CHECK_THROWS( tx2.exec(pqxx::prepped{"broken2"}, {5, 4, 3}), pqxx::protocol_violation, "Passing too many params no longer thrws protocol violation."); } } void test_query_prepped() { pqxx::connection cx; pqxx::transaction tx{cx}; cx.prepare("hop", "SELECT x * 3 FROM generate_series(1, 2) AS x"); std::vector out; for (auto [i] : tx.query(pqxx::prepped{"hop"})) out.push_back(i); PQXX_CHECK_EQUAL(std::size(out), 2u, "Wrong number of results."); PQXX_CHECK_EQUAL(out.at(0), 3, "Wrong data came out of prepped query."); PQXX_CHECK_EQUAL(out.at(1), 6, "First item was correct, second was not!"); } void test_query_value_prepped() { pqxx::connection cx; pqxx::transaction tx{cx}; cx.prepare("pick", "SELECT 92"); PQXX_CHECK_EQUAL( tx.query_value(pqxx::prepped{"pick"}), 92, "Wrong value."); } void test_for_query_prepped() { pqxx::connection cx; pqxx::transaction tx{cx}; cx.prepare("series", "SELECT * FROM generate_series(3, 4)"); std::vector out; tx.for_query(pqxx::prepped("series"), [&out](int x) { out.push_back(x); }); PQXX_CHECK_EQUAL(std::size(out), 2u, "Wrong result size."); PQXX_CHECK_EQUAL(out.at(0), 3, "Wrong data came out of prepped query."); PQXX_CHECK_EQUAL(out.at(1), 4, "First item was correct, second was not."); } PQXX_REGISTER_TEST(test_prepared_statements); PQXX_REGISTER_TEST(test_placeholders_generates_names); PQXX_REGISTER_TEST(test_wrong_number_of_params); PQXX_REGISTER_TEST(test_query_prepped); PQXX_REGISTER_TEST(test_query_value_prepped); PQXX_REGISTER_TEST(test_for_query_prepped); } // namespace libpqxx-7.10.0/test/unit/test_range.cxx000066400000000000000000000505131473205454700201220ustar00rootroot00000000000000#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."); } } constexpr void test_range_is_constexpr() { // Test compile-time operations. // // A few things in the standard library need to be constexpr for this to work, // so we only test it in C++20. #if __cplusplus >= 202002L using range = pqxx::range; using ibound = pqxx::inclusive_bound; constexpr ibound one{1}, three{3}; constexpr range oneone{one, one}, onethree{one, three}; static_assert(oneone == oneone); static_assert(oneone != onethree); static_assert(onethree.contains(oneone)); #endif } 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); PQXX_REGISTER_TEST(test_range_is_constexpr); } // namespace libpqxx-7.10.0/test/unit/test_read_transaction.cxx000066400000000000000000000007361473205454700223500ustar00rootroot00000000000000#include #include "../test_helpers.hxx" namespace { void test_read_transaction() { pqxx::connection cx; pqxx::read_transaction tx{cx}; PQXX_CHECK_EQUAL( tx.query_value("SELECT 1"), 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 libpqxx-7.10.0/test/unit/test_result_iteration.cxx000066400000000000000000000076631473205454700224320ustar00rootroot00000000000000#include #include #include "../test_helpers.hxx" namespace { void test_result_iteration() { pqxx::connection cx; pqxx::work tx{cx}; 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 cx; pqxx::work tx{cx}; 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 cx; pqxx::work tx{cx}; 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 cx; pqxx::work tx{cx}; 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 cx; pqxx::work tx{cx}; tx.exec("CREATE TEMP TABLE employee(name varchar, salary int)").no_rows(); 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 libpqxx-7.10.0/test/unit/test_result_slicing.cxx000066400000000000000000000121311473205454700220460ustar00rootroot00000000000000#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 cx; pqxx::work tx{cx}; 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" libpqxx-7.10.0/test/unit/test_row.cxx000066400000000000000000000063741473205454700176430ustar00rootroot00000000000000#include #include "../test_helpers.hxx" namespace { void test_row() { pqxx::connection cx; pqxx::work tx{cx}; 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 cx; pqxx::work tx{cx}; 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 cx; pqxx::work tx{cx}; pqxx::row const r{tx.exec("SELECT 1, 2, 3").one_row()}; 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.exec("SELECT 999").one_row().as()), 999, "Unary tuple did not extract right."); } // In a random access iterator i, i[n] == *(i + n). void test_row_iterator_array_index_offsets_iterator() { pqxx::connection cx; pqxx::work tx{cx}; auto const row{tx.exec("SELECT 5, 4, 3, 2").one_row()}; PQXX_CHECK_EQUAL( row.begin()[1].as(), "4", "Row iterator indexing went wrong."); PQXX_CHECK_EQUAL( row.rbegin()[1].as(), "3", "Reverse row iterator indexing went wrong."); } PQXX_REGISTER_TEST(test_row); PQXX_REGISTER_TEST(test_row_iterator); PQXX_REGISTER_TEST(test_row_as); PQXX_REGISTER_TEST(test_row_iterator_array_index_offsets_iterator); } // namespace libpqxx-7.10.0/test/unit/test_separated_list.cxx000066400000000000000000000014231473205454700220250ustar00rootroot00000000000000#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 libpqxx-7.10.0/test/unit/test_simultaneous_transactions.cxx000066400000000000000000000006171473205454700243460ustar00rootroot00000000000000#include #include #include "../test_helpers.hxx" namespace { void test_simultaneous_transactions() { pqxx::connection cx; pqxx::nontransaction n1{cx}; PQXX_CHECK_THROWS( pqxx::nontransaction n2{cx}, std::logic_error, "Allowed to open simultaneous nontransactions."); } PQXX_REGISTER_TEST(test_simultaneous_transactions); } // namespace libpqxx-7.10.0/test/unit/test_sql_cursor.cxx000066400000000000000000000255161473205454700212270ustar00rootroot00000000000000#include #include #include "../test_helpers.hxx" namespace { void test_forward_sql_cursor() { pqxx::connection cx; pqxx::work tx{cx}; // 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 cx; pqxx::work tx{cx}; 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 cx; pqxx::work tx{cx}; tx.exec( "DECLARE adopted SCROLL CURSOR FOR " "SELECT generate_series(1, 3)") .no_rows(); 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 .exec( "DECLARE adopted2 CURSOR FOR " "SELECT generate_series(1, 3)") .no_rows(); { 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 cx; pqxx::work tx{cx}; // "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(cx, "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(cx, "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 libpqxx-7.10.0/test/unit/test_stateless_cursor.cxx000066400000000000000000000061471473205454700224360ustar00rootroot00000000000000#include #include #include "../test_helpers.hxx" namespace { void test_stateless_cursor() { pqxx::connection cx; pqxx::work tx{cx}; 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 libpqxx-7.10.0/test/unit/test_strconv.cxx000066400000000000000000000105001473205454700205140ustar00rootroot00000000000000#include #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."); pqxx::connection cx; pqxx::work tx{cx}; std::tuple out; tx.exec("SELECT 0").one_row().to(out); } 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 libpqxx-7.10.0/test/unit/test_stream_from.cxx000066400000000000000000000302161473205454700213420ustar00rootroot00000000000000#include #include #include "../test_helpers.hxx" #include "../test_types.hxx" #include #include #include #include #include #include #include namespace { #include "pqxx/internal/ignore-deprecated-pre.hxx" 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 &cx) { pqxx::work tx{cx}; 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."); 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 cx; pqxx::work tx{cx}; 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( "INSERT INTO stream_from_test VALUES ($1,$2,$3,$4,$5,$6)", pqxx::params{910, nullptr, nullptr, nullptr, "\\N", bytea{}}); tx.exec( "INSERT INTO stream_from_test VALUES ($1,$2,$3,$4,$5,$6)", pqxx::params{ 1234, "now", 4321, ipv4{8, 8, 8, 8}, "hello\n \tworld", bytea{'\x00', '\x01', '\x02'}}); tx.exec( "INSERT INTO stream_from_test VALUES ($1,$2,$3,$4,$5,$6)", pqxx::params{ 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(cx); test_bad_tuples(cx); std::cout << "testing `std::unique_ptr` as optional...\n"; test_optional(cx); std::cout << "testing `std::optional` as optional...\n"; test_optional(cx); } void test_stream_from_does_escaping() { std::string const input{"a\t\n\n\n \\b\nc"}; pqxx::connection cx; pqxx::work tx{cx}; tx.exec("CREATE TEMP TABLE badstr (str text)").no_rows(); tx.exec("INSERT INTO badstr (str) VALUES ($1)", pqxx::params{input}) .no_rows(); 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 cx; pqxx::work tx{cx}; 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_stream_from_read_row() { pqxx::connection cx; pqxx::work tx{cx}; 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."); } void test_stream_from_parses_awkward_strings() { pqxx::connection cx; // This is a particularly awkward encoding that we should test. Its // multibyte characters can include byte values that *look* like ASCII // characters, such as quotes and backslashes. It is crucial that we parse // those properly. A byte-for-byte scan could find special ASCII characters // that aren't really there. cx.set_client_encoding("SJIS"); pqxx::work tx{cx}; tx.exec0("CREATE TEMP TABLE nasty(id integer, value varchar)"); tx.exec0( "INSERT INTO nasty(id, value) VALUES " // A proper null. "(0, NULL), " // Some strings that could easily be mis-parsed as null. "(1, 'NULL'), " "(2, '\\N'), " "(3, '''NULL'''), " // An SJIS multibyte character that ends in a byte that happens to be the // ASCII value for a backslash. This is one example of how an SJIS SQL // injection can break out of a string. "(4, '\x81\x5c')"); std::vector> values; for (auto [id, value] : tx.query>( "SELECT id, value FROM nasty ORDER BY id")) { PQXX_CHECK_EQUAL(id, std::size(values), "Test data is broken."); values.push_back(value); } PQXX_CHECK(not values[0].has_value(), "Null did not work properly."); PQXX_CHECK(values[1].has_value(), "String 'NULL' became a NULL."); PQXX_CHECK_EQUAL(values[1].value(), "NULL", "String 'NULL' went badly."); PQXX_CHECK(values[2].has_value(), "String '\\N' became a NULL."); PQXX_CHECK_EQUAL(values[2].value(), "\\N", "String '\\N' went badly."); PQXX_CHECK(values[3].has_value(), "String \"'NULL'\" became a NULL."); PQXX_CHECK_EQUAL( values[3].value(), "'NULL'", "String \"'NULL'\" went badly."); PQXX_CHECK_EQUAL( values[4].value(), "\x81\x5c", "Finicky SJIS character went badly."); } #include "pqxx/internal/ignore-deprecated-post.hxx" 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_stream_from_read_row); PQXX_REGISTER_TEST(test_stream_from_parses_awkward_strings); } // namespace libpqxx-7.10.0/test/unit/test_stream_query.cxx000066400000000000000000000163011473205454700215430ustar00rootroot00000000000000#include #include "../test_helpers.hxx" #include "../test_types.hxx" #include #include #include #include #include #include #include namespace { void test_stream_handles_empty() { pqxx::connection cx; pqxx::work tx{cx}; for (auto [out] : tx.stream("SELECT generate_series(1, 0)")) PQXX_CHECK(false, "Unexpectedly got a value: " + pqxx::to_string(out)); PQXX_CHECK_EQUAL( tx.query_value("SELECT 99"), 99, "Things went wrong after empty stream."); } void test_stream_does_escaping() { std::string const input{"a\t\n\n\n \\b\nc"}; pqxx::connection cx; pqxx::work tx{cx}; int counter{0}; for (auto [out] : tx.stream("SELECT " + tx.quote(input))) { PQXX_CHECK_EQUAL(out, input, "stream got weird characters wrong."); ++counter; } PQXX_CHECK_EQUAL(counter, 1, "Expected exactly 1 iteration."); } void test_stream_iterates() { pqxx::connection cx; pqxx::work tx{cx}; std::vector ids; std::vector values; for (auto [id, value] : tx.stream( "SELECT generate_series, 'String ' || generate_series::text || '.' " "FROM generate_series(1, 2)")) { ids.push_back(id); values.push_back(value); } PQXX_CHECK_EQUAL( tx.query_value("SELECT 99"), 99, "Things went wrong after stream."); tx.commit(); PQXX_CHECK_EQUAL(std::size(ids), 2u, "Wrong number of rows."); PQXX_CHECK_EQUAL(std::size(values), 2u, "Wrong number of values."); PQXX_CHECK_EQUAL(ids[0], 1, "Wrong IDs."); PQXX_CHECK_EQUAL(values[0], "String 1.", "Wrong values."); PQXX_CHECK_EQUAL(ids[1], 2, "Wrong second ID."); PQXX_CHECK_EQUAL(values[1], "String 2.", "Wrong second value."); } void test_stream_reads_simple_values() { pqxx::connection cx; pqxx::work tx{cx}; int counter{0}; for (auto [id, name] : tx.stream("SELECT 213, 'Hi'")) { PQXX_CHECK_EQUAL(id, 213u, "Bad ID."); PQXX_CHECK_EQUAL(name, "Hi", "Bad name."); ++counter; } PQXX_CHECK_EQUAL(counter, 1, "Expected exactly 1 row."); PQXX_CHECK_EQUAL( tx.query_value("SELECT 333"), 333, "Bad value after stream."); } void test_stream_reads_string_view() { pqxx::connection cx; pqxx::work tx{cx}; std::vector out; for (auto [v] : tx.stream( "SELECT 'x' || generate_series FROM generate_series(1, 2)")) { static_assert(std::is_same_v); out.push_back(std::string{v}); } PQXX_CHECK_EQUAL(std::size(out), 2u, "Wrong number of rows."); PQXX_CHECK_EQUAL(out[0], "x1", "Wrong first value."); PQXX_CHECK_EQUAL(out[1], "x2", "Wrong second value."); } void test_stream_reads_nulls_as_optionals() { pqxx::connection cx; pqxx::work tx{cx}; for (auto [null] : tx.stream>("SELECT NULL")) PQXX_CHECK(not null.has_value(), "NULL translated to nonempty optional."); for (auto [val] : tx.stream>("SELECT 'x'")) { PQXX_CHECK( val.has_value(), "Non-null value did not come through as optional."); PQXX_CHECK_EQUAL(*val, "x", "Bad value in optional."); } } void test_stream_parses_awkward_strings() { pqxx::connection cx; // This is a particularly awkward encoding that we should test. Its // multibyte characters can include byte values that *look* like ASCII // characters, such as quotes and backslashes. It is crucial that we parse // those properly. A byte-for-byte scan could find special ASCII characters // that aren't really there. cx.set_client_encoding("SJIS"); pqxx::work tx{cx}; tx.exec("CREATE TEMP TABLE nasty(id integer, value varchar)").no_rows(); tx.exec( "INSERT INTO nasty(id, value) VALUES " // A proper null. "(0, NULL), " // Some strings that could easily be mis-parsed as null. "(1, 'NULL'), " "(2, '\\N'), " "(3, '''NULL'''), " // An SJIS multibyte character that ends in a byte that happens to be the // ASCII value for a backslash. This is one example of how an SJIS SQL // injection can break out of a string. "(4, '\x81\x5c'), " "(5, '\t'), " "(6, '\\\\\\\n\\\\')") .no_rows(); std::vector> values; for (auto [id, value] : tx.stream>( "SELECT id, value FROM nasty ORDER BY id")) { PQXX_CHECK_EQUAL(id, std::size(values), "Test data is broken."); values.push_back(value); } PQXX_CHECK(not values[0].has_value(), "Null did not work properly."); PQXX_CHECK(values[1].has_value(), "String 'NULL' became a NULL."); PQXX_CHECK_EQUAL(values[1].value(), "NULL", "String 'NULL' went badly."); PQXX_CHECK(values[2].has_value(), "String '\\N' became a NULL."); PQXX_CHECK_EQUAL(values[2].value(), "\\N", "String '\\N' went badly."); PQXX_CHECK(values[3].has_value(), "String \"'NULL'\" became a NULL."); PQXX_CHECK_EQUAL( values[3].value(), "'NULL'", "String \"'NULL'\" went badly."); PQXX_CHECK_EQUAL( values[4].value(), "\x81\x5c", "Finicky SJIS character went badly."); PQXX_CHECK_EQUAL(values[5].value(), "\t", "Tab unescaped wrong."); PQXX_CHECK_EQUAL( values[6].value(), "\\\\\\\n\\\\", "Backslashes confused stream."); } void test_stream_handles_nulls_in_all_places() { pqxx::connection cx; pqxx::work tx{cx}; for (auto [a, b, c, d, e] : tx.stream< std::optional, std::optional, int, std::optional, std::optional>( "SELECT NULL::text, NULL::integer, 11, NULL::text, NULL::text")) { PQXX_CHECK(not a, "Starting null did not come through."); PQXX_CHECK(not b, "Null in 2nd column did not come through."); PQXX_CHECK_EQUAL(c, 11, "Integer in the middle went wrong."); PQXX_CHECK(not d, "Null further in did not come through."); PQXX_CHECK(not e, "Final null did not come through."); } } void test_stream_handles_empty_string() { pqxx::connection cx; pqxx::work tx{cx}; std::string out{""}; for (auto [empty] : tx.stream("SELECT ''")) out = empty; PQXX_CHECK_EQUAL(out, "", "Empty string_view parsed wrong."); out = ""; int num{0}; for (auto [i, s] : tx.stream("SELECT 99, ''")) { num = i; out = s; } PQXX_CHECK_EQUAL(num, 99, "Integer came out wrong before empty string."); PQXX_CHECK_EQUAL(out, "", "Final empty string came out wrong."); for (auto [s2, i2] : tx.stream("SELECT '', 33")) { out = s2; num = i2; } PQXX_CHECK_EQUAL(out, "", "Leading empty string came out wrong."); PQXX_CHECK_EQUAL(num, 33, "Integer came out wrong after empty string."); } PQXX_REGISTER_TEST(test_stream_handles_empty); PQXX_REGISTER_TEST(test_stream_does_escaping); PQXX_REGISTER_TEST(test_stream_reads_simple_values); PQXX_REGISTER_TEST(test_stream_reads_string_view); PQXX_REGISTER_TEST(test_stream_iterates); PQXX_REGISTER_TEST(test_stream_reads_nulls_as_optionals); PQXX_REGISTER_TEST(test_stream_parses_awkward_strings); PQXX_REGISTER_TEST(test_stream_handles_nulls_in_all_places); PQXX_REGISTER_TEST(test_stream_handles_empty_string); } // namespace libpqxx-7.10.0/test/unit/test_stream_to.cxx000066400000000000000000000432621473205454700210260ustar00rootroot00000000000000#include #include #include #include #include "../test_helpers.hxx" #include "../test_types.hxx" namespace { using namespace std::literals; 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.exec("SELECT * FROM stream_to_test WHERE number0 = 1234").one_row()}; 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.exec("SELECT * FROM stream_to_test WHERE number0 = 5678").one_row()}; 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.exec("SELECT * FROM stream_to_test WHERE number0 = 1234").one_row()}; 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.exec("SELECT * FROM stream_to_test WHERE number0 = 5678").one_row()}; 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 cx; pqxx::work tx{cx}; tx.exec("CREATE TEMP TABLE foo(x integer, y text)").no_rows(); auto inserter{pqxx::stream_to::table(tx, {"foo"})}; inserter.write_values( std::optional{368}, std::optional{"Text"}); inserter.complete(); auto const row{tx.exec("SELECT x, y FROM foo").one_row()}; 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 cx; pqxx::work tx{cx}; tx.exec("CREATE TEMP TABLE test_container(a integer, b integer)").no_rows(); auto inserter{pqxx::stream_to::table(tx, {"test_container"})}; inserter << std::vector{112, 244}; inserter.complete(); auto read{tx.exec("SELECT * FROM test_container").one_row()}; 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 &cx) { pqxx::work tx{cx}; tx.exec("DELETE FROM stream_to_test").no_rows(); tx.commit(); } void test_stream_to() { pqxx::connection cx; pqxx::work tx{cx}; tx.exec( "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" ")") .no_rows(); tx.commit(); test_nonoptionals(cx); clear_table(cx); test_nonoptionals_fold(cx); clear_table(cx); test_bad_null(cx); clear_table(cx); test_bad_null_fold(cx); clear_table(cx); test_too_few_fields(cx); clear_table(cx); test_too_few_fields_fold(cx); clear_table(cx); test_too_many_fields(cx); clear_table(cx); test_too_many_fields_fold(cx); clear_table(cx); test_optional(cx); clear_table(cx); test_optional_fold(cx); clear_table(cx); test_optional(cx); clear_table(cx); test_optional_fold(cx); clear_table(cx); test_variant_fold(cx); } void test_stream_to_factory_with_static_columns() { pqxx::connection cx; pqxx::work tx{cx}; tx.exec("CREATE TEMP TABLE pqxx_stream_to(a integer, b varchar)").no_rows(); auto stream{pqxx::stream_to::table(tx, {"pqxx_stream_to"}, {"a", "b"})}; stream.write_values(3, "three"); stream.complete(); auto r{tx.exec("SELECT a, b FROM pqxx_stream_to").one_row()}; 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 cx; pqxx::work tx{cx}; tx.exec("CREATE TEMP TABLE pqxx_stream_to(a integer, b varchar)").no_rows(); 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, cx.quote_table({"pqxx_stream_to"}), cx.quote_columns(columns))}; #endif stream.write_values(4, "four"); stream.complete(); auto r{tx.exec("SELECT a, b FROM pqxx_stream_to").one_row()}; 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 cx; pqxx::work tx{cx}; std::string const table{R"--(pqxx_Stream"'x)--"}, column{R"--(a'"b)--"}; tx.exec( "CREATE TEMP TABLE " + tx.quote_name(table) + "(" + tx.quote_name(column) + " integer)") .no_rows(); 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."); } void test_stream_to_optionals() { pqxx::connection cx; pqxx::work tx{cx}; tx.exec("CREATE TEMP TABLE pqxx_strings(key integer, value varchar)") .no_rows(); auto stream{pqxx::stream_to::table(tx, {"pqxx_strings"}, {"key", "value"})}; stream.write_values(1, std::optional{}); stream.write_values(2, std::optional{}); stream.write_values(3, std::optional{}); stream.write_values(4, std::optional{"Opt str."}); stream.write_values(5, std::optional{"Opt sv."}); stream.write_values(6, std::optional{"Opt zv."}); stream.write_values(7, std::shared_ptr{}); stream.write_values(8, std::shared_ptr{}); stream.write_values(9, std::shared_ptr{}); stream.write_values(10, std::make_shared("Shared str.")); stream.write_values(11, std::make_shared("Shared sv.")); stream.write_values(12, std::make_shared("Shared zv.")); stream.write_values(13, std::unique_ptr{}); stream.write_values(14, std::unique_ptr{}); stream.write_values(15, std::unique_ptr{}); stream.write_values(16, std::make_unique("Uq str.")); stream.write_values(17, std::make_unique("Uq sv.")); stream.write_values(18, std::make_unique("Uq zv.")); stream.complete(); std::string nulls; for (auto [key] : tx.query( "SELECT key FROM pqxx_strings WHERE value IS NULL ORDER BY key")) nulls += pqxx::to_string(key) + '.'; PQXX_CHECK_EQUAL( nulls, "1.2.3.7.8.9.13.14.15.", "Unexpected list of nulls."); std::string values; for (auto [value] : tx.query("SELECT value FROM pqxx_strings WHERE value IS " "NOT NULL ORDER BY key")) values += value; PQXX_CHECK_EQUAL( values, "Opt str.Opt sv.Opt zv.Shared str.Shared sv.Shared zv.Uq str.Uq sv.Uq zv.", "Unexpected list of values."); } void test_stream_to_escaping() { pqxx::connection cx; pqxx::work tx{cx}; tx.exec("CREATE TEMP TABLE foo (i integer, t varchar)").no_rows(); // We'll check that streaming these strings to the database and querying them // back reproduces them faithfully. std::string_view const inputs[] = { ""sv, "hello"sv, "a\tb"sv, "a\nb"sv, "don't"sv, "\\\\\\''"sv, "\\N"sv, "\\Nfoo"sv, }; // Stream the input strings into the databsae. pqxx::stream_to out{pqxx::stream_to::table(tx, {"foo"}, {"i", "t"})}; for (std::size_t i{0}; i < std::size(inputs); ++i) out.write_values(i, inputs[i]); out.complete(); // Verify. auto outputs{tx.exec("SELECT i, t FROM foo ORDER BY i")}; PQXX_CHECK_EQUAL( static_cast(std::size(outputs)), std::size(inputs), "Wrong number of rows came back."); for (std::size_t i{0}; i < std::size(inputs); ++i) { int idx{static_cast(i)}; PQXX_CHECK_EQUAL( outputs[idx][0].as(), i, "Unexpected index."); PQXX_CHECK_EQUAL( outputs[idx][1].as(), inputs[i], "String changed in transit."); } } void test_stream_to_moves_into_optional() { pqxx::connection cx; pqxx::transaction tx{cx}; tx.exec("CREATE TEMP TABLE foo (a integer)").no_rows(); std::optional org{ std::in_place, pqxx::stream_to::table(tx, {"foo"}, {"a"})}; org->write_values(1); auto copy{std::move(org)}; copy->write_values(2); copy->complete(); auto values{tx.exec("SELECT a FROM foo ORDER BY a").expect_rows(2)}; PQXX_CHECK_EQUAL( values[0][0].as(), 1, "Streaming results start off wrong."); PQXX_CHECK_EQUAL(values[1][0].as(), 2, "Moved stream went wrong."); } void test_stream_to_empty_strings() { // Reproduce #816: Streaming an array of 4 or more empty strings to a table // using stream_to crashes. pqxx::connection cx; pqxx::transaction tx{cx}; tx.exec("CREATE TEMP TABLE strs (list text[])").no_rows(); std::vector empties{"", "", "", ""}; auto stream{pqxx::stream_to::table(tx, {"strs"})}; stream.write_values(std::variant>{empties}); stream.complete(); tx.commit(); } 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); PQXX_REGISTER_TEST(test_stream_to_optionals); PQXX_REGISTER_TEST(test_stream_to_escaping); PQXX_REGISTER_TEST(test_stream_to_moves_into_optional); PQXX_REGISTER_TEST(test_stream_to_empty_strings); } // namespace libpqxx-7.10.0/test/unit/test_string_conversion.cxx000066400000000000000000000152541473205454700226040ustar00rootroot00000000000000#include #include #include #include #include "../test_helpers.hxx" using namespace std::literals; // 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 cx; pqxx::work tx{cx}; 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'."); } void test_string_view_conversion() { using traits = pqxx::string_traits; PQXX_CHECK_EQUAL( pqxx::to_string("view here"sv), "view here"s, "Bad conversion from string_view."); char buf[200]; char *end{traits::into_buf(std::begin(buf), std::end(buf), "more view"sv)}; PQXX_CHECK( std::begin(buf) < end and end < std::end(buf), "string_view into_buf did not stay within its buffer."); assert(end > std::begin(buf)); PQXX_CHECK( *(end - 1) == '\0', "string_view into_buf did not zero-terminate."); PQXX_CHECK_EQUAL( (std::string{buf, static_cast(end - std::begin(buf) - 1)}), "more view"s, "string_view into_buf wrote wrong data."); PQXX_CHECK(*(end - 2) == 'w', "string_view into_buf is in the wrong place."); std::string_view org{"another!"sv}; pqxx::zview out{traits::to_buf(std::begin(buf), std::end(buf), org)}; PQXX_CHECK_EQUAL( std::string{out}, "another!"s, "string_view to_buf returned wrong data."); PQXX_CHECK( std::data(out) != std::data(org), "string_view to_buf returned original view, which may not be terminated."); } 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); PQXX_REGISTER_TEST(test_string_view_conversion); } // namespace libpqxx-7.10.0/test/unit/test_subtransaction.cxx000066400000000000000000000030171473205454700220620ustar00rootroot00000000000000#include #include #include "../test_helpers.hxx" namespace { void make_table(pqxx::transaction_base &tx) { tx.exec("CREATE TEMP TABLE foo (x INTEGER)").no_rows(); } void insert_row(pqxx::transaction_base &tx) { tx.exec("INSERT INTO foo(x) VALUES (1)").no_rows(); } int count_rows(pqxx::transaction_base &tx) { return tx.query_value("SELECT count(*) FROM foo"); } void test_subtransaction_commits_if_commit_called(pqxx::connection &cx) { pqxx::work tx(cx); make_table(tx); { pqxx::subtransaction sub(tx); insert_row(sub); sub.commit(); } PQXX_CHECK_EQUAL( count_rows(tx), 1, "Work done in committed subtransaction was lost."); } void test_subtransaction_aborts_if_abort_called(pqxx::connection &cx) { pqxx::work tx(cx); make_table(tx); { pqxx::subtransaction sub(tx); insert_row(sub); sub.abort(); } PQXX_CHECK_EQUAL( count_rows(tx), 0, "Aborted subtransaction was not rolled back."); } void test_subtransaction_aborts_implicitly(pqxx::connection &cx) { pqxx::work tx(cx); make_table(tx); { pqxx::subtransaction sub(tx); insert_row(sub); } PQXX_CHECK_EQUAL( count_rows(tx), 0, "Uncommitted subtransaction was not rolled back uring destruction."); } void test_subtransaction() { pqxx::connection cx; test_subtransaction_commits_if_commit_called(cx); test_subtransaction_aborts_if_abort_called(cx); test_subtransaction_aborts_implicitly(cx); } PQXX_REGISTER_TEST(test_subtransaction); } // namespace libpqxx-7.10.0/test/unit/test_test_helpers.cxx000066400000000000000000000153731473205454700215340ustar00rootroot00000000000000#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{ #if !defined(PQXX_HAVE_SOURCE_LOCATION) __FILE__, __LINE__, #endif "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. #if defined(PQXX_HAVE_SOURCE_LOCATION) PQXX_CHECK_THROWS_EXCEPTION( throw pqxx::test::test_failure{"(expected)"}, "PQXX_CHECK_THROWS_EXCEPTION() failed to catch expected exception."); #else PQXX_CHECK_THROWS_EXCEPTION( throw(pqxx::test::test_failure{__FILE__, __LINE__, "(expected)"}), "PQXX_CHECK_THROWS_EXCEPTION() failed to catch expected exception."); #endif // 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() { #if defined(PQXX_HAVE_SOURCE_LOCATION) PQXX_CHECK_THROWS( throw pqxx::test::test_failure{"(expected)"}, pqxx::test::test_failure, "PQXX_CHECK_THROWS() failed to catch expected exception."); #else PQXX_CHECK_THROWS( throw pqxx::test::test_failure(__FILE__, __LINE__, "(expected)"), pqxx::test::test_failure, "PQXX_CHECK_THROWS() failed to catch expected exception."); #endif // 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 libpqxx-7.10.0/test/unit/test_thread_safety_model.cxx000066400000000000000000000010031473205454700230160ustar00rootroot00000000000000#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 libpqxx-7.10.0/test/unit/test_time.cxx000066400000000000000000000044751473205454700177720ustar00rootroot00000000000000#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 cx; pqxx::work tx{cx}; 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 libpqxx-7.10.0/test/unit/test_transaction.cxx000066400000000000000000000045521473205454700213550ustar00rootroot00000000000000#include #include #include "../test_helpers.hxx" namespace { void test_nontransaction_continues_after_error() { pqxx::connection cx; pqxx::nontransaction tx{cx}; 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.exec(std::string{"DROP TABLE IF EXISTS "} + table).no_rows(); } void create_temp_table(pqxx::transaction_base &tx) { tx.exec("CREATE TEMP TABLE " + table + " (x integer)").no_rows(); } void insert_temp_table(pqxx::transaction_base &tx, int value) { tx.exec( "INSERT INTO " + table + " (x) VALUES (" + pqxx::to_string(value) + ")") .no_rows(); } int count_temp_table(pqxx::transaction_base &tx) { return tx.query_value("SELECT count(*) FROM " + table); } void test_nontransaction_autocommits() { pqxx::connection cx; pqxx::nontransaction tx1{cx}; delete_temp_table(tx1); create_temp_table(tx1); tx1.commit(); pqxx::nontransaction tx2{cx}; insert_temp_table(tx2, 4); tx2.abort(); pqxx::nontransaction tx3{cx}; 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 cx; TX tx1{cx}; tx1.exec("SELECT 1").one_row(); tx1.commit(); tx1.commit(); TX tx2{cx}; tx2.exec("SELECT 2").one_row(); tx2.abort(); tx2.abort(); TX tx3{cx}; tx3.exec("SELECT 3").one_row(); tx3.commit(); PQXX_CHECK_THROWS( tx3.abort(), pqxx::usage_error, "Abort after commit not caught."); ; TX tx4{cx}; tx4.exec("SELECT 4").one_row(); 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 libpqxx-7.10.0/test/unit/test_transaction_base.cxx000066400000000000000000000244061473205454700223470ustar00rootroot00000000000000#include #include #include "../test_helpers.hxx" namespace { void test_exec0(pqxx::transaction_base &tx) { #include "pqxx/internal/ignore-deprecated-pre.hxx" pqxx::result E{tx.exec0("SELECT * FROM pg_tables WHERE 0 = 1")}; PQXX_CHECK(std::empty(E), "Nonempty result from exec0."); PQXX_CHECK_THROWS( tx.exec0("SELECT 99"), pqxx::unexpected_rows, "Nonempty exec0 result did not throw unexpected_rows."); #include "pqxx/internal/ignore-deprecated-post.hxx" } void test_exec1(pqxx::transaction_base &tx) { #include "pqxx/internal/ignore-deprecated-pre.hxx" pqxx::row R{tx.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( tx.exec1("SELECT * FROM pg_tables WHERE 0 = 1"), pqxx::unexpected_rows, "Empty exec1 result did not throw unexpected_rows."); PQXX_CHECK_THROWS( tx.exec1("SELECT * FROM generate_series(1, 2)"), pqxx::unexpected_rows, "Two-row exec1 result did not throw unexpected_rows."); #include "pqxx/internal/ignore-deprecated-post.hxx" } void test_exec_n(pqxx::transaction_base &tx) { #include "pqxx/internal/ignore-deprecated-pre.hxx" pqxx::result R{tx.exec_n(3u, "SELECT * FROM generate_series(1, 3)")}; PQXX_CHECK_EQUAL(std::size(R), 3, "Wrong result size from exec_n."); PQXX_CHECK_THROWS( tx.exec_n(2u, "SELECT * FROM generate_series(1, 3)"), pqxx::unexpected_rows, "exec_n did not throw unexpected_rows for an undersized result."); PQXX_CHECK_THROWS( tx.exec_n(4u, "SELECT * FROM generate_series(1, 3)"), pqxx::unexpected_rows, "exec_n did not throw unexpected_rows for an oversized result."); #include "pqxx/internal/ignore-deprecated-post.hxx" } void test_query_value(pqxx::connection &cx) { pqxx::work tx{cx}; 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::usage_error, "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."); // Now with parameters: PQXX_CHECK_EQUAL( tx.query_value("SELECT $1 + 1", {5}), 6, "Wrong value from query_value with params."); } void test_transaction_base() { pqxx::connection cx; { pqxx::work tx{cx}; test_exec_n(tx); test_exec0(tx); test_exec1(tx); } test_query_value(cx); } void test_transaction_query() { pqxx::connection cx; pqxx::work tx{cx}; std::vector names; std::vector salaries; for (auto [name, salary] : tx.query( "SELECT 'name' || i, i * 1000 FROM generate_series(1, 5) AS i")) { names.emplace_back(name); salaries.emplace_back(salary); } PQXX_CHECK_EQUAL(std::size(names), 5u, "Wrong number of rows."); PQXX_CHECK_EQUAL(std::size(salaries), 5u, "Mismatched number of salaries!"); PQXX_CHECK_EQUAL(names[0], "name1", "Names start out wrong."); PQXX_CHECK_EQUAL(names[4], "name5", "Names end wrong."); PQXX_CHECK_EQUAL(salaries[0], 1'000, "Salaries start out wrong."); PQXX_CHECK_EQUAL(salaries[4], 5'000, "Salaries end wrong."); } void test_transaction_query_params() { pqxx::connection cx; pqxx::work tx{cx}; int outcome{-1}; for (auto [value] : tx.query("SELECT $1 * 2", {32})) { PQXX_CHECK_EQUAL(outcome, -1, "Queried one row, got multiple."); outcome = value; } PQXX_CHECK_EQUAL( outcome, 64, "Parameterised query() produced wrong result."); outcome = -1; #include "pqxx/internal/ignore-deprecated-pre.hxx" for (auto [value] : tx.query_n(1, "SELECT * FROM generate_series(1, $1)", {1})) { PQXX_CHECK_EQUAL(outcome, -1, "Queried one row, got multiple."); outcome = value; } PQXX_CHECK_EQUAL(outcome, 1, "Bad value from query_n() with params."); PQXX_CHECK_THROWS( tx.query_n(2, "SELECT $1", {9}), pqxx::unexpected_rows, "query_n() with params failed to detect unexpected rows."); std::tuple res{tx.query1("SELECT $1 / 3", {33})}; auto [res_int] = res; PQXX_CHECK_EQUAL(res_int, 11, "Wrong value from query1() with params."); PQXX_CHECK_THROWS( pqxx::ignore_unused( tx.query1("SELECT * from generate_series(1, $1)", {4})), pqxx::unexpected_rows, "query1() with params failed to detect wrong number of rows."); std::tuple const res2{ tx.query1("SELECT $1, $2", {3, 6})}; auto [res2_a, res2_b] = res2; PQXX_CHECK_EQUAL( res2_a, 3, "Multi-column query1() with params gave wrong result."); PQXX_CHECK_EQUAL( res2_b, 6, "Multi-column query1() with params gave wrong result."); std::optional> const opt1{ tx.query01("SELECT 1 WHERE 1 = $1", {0})}; PQXX_CHECK(not opt1, "query01 got a result it shouldn't have."); std::optional> const opt2{ tx.query01("SELECT $1 - 10", {12})}; PQXX_CHECK( opt2.has_value(), "query01 did not get the result it should have."); auto const [opt2_val] = *opt2; PQXX_CHECK_EQUAL(opt2_val, 2, "query01 got wrong result."); auto const [opt3_a, opt3_b] = tx.query01("SELECT $1, $2", {12, 99}).value(); PQXX_CHECK_EQUAL( opt3_a, 12, "Multi-column query01() with params gave wrong result."); PQXX_CHECK_EQUAL( opt3_b, 99, "Multi-column query01() with params gave wrong result."); #include "pqxx/internal/ignore-deprecated-post.hxx" } void test_transaction_for_query() { constexpr auto query{ "SELECT i, concat('x', (2*i)::text) " "FROM generate_series(1, 3) AS i " "ORDER BY i"}; pqxx::connection cx; pqxx::work tx{cx}; std::string ints; std::string strings; tx.for_query(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."); // And now with parameters... int x{0}, y{0}; tx.for_query( "SELECT $1, $2", [&x, &y](int xout, int yout) { PQXX_CHECK_EQUAL(x, 0, "for_query() called too many times."); PQXX_CHECK_EQUAL(y, 0, "for_query() called too many times."); x = xout; y = yout; }, {42, 67}); PQXX_CHECK_EQUAL(x, 42, "for_query() with parameters got wrong value."); PQXX_CHECK_EQUAL(y, 67, "for_query() with parameters got wrong value."); } void test_transaction_for_stream() { constexpr auto query{ "SELECT i, concat('x', (2*i)::text) " "FROM generate_series(1, 3) AS i " "ORDER BY i"}; pqxx::connection cx; pqxx::work tx{cx}; std::string ints; std::string strings; tx.for_stream(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."); } void test_transaction_query01() { pqxx::connection cx; pqxx::work tx{cx}; #include "pqxx/internal/ignore-deprecated-pre.hxx" std::optional> o{ tx.query01("SELECT * FROM generate_series(1, 1) AS i WHERE i = 5")}; PQXX_CHECK(not o.has_value(), "Why did we get a row?"); o = tx.query01("SELECT * FROM generate_series(8, 8)"); PQXX_CHECK(o.has_value(), "Why did we not get a row?"); // The "if" is redundant (see the check above). But gcc 11 complains when // enabling maintainer mode but not audit mode: something inside the optional // "may be used uninitialized." if (o.has_value()) PQXX_CHECK_EQUAL(std::get<0>(*o), 8, "Bad value from query01()."); PQXX_CHECK_THROWS( o = tx.query01("SELECT * FROM generate_series(1, 2)"), pqxx::unexpected_rows, "Wrong number of rows did not throw unexpected_rows."); PQXX_CHECK_THROWS( o = tx.query01("SELECT 1, 2"), pqxx::usage_error, "Wrong number of columns did not throw usage_error."); #include "pqxx/internal/ignore-deprecated-post.hxx" } void test_transaction_query1() { pqxx::connection cx; pqxx::work tx{cx}; std::tuple x; PQXX_CHECK_THROWS( x = tx.query1("SELECT * FROM generate_series(1, 1) AS i WHERE i = 5"), pqxx::unexpected_rows, "Zero rows did not throw unexpected_rows."); std::optional> const o{ tx.query1("SELECT * FROM generate_series(8, 8)")}; PQXX_CHECK(o.has_value(), "Why did we not get a row?"); PQXX_CHECK_EQUAL(std::get<0>(*o), 8, "Bad value from query1()."); PQXX_CHECK_THROWS( x = tx.query1("SELECT * FROM generate_series(1, 2)"), pqxx::unexpected_rows, "Too many rows did not throw unexpected_rows."); PQXX_CHECK_THROWS( x = tx.query1("SELECT 1, 2"), pqxx::usage_error, "Wrong number of columns did not throw usage_error."); pqxx::ignore_unused(x); } void test_transaction_query_n() { pqxx::connection cx; pqxx::work tx{cx}; #include "pqxx/internal/ignore-deprecated-pre.hxx" PQXX_CHECK_THROWS( pqxx::ignore_unused(tx.query_n(5, "SELECT generate_series(1, 3)")), pqxx::unexpected_rows, "No exception when query_n returns too few rows."); PQXX_CHECK_THROWS( pqxx::ignore_unused(tx.query_n(5, "SELECT generate_series(1, 10)")), pqxx::unexpected_rows, "No exception when query_n returns too many rows."); std::vector v; for (auto [n] : tx.query_n(3, "SELECT generate_series(7, 9)")) v.push_back(n); #include "pqxx/internal/ignore-deprecated-post.hxx" PQXX_CHECK_EQUAL(std::size(v), 3u, "Wrong number of rows."); PQXX_CHECK_EQUAL(v[0], 7, "Wrong result data."); PQXX_CHECK_EQUAL(v[2], 9, "Data started out right but went wrong."); } PQXX_REGISTER_TEST(test_transaction_base); PQXX_REGISTER_TEST(test_transaction_query); PQXX_REGISTER_TEST(test_transaction_query_params); PQXX_REGISTER_TEST(test_transaction_for_query); PQXX_REGISTER_TEST(test_transaction_for_stream); PQXX_REGISTER_TEST(test_transaction_query01); PQXX_REGISTER_TEST(test_transaction_query1); PQXX_REGISTER_TEST(test_transaction_query_n); } // namespace libpqxx-7.10.0/test/unit/test_transaction_focus.cxx000066400000000000000000000027521473205454700225540ustar00rootroot00000000000000#include #include #include "../test_helpers.hxx" namespace { auto make_focus(pqxx::dbtransaction &tx) { #include "pqxx/internal/ignore-deprecated-pre.hxx" return pqxx::stream_from::query(tx, "SELECT * from generate_series(1, 10)"); #include "pqxx/internal/ignore-deprecated-post.hxx" } void test_cannot_run_statement_during_focus() { pqxx::connection cx; pqxx::transaction tx{cx}; 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 cx; cx.prepare("foo", "SELECT 1"); pqxx::transaction tx{cx}; tx.exec(pqxx::prepped{"foo"}); auto focus{make_focus(tx)}; PQXX_CHECK_THROWS( tx.exec(pqxx::prepped{"foo"}), pqxx::usage_error, "Prepared statement during focus did not throw expected error."); } void test_cannot_run_params_statement_during_focus() { pqxx::connection cx; pqxx::transaction tx{cx}; tx.exec("select $1", pqxx::params{10}); auto focus{make_focus(tx)}; PQXX_CHECK_THROWS( tx.exec("select $1", pqxx::params{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 libpqxx-7.10.0/test/unit/test_transactor.cxx000066400000000000000000000067131473205454700212110ustar00rootroot00000000000000#include #include #include "../test_helpers.hxx" namespace { void test_transactor_newstyle_executes_simple_query() { pqxx::connection cx; auto const r{pqxx::perform( [&cx] { return pqxx::work{cx}.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 libpqxx-7.10.0/test/unit/test_type_name.cxx000066400000000000000000000010761473205454700210070ustar00rootroot00000000000000#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 libpqxx-7.10.0/test/unit/test_zview.cxx000066400000000000000000000023261473205454700201710ustar00rootroot00000000000000#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."); } void test_zview_converts_to_string() { using pqxx::operator"" _zv; using traits = pqxx::string_traits; PQXX_CHECK_EQUAL( pqxx::to_string("hello"_zv), std::string{"hello"}, "to_string on zview failed."); char buf[100]; auto const v{traits::to_buf(std::begin(buf), std::end(buf), "myview"_zv)}; PQXX_CHECK_EQUAL(std::string{v}, "myview", "to_buf on zview failed."); auto const p{ traits::into_buf(std::begin(buf), std::end(buf), "moreview"_zv)}; PQXX_CHECK_NOT_EQUAL( p, std::begin(buf), "into_buf on zview returns beginning of buffer."); PQXX_CHECK( p > std::begin(buf) and p < std::end(buf), "into_buf on zview did not store in buffer."); PQXX_CHECK(*(p - 1) == '\0', "into_buf on zview wasted space."); PQXX_CHECK(*(p - 2) == 'w', "into_buf on zview has extraneous data."); PQXX_CHECK_EQUAL(std::string(buf), "moreview", "into_buf on zview failed."); } PQXX_REGISTER_TEST(test_zview_literal); PQXX_REGISTER_TEST(test_zview_converts_to_string); } // namespace libpqxx-7.10.0/tools/000077500000000000000000000000001473205454700144415ustar00rootroot00000000000000libpqxx-7.10.0/tools/Makefile.am000066400000000000000000000013331473205454700164750ustar00rootroot00000000000000EXTRA_DIST = \ deprecations \ extract_version \ format \ generate_check_config.py \ generate_cxx_checks.py \ lint \ m4esc.py \ pqxxthreadsafety.cxx \ rmlo.cxx \ splitconfig.py \ template2mak.py \ todo \ update-copyright 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} libpqxx-7.10.0/tools/Makefile.in000066400000000000000000000465761473205454700165300ustar00rootroot00000000000000# Makefile.in generated by automake 1.16.5 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)/pqxx_cxx_feature_checks.ac \ $(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@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ 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 = \ deprecations \ extract_version \ format \ generate_check_config.py \ generate_cxx_checks.py \ lint \ m4esc.py \ pqxxthreadsafety.cxx \ rmlo.cxx \ splitconfig.py \ template2mak.py \ todo \ update-copyright 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: libpqxx-7.10.0/tools/deprecations000077500000000000000000000002021473205454700170410ustar00rootroot00000000000000#! /bin/sh set -eu MARKER='include.*ignore-deprecated-pre' grep -Ircl "$MARKER" src include tools/*.cxx test config-tests | sort libpqxx-7.10.0/tools/extract_version000077500000000000000000000025701473205454700176120ustar00rootroot00000000000000#! /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 libpqxx-7.10.0/tools/format000077500000000000000000000011021473205454700156510ustar00rootroot00000000000000#! /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 '*.[ch]xx' -print0 | xargs -0 clang-format -i # Reformat CMake files. WORKDIR=$(mktemp -d) virtualenv -q --python="$(which python3)" "$WORKDIR/venv" # shellcheck disable=SC1091 source "$WORKDIR"/venv/bin/activate pip install -q six pyaml cmake-format (find . -name '*.cmake' -print0 | xargs -0 -n1 cmake-format -i) || true rm -rf "$WORKDIR" libpqxx-7.10.0/tools/generate_check_config.py000077500000000000000000000062001473205454700212700ustar00rootroot00000000000000#! /usr/bin/env python3 """Write autoconf and CMake configuration for our C++ feature checks. Produces configuration files for inclusion in the autoconf script and the CMake configuration, respectively. The config will ask the build systems to try and compile each of the snippets of check code in `config-tests/`, and where that succeeds, define the C++ macro of the same name as the base name of the check snippet. """ from argparse import ( ArgumentParser, Namespace, ) import os.path from pathlib import Path from textwrap import dedent # Name of the autoconf configuration script that we produce. (Lives in the # main source directory.) AUTOCONF_CONFIG = 'pqxx_cxx_feature_checks.ac' # Name of the CMake config that we produce. (Lives in the cmake directory.) CMAKE_CONFIG = 'pqxx_cxx_feature_checks.cmake' def parse_args() -> Namespace: """Parse command line.""" parser = ArgumentParser(__doc__) parser.add_argument( '--source', '-s', metavar='DIR', type=Path, default=Path(), help="Location of the source tree. Defaults to current directory.") return parser.parse_args() def list_snippets(source: Path) -> list[str]: """Return list of C++ snippets.""" return sorted(map(str, (source / 'config-tests').glob('*.cxx'))) # Comment header for either autoconf or CMake config we generate. HEAD = dedent("""\ # Configuration for feature checks. Generated by %(script)s. """) def compose_header() -> str: """Produce a config header.""" return HEAD % {'script': os.path.basename(__file__)} FOOT = "# End of config.\n" # Template for an autoconf feature check. AUTOCONF_TEMPLATE = dedent("""\ AC_MSG_CHECKING([%(macro)s]) %(macro)s=yes AC_COMPILE_IFELSE( [read_test(%(macro)s.cxx)], AC_DEFINE( [%(macro)s], 1, [Define if this feature is available.]), %(macro)s=no) AC_MSG_RESULT($%(macro)s) """) def generate_autoconf(source: Path, snippets: list[str]) -> None: """Generate autoconf configuration.""" dest = source / AUTOCONF_CONFIG with dest.open('w', encoding='ascii') as stream: stream.write(compose_header()) for snippet in snippets: stream.write(AUTOCONF_TEMPLATE % {'macro': Path(snippet).stem}) stream.write(FOOT) # Template for a CMake feature check. # # Makes use of a custom function, try_compile. CMAKE_TEMPLATE = dedent("""\ try_compile( %(macro)s ${PROJECT_BINARY_DIR} SOURCES ${PROJECT_SOURCE_DIR}/config-tests/%(macro)s.cxx ) """) def generate_cmake(source: Path, snippets: list[str]) -> None: """Generate CMake configuration.""" dest = source / 'cmake' / CMAKE_CONFIG with dest.open('w', encoding='ascii') as stream: stream.write(compose_header()) for snippet in snippets: stream.write(CMAKE_TEMPLATE % {'macro': Path(snippet).stem}) stream.write(FOOT) def main(args: Namespace) -> None: """Main entry point.""" snippets = list_snippets(args.source) generate_autoconf(args.source, snippets) generate_cmake(args.source, snippets) if __name__ == '__main__': main(parse_args()) libpqxx-7.10.0/tools/generate_cxx_checks.py000077500000000000000000000067161473205454700210240ustar00rootroot00000000000000#! /usr/bin/env python3 """Generate autoconf/CMake checks for C++ feature check macros. Produces feature checks for those features that we can detect based on just the C++20 feature check macros. Reads the test libpqxx feature macro names, as well as the C++ feature check macros that control them, from cxx_features.txt in the source tree. """ from argparse import ( ArgumentParser, Namespace, ) import os.path from pathlib import Path from textwrap import dedent from typing import cast # Name of the config file listing, one per line, the macros to test and set. # # Ignoring whitespace, a line can be: # * empty, or # * a comment starting with '#', or # * a tuple of macro names. # # In that last case, the line must consist of a libpqxx feature macro name # (which the configuration will either define or not define depening on whether # there is support for the corresponding feature), followed by the name of the # C++ feature test macro that we will need to check in order to determinue # whether that feature is present. CONFIG = 'cxx_features.txt' def parse_args() -> Namespace: """Parse command line.""" parser = ArgumentParser(description=__doc__) parser.add_argument( '--source', '-s', metavar='DIR', type=Path, default=Path(), help="Location of the source tree. Defaults to current directory.") return parser.parse_args() def read_config(config: Path) -> list[tuple[str, str]]: """Read config file, return as list of tuples. Each item is a tuple of a libpqxx feature macro, and the corresponding C++ feature check macro. """ contents = config.read_text(encoding='ascii') lines = [line.strip() for line in contents.splitlines()] return [ cast(tuple[str, str], tuple(line.split())) for line in lines if line != '' and not line.startswith('#') ] # Template for a check snippet. # # Strictly speaking, this is unnecessarily verbose. Why does it check first # whether the macro is defined, and only then what its value is? Because it's # just conceivable that a user might have their compiler set to be extremely # strict when it comes to checking undefined macros in a conditional. The # C++ standard says that in a conditional, an undefined macro shows up as if # its value were zero. But I can imagine some people wanting the compiler to # warn them when they evaluate an undefined macro. TEMPLATE = dedent("""\ // Feature check for '%(pqxx_macro)s'. // Generated by %(script)s. #include #if !defined(%(cxx_macro)s) # error "No %(pqxx_macro)s: %(cxx_macro)s is not set." #endif #if !%(cxx_macro)s # error "No %(pqxx_macro)s: %(cxx_macro)s is false." #endif int main() {} """) def write_check( source: Path, pqxx_macro: str, cxx_macro: str, base_params: dict ) -> None: """Write a piece of C++ for checking a feature macro.""" params = dict( { 'pqxx_macro': pqxx_macro, 'cxx_macro': cxx_macro, }, **base_params) check = source / 'config-tests' / f'{pqxx_macro}.cxx' check.write_text(TEMPLATE % params, encoding='ascii') def main(args: Namespace) -> None: """Main entry point.""" items = read_config(args.source / 'cxx_features.txt') base_params = { 'script': os.path.basename(__file__), } for pqxx_macro, cxx_macro in items: write_check(args.source, pqxx_macro, cxx_macro, base_params) if __name__ == '__main__': main(parse_args()) libpqxx-7.10.0/tools/lint000077500000000000000000000124161473205454700153410ustar00rootroot00000000000000#! /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:-}" set_up() { MY_VENV="$(mktemp -d)" if [ -z "$MY_VENV" ] then echo "Failed to set up virtualenv." >&2 exit 2 fi virtualenv -q "$MY_VENV" # shellcheck disable=SC1091 . "$MY_VENV/bin/activate" pip install -q pyflakes ruff shellcheck-py } clean_up() { if [ -n "${MY_VENV:-}" ] && [ "${VIRTUAL_ENV:-x}" = "${MY_VENV:-y}" ] then deactivate || true fi if [ -n "${MY_VENV:-}" ] && [ -d "${MY_VENV:-/nonexistent/dir}" ] then rm -r "$MY_VENV" fi } trap clean_up EXIT set_up # 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 exotics="$( find "$SRCDIR" -type f -name '*.[ch].cxx' -print0 | xargs -0 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 PAT HEADER_NAME="$1" shift PAT='^[[:space:]]*#[[:space:]]*include[[:space:]]*[<"]'"$HEADER_NAME"'[>"]' # It's OK for the grep to fail. find "$SRCDIR/include/pqxx" -type f -print0 | ( xargs -0 grep -c "$PAT" || 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 NAME="$1" TEMPDIR="$MY_VENV/tmp-lint" mkdir -p "$TEMPDIR" PRE="$TEMPDIR/pre" POST="$TEMPDIR/post" count_includes "$SRCDIR/$NAME-pre.hxx" >"$PRE" count_includes "$SRCDIR/$NAME-post.hxx" >"$POST" DIFF="$(diff "$PRE" "$POST")" || 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 dialect includes pip install -q clang-tidy 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 # TODO: Please, is there any way we can parallelise this? # TODO: Check test/, but tolerate some of the dubious stuff tests do. # shellcheck disable=SC2086,2046 clang-tidy "$SRCDIR"/src/*.cxx "$SRCDIR"/tools/*.cxx \ -- \ -I"$SRCDIR/include" -Iinclude $dialect $includes # Run Facebook's "infer" static analyser, if available. # A "pip install" didn't work for me: No module named 'nltk'. # 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() { pyflakes "$SRCDIR"/tools/*.py ruff check "$SRCDIR"/tools/*.py } shelllint() { local TLS="deprecations extract_version format lint todo update-copyright" shellcheck "$SRCDIR/autogen.sh" for s in $TLS do shellcheck "$SRCDIR/tools/$s" done } mdlint() { if which mdl >/dev/null then find . -name \*.md -exec mdl -c .markdownlint.yaml '{}' ';' 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 shelllint check_news_version check_compiler_internal_headers mdlint if [ $full == "yes" ] then cpplint fi } main libpqxx-7.10.0/tools/m4esc.py000077500000000000000000000031671473205454700160400ustar00rootroot00000000000000#! /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()) libpqxx-7.10.0/tools/pqxxthreadsafety.cxx000066400000000000000000000003011473205454700205630ustar00rootroot00000000000000// Print thread-safety information for present libpqxx build. #include #include "pqxx/util" int main() { std::cout << pqxx::describe_thread_safety().description << std::endl; } libpqxx-7.10.0/tools/rmlo.cxx000066400000000000000000000013111473205454700161320ustar00rootroot00000000000000// Remove large objects given on the command line from the default database. #include #include "pqxx/pqxx" int main(int, char *argv[]) { pqxx::connection cx; bool failures = false; try { for (int i{1}; argv[i]; ++i) { auto o{pqxx::from_string(argv[i])}; try { pqxx::perform([o, &cx] { pqxx::work tx{cx}; 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; } libpqxx-7.10.0/tools/splitconfig.py000077500000000000000000000175721473205454700173530ustar00rootroot00000000000000#! /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(r'\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() libpqxx-7.10.0/tools/template2mak.py000077500000000000000000000125021473205454700174040ustar00rootroot00000000000000#! /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-2024, 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) libpqxx-7.10.0/tools/test_all.py000077500000000000000000000451631473205454700166360ustar00rootroot00000000000000#! /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 dataclasses import dataclass 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, ) import sys from tempfile import mkdtemp from textwrap import dedent CPUS = cpu_count() GCC_VERSIONS = list(range(8, 14)) GCC = [f'g++-{ver}' for ver in GCC_VERSIONS] CLANG_VERSIONS = list(range(7, 15)) CLANG = [f'clang++-{ver}' for ver in CLANG_VERSIONS] CXX = GCC + CLANG DIALECTS = ['17', '20', '2b'] 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', f'-j{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(f"{command_line}\n\n") 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: sys.stdout.write(errors.read()) print(f"Can't build with '{cxx} {stdlib}'. Skipping.") 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: if gen in names: return gen return None class Config(metaclass=ABCMeta): """Configuration for a build. These classes must be suitable for pickling, so we can send its objects to worker processes. """ @abstractmethod def name(self): """Return an identifier for this build configuration.""" def make_log_name(self): """Compose log file name for this build.""" return f"build-{self.name()}.out" 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(f"Starting {datetime.utcnow()}.\n") 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(f"{error}\n") 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) @dataclass class AutotoolsConfig(Config): """A combination of build options for the "configure" script.""" cxx: str opt: str stdlib: str link: str link_opts: str debug: str debug_opts: str dialect: str def name(self): return '_'.join([ self.cxx, self.dialect, self.opt, self.stdlib, self.link, self.debug, ]) class AutotoolsBuild(Build): """Build using the "configure" script.""" def configure(self, log): configure = [ os.path.join(getcwd(), "configure"), f"CXX={self.config.cxx}", ] dialect_option = f'-std=c++{self.config.dialect}' cxx_flags = ' '.join(filter( None, [dialect_option, self.config.opt, self.config.stdlib])) configure += [f"CXXFLAGS={cxx_flags}"] if self.config.stdlib != "": configure += [f"LDFLAGS={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', f'-j{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', f'-j{CPUS}', 'check', 'TESTS='], log, cwd=self.work_dir) class CMakeConfig(Config): """Configuration for a CMake build.""" def __init__(self, generator, dialect): self.generator = generator self.builder = CMAKE_GENERATORS[generator] self.dialect = dialect def name(self): return "cmake" class CMakeBuild(Build, metaclass=ABCMeta): """Build using CMake. Ignores the config for now. """ def configure(self, log): source_dir = getcwd() generator = self.config.generator dialect_flag = f'-DCMAKE_CXX_VERSION={self.config.dialect}' run( ['cmake', '-G', generator, source_dir, dialect_flag], 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( '--dialects', '-d', default=','.join(DIALECTS), help=( "C++ dialects, separated by commas. " f"Default is {','.join(DIALECTS)}.")) 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() # (Ignore warning about "too broad" an except.) except Exception as error: # pylint: disable=W0703 fail_queue.put((build, f"{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() # (Ignore warning about "too broad" an except.) except Exception as error: # pylint: disable=W0703 fail_queue.put((build, f"{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(f"{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. " f"Tried: {', '.join(compiler_candidates)}.") dialects = args.dialects.split(',') 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, dialect=dialect)) 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 for dialect in dialects ] cmake = find_cmake_command() if cmake is not None: builds.append(CMakeBuild( args.logs, CMakeConfig(cmake, dialect=dialects[0]))) return builds # (Ignore warning about unused parameter.) def enqueue(queue, build, *args): # pylint: disable=W0613 """Put `build` on `queue`. Ignores additional arguments, so that it can be used as a callback 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)) # Disable pylint warning about too many local variables. I see no way to # simplify this that doesn't make it less clear. def main(args): # pylint: disable=R0914 """Do it all.""" if not os.path.isdir(args.logs): raise Fail(f"Logs location '{args.logs}' is not a directory.") builds = gather_builds(args) if args.verbose: print(f"Lined up {len(builds)} 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( f"Failures during configure: {configure_fail_count} - " f"build: {build_fail_count} - " f"test: {test_fail_count}. " f"OK: {ok_count}." ) if __name__ == '__main__': try: main(parse_args()) except Fail as failure: sys.stderr.write(f"{failure}\n") sys.exit(2) libpqxx-7.10.0/tools/todo000077500000000000000000000011121473205454700153270ustar00rootroot00000000000000#! /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 '*.[ch]xx' | sed -e 's|^\./||' | sort echo tools/* } 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() { local key="$1:" shift find_source | xargs grep "$key" } search_for XXX "$FILES" || true search_for TODO "$FILES" || true libpqxx-7.10.0/tools/update-copyright000077500000000000000000000017551473205454700176670ustar00rootroot00000000000000#! /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/source/conf.py