457 changed files with 110654 additions and 0 deletions
@ -0,0 +1,60 @@
|
||||
# CircleCI config for automated test builds triggered from Github. |
||||
version: 2 |
||||
jobs: |
||||
build: |
||||
docker: |
||||
- image: debian:testing |
||||
# - image: postgres:latest |
||||
environment: |
||||
- PGHOST: "/tmp" |
||||
steps: |
||||
- checkout |
||||
- run: |
||||
name: Configure apt archives |
||||
command: apt update |
||||
- run: |
||||
name: Install |
||||
command: apt install -y lsb-release python3 cmake postgresql libpq-dev postgresql-server-dev-all build-essential autoconf dh-autoreconf autoconf-archive automake cppcheck |
||||
- run: |
||||
name: Identify |
||||
command: lsb_release -a && c++ --version |
||||
- run: |
||||
name: Prepare postgres |
||||
command: | |
||||
mkdir /tmp/db && |
||||
chown postgres /tmp/db && |
||||
su postgres -c '/usr/lib/postgresql/*/bin/initdb --pgdata /tmp/db --auth trust --nosync' |
||||
- run: |
||||
name: Run postgres |
||||
command: (su postgres -c '/usr/lib/postgresql/*/bin/postgres -D /tmp/db -k /tmp' &) && sleep 5 |
||||
- run: |
||||
name: Create postgres user |
||||
command: su postgres -c "createuser -w -d root" |
||||
- run: |
||||
name: Set up database |
||||
command: createdb root |
||||
- run: |
||||
name: Autogen |
||||
command: NOCONFIGURE=1 ./autogen.sh |
||||
- run: |
||||
name: Configure |
||||
command: | |
||||
./configure \ |
||||
--disable-documentation \ |
||||
--enable-maintainer-mode \ |
||||
--enable-audit \ |
||||
--enable-shared --disable-static \ |
||||
CXXFLAGS=-O3 |
||||
- store_artifacts: |
||||
path: config.log |
||||
- run: |
||||
name: Make |
||||
command: make -j$(nproc) |
||||
- run: |
||||
name: Test |
||||
command: PGDATA=db/data make check |
||||
- run: |
||||
name: Analyse |
||||
command: ./tools/lint --full >lint.log |
||||
- store_artifacts: |
||||
path: lint.log |
||||
@ -0,0 +1,71 @@
|
||||
Language: Cpp |
||||
|
||||
AlignAfterOpenBracket: AlwaysBreak |
||||
# AllowAllArgumentsOnNextLine: true |
||||
# AllowAllConstructorInitializersOnNextLine: true |
||||
AllowAllParametersOfDeclarationOnNextLine: true |
||||
AllowShortBlocksOnASingleLine: true |
||||
AllowShortCaseLabelsOnASingleLine: true |
||||
AllowShortFunctionsOnASingleLine: Inline |
||||
# AllowShortIfStatementsOnASingleLine: WithoutElse |
||||
# AllowShortLambdasOnASingleLine: All |
||||
AllowShortLoopsOnASingleLine: true |
||||
AlwaysBreakAfterReturnType: None |
||||
AlwaysBreakBeforeMultilineStrings: true |
||||
# AlwaysBreakTemplateDeclarations: No |
||||
BinPackArguments: true |
||||
BinPackParameters: true |
||||
BreakBeforeBraces: Custom |
||||
BraceWrapping: |
||||
# AfterCaseLabel: true |
||||
AfterClass: true |
||||
AfterControlStatement: true |
||||
AfterEnum: true |
||||
AfterExternBlock: true |
||||
AfterFunction: true |
||||
AfterNamespace: true |
||||
AfterStruct: true |
||||
BeforeCatch: true |
||||
BeforeElse: true |
||||
IndentBraces: false |
||||
SplitEmptyFunction: false |
||||
SplitEmptyNamespace: false |
||||
SplitEmptyRecord: false |
||||
BreakBeforeBinaryOperators: None |
||||
BreakBeforeTernaryOperators: false |
||||
BreakConstructorInitializers: AfterColon |
||||
# BreakInheritanceList: AfterColon |
||||
BreakStringLiterals: true |
||||
ColumnLimit: 79 |
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true |
||||
ConstructorInitializerIndentWidth: 8 |
||||
ContinuationIndentWidth: 2 |
||||
Cpp11BracedListStyle: true |
||||
FixNamespaceComments: true |
||||
IncludeBlocks: Preserve |
||||
IndentCaseLabels: false |
||||
IndentPPDirectives: AfterHash |
||||
IndentWidth: 2 |
||||
IndentWrappedFunctionNames: false |
||||
KeepEmptyLinesAtTheStartOfBlocks: false |
||||
MaxEmptyLinesToKeep: 2 |
||||
# NamespaceIndentation: All |
||||
SortIncludes: true |
||||
SortUsingDeclarations: true |
||||
SpaceAfterCStyleCast: false |
||||
SpaceAfterTemplateKeyword: false |
||||
SpaceBeforeAssignmentOperators: true |
||||
# SpaceBeforeCpp11BracedList: false |
||||
# SpaceBeforeCtorInitializerColon: true |
||||
# SpaceBeforeInheritanceColon: true |
||||
# SpaceBeforeParents: ControlStatements |
||||
# SpaceBeforeRangedBasedForLoopColon: true |
||||
SpaceInEmptyParentheses: false |
||||
SpacesInAngles: false |
||||
SpacesInCStyleCastParentheses: false |
||||
SpacesInContainerLiterals: false |
||||
SpacesInParentheses: false |
||||
SpacesInSquareBrackets: false |
||||
Standard: Cpp11 |
||||
UseTab: Never |
||||
--- |
||||
@ -0,0 +1,184 @@
|
||||
format: |
||||
_help_max_prefix_chars: |
||||
- !!python/unicode 'If the statement spelling length (including space and' |
||||
- !!python/unicode 'parenthesis) is larger than the tab width by more than this' |
||||
- !!python/unicode 'amount, then force reject un-nested layouts.' |
||||
max_prefix_chars: 10 |
||||
_help_dangle_align: |
||||
- !!python/unicode 'If the trailing parenthesis must be ''dangled'' on its own' |
||||
- !!python/unicode 'line, then align it to this reference: `prefix`: the start' |
||||
- !!python/unicode 'of the statement, `prefix-indent`: the start of the' |
||||
- !!python/unicode 'statement, plus one indentation level, `child`: align to' |
||||
- !!python/unicode 'the column of the arguments' |
||||
dangle_align: !!python/unicode 'prefix' |
||||
_help_max_subgroups_hwrap: |
||||
- !!python/unicode 'If an argument group contains more than this many sub-groups' |
||||
- !!python/unicode '(parg or kwarg groups) then force it to a vertical layout.' |
||||
max_subgroups_hwrap: 2 |
||||
_help_min_prefix_chars: |
||||
- !!python/unicode 'If the statement spelling length (including space and' |
||||
- !!python/unicode 'parenthesis) is smaller than this amount, then force reject' |
||||
- !!python/unicode 'nested layouts.' |
||||
min_prefix_chars: 4 |
||||
_help_max_pargs_hwrap: |
||||
- !!python/unicode 'If a positional argument group contains more than this many' |
||||
- !!python/unicode 'arguments, then force it to a vertical layout.' |
||||
max_pargs_hwrap: 6 |
||||
_help_max_lines_hwrap: |
||||
- !!python/unicode 'If a candidate layout is wrapped horizontally but it exceeds' |
||||
- !!python/unicode 'this many lines, then reject the layout.' |
||||
max_lines_hwrap: 2 |
||||
_help_autosort: |
||||
- !!python/unicode 'If true, the parsers may infer whether or not an argument' |
||||
- !!python/unicode 'list is sortable (without annotation).' |
||||
autosort: false |
||||
_help_line_ending: |
||||
- !!python/unicode 'What style line endings to use in the output.' |
||||
line_ending: !!python/unicode 'unix' |
||||
_help_line_width: |
||||
- !!python/unicode 'How wide to allow formatted cmake files' |
||||
line_width: 80 |
||||
_help_dangle_parens: |
||||
- !!python/unicode 'If a statement is wrapped to more than one line, then dangle' |
||||
- !!python/unicode 'the closing parenthesis on its own line.' |
||||
dangle_parens: true |
||||
_help_tab_size: |
||||
- !!python/unicode 'How many spaces to tab for indent' |
||||
tab_size: 4 |
||||
_help_always_wrap: |
||||
- !!python/unicode 'A list of command names which should always be wrapped' |
||||
always_wrap: [] |
||||
_help_require_valid_layout: |
||||
- !!python/unicode 'By default, if cmake-format cannot successfully fit' |
||||
- !!python/unicode 'everything into the desired linewidth it will apply the' |
||||
- !!python/unicode 'last, most agressive attempt that it made. If this flag is' |
||||
- !!python/unicode 'True, however, cmake-format will print error, exit with non-' |
||||
- !!python/unicode 'zero status code, and write-out nothing' |
||||
require_valid_layout: true |
||||
_help_keyword_case: |
||||
- !!python/unicode 'Format keywords consistently as ''lower'' or ''upper'' case' |
||||
keyword_case: !!python/unicode 'unchanged' |
||||
_help_layout_passes: |
||||
- !!python/unicode 'A dictionary mapping layout nodes to a list of wrap' |
||||
- !!python/unicode 'decisions. See the documentation for more information.' |
||||
layout_passes: {} |
||||
_help_enable_sort: |
||||
- !!python/unicode 'If true, the argument lists which are known to be sortable' |
||||
- !!python/unicode 'will be sorted lexicographically' |
||||
enable_sort: true |
||||
_help_markup: !!python/unicode 'Options affecting comment reflow and formatting.' |
||||
markup: |
||||
_help_literal_comment_pattern: |
||||
- !!python/unicode 'If comment markup is enabled, don''t reflow any comment block' |
||||
- !!python/unicode 'which matches this (regex) pattern. Default is `None`' |
||||
- !!python/unicode '(disabled).' |
||||
literal_comment_pattern: null |
||||
_help_hashruler_min_length: |
||||
- !!python/unicode 'If a comment line starts with at least this many consecutive' |
||||
- !!python/unicode 'hash characters, then don''t lstrip() them off. This allows' |
||||
- !!python/unicode 'for lazy hash rulers where the first hash char is not' |
||||
- !!python/unicode 'separated by space' |
||||
hashruler_min_length: 10 |
||||
_help_fence_pattern: |
||||
- !!python/unicode 'Regular expression to match preformat fences in comments' |
||||
- !!python/unicode 'default=r''^\s*([`~]{3}[`~]*)(.*)$''' |
||||
fence_pattern: !!python/unicode '^\s*([`~]{3}[`~]*)(.*)$' |
||||
_help_canonicalize_hashrulers: |
||||
- !!python/unicode 'If true, then insert a space between the first hash char and' |
||||
- !!python/unicode 'remaining hash chars in a hash ruler, and normalize its' |
||||
- !!python/unicode 'length to fill the column' |
||||
canonicalize_hashrulers: true |
||||
_help_explicit_trailing_pattern: |
||||
- !!python/unicode 'If a comment line matches starts with this pattern then it' |
||||
- !!python/unicode 'is explicitly a trailing comment for the preceeding' |
||||
- !!python/unicode 'argument. Default is ''#<''' |
||||
explicit_trailing_pattern: !!python/unicode '#<' |
||||
_help_first_comment_is_literal: |
||||
- !!python/unicode 'If comment markup is enabled, don''t reflow the first comment' |
||||
- !!python/unicode 'block in each listfile. Use this to preserve formatting of' |
||||
- !!python/unicode 'your copyright/license statements.' |
||||
first_comment_is_literal: false |
||||
_help_enable_markup: |
||||
- !!python/unicode 'enable comment markup parsing and reflow' |
||||
enable_markup: true |
||||
_help_ruler_pattern: |
||||
- !!python/unicode 'Regular expression to match rulers in comments' |
||||
- !!python/unicode 'default=r''^\s*[^\w\s]{3}.*[^\w\s]{3}$''' |
||||
ruler_pattern: !!python/unicode '^\s*[^\w\s]{3}.*[^\w\s]{3}$' |
||||
_help_enum_char: |
||||
- !!python/unicode 'What character to use as punctuation after numerals in an' |
||||
- !!python/unicode 'enumerated list' |
||||
enum_char: . |
||||
_help_bullet_char: |
||||
- !!python/unicode 'What character to use for bulleted lists' |
||||
bullet_char: '*' |
||||
_help_lint: !!python/unicode 'Options affecting the linter' |
||||
lint: |
||||
_help_function_pattern: |
||||
- !!python/unicode 'regular expression pattern describing valid function names' |
||||
function_pattern: !!python/unicode '[0-9a-z_]+' |
||||
_help_disabled_codes: |
||||
- !!python/unicode 'a list of lint codes to disable' |
||||
disabled_codes: [] |
||||
_help_min_statement_spacing: |
||||
- !!python/unicode 'Require at least this many newlines between statements' |
||||
min_statement_spacing: 1 |
||||
_help_macro_pattern: |
||||
- !!python/unicode 'regular expression pattern describing valid macro names' |
||||
macro_pattern: !!python/unicode '[0-9A-Z_]+' |
||||
_help_public_var_pattern: |
||||
- !!python/unicode 'regular expression pattern describing valid names for' |
||||
- !!python/unicode 'publicdirectory variables' |
||||
public_var_pattern: !!python/unicode '[0-9A-Z][0-9A-Z_]+' |
||||
max_statements: 50 |
||||
_help_max_conditionals_custom_parser: |
||||
- !!python/unicode 'In the heuristic for C0201, how many conditionals to match' |
||||
- !!python/unicode 'within a loop in before considering the loop a parser.' |
||||
max_conditionals_custom_parser: 2 |
||||
_help_global_var_pattern: |
||||
- !!python/unicode 'regular expression pattern describing valid names for' |
||||
- !!python/unicode 'variables with global scope' |
||||
global_var_pattern: !!python/unicode '[0-9A-Z][0-9A-Z_]+' |
||||
_help_keyword_pattern: |
||||
- !!python/unicode 'regular expression pattern describing valid names for' |
||||
- !!python/unicode 'keywords used in functions or macros' |
||||
keyword_pattern: !!python/unicode '[0-9A-Z_]+' |
||||
max_arguments: 5 |
||||
_help_private_var_pattern: |
||||
- !!python/unicode 'regular expression pattern describing valid names for' |
||||
- !!python/unicode 'privatedirectory variables' |
||||
private_var_pattern: !!python/unicode '_[0-9a-z_]+' |
||||
max_localvars: 15 |
||||
max_branches: 12 |
||||
_help_local_var_pattern: |
||||
- !!python/unicode 'regular expression pattern describing valid names for' |
||||
- !!python/unicode 'variables with local scope' |
||||
local_var_pattern: !!python/unicode '[0-9a-z_]+' |
||||
_help_max_statement_spacing: |
||||
- !!python/unicode 'Require no more than this many newlines between statements' |
||||
max_statement_spacing: 1 |
||||
_help_internal_var_pattern: |
||||
- !!python/unicode 'regular expression pattern describing valid names for' |
||||
- !!python/unicode 'variables with global scope (but internal semantic)' |
||||
internal_var_pattern: !!python/unicode '_[0-9A-Z][0-9A-Z_]+' |
||||
max_returns: 6 |
||||
_help_misc: !!python/unicode 'Miscellaneous configurations options.' |
||||
misc: |
||||
_help_per_command: |
||||
- !!python/unicode 'A dictionary containing any per-command configuration' |
||||
- !!python/unicode 'overrides. Currently only `command_case` is supported.' |
||||
per_command: {} |
||||
_help_parse: !!python/unicode 'Options affecting listfile parsing' |
||||
parse: |
||||
_help_additional_commands: |
||||
- !!python/unicode 'Specify structure for custom cmake functions' |
||||
additional_commands: |
||||
!!python/unicode 'foo': |
||||
!!python/unicode 'flags': |
||||
- !!python/unicode 'BAR' |
||||
- !!python/unicode 'BAZ' |
||||
!!python/unicode 'kwargs': |
||||
!!python/unicode 'HEADERS': !!python/unicode '*' |
||||
!!python/unicode 'DEPENDS': !!python/unicode '*' |
||||
!!python/unicode 'SOURCES': !!python/unicode '*' |
||||
_help_encode: !!python/unicode 'Options effecting file encoding' |
||||
@ -0,0 +1,19 @@
|
||||
name: Mark stale issues and pull requests |
||||
|
||||
on: |
||||
schedule: |
||||
- cron: "30 1 * * *" |
||||
|
||||
jobs: |
||||
stale: |
||||
|
||||
runs-on: ubuntu-latest |
||||
|
||||
steps: |
||||
- uses: actions/stale@v1 |
||||
with: |
||||
repo-token: ${{ secrets.GITHUB_TOKEN }} |
||||
stale-issue-message: 'There has been no activity on this ticket. Consider closing it.' |
||||
stale-pr-message: 'There has been no activity on this pull request. Complete it or drop it.' |
||||
stale-issue-label: 'no-issue-activity' |
||||
stale-pr-label: 'no-pr-activity' |
||||
@ -0,0 +1,49 @@
|
||||
autom4te.cache |
||||
build-*.out |
||||
ChangeLog |
||||
CMakeFiles/CMakeTmp |
||||
confdefs.h |
||||
config.log |
||||
config.status |
||||
conftest |
||||
conftest.cpp |
||||
conftest.err |
||||
doc/_build |
||||
doc/Doxyfile |
||||
doc/html/Reference/*.css |
||||
doc/html/Reference/*.html |
||||
doc/html/Reference/*.js |
||||
doc/html/Reference/*.png |
||||
doc/html/Reference/*.map |
||||
doc/html/Reference/*.md5 |
||||
doc/reference-stamp |
||||
include/pqxx/config-*-*.h |
||||
include/pqxx/config.h |
||||
include/pqxx/stamp-h1 |
||||
libpqxx.pc |
||||
libpqxx-*.tar.gz |
||||
libtool |
||||
pqxx-config |
||||
pqxxlo.txt |
||||
test/pqxxlo.txt |
||||
tools/pqxxthreadsafety |
||||
tools/rmlo |
||||
README |
||||
win32/common |
||||
**/Makefile |
||||
**/*.la |
||||
**/*.lo |
||||
**/*.o |
||||
**/*.out |
||||
**/.*.swp |
||||
**/.swp |
||||
**/*.tmp |
||||
**/.deps |
||||
**/.libs |
||||
**/*~ |
||||
**/lint.log |
||||
**/lint.trs |
||||
**/runner |
||||
**/runner.log |
||||
**/runner.trs |
||||
**/test-suite.log |
||||
@ -0,0 +1,9 @@
|
||||
# Config file for lgtm.com static analysis. |
||||
|
||||
path_classifiers: |
||||
test: |
||||
- test |
||||
generated: |
||||
- aclocal.m4 |
||||
- configure |
||||
- ltmain.sh |
||||
@ -0,0 +1,3 @@
|
||||
# Make Sonatype Lift ignore these generated files. |
||||
configure |
||||
config/* |
||||
@ -0,0 +1,4 @@
|
||||
Jeroen T. Vermeulen. Wrote the code. |
||||
Ray Dassen. Did most of the autoconf etc. stuff. |
||||
|
||||
Lots of others helped with various other contributions. |
||||
@ -0,0 +1,272 @@
|
||||
Building using CMake |
||||
==================== |
||||
|
||||
The build requires the full PostgreSQL development package. That package must |
||||
be installed before you can build libpqxx. |
||||
|
||||
The instructions will assume that you're working from a command-line shell. |
||||
If you prefer to work from an IDE, you'll have to know how your IDE likes to |
||||
do things, and you'll want to follow the shell instructions as a guide. |
||||
|
||||
I'm not too familiar with CMake, and this build relies heavily on contributions |
||||
from users. If you see something wrong here, please file a bug and explain, in |
||||
simple words, what needs changing and why. |
||||
|
||||
|
||||
Quick start |
||||
----------- |
||||
|
||||
If you just want to get it built and installed quickly, run `cmake` from the |
||||
root of the libpqxx source tree. This configures your build. |
||||
|
||||
Then compile libpqxx by running: |
||||
|
||||
```shell |
||||
cmake --build . |
||||
``` |
||||
|
||||
To install in the default location: |
||||
|
||||
```shell |
||||
cmake --install . |
||||
``` |
||||
|
||||
|
||||
Stages |
||||
------ |
||||
|
||||
I'll explain the main build steps in more detail below, but here's a quick |
||||
rundown: |
||||
1. Configure |
||||
2. Compile |
||||
3. Test |
||||
4. Install |
||||
5. Use |
||||
|
||||
The Test step is optional. |
||||
|
||||
|
||||
Configure |
||||
--------- |
||||
|
||||
Run `cmake` to configure your build. It figures out various parameters, such |
||||
as where libpq and its headers are, which C++ features your compiler supports, |
||||
and which options your compiler needs. CMake generates configuration for your |
||||
build tool: `Makefile`s for `make`, or a Solution (".sln") file for MSVC's |
||||
`msbuild`, and so on. |
||||
|
||||
At this stage you can also override those options yourself. e.g. to instruct |
||||
the compiler to look for libpq in a non-standard place, or to use a different |
||||
compiler, or pass different compiler flags. Don't try to specify those while |
||||
doing the actual compile; set them once when running `cmake`. |
||||
|
||||
Let's say `$BUILD` is the directory where you want to build libpqxx, and |
||||
`$SRC` is where its source code is. So for example, the readme file will be at |
||||
`$SRC/README.md`. |
||||
|
||||
In the simplest case, you just do: |
||||
|
||||
```shell |
||||
cd $BUILD |
||||
cmake $SRC |
||||
``` |
||||
|
||||
Add CMake options as needed. There's more about the options below. I'll also |
||||
explain the two directories. |
||||
|
||||
|
||||
### Cheat sheet |
||||
|
||||
Here are some popular `cmake` options for libpqxx: |
||||
* `-DSKIP_BUILD_TEST=on` skips compiling libpqxx's tests. |
||||
* `-DBUILD_SHARED_LIBS=on` to build a shared library. |
||||
* `-DBUILD_SHARED_LIBS=off` to build a static library. |
||||
* `-DBUILD_DOC=on` to build documentation. |
||||
* `-DINSTALL_TEST=on` to install test executor binary. |
||||
|
||||
On Windows, I recommend building libpqxx as a shared library and bundling it |
||||
with your application. On other platforms I would prefer a static library. |
||||
|
||||
Building the documentation requires some tools to be installed. It takes at |
||||
least Doxygen, but there's no list of requirements. The way to get this set up |
||||
is to just try it and see what it's missing. |
||||
|
||||
|
||||
### Generators |
||||
|
||||
You can also choose your own build tool by telling CMake to use a particular |
||||
"generator." For example, here's how to force use of `make`: |
||||
|
||||
```shell |
||||
cmake -G 'Unix Makefiles' |
||||
``` |
||||
|
||||
Or if you prefer to build using `ninja` instead: |
||||
|
||||
```shell |
||||
cmake -G Ninja |
||||
``` |
||||
|
||||
There are many more options. You may prefer yet a different build tool. |
||||
|
||||
|
||||
### Finding libpq |
||||
|
||||
The CMake step tries to figure out where libpq is, using Cmake's `find_package` |
||||
function. If that doesn't work, or if you want a libpq in a different location |
||||
from the one it finds, there are two ways to override it. |
||||
|
||||
The first is to set the individual include and link paths. |
||||
|
||||
To make the build look for the libpq headers in some directory `$DIR`, add |
||||
these options: |
||||
* `-DPostgreSQL_TYPE_INCLUDE_DIR=$DIR` |
||||
* `-DPostgreSQL_INCLUDE_DIR=$DIR` |
||||
|
||||
To make the build look for the libpq library binary in a directory `$DIR`, add |
||||
this option: |
||||
* `-DPostgreSQL_LIBRARY_DIR=$DIR` |
||||
|
||||
The second, easier way requires CMake 3.12 or better. Here, you specify a path |
||||
to a full PostgreSQL build tree. You do this (again for some directory `$DIR`) |
||||
by simply passing this cmake option: `-DPostgreSQL_ROOT=$DIR` |
||||
|
||||
|
||||
### Source and Build trees |
||||
|
||||
Where should you run `cmake`? |
||||
|
||||
Two directories matter when building libpqxx: the _source tree_ (where the |
||||
libpqxx source code is) and the _build tree_ (where you want your build |
||||
artefacts). Here I will call them `$SRC` and `$BUILD`, but you can call them |
||||
anything you like. |
||||
|
||||
They can be one and the same, if you like. It's convenient, but less clean, as |
||||
source code and build artefacts will exist in the same directory tree. If |
||||
you're going to delete the source tree after installing, of course it's fine to |
||||
make a mess in there. |
||||
|
||||
|
||||
Compile |
||||
------- |
||||
|
||||
To compile, run: |
||||
|
||||
```shell |
||||
cmake --build $BUILD |
||||
``` |
||||
|
||||
(Where `$BUILD` is again the directory where you wish to do the build.) |
||||
|
||||
This command will invoke your build tool. Other ways to do the same thing |
||||
would be... |
||||
* With Unix Makefiles: `make` |
||||
* With Ninja: `ninja` |
||||
* With Visual Studio: `msbuild libpqxx.sln` |
||||
* etc. |
||||
|
||||
Depending on your build tool, you may want to speed this up by adding an option |
||||
like `-j 16`, where `16` is an example of how many processes you might want to |
||||
run in parallel. The optimal number depends on your available CPUs and memory. |
||||
If you have enough memory, usually the number of CPUs will be a good starting |
||||
point for the right number. Don't use this option with Ninja though. It |
||||
figures things out for itself. |
||||
|
||||
|
||||
Test |
||||
---- |
||||
|
||||
Of course libpqxx comes with a test suite, to check that the library is |
||||
functioning correctly. |
||||
|
||||
You can run it, but there's one caveat: you need to give it a database where it |
||||
can log in, without a password or any other parameters, and try out various |
||||
things. |
||||
|
||||
And when I say you need to "give" it a database, I really mean "give." The |
||||
test suite will create and drop tables. Those will all have names prefixed |
||||
with "pqxx", so it's probably safe to use a database you already had, but if |
||||
any of the items in your database happen to have names starting with `pqxx`, |
||||
tough luck. They're fair game. |
||||
|
||||
Enter this in your shell to build and run the tests: |
||||
|
||||
```shell |
||||
test/runner |
||||
``` |
||||
|
||||
|
||||
### Configuring the test database |
||||
|
||||
But what if you do need a password to log into your test database? Or, what if |
||||
it's running on a different system so you need to pass that machine's address? |
||||
What if it's not running on the default port? |
||||
|
||||
You can set these parameters for the test suite, or for any other libpq-based |
||||
application, using the following environment variables. (They only set default |
||||
values, so they won't override parameters that the application sets in some |
||||
other way.) |
||||
* `PGHOST` — the IP address where we can contact the database's socket. Or |
||||
for a Unix domain socket, its absolute path on the filesystem. |
||||
* `PGPORT` — TCP port number on which we can connect to the database. |
||||
* `PGDATABASE` — the name of the database to which you wish to connect. |
||||
* `PGUSER` — user name under which you wish to log in on the database. |
||||
* `PGPASSWORD` — user name's password for accessing the database. |
||||
|
||||
See the full list at https://www.postgresql.org/docs/current/libpq-envars.html |
||||
|
||||
**Be careful with passwords,** by the way. Depending on your operating system |
||||
and configuration, an attacker with access to your machine could try to read |
||||
your password if you set it on the command line: |
||||
* Your shell may keep a log of the commands you have entered. |
||||
* Environment variables may be visible to other users on the system. |
||||
|
||||
If at all possible, rely on postgres "peer authentication." Once set up, it is |
||||
both more secure and more convenient than passwords. |
||||
|
||||
|
||||
Install |
||||
------- |
||||
|
||||
Once you've built libpqxx, CMake can also help you install the library and |
||||
headers on your system. The default installation location will vary from one |
||||
operating system to another, but you can set it explicitly. |
||||
|
||||
Let's say you've got your finished build in `$BUILD`, and you want to install |
||||
it to your system's default install location. The command for this is: |
||||
|
||||
```shell |
||||
cmake --install $BUILD |
||||
``` |
||||
|
||||
But you may want to install to some other location. Let's call it `$DEST`. |
||||
`$DEST` might be something like `/usr/local` on a Unix-like system, or |
||||
something like `D:\Software` on a Windows system. |
||||
|
||||
To install to `$DEST`, run: |
||||
|
||||
```shell |
||||
cmake --install $BUILD --prefix $DEST |
||||
``` |
||||
|
||||
|
||||
Use |
||||
--- |
||||
|
||||
Other projects can include libpqxx in their CMake builds. |
||||
|
||||
`@abrownsword` uses this configuration: |
||||
|
||||
```cmake |
||||
set(libpqxxdir "libpqxx-${LIBVERSION}") # LIBVERSION set above |
||||
set(SKIP_BUILD_TEST on) |
||||
set(BUILD_SHARED_LIBS OFF) |
||||
|
||||
# Used this instead of FindLibrary. |
||||
# Setting PostgresSQL_INCLUDE_DIRS externally. |
||||
set(PostgreSQL_FOUND true) |
||||
set(PostgresSQL_INCLUDE_DIR ${PostgresSQL_INCLUDE_DIRS}) |
||||
set(PostgresSQL_TYPE_INCLUDE_DIR ${PostgresSQL_INCLUDE_DIRS}) |
||||
|
||||
add_subdirectory(${libpqxxdir}) |
||||
``` |
||||
@ -0,0 +1,275 @@
|
||||
Building using `configure` |
||||
========================== |
||||
|
||||
The build requires `libpq`, the C client library for PostgreSQL. This library |
||||
must be installed before you can build libpqxx. You'll need the headers as |
||||
well as the library binary. |
||||
|
||||
The instructions will assume that you're working from a command-line shell. |
||||
If you prefer to work from an IDE, you'll have to know how your IDE likes to |
||||
do things, and you'll want to follow the shell instructions as a guide. |
||||
|
||||
|
||||
Quick start |
||||
----------- |
||||
|
||||
If you just want to get it built and installed quickly, try: |
||||
|
||||
```shell |
||||
./configure |
||||
make |
||||
sudo make install |
||||
``` |
||||
|
||||
Want more detail? Read on. |
||||
|
||||
|
||||
Stages |
||||
------ |
||||
|
||||
I'll explain the main build steps in more detail below, but here's a quick |
||||
overview: |
||||
1. Configure |
||||
2. Compile |
||||
3. Test |
||||
4. Install |
||||
|
||||
The Test step is optional. |
||||
|
||||
|
||||
Configure |
||||
--------- |
||||
|
||||
The `configure` script configures your build. It figures out various |
||||
parameters, such as where libpq and its headers are, which C++ features your |
||||
compiler supports, and which options your compiler needs. It generates |
||||
Makefiles, which in turn tell the `make` utility how to perform tasks such as |
||||
compiling libpqxx, running tests, cleaning up after itself, and installing |
||||
libpqxx. |
||||
|
||||
The `configure` step is also where you can set these options, e.g. to instruct |
||||
the compiler to look for libpq in a non-standard place, or to use a different |
||||
compiler, or pass different compiler flags. Don't try to specify those while |
||||
doing the actual compile; set them once when running `configure`. |
||||
|
||||
Let's say `$BUILD` is the directory where you want to build libpqxx, and |
||||
`$SRC` is where its source code is. So for example, the readme file will be at |
||||
`$SRC/README.md`. |
||||
|
||||
In the simplest case, you just do: |
||||
|
||||
```shell |
||||
cd $BUILD |
||||
$SRC/configure |
||||
``` |
||||
|
||||
Add `configure` options as needed. There's more about the options below, or in |
||||
the output of `configure --help`. I'll also explain the two directories. |
||||
|
||||
|
||||
### Cheat sheet |
||||
|
||||
Here are some popular `configure` options: |
||||
* `--disable-documentation` skips building of the documentation. |
||||
* `CXXFLAGS=-O0` disables optimisation. Slower code, but faster build. |
||||
* `CXXFLAGS=-O3` asks for _more_ optimisation. Faster code, slower build. |
||||
* `CXX=clang++` compiles with `clang++` as the compiler. |
||||
* `--enable-maintainer-mode` makes the compiler more pedantic about the code. |
||||
* `--enable-audit` enables expensive run-time checks for debugging. |
||||
* `--with-postgres-lib=$DIR` looks for libpq in `$DIR`. |
||||
* `--with-postgres-include=$DIR` looks for the libpq headers in `$DIR`. |
||||
* `--prefix=$PATH` prepares to install libpqxx in `$PATH`. |
||||
* `--enable-shared` enables compilation of libpqxx as a shared library. |
||||
* `--disable-shared` disbles compilation of libpqxx as a shared library. |
||||
* `--enable-static` enables compilation of libpqxx as a static library. |
||||
* `--disable-static` disables compilation of libpqxx as a static library. |
||||
* `--help` shows you a lot more of the options. |
||||
|
||||
So for example, to get a very quick build but produce very inefficient code: |
||||
|
||||
```shell |
||||
./configure --disable-documentation CXXFLAGS=-O0 |
||||
``` |
||||
|
||||
|
||||
Or if you want to pull out all the stops to find problems in the code: |
||||
|
||||
```shell |
||||
./configure --enable-maintainer-mode --enable-audit CXXFLAGS=-O3 |
||||
``` |
||||
|
||||
(Requesting `-O3` optimisation will make some compilers perform extra analysis |
||||
which may, as a side effect, cause them to notice and warn about certain kinds |
||||
of mistakes in the code, such as occasionally-unused variables.) |
||||
|
||||
|
||||
### Finding libpq |
||||
|
||||
One of `configure`'s most important jobs in the libpqxx build is to find the |
||||
headers and library for libpq. It has three ways of finding those: |
||||
1. Asking a popular tool called `pkg-config`, if installed. |
||||
2. Asking postgres' deprecated `pg_config` tool, if installed. |
||||
3. Through explicit command-line options to `configure`. |
||||
|
||||
The explicit command-line options are `--with-postgres-lib` (for the libpq |
||||
library binary) and `--with-postgres-include` (for the libpq headers). |
||||
|
||||
If you want to use a version of libpq that's not installed in a standard |
||||
location, e.g. if you're cross-compiling to produce a binary for a different |
||||
CPU architecture than your native system's, use the explicit options. |
||||
|
||||
|
||||
### Where does the `configure` script come from? |
||||
|
||||
I didn't write the `configure` script. It was generated by GNU `autoconf` and |
||||
related GNU tools. There's a script to re-generate it, called `autogen.sh`. |
||||
|
||||
The contents of `configure` are based on a higher-level script called |
||||
`configure.ac`. This is where I script checks for specific features in libpq |
||||
or the compiler. The `configure` script adds a lot of built-in items that I |
||||
don't need to worry about, such as figuring out exactly how your build tools |
||||
work. |
||||
|
||||
Don't try to debug `configure` yourself if you can help it. It's very hard to |
||||
read, partly because it's automatically generated, but also because it is |
||||
engineered to work with an extremely broad range of shells, compilers, tools, |
||||
and operating systems. If you're going to do a "deep dive," try looking at |
||||
`configure.ac` instead. |
||||
|
||||
|
||||
### Source and Build trees |
||||
|
||||
Where should you run `configure`? |
||||
|
||||
Two directories matter when building libpqxx: the _source tree_ (where the |
||||
libpqxx source code is) and the _build tree_ (where you want your build |
||||
artefacts). Here I will call them `$SRC` and `$BUILD`, but you can call them |
||||
anything you like. |
||||
|
||||
They can be one and the same, if you like. It's convenient, but less clean, as |
||||
source code and build artefacts will exist in the same directory tree. If |
||||
you're going to delete the source tree after installing, of course it's fine to |
||||
make a mess in there. |
||||
|
||||
|
||||
Compile |
||||
------- |
||||
|
||||
To start the compile, run the `make` tool. It will go through all the steps to |
||||
produce a libpqxx library binary. |
||||
|
||||
Beware though, it only runs _one_ compiler process at a time. That could take |
||||
a while. Use the `-j` option to make it run concurrent processes, e.g.: |
||||
|
||||
```shell |
||||
make -j8 |
||||
``` |
||||
|
||||
Very roughly speaking, it's probably fastest if you run one process per CPU |
||||
core in your system. If you have the `nproc` utility installed: |
||||
|
||||
```shell |
||||
make -j$(nproc) |
||||
``` |
||||
|
||||
If you want a very fast build and don't mind missing out on efficient code or |
||||
documentation, tweak the Configure step above by adding `configure` options |
||||
like `CXXFLAGS=-O0` and `--disable-documentation`. |
||||
|
||||
|
||||
Test |
||||
---- |
||||
|
||||
Of course libpqxx comes with a test suite, to check that the library is |
||||
functioning correctly. |
||||
|
||||
You can run it, but there's one caveat: you need to give it a database where it |
||||
can log in, without a password or any other parameters, and try out various |
||||
things. |
||||
|
||||
And when I say you need to "give" it a database, I really mean "give." The |
||||
test suite will create and drop tables. Those will all have names prefixed |
||||
with "pqxx", so it's probably safe to use a database you already had, but if |
||||
any of the items in your database happen to have names starting with `pqxx`, |
||||
tough luck. They're fair game. |
||||
|
||||
Enter this in your shell to build and run the tests: |
||||
|
||||
```shell |
||||
make check |
||||
``` |
||||
|
||||
As with compiling, use the `-j` option to make better use of your CPUs. For |
||||
example: |
||||
|
||||
```shell |
||||
make check -j$(nproc) |
||||
``` |
||||
|
||||
|
||||
### Configuring the test database |
||||
|
||||
But what if you do need a password to log into your test database? Or, what if |
||||
it's running on a different system so you need to pass that machine's address? |
||||
What if it's not running on the default port? |
||||
|
||||
You can set these parameters for the test suite, or for any other libpq-based |
||||
application, using the following environment variables. (They only set default |
||||
values, so they won't override parameters that the application sets in some |
||||
other way.) |
||||
* `PGHOST` — the IP address where we can contact the database's socket. Or |
||||
for a Unix domain socket, its absolute path on the filesystem. |
||||
* `PGPORT` — |
||||
* `PGDATABASE` — the name of the database to which you wish to connect. |
||||
* `PGUSER` — user name under which you wish to log in on the database. |
||||
* `PGPASSWORD` — user name's password for accessing the database. |
||||
|
||||
See the full list at https://www.postgresql.org/docs/current/libpq-envars.html |
||||
|
||||
**Be careful with passwords,** by the way. Depending on your operating system |
||||
and configuration, an attacker with access to your machine could try to read |
||||
your password if you set it on the command line: |
||||
* Your shell may keep a log of the commands you have entered. |
||||
* Environment variables may be visible to other users on the system. |
||||
|
||||
If at all possible, rely on postgres "peer authentication." Once set up, it is |
||||
both more secure and more convenient than passwords. |
||||
|
||||
|
||||
Install |
||||
------- |
||||
|
||||
Installing libpqxx will install the library and headers in a location chosen at |
||||
the time you can the `configure` script. On some systems it defaults to the |
||||
`/usr/local/` tree, but it may be different in your environment. Or, use the |
||||
`configure` script's `--prefix` option to set an install location. |
||||
|
||||
(If you want to see exactly what happens, you can run any `make` command line |
||||
with the `-n` option, which means: don't actually do this, but print all the |
||||
commands you would execute if you did. It's a lot of output though.) |
||||
|
||||
To install, ensure that you have sufficient privileges to write the files to |
||||
their install locations, and run: |
||||
|
||||
```shell |
||||
make install |
||||
``` |
||||
|
||||
Save your build tree somewhere, so that you will be able to undo installation |
||||
in the future: |
||||
|
||||
```shell |
||||
make uninstall |
||||
``` |
||||
|
||||
When using the library, make sure the libpqxx headers are in your compiler's |
||||
include path. (You will no longer need the libpq headers at that time.) |
||||
|
||||
Also, building an application which uses libpqxx, make sure the libpqxx library |
||||
binary is in your compiler's library search path. And if the library binary is |
||||
a shared library, you'll also need it in your loader's search path when running |
||||
your application. |
||||
|
||||
This last part goes for libpq as well: when using libpq, make sure you have |
||||
the libpq library binary in your compiler's library search path, and if it's a |
||||
shared library, also have it in your loader's search path when running. |
||||
@ -0,0 +1,66 @@
|
||||
cmake_minimum_required(VERSION 3.8) |
||||
|
||||
file(READ VERSION VER_FILE_CONTENT) |
||||
string(STRIP ${VER_FILE_CONTENT} VER_FILE_CONTENT) |
||||
|
||||
project( |
||||
libpqxx |
||||
VERSION ${VER_FILE_CONTENT} |
||||
LANGUAGES CXX |
||||
) |
||||
|
||||
if(NOT "${CMAKE_CXX_STANDARD}") |
||||
set(CMAKE_CXX_STANDARD 17) |
||||
endif() |
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON) |
||||
set(CMAKE_CXX_EXTENSIONS OFF) |
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) |
||||
|
||||
option(BUILD_DOC "Build documentation" OFF) |
||||
|
||||
if(NOT SKIP_BUILD_TEST) |
||||
option(BUILD_TEST "Build all test cases" ON) |
||||
endif() |
||||
|
||||
include(GNUInstallDirs) |
||||
include(CMakePackageConfigHelpers) |
||||
include(config) |
||||
|
||||
add_subdirectory(src) |
||||
add_subdirectory(include) |
||||
if(BUILD_DOC) |
||||
add_subdirectory(doc) |
||||
endif() |
||||
if(BUILD_TEST) |
||||
add_subdirectory(test) |
||||
endif() |
||||
|
||||
# installation |
||||
write_basic_package_version_file( |
||||
"${CMAKE_CURRENT_BINARY_DIR}/libpqxx-config-version.cmake" |
||||
VERSION ${PROJECT_VERSION} |
||||
COMPATIBILITY SameMajorVersion |
||||
) |
||||
install(FILES cmake/libpqxx-config.cmake |
||||
"${CMAKE_CURRENT_BINARY_DIR}/libpqxx-config-version.cmake" |
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libpqxx |
||||
) |
||||
install( |
||||
EXPORT libpqxx-targets |
||||
NAMESPACE libpqxx:: |
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libpqxx |
||||
) |
||||
# Build tree export |
||||
export( |
||||
EXPORT libpqxx-targets |
||||
NAMESPACE libpqxx:: |
||||
FILE ${CMAKE_CURRENT_BINARY_DIR}/libpqxx-targets.cmake |
||||
) |
||||
configure_file( |
||||
cmake/libpqxx-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/libpqxx-config.cmake |
||||
COPYONLY |
||||
) |
||||
# Package generation |
||||
set(CPACK_GENERATOR TGZ) |
||||
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) |
||||
include(CPack) |
||||
@ -0,0 +1,27 @@
|
||||
Copyright (c) 2000-2022 Jeroen T. Vermeulen. |
||||
|
||||
All rights reserved. |
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, |
||||
are permitted provided that the following conditions are met: |
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this |
||||
list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright notice, |
||||
this list of conditions and the following disclaimer in the documentation |
||||
and/or other materials provided with the distribution. |
||||
* Neither the name of the author, nor the names of other contributors may be |
||||
used to endorse or promote products derived from this software without |
||||
specific prior written permission. |
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR |
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
@ -0,0 +1,2 @@
|
||||
For installation instructions, see `BUILDING-configure.md` (for the `configure` |
||||
build) and `BUILDING-cmake.md` (for the CMake build). |
||||
@ -0,0 +1,23 @@
|
||||
SUBDIRS = include src test tools config doc
|
||||
EXTRA_DIST = autogen.sh configitems README.md VERSION requirements.json
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in aclocal.m4 config.h.in config.log configure stamp-h.in
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libpqxx.pc
|
||||
|
||||
TESTS = tools/lint
|
||||
|
||||
|
||||
# Generate ChangeLog from git history. It goes all the way back through
|
||||
# the project's git, bzr, svn, and cvs days.
|
||||
dist-hook: ChangeLog |
||||
|
||||
ChangeLog: configure.ac |
||||
git log --stat --name-only --date=short --abbrev-commit >$@
|
||||
|
||||
|
||||
# We use README.md, but automake expects plain README.
|
||||
README: README.md |
||||
ln -s $< $@
|
||||
@ -0,0 +1,199 @@
|
||||
libpqxx |
||||
======= |
||||
|
||||
Welcome to libpqxx, the C++ API to the PostgreSQL database management system. |
||||
|
||||
Home page: http://pqxx.org/development/libpqxx/ |
||||
|
||||
Find libpqxx on Github: https://github.com/jtv/libpqxx |
||||
|
||||
Documentation on Read The Docs: https://libpqxx.readthedocs.io |
||||
|
||||
Compiling this package requires PostgreSQL to be installed -- or at least the C |
||||
headers and library for client development. The library builds on top of |
||||
PostgreSQL's standard C API, libpq, though your code won't notice. |
||||
|
||||
If you're getting the code straight from the Git repo, the head of the `master` |
||||
branch represents the current _development version._ Releases are tags on |
||||
commits in `master`. For example, to get version 7.1.1: |
||||
|
||||
git checkout 7.1.1 |
||||
|
||||
|
||||
Upgrade notes |
||||
------------- |
||||
|
||||
**The 7.x versions require at least C++17.** Make sure your compiler is up to |
||||
date. For libpqxx 8.x you will need at least C++20. |
||||
|
||||
Also, **7.0 makes some breaking changes in rarely used APIs:** |
||||
* There is just a single `connection` class. It connects immediately. |
||||
* Custom `connection` classes are no longer supported. |
||||
* It's no longer possible to reactivate a connection once it's been closed. |
||||
* The API for defining string conversions has changed. |
||||
|
||||
If you're defining your own type conversions, **7.1 requires one additional |
||||
field in your `nullness` traits.** |
||||
|
||||
|
||||
Building libpqxx |
||||
---------------- |
||||
|
||||
There are two different ways of building libpqxx from the command line: |
||||
1. Using CMake, on any system which supports it. |
||||
2. On Unix-like systems, using a `configure` script. |
||||
|
||||
"Unix-like" systems include GNU/Linux, Apple macOS and the BSD family, AIX, |
||||
HP-UX, Irix, Solaris, etc. Even on Microsoft Windows, a Unix-like environment |
||||
such as WSL, Cygwin, or MinGW should work. |
||||
|
||||
You'll find detailed build and install instructions in `BUILDING-configure.md` |
||||
and `BUILDING-cmake.md`, respectively. |
||||
|
||||
And if you're working with Microsoft Visual Studio, have a look at Gordon |
||||
Elliott's |
||||
[ |
||||
Easy-PQXX Build for Windows Visual Studio |
||||
](https://github.com/GordonLElliott/Easy-PQXX-Build-for-Windows-Visual-Studio) |
||||
project. |
||||
|
||||
|
||||
Documentation |
||||
------------- |
||||
|
||||
Building the library, if you have the right tools installed, generates HTML |
||||
documentation in the `doc/` directory. It is based on the headers in |
||||
`include/pqxx/` and text in `include/pqxx/doc/`. This documentation is also |
||||
available online at [readthedocs](https://libpqxx.readthedocs.io). |
||||
|
||||
|
||||
Programming with libpqxx |
||||
------------------------ |
||||
|
||||
Your first program will involve the libpqxx classes `connection` (see the |
||||
`pqxx/connection.hxx` header), and `work` (a convenience alias for |
||||
`transaction<>` which conforms to the interface defined in |
||||
`pqxx/transaction_base.hxx`). |
||||
|
||||
These `*.hxx` headers are not the ones you include in your program. Instead, |
||||
include the versions without filename suffix (e.g. `pqxx/connection`). Those |
||||
will include the actual .hxx files for you. This was done so that includes are |
||||
in standard C++ style (as in `<iostream>` etc.), but an editor will still |
||||
recognize them as files containing C++ code. |
||||
|
||||
Continuing the list of classes, you will most likely also need the result class |
||||
(`pqxx/result.hxx`). In a nutshell, you create a `connection` based on a |
||||
Postgres connection string (see below), create a `work` in the context of that |
||||
connection, and run one or more queries on the work which return `result` |
||||
objects. The results are containers of rows of data, each of which you can |
||||
treat as an array of strings: one for each field in the row. It's that simple. |
||||
|
||||
Here is a simple example program to get you going, with full error handling: |
||||
|
||||
```c++ |
||||
#include <iostream> |
||||
#include <pqxx/pqxx> |
||||
|
||||
int main() |
||||
{ |
||||
try |
||||
{ |
||||
// Connect to the database. |
||||
pqxx::connection C; |
||||
std::cout << "Connected to " << C.dbname() << '\n'; |
||||
|
||||
// Start a transaction. |
||||
pqxx::work W{C}; |
||||
|
||||
// Perform a query and retrieve all results. |
||||
pqxx::result R{W.exec("SELECT name FROM employee")}; |
||||
|
||||
// Iterate over results. |
||||
std::cout << "Found " << R.size() << "employees:\n"; |
||||
for (auto row: R) |
||||
std::cout << row[0].c_str() << '\n'; |
||||
|
||||
// Perform a query and check that it returns no result. |
||||
std::cout << "Doubling all employees' salaries...\n"; |
||||
W.exec0("UPDATE employee SET salary = salary*2"); |
||||
|
||||
// Commit the transaction. |
||||
std::cout << "Making changes definite: "; |
||||
W.commit(); |
||||
std::cout << "OK.\n"; |
||||
} |
||||
catch (std::exception const &e) |
||||
{ |
||||
std::cerr << e.what() << '\n'; |
||||
return 1; |
||||
} |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
|
||||
Connection strings |
||||
------------------ |
||||
|
||||
Postgres connection strings state which database server you wish to connect to, |
||||
under which username, using which password, and so on. Their format is defined |
||||
in the documentation for libpq, the C client interface for PostgreSQL. |
||||
Alternatively, these values may be defined by setting certain environment |
||||
variables as documented in e.g. the manual for psql, the command line interface |
||||
to PostgreSQL. Again the definitions are the same for libpqxx-based programs. |
||||
|
||||
The connection strings and variables are not fully and definitively documented |
||||
here; this document will tell you just enough to get going. Check the |
||||
PostgreSQL documentation for authoritative information. |
||||
|
||||
The connection string consists of attribute=value pairs separated by spaces, |
||||
e.g. "user=john password=1x2y3z4". The valid attributes include: |
||||
* `host` — |
||||
Name of server to connect to, or the full file path (beginning with a |
||||
slash) to a Unix-domain socket on the local machine. Defaults to |
||||
"/tmp". Equivalent to (but overrides) environment variable PGHOST. |
||||
* `hostaddr` — |
||||
IP address of a server to connect to; mutually exclusive with "host". |
||||
* `port` — |
||||
Port number at the server host to connect to, or socket file name |
||||
extension for Unix-domain connections. Equivalent to (but overrides) |
||||
environment variable PGPORT. |
||||
* `dbname` — |
||||
Name of the database to connect to. A single server may host multiple |
||||
databases. Defaults to the same name as the current user's name. |
||||
Equivalent to (but overrides) environment variable PGDATABASE. |
||||
* `user` — |
||||
User name to connect under. This defaults to the name of the current |
||||
user, although PostgreSQL users are not necessarily the same thing as |
||||
system users. |
||||
* `requiressl` — |
||||
If set to 1, demands an encrypted SSL connection (and fails if no SSL |
||||
connection can be created). |
||||
|
||||
Settings in the connection strings override the environment variables, which in |
||||
turn override the default, on a variable-by-variable basis. You only need to |
||||
define those variables that require non-default values. |
||||
|
||||
|
||||
Linking with libpqxx |
||||
-------------------- |
||||
|
||||
To link your final program, make sure you link to both the C-level libpq library |
||||
and the actual C++ library, libpqxx. With most Unix-style compilers, you'd do |
||||
this using the options |
||||
|
||||
-lpqxx -lpq |
||||
|
||||
while linking. Both libraries must be in your link path, so the linker knows |
||||
where to find them. Any dynamic libraries you use must also be in a place |
||||
where the loader can find them when loading your program at runtime. |
||||
|
||||
Some users have reported problems using the above syntax, however, particularly |
||||
when multiple versions of libpqxx are partially or incorrectly installed on the |
||||
system. If you get massive link errors, try removing the "-lpqxx" argument from |
||||
the command line and replacing it with the name of the libpqxx library binary |
||||
instead. That's typically libpqxx.a, but you'll have to add the path to its |
||||
location as well, e.g. /usr/local/pqxx/lib/libpqxx.a. This will ensure that the |
||||
linker will use that exact version of the library rather than one found |
||||
elsewhere on the system, and eliminate worries about the exact right version of |
||||
the library being installed with your program.. |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,30 @@
|
||||
# Configuration for test runs in Appveyor. |
||||
version: 1.0.{build} |
||||
image: Visual Studio 2022 |
||||
services: postgresql13 |
||||
# Run CMake to build libpqxx.sln. |
||||
before_build: |
||||
- cmd: >- |
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" |
||||
|
||||
cmake -DBUILD_SHARED_LIBS=1 -DCMAKE_CXX_STANDARD=23 |
||||
configuration: Release |
||||
build: |
||||
parallel: true |
||||
project: libpqxx.sln |
||||
test_script: |
||||
- ps: >- |
||||
$env:Path += ";.\src\Release;C:\Program Files\PostgreSQL\13\bin" |
||||
|
||||
$env:PGUSER = "postgres" |
||||
|
||||
$env:PGPASSWORD = "Password12!" |
||||
|
||||
.\test\Release\runner.exe |
||||
notifications: |
||||
- provider: Email |
||||
subject: 'libpqxx: AppVeyor build failure' |
||||
message: The libpqxx AppVeyor build has failed. |
||||
on_build_success: false |
||||
on_build_failure: true |
||||
on_build_status_changed: false |
||||
@ -0,0 +1,44 @@
|
||||
#! /bin/sh |
||||
# Run this to generate the configure script etc. |
||||
|
||||
set -eu |
||||
|
||||
PQXXVERSION=$(./tools/extract_version) |
||||
PQXX_ABI=$(./tools/extract_version --abi) |
||||
PQXX_MAJOR=$(./tools/extract_version --major) |
||||
PQXX_MINOR=$(./tools/extract_version --minor) |
||||
echo "libpqxx version $PQXXVERSION" |
||||
echo "libpqxx ABI version $PQXX_ABI" |
||||
|
||||
substitute() { |
||||
sed -e "s/@PQXXVERSION@/$PQXXVERSION/g" \ |
||||
-e "s/@PQXX_MAJOR@/$PQXX_MAJOR/g" \ |
||||
-e "s/@PQXX_MINOR@/$PQXX_MINOR/g" \ |
||||
-e "s/@PQXX_ABI@/$PQXX_ABI/g" \ |
||||
"$1" |
||||
} |
||||
|
||||
|
||||
# Use templating system to generate various Makefiles. |
||||
expand_templates() { |
||||
for template in "$@" |
||||
do |
||||
./tools/template2mak.py "$template" "${template%.template}" |
||||
done |
||||
} |
||||
|
||||
|
||||
# We have two kinds of templates. One uses our custom templating tool. And |
||||
# a few others simply have some substitutions done. |
||||
expand_templates $(find -name \*.template) |
||||
substitute include/pqxx/version.hxx.template >include/pqxx/version.hxx |
||||
substitute include/pqxx/doc/mainpage.md.template >include/pqxx/doc/mainpage.md |
||||
|
||||
|
||||
autoheader |
||||
libtoolize --force --automake --copy |
||||
aclocal -I . -I config/m4 |
||||
automake --add-missing --copy |
||||
autoconf |
||||
|
||||
echo "Done." |
||||
@ -0,0 +1,157 @@
|
||||
function(detect_code_compiled code macro msg) |
||||
message(STATUS "Detecting ${msg}") |
||||
check_cxx_source_compiles("${code}" "${macro}" FAIL_REGEX "warning") |
||||
if(${macro}) |
||||
message(STATUS "Detecting ${msg} - supported") |
||||
else() |
||||
message(STATUS "Detecting ${msg} - not supported") |
||||
endif() |
||||
endfunction(detect_code_compiled) |
||||
|
||||
include(CheckIncludeFileCXX) |
||||
include(CheckFunctionExists) |
||||
include(CheckSymbolExists) |
||||
include(CMakeDetermineCompileFeatures) |
||||
include(CheckCXXSourceCompiles) |
||||
include(CMakeFindDependencyMacro) |
||||
|
||||
if(NOT PostgreSQL_FOUND) |
||||
if(POLICY CMP0074) |
||||
cmake_policy(PUSH) |
||||
# CMP0074 is `OLD` by `cmake_minimum_required(VERSION 3.7)`, |
||||
# sets `NEW` to enable support CMake variable `PostgreSQL_ROOT`. |
||||
cmake_policy(SET CMP0074 NEW) |
||||
endif() |
||||
|
||||
find_package(PostgreSQL REQUIRED) |
||||
|
||||
if(POLICY CMP0074) |
||||
cmake_policy(POP) |
||||
endif() |
||||
endif() |
||||
|
||||
check_function_exists("poll" PQXX_HAVE_POLL) |
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES pq) |
||||
check_symbol_exists( |
||||
PQencryptPasswordConn |
||||
"${PostgreSQL_INCLUDE_DIR}/libpq-fe.h" |
||||
PQXX_HAVE_PQENCRYPTPASSWORDCONN) |
||||
check_symbol_exists( |
||||
PQenterPipelineMode |
||||
"${PostgreSQL_INCLUDE_DIR}/libpq-fe.h" |
||||
PQXX_HAVE_PQ_PIPELINE) |
||||
|
||||
cmake_determine_compile_features(CXX) |
||||
cmake_policy(SET CMP0057 NEW) |
||||
|
||||
# check_cxx_source_compiles requires CMAKE_REQUIRED_DEFINITIONS to specify |
||||
# compiling arguments. |
||||
# Wordaround: Push CMAKE_REQUIRED_DEFINITIONS |
||||
if(CMAKE_REQUIRED_DEFINITIONS) |
||||
set(def "${CMAKE_REQUIRED_DEFINITIONS}") |
||||
endif() |
||||
set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION}) |
||||
set(CMAKE_REQUIRED_QUIET ON) |
||||
|
||||
try_compile( |
||||
PQXX_HAVE_GCC_PURE |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/gcc_pure.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_GCC_VISIBILITY |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/gcc_visibility.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_LIKELY |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/likely.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_CXA_DEMANGLE |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/cxa_demangle.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_CONCEPTS |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/concepts.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_SPAN |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/span.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/multidim-subscript.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_CHARCONV_FLOAT |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/charconv_float.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_CHARCONV_INT |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/charconv_int.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_PATH |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/fs.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_THREAD_LOCAL |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/thread_local.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_SLEEP_FOR |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/sleep_for.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_STRERROR_R |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/strerror_r.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_STRERROR_S |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/strerror_s.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_YEAR_MONTH_DAY |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/year_month_day.cxx) |
||||
try_compile( |
||||
PQXX_HAVE_CMP |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/cmp.cxx) |
||||
|
||||
try_compile( |
||||
need_fslib |
||||
${PROJECT_BINARY_DIR} |
||||
SOURCES ${PROJECT_SOURCE_DIR}/config-tests/need_fslib.cxx) |
||||
if(!need_fslib) |
||||
# TODO: This may work for gcc 8, but some clang versions may need -lc++fs. |
||||
link_libraries(stdc++fs) |
||||
endif() |
||||
|
||||
# check_cxx_source_compiles requires CMAKE_REQUIRED_DEFINITIONS to specify |
||||
# compiling arguments. |
||||
# Workaround: Pop CMAKE_REQUIRED_DEFINITIONS |
||||
if(def) |
||||
set(CMAKE_REQUIRED_DEFINITIONS ${def}) |
||||
unset(def CACHE) |
||||
else() |
||||
unset(CMAKE_REQUIRED_DEFINITIONS CACHE) |
||||
endif() |
||||
set(CMAKE_REQUIRED_QUIET OFF) |
||||
|
||||
set(AC_CONFIG_H_IN "${PROJECT_SOURCE_DIR}/include/pqxx/config.h.in") |
||||
set(CM_CONFIG_H_IN "${PROJECT_BINARY_DIR}/include/pqxx/config_cmake.h.in") |
||||
set(CM_CONFIG_PUB "${PROJECT_BINARY_DIR}/include/pqxx/config-public-compiler.h") |
||||
set(CM_CONFIG_INT "${PROJECT_BINARY_DIR}/include/pqxx/config-internal-compiler.h") |
||||
set(CM_CONFIG_PQ "${PROJECT_BINARY_DIR}/include/pqxx/config-internal-libpq.h") |
||||
message(STATUS "Generating config.h") |
||||
file(WRITE "${CM_CONFIG_H_IN}" "") |
||||
file(STRINGS "${AC_CONFIG_H_IN}" lines) |
||||
foreach(line ${lines}) |
||||
string(REGEX REPLACE "^#undef" "#cmakedefine" l "${line}") |
||||
file(APPEND "${CM_CONFIG_H_IN}" "${l}\n") |
||||
endforeach() |
||||
configure_file("${CM_CONFIG_H_IN}" "${CM_CONFIG_INT}" @ONLY) |
||||
configure_file("${CM_CONFIG_H_IN}" "${CM_CONFIG_PUB}" @ONLY) |
||||
configure_file("${CM_CONFIG_H_IN}" "${CM_CONFIG_PQ}" @ONLY) |
||||
message(STATUS "Generating config.h - done") |
||||
@ -0,0 +1,4 @@
|
||||
include(CMakeFindDependencyMacro) |
||||
find_dependency(PostgreSQL) |
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/libpqxx-targets.cmake") |
||||
@ -0,0 +1,22 @@
|
||||
Configuration tests |
||||
=================== |
||||
|
||||
Libpqxx comes with support for different build systems: the GNU autotools, |
||||
CMake, Visual Studio's "nmake", and raw GNU "make" on Windows. |
||||
|
||||
For several of these build systems, we need to test things like "does this |
||||
compiler environment support `std::to_chars` for floating-point types?" |
||||
|
||||
We test these things by trying to compile a particular snippet of code, and |
||||
seeing whether that succeeds. |
||||
|
||||
To avoid duplicating those snippets for multiple build systems, we put them |
||||
here. Both the autotools configuration and the CMake configuration can refer to |
||||
them that way. |
||||
|
||||
It took a bit of nasty magic to read a C++ source file into m4 and treat it as |
||||
a string literal, without macro expansion. There is every chance that I missed |
||||
something, so be prepared for tests failing for unexpected reasons! Some C++ |
||||
syntax may end up having an unforeseen meaning in m4, and screw up the handling |
||||
of the code snippet. Re-configure, and read your logs carefully after editing |
||||
these snippets. |
||||
@ -0,0 +1,16 @@
|
||||
// Test for std::to_string/std::from_string for floating-point types.
|
||||
#include <charconv> |
||||
#include <iterator> |
||||
|
||||
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; |
||||
} |
||||
@ -0,0 +1,16 @@
|
||||
// Test for std::to_string/std::from_string for integral types.
|
||||
#include <charconv> |
||||
#include <iterator> |
||||
|
||||
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; |
||||
} |
||||
@ -0,0 +1,8 @@
|
||||
// Test for C++20 std::cmp_greater etc. support.
|
||||
#include <utility> |
||||
|
||||
|
||||
int main() |
||||
{ |
||||
return std::cmp_greater(-1, 2u) && std::cmp_less_equal(3, 0); |
||||
} |
||||
@ -0,0 +1,21 @@
|
||||
// Test for concepts support. Not just the language feature; also headers.
|
||||
#include <iostream> |
||||
#include <ranges> |
||||
#include <vector> |
||||
|
||||
|
||||
template<typename T> |
||||
concept Foo = std::ranges::input_range<T>; |
||||
|
||||
|
||||
template<Foo F> auto foo(F const &r) |
||||
{ |
||||
return std::distance(std::begin(r), std::end(r)); |
||||
} |
||||
|
||||
|
||||
int main() |
||||
{ |
||||
std::vector<int> const v{1, 2, 3}; |
||||
std::cout << foo(v) << '\n'; |
||||
} |
||||
@ -0,0 +1,19 @@
|
||||
// Test for cross-vendor C++ ABI's __cxa_demangle function.
|
||||
#include <cstdlib> |
||||
#include <cstring> |
||||
#include <stdexcept> |
||||
#include <typeinfo> |
||||
|
||||
#include <cxxabi.h> |
||||
|
||||
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; |
||||
} |
||||
@ -0,0 +1,9 @@
|
||||
// Check for working std::filesystem support.
|
||||
#include <filesystem> |
||||
|
||||
|
||||
int main() |
||||
{ |
||||
// Apparently some versions of MinGW lack this comparison operator.
|
||||
return std::filesystem::path{} != std::filesystem::path{}; |
||||
} |
||||
@ -0,0 +1,10 @@
|
||||
// Test for gcc-style "pure" attribute.
|
||||
int __attribute__((pure)) f() |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
int main() |
||||
{ |
||||
return f(); |
||||
} |
||||
@ -0,0 +1,12 @@
|
||||
// Test for gcc-style "visibility" attribute.
|
||||
struct __attribute__((visibility("hidden"))) D |
||||
{ |
||||
D() {} |
||||
int f() { return 0; } |
||||
}; |
||||
|
||||
int main() |
||||
{ |
||||
D d; |
||||
return d.f(); |
||||
} |
||||
@ -0,0 +1,15 @@
|
||||
// Test for C++20 [[likely]] and [[unlikely]] attributes.
|
||||
|
||||
int main(int argc, char **) |
||||
{ |
||||
#if __cplusplus < 202002L |
||||
deliberately_fail(because, older, C++, standard); |
||||
#endif |
||||
|
||||
int x = 0; |
||||
if (argc == 1) [[likely]] |
||||
x = 0; |
||||
else |
||||
x = 1; |
||||
return x; |
||||
} |
||||
@ -0,0 +1,14 @@
|
||||
// Test for multidimensional subscript operator support.
|
||||
// Proposed for C++23: P2128R6.
|
||||
struct table |
||||
{ |
||||
int width = 100; |
||||
|
||||
int operator[](int x, int y) const { return x + width * y; } |
||||
}; |
||||
|
||||
|
||||
int main() |
||||
{ |
||||
return table{}[0, 0]; |
||||
} |
||||
@ -0,0 +1,21 @@
|
||||
// Check whether we need to link to the stdc++fs library.
|
||||
//
|
||||
// We assume that the presence of the <filesystem> header means that we have
|
||||
// support for the basics of std::filesystem. This check will succeed if
|
||||
// either there is no <filesystem> 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 <iostream> |
||||
|
||||
#if __has_include(<filesystem>) |
||||
# include <filesystem> |
||||
#endif |
||||
|
||||
|
||||
int main() |
||||
{ |
||||
#if __has_include(<filesystem>) |
||||
std::cout << std::filesystem::path{"foo.bar"}.c_str() << '\n'; |
||||
#endif |
||||
} |
||||
@ -0,0 +1,7 @@
|
||||
// Test for poll().
|
||||
#include <poll.h> |
||||
|
||||
int main() |
||||
{ |
||||
return poll(nullptr, 0, 0); |
||||
} |
||||
@ -0,0 +1,28 @@
|
||||
// Test for std::this_thread::sleep_for().
|
||||
/* For some reason MinGW's <thread> header seems to be broken.
|
||||
* |
||||
* But it gets worse. It looks as if we can include <thread> without problems |
||||
* in this configuration test. Why does it break when MinGW users try to build |
||||
* the library, but succeed when we try it here? |
||||
* |
||||
* To try and get close to the situation in the library code itself, we try |
||||
* including some standard headers that we don't strictly need here. |
||||
*/ |
||||
|
||||
#if __has_include(<ciso646>) |
||||
# include <ciso646> |
||||
#endif |
||||
|
||||
#include <cerrno> |
||||
#include <cmath> |
||||
#include <cstdlib> |
||||
#include <cstring> |
||||
#include <new> |
||||
|
||||
#include <chrono> |
||||
#include <thread> |
||||
|
||||
int main() |
||||
{ |
||||
std::this_thread::sleep_for(std::chrono::microseconds{10u}); |
||||
} |
||||
@ -0,0 +1,8 @@
|
||||
// Test for std::span.
|
||||
#include <span> |
||||
|
||||
int main(int argc, char **argv) |
||||
{ |
||||
std::span<char *> args{argv, static_cast<std::size_t>(argc)}; |
||||
return static_cast<int>(std::size(args) - 1u); |
||||
} |
||||
@ -0,0 +1,14 @@
|
||||
// Check for strerror_r.
|
||||
// It can be either the POSIX version (which returns int) or the GNU version
|
||||
// (which returns char *).
|
||||
|
||||
#include <cstring> |
||||
#include <type_traits> |
||||
|
||||
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; |
||||
} |
||||
@ -0,0 +1,11 @@
|
||||
// Test for strerror_s, as defined in Windows and C11.
|
||||
// Presumably this'll be part of the C++ standard some day.
|
||||
|
||||
#include <cstring> |
||||
|
||||
int main() |
||||
{ |
||||
using namespace std; |
||||
char buf[200]; |
||||
return strerror_s(buf, 200, 1); |
||||
} |
||||
@ -0,0 +1,15 @@
|
||||
// Test for std::to_string/std::from_string for floating-point types.
|
||||
#include <iostream> |
||||
#include <sstream> |
||||
|
||||
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(); |
||||
} |
||||
@ -0,0 +1,7 @@
|
||||
// Test for std::chrono::year_month_day etc.
|
||||
#include <chrono> |
||||
|
||||
int main() |
||||
{ |
||||
return int(std::chrono::year{1}); |
||||
} |
||||
@ -0,0 +1,8 @@
|
||||
EXTRA_DIST=m4/Makefile.am sample-headers
|
||||
MAINTAINERCLEANFILES=Makefile.in config.guess config.sub install-sh \
|
||||
ltmain.sh missing mkinstalldirs
|
||||
|
||||
dist-hook: |
||||
find "${distdir}" -type d -name CVS -print0 | xargs -0 rm -rf
|
||||
find "${distdir}" -type d -name .svn -print0 | xargs -0 rm -rf
|
||||
|
||||
@ -0,0 +1,470 @@
|
||||
# Makefile.in generated by automake 1.16.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@ |
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
} |
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
subdir = config
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \
|
||||
$(top_srcdir)/config/m4/ltoptions.m4 \
|
||||
$(top_srcdir)/config/m4/ltsugar.m4 \
|
||||
$(top_srcdir)/config/m4/ltversion.m4 \
|
||||
$(top_srcdir)/config/m4/lt~obsolete.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/include/pqxx/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in compile config.guess \
|
||||
config.sub install-sh ltmain.sh missing mkinstalldirs
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CSCOPE = @CSCOPE@
|
||||
CTAGS = @CTAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DOXYGEN = @DOXYGEN@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
HAVE_DOT = @HAVE_DOT@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR = @MKDIR@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PG_CONFIG = @PG_CONFIG@
|
||||
PKG_CONFIG = @PKG_CONFIG@
|
||||
POSTGRES_INCLUDE = @POSTGRES_INCLUDE@
|
||||
PQXXVERSION = @PQXXVERSION@
|
||||
PQXX_ABI = @PQXX_ABI@
|
||||
RANLIB = @RANLIB@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
runstatedir = @runstatedir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
with_postgres_lib = @with_postgres_lib@
|
||||
EXTRA_DIST = m4/Makefile.am sample-headers
|
||||
MAINTAINERCLEANFILES = Makefile.in config.guess config.sub install-sh \
|
||||
ltmain.sh missing mkinstalldirs
|
||||
|
||||
all: all-am |
||||
|
||||
.SUFFIXES: |
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) |
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu config/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu config/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status |
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) |
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) |
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) |
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps): |
||||
|
||||
mostlyclean-libtool: |
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool: |
||||
-rm -rf .libs _libs
|
||||
tags TAGS: |
||||
|
||||
ctags CTAGS: |
||||
|
||||
cscope cscopelist: |
||||
|
||||
distdir: $(BUILT_SOURCES) |
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
distdir-am: $(DISTFILES) |
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$(top_distdir)" distdir="$(distdir)" \
|
||||
dist-hook
|
||||
check-am: all-am |
||||
check: check-am |
||||
all-am: Makefile |
||||
installdirs: |
||||
install: install-am |
||||
install-exec: install-exec-am |
||||
install-data: install-data-am |
||||
uninstall: uninstall-am |
||||
|
||||
install-am: all-am |
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am |
||||
install-strip: |
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic: |
||||
|
||||
clean-generic: |
||||
|
||||
distclean-generic: |
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic: |
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
clean: clean-am |
||||
|
||||
clean-am: clean-generic clean-libtool mostlyclean-am |
||||
|
||||
distclean: distclean-am |
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic |
||||
|
||||
dvi: dvi-am |
||||
|
||||
dvi-am: |
||||
|
||||
html: html-am |
||||
|
||||
html-am: |
||||
|
||||
info: info-am |
||||
|
||||
info-am: |
||||
|
||||
install-data-am: |
||||
|
||||
install-dvi: install-dvi-am |
||||
|
||||
install-dvi-am: |
||||
|
||||
install-exec-am: |
||||
|
||||
install-html: install-html-am |
||||
|
||||
install-html-am: |
||||
|
||||
install-info: install-info-am |
||||
|
||||
install-info-am: |
||||
|
||||
install-man: |
||||
|
||||
install-pdf: install-pdf-am |
||||
|
||||
install-pdf-am: |
||||
|
||||
install-ps: install-ps-am |
||||
|
||||
install-ps-am: |
||||
|
||||
installcheck-am: |
||||
|
||||
maintainer-clean: maintainer-clean-am |
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic |
||||
|
||||
mostlyclean: mostlyclean-am |
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool |
||||
|
||||
pdf: pdf-am |
||||
|
||||
pdf-am: |
||||
|
||||
ps: ps-am |
||||
|
||||
ps-am: |
||||
|
||||
uninstall-am: |
||||
|
||||
.MAKE: install-am install-strip |
||||
|
||||
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
|
||||
cscopelist-am ctags-am dist-hook distclean distclean-generic \
|
||||
distclean-libtool distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags-am uninstall uninstall-am
|
||||
|
||||
.PRECIOUS: Makefile |
||||
|
||||
|
||||
dist-hook: |
||||
find "${distdir}" -type d -name CVS -print0 | xargs -0 rm -rf
|
||||
find "${distdir}" -type d -name .svn -print0 | xargs -0 rm -rf
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT: |
||||
@ -0,0 +1,348 @@
|
||||
#! /bin/sh |
||||
# Wrapper for compilers which do not understand '-c -o'. |
||||
|
||||
scriptversion=2018-03-07.03; # UTC |
||||
|
||||
# Copyright (C) 1999-2021 Free Software Foundation, Inc. |
||||
# Written by Tom Tromey <tromey@cygnus.com>. |
||||
# |
||||
# This program is free software; you can redistribute it and/or modify |
||||
# it under the terms of the GNU General Public License as published by |
||||
# the Free Software Foundation; either version 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 <https://www.gnu.org/licenses/>. |
||||
|
||||
# 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 <bug-automake@gnu.org> or send patches to |
||||
# <automake-patches@gnu.org>. |
||||
|
||||
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 <bug-automake@gnu.org>. |
||||
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: |
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,791 @@
|
||||
#! /bin/sh |
||||
# depcomp - compile a program generating dependencies as side-effects |
||||
|
||||
scriptversion=2018-03-07.03; # UTC |
||||
|
||||
# Copyright (C) 1999-2021 Free Software Foundation, Inc. |
||||
|
||||
# This program is free software; you can redistribute it and/or modify |
||||
# it under the terms of the GNU General Public License as published by |
||||
# the Free Software Foundation; either version 2, or (at your option) |
||||
# any later version. |
||||
|
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
|
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
||||
# 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 <oliva@dcc.unicamp.br>. |
||||
|
||||
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 <bug-automake@gnu.org>. |
||||
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: |
||||
@ -0,0 +1,520 @@
|
||||
#!/bin/sh |
||||
# install - install a program, script, or datafile |
||||
|
||||
scriptversion=2009-04-28.21; # UTC |
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was |
||||
# later released in X11R6 (xc/config/util/install.sh) with the |
||||
# following copyright and license. |
||||
# |
||||
# Copyright (C) 1994 X Consortium |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to |
||||
# deal in the Software without restriction, including without limitation the |
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
||||
# sell copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in |
||||
# all copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- |
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
# |
||||
# Except as contained in this notice, the name of the X Consortium shall not |
||||
# be used in advertising or otherwise to promote the sale, use or other deal- |
||||
# ings in this Software without prior written authorization from the X Consor- |
||||
# tium. |
||||
# |
||||
# |
||||
# FSF changes to this file are in the public domain. |
||||
# |
||||
# Calling this script install-sh is preferred over install.sh, to prevent |
||||
# `make' implicit rules from creating a file called install from it |
||||
# when there is no Makefile. |
||||
# |
||||
# This script is compatible with the BSD install script, but was written |
||||
# from scratch. |
||||
|
||||
nl=' |
||||
' |
||||
IFS=" "" $nl" |
||||
|
||||
# set DOITPROG to echo to test this script |
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it. |
||||
doit=${DOITPROG-} |
||||
if test -z "$doit"; then |
||||
doit_exec=exec |
||||
else |
||||
doit_exec=$doit |
||||
fi |
||||
|
||||
# Put in absolute file names if you don't have them in your path; |
||||
# or use environment vars. |
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp} |
||||
chmodprog=${CHMODPROG-chmod} |
||||
chownprog=${CHOWNPROG-chown} |
||||
cmpprog=${CMPPROG-cmp} |
||||
cpprog=${CPPROG-cp} |
||||
mkdirprog=${MKDIRPROG-mkdir} |
||||
mvprog=${MVPROG-mv} |
||||
rmprog=${RMPROG-rm} |
||||
stripprog=${STRIPPROG-strip} |
||||
|
||||
posix_glob='?' |
||||
initialize_posix_glob=' |
||||
test "$posix_glob" != "?" || { |
||||
if (set -f) 2>/dev/null; then |
||||
posix_glob= |
||||
else |
||||
posix_glob=: |
||||
fi |
||||
} |
||||
' |
||||
|
||||
posix_mkdir= |
||||
|
||||
# Desired mode of installed file. |
||||
mode=0755 |
||||
|
||||
chgrpcmd= |
||||
chmodcmd=$chmodprog |
||||
chowncmd= |
||||
mvcmd=$mvprog |
||||
rmcmd="$rmprog -f" |
||||
stripcmd= |
||||
|
||||
src= |
||||
dst= |
||||
dir_arg= |
||||
dst_arg= |
||||
|
||||
copy_on_change=false |
||||
no_target_directory= |
||||
|
||||
usage="\ |
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE |
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY |
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES... |
||||
or: $0 [OPTION]... -d DIRECTORIES... |
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE. |
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. |
||||
In the 4th, create DIRECTORIES. |
||||
|
||||
Options: |
||||
--help display this help and exit. |
||||
--version display version info and exit. |
||||
|
||||
-c (ignored) |
||||
-C install only if different (preserve the last data modification time) |
||||
-d create directories instead of installing files. |
||||
-g GROUP $chgrpprog installed files to GROUP. |
||||
-m MODE $chmodprog installed files to MODE. |
||||
-o USER $chownprog installed files to USER. |
||||
-s $stripprog installed files. |
||||
-t DIRECTORY install into DIRECTORY. |
||||
-T report an error if DSTFILE is a directory. |
||||
|
||||
Environment variables override the default commands: |
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG |
||||
RMPROG STRIPPROG |
||||
" |
||||
|
||||
while test $# -ne 0; do |
||||
case $1 in |
||||
-c) ;; |
||||
|
||||
-C) copy_on_change=true;; |
||||
|
||||
-d) dir_arg=true;; |
||||
|
||||
-g) chgrpcmd="$chgrpprog $2" |
||||
shift;; |
||||
|
||||
--help) echo "$usage"; exit $?;; |
||||
|
||||
-m) mode=$2 |
||||
case $mode in |
||||
*' '* | *' '* | *' |
||||
'* | *'*'* | *'?'* | *'['*) |
||||
echo "$0: invalid mode: $mode" >&2 |
||||
exit 1;; |
||||
esac |
||||
shift;; |
||||
|
||||
-o) chowncmd="$chownprog $2" |
||||
shift;; |
||||
|
||||
-s) stripcmd=$stripprog;; |
||||
|
||||
-t) dst_arg=$2 |
||||
shift;; |
||||
|
||||
-T) no_target_directory=true;; |
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;; |
||||
|
||||
--) shift |
||||
break;; |
||||
|
||||
-*) echo "$0: invalid option: $1" >&2 |
||||
exit 1;; |
||||
|
||||
*) break;; |
||||
esac |
||||
shift |
||||
done |
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then |
||||
# When -d is used, all remaining arguments are directories to create. |
||||
# When -t is used, the destination is already specified. |
||||
# Otherwise, the last argument is the destination. Remove it from $@. |
||||
for arg |
||||
do |
||||
if test -n "$dst_arg"; then |
||||
# $@ is not empty: it contains at least $arg. |
||||
set fnord "$@" "$dst_arg" |
||||
shift # fnord |
||||
fi |
||||
shift # arg |
||||
dst_arg=$arg |
||||
done |
||||
fi |
||||
|
||||
if test $# -eq 0; then |
||||
if test -z "$dir_arg"; then |
||||
echo "$0: no input file specified." >&2 |
||||
exit 1 |
||||
fi |
||||
# It's OK to call `install-sh -d' without argument. |
||||
# This can happen when creating conditional directories. |
||||
exit 0 |
||||
fi |
||||
|
||||
if test -z "$dir_arg"; then |
||||
trap '(exit $?); exit' 1 2 13 15 |
||||
|
||||
# Set umask so as not to create temps with too-generous modes. |
||||
# However, 'strip' requires both read and write access to temps. |
||||
case $mode in |
||||
# Optimize common cases. |
||||
*644) cp_umask=133;; |
||||
*755) cp_umask=22;; |
||||
|
||||
*[0-7]) |
||||
if test -z "$stripcmd"; then |
||||
u_plus_rw= |
||||
else |
||||
u_plus_rw='% 200' |
||||
fi |
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; |
||||
*) |
||||
if test -z "$stripcmd"; then |
||||
u_plus_rw= |
||||
else |
||||
u_plus_rw=,u+rw |
||||
fi |
||||
cp_umask=$mode$u_plus_rw;; |
||||
esac |
||||
fi |
||||
|
||||
for src |
||||
do |
||||
# Protect names starting with `-'. |
||||
case $src in |
||||
-*) src=./$src;; |
||||
esac |
||||
|
||||
if test -n "$dir_arg"; then |
||||
dst=$src |
||||
dstdir=$dst |
||||
test -d "$dstdir" |
||||
dstdir_status=$? |
||||
else |
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command |
||||
# might cause directories to be created, which would be especially bad |
||||
# if $src (and thus $dsttmp) contains '*'. |
||||
if test ! -f "$src" && test ! -d "$src"; then |
||||
echo "$0: $src does not exist." >&2 |
||||
exit 1 |
||||
fi |
||||
|
||||
if test -z "$dst_arg"; then |
||||
echo "$0: no destination specified." >&2 |
||||
exit 1 |
||||
fi |
||||
|
||||
dst=$dst_arg |
||||
# Protect names starting with `-'. |
||||
case $dst in |
||||
-*) dst=./$dst;; |
||||
esac |
||||
|
||||
# If destination is a directory, append the input filename; won't work |
||||
# if double slashes aren't ignored. |
||||
if test -d "$dst"; then |
||||
if test -n "$no_target_directory"; then |
||||
echo "$0: $dst_arg: Is a directory" >&2 |
||||
exit 1 |
||||
fi |
||||
dstdir=$dst |
||||
dst=$dstdir/`basename "$src"` |
||||
dstdir_status=0 |
||||
else |
||||
# Prefer dirname, but fall back on a substitute if dirname fails. |
||||
dstdir=` |
||||
(dirname "$dst") 2>/dev/null || |
||||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ |
||||
X"$dst" : 'X\(//\)[^/]' \| \ |
||||
X"$dst" : 'X\(//\)$' \| \ |
||||
X"$dst" : 'X\(/\)' \| . 2>/dev/null || |
||||
echo X"$dst" | |
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ |
||||
s//\1/ |
||||
q |
||||
} |
||||
/^X\(\/\/\)[^/].*/{ |
||||
s//\1/ |
||||
q |
||||
} |
||||
/^X\(\/\/\)$/{ |
||||
s//\1/ |
||||
q |
||||
} |
||||
/^X\(\/\).*/{ |
||||
s//\1/ |
||||
q |
||||
} |
||||
s/.*/./; q' |
||||
` |
||||
|
||||
test -d "$dstdir" |
||||
dstdir_status=$? |
||||
fi |
||||
fi |
||||
|
||||
obsolete_mkdir_used=false |
||||
|
||||
if test $dstdir_status != 0; then |
||||
case $posix_mkdir in |
||||
'') |
||||
# Create intermediate dirs using mode 755 as modified by the umask. |
||||
# This is like FreeBSD 'install' as of 1997-10-28. |
||||
umask=`umask` |
||||
case $stripcmd.$umask in |
||||
# Optimize common cases. |
||||
*[2367][2367]) mkdir_umask=$umask;; |
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; |
||||
|
||||
*[0-7]) |
||||
mkdir_umask=`expr $umask + 22 \ |
||||
- $umask % 100 % 40 + $umask % 20 \ |
||||
- $umask % 10 % 4 + $umask % 2 |
||||
`;; |
||||
*) mkdir_umask=$umask,go-w;; |
||||
esac |
||||
|
||||
# With -d, create the new directory with the user-specified mode. |
||||
# Otherwise, rely on $mkdir_umask. |
||||
if test -n "$dir_arg"; then |
||||
mkdir_mode=-m$mode |
||||
else |
||||
mkdir_mode= |
||||
fi |
||||
|
||||
posix_mkdir=false |
||||
case $umask in |
||||
*[123567][0-7][0-7]) |
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which |
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0. |
||||
;; |
||||
*) |
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ |
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 |
||||
|
||||
if (umask $mkdir_umask && |
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 |
||||
then |
||||
if test -z "$dir_arg" || { |
||||
# Check for POSIX incompatibilities with -m. |
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or |
||||
# other-writeable bit of parent directory when it shouldn't. |
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory. |
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"` |
||||
case $ls_ld_tmpdir in |
||||
d????-?r-*) different_mode=700;; |
||||
d????-?--*) different_mode=755;; |
||||
*) false;; |
||||
esac && |
||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && { |
||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"` |
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" |
||||
} |
||||
} |
||||
then posix_mkdir=: |
||||
fi |
||||
rmdir "$tmpdir/d" "$tmpdir" |
||||
else |
||||
# Remove any dirs left behind by ancient mkdir implementations. |
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null |
||||
fi |
||||
trap '' 0;; |
||||
esac;; |
||||
esac |
||||
|
||||
if |
||||
$posix_mkdir && ( |
||||
umask $mkdir_umask && |
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" |
||||
) |
||||
then : |
||||
else |
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX, |
||||
# or it failed possibly due to a race condition. Create the |
||||
# directory the slow way, step by step, checking for races as we go. |
||||
|
||||
case $dstdir in |
||||
/*) prefix='/';; |
||||
-*) prefix='./';; |
||||
*) prefix='';; |
||||
esac |
||||
|
||||
eval "$initialize_posix_glob" |
||||
|
||||
oIFS=$IFS |
||||
IFS=/ |
||||
$posix_glob set -f |
||||
set fnord $dstdir |
||||
shift |
||||
$posix_glob set +f |
||||
IFS=$oIFS |
||||
|
||||
prefixes= |
||||
|
||||
for d |
||||
do |
||||
test -z "$d" && continue |
||||
|
||||
prefix=$prefix$d |
||||
if test -d "$prefix"; then |
||||
prefixes= |
||||
else |
||||
if $posix_mkdir; then |
||||
(umask=$mkdir_umask && |
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break |
||||
# Don't fail if two instances are running concurrently. |
||||
test -d "$prefix" || exit 1 |
||||
else |
||||
case $prefix in |
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; |
||||
*) qprefix=$prefix;; |
||||
esac |
||||
prefixes="$prefixes '$qprefix'" |
||||
fi |
||||
fi |
||||
prefix=$prefix/ |
||||
done |
||||
|
||||
if test -n "$prefixes"; then |
||||
# Don't fail if two instances are running concurrently. |
||||
(umask $mkdir_umask && |
||||
eval "\$doit_exec \$mkdirprog $prefixes") || |
||||
test -d "$dstdir" || exit 1 |
||||
obsolete_mkdir_used=true |
||||
fi |
||||
fi |
||||
fi |
||||
|
||||
if test -n "$dir_arg"; then |
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } && |
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && |
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || |
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 |
||||
else |
||||
|
||||
# Make a couple of temp file names in the proper directory. |
||||
dsttmp=$dstdir/_inst.$$_ |
||||
rmtmp=$dstdir/_rm.$$_ |
||||
|
||||
# Trap to clean up those temp files at exit. |
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 |
||||
|
||||
# Copy the file name to the temp name. |
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && |
||||
|
||||
# and set any options; do chmod last to preserve setuid bits. |
||||
# |
||||
# If any of these fail, we abort the whole thing. If we want to |
||||
# ignore errors from any of these, just make sure not to ignore |
||||
# errors from the above "$doit $cpprog $src $dsttmp" command. |
||||
# |
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && |
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && |
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && |
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && |
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file. |
||||
if $copy_on_change && |
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && |
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && |
||||
|
||||
eval "$initialize_posix_glob" && |
||||
$posix_glob set -f && |
||||
set X $old && old=:$2:$4:$5:$6 && |
||||
set X $new && new=:$2:$4:$5:$6 && |
||||
$posix_glob set +f && |
||||
|
||||
test "$old" = "$new" && |
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 |
||||
then |
||||
rm -f "$dsttmp" |
||||
else |
||||
# Rename the file to the real destination. |
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || |
||||
|
||||
# The rename failed, perhaps because mv can't rename something else |
||||
# to itself, or perhaps because mv is so ancient that it does not |
||||
# support -f. |
||||
{ |
||||
# Now remove or move aside any old file at destination location. |
||||
# We try this two ways since rm can't unlink itself on some |
||||
# systems and the destination file might be busy for other |
||||
# reasons. In this case, the final cleanup might fail but the new |
||||
# file should still install successfully. |
||||
{ |
||||
test ! -f "$dst" || |
||||
$doit $rmcmd -f "$dst" 2>/dev/null || |
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && |
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } |
||||
} || |
||||
{ echo "$0: cannot unlink or rename $dst" >&2 |
||||
(exit 1); exit 1 |
||||
} |
||||
} && |
||||
|
||||
# Now rename the file to the real destination. |
||||
$doit $mvcmd "$dsttmp" "$dst" |
||||
} |
||||
fi || exit 1 |
||||
|
||||
trap '' 0 |
||||
fi |
||||
done |
||||
|
||||
# Local variables: |
||||
# eval: (add-hook 'write-file-hooks 'time-stamp) |
||||
# time-stamp-start: "scriptversion=" |
||||
# time-stamp-format: "%:y-%02m-%02d.%02H" |
||||
# time-stamp-time-zone: "UTC" |
||||
# time-stamp-end: "; # UTC" |
||||
# End: |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,3 @@
|
||||
MAINTAINERCLEANFILES=Makefile.in config.guess config.sub install-sh \
|
||||
ltmain.sh missing mkinstalldirs
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,437 @@
|
||||
# Helper functions for option handling. -*- Autoconf -*- |
||||
# |
||||
# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software |
||||
# Foundation, Inc. |
||||
# Written by Gary V. Vaughan, 2004 |
||||
# |
||||
# This file is free software; the Free Software Foundation gives |
||||
# unlimited permission to copy and/or distribute it, with or without |
||||
# modifications, as long as this notice is preserved. |
||||
|
||||
# serial 8 ltoptions.m4 |
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define. |
||||
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) |
||||
|
||||
|
||||
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) |
||||
# ------------------------------------------ |
||||
m4_define([_LT_MANGLE_OPTION], |
||||
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) |
||||
|
||||
|
||||
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) |
||||
# --------------------------------------- |
||||
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a |
||||
# matching handler defined, dispatch to it. Other OPTION-NAMEs are |
||||
# saved as a flag. |
||||
m4_define([_LT_SET_OPTION], |
||||
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl |
||||
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), |
||||
_LT_MANGLE_DEFUN([$1], [$2]), |
||||
[m4_warning([Unknown $1 option '$2'])])[]dnl |
||||
]) |
||||
|
||||
|
||||
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) |
||||
# ------------------------------------------------------------ |
||||
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. |
||||
m4_define([_LT_IF_OPTION], |
||||
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) |
||||
|
||||
|
||||
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) |
||||
# ------------------------------------------------------- |
||||
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME |
||||
# are set. |
||||
m4_define([_LT_UNLESS_OPTIONS], |
||||
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), |
||||
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), |
||||
[m4_define([$0_found])])])[]dnl |
||||
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 |
||||
])[]dnl |
||||
]) |
||||
|
||||
|
||||
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) |
||||
# ---------------------------------------- |
||||
# OPTION-LIST is a space-separated list of Libtool options associated |
||||
# with MACRO-NAME. If any OPTION has a matching handler declared with |
||||
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about |
||||
# the unknown option and exit. |
||||
m4_defun([_LT_SET_OPTIONS], |
||||
[# Set options |
||||
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), |
||||
[_LT_SET_OPTION([$1], _LT_Option)]) |
||||
|
||||
m4_if([$1],[LT_INIT],[ |
||||
dnl |
||||
dnl Simply set some default values (i.e off) if boolean options were not |
||||
dnl specified: |
||||
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no |
||||
]) |
||||
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no |
||||
]) |
||||
dnl |
||||
dnl If no reference was made to various pairs of opposing options, then |
||||
dnl we run the default mode handler for the pair. For example, if neither |
||||
dnl 'shared' nor 'disable-shared' was passed, we enable building of shared |
||||
dnl archives by default: |
||||
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) |
||||
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) |
||||
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) |
||||
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], |
||||
[_LT_ENABLE_FAST_INSTALL]) |
||||
_LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], |
||||
[_LT_WITH_AIX_SONAME([aix])]) |
||||
]) |
||||
])# _LT_SET_OPTIONS |
||||
|
||||
|
||||
## --------------------------------- ## |
||||
## Macros to handle LT_INIT options. ## |
||||
## --------------------------------- ## |
||||
|
||||
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) |
||||
# ----------------------------------------- |
||||
m4_define([_LT_MANGLE_DEFUN], |
||||
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) |
||||
|
||||
|
||||
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) |
||||
# ----------------------------------------------- |
||||
m4_define([LT_OPTION_DEFINE], |
||||
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl |
||||
])# LT_OPTION_DEFINE |
||||
|
||||
|
||||
# dlopen |
||||
# ------ |
||||
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes |
||||
]) |
||||
|
||||
AU_DEFUN([AC_LIBTOOL_DLOPEN], |
||||
[_LT_SET_OPTION([LT_INIT], [dlopen]) |
||||
AC_DIAGNOSE([obsolete], |
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you |
||||
put the 'dlopen' option into LT_INIT's first parameter.]) |
||||
]) |
||||
|
||||
dnl aclocal-1.4 backwards compatibility: |
||||
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) |
||||
|
||||
|
||||
# win32-dll |
||||
# --------- |
||||
# Declare package support for building win32 dll's. |
||||
LT_OPTION_DEFINE([LT_INIT], [win32-dll], |
||||
[enable_win32_dll=yes |
||||
|
||||
case $host in |
||||
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) |
||||
AC_CHECK_TOOL(AS, as, false) |
||||
AC_CHECK_TOOL(DLLTOOL, dlltool, false) |
||||
AC_CHECK_TOOL(OBJDUMP, objdump, false) |
||||
;; |
||||
esac |
||||
|
||||
test -z "$AS" && AS=as |
||||
_LT_DECL([], [AS], [1], [Assembler program])dnl |
||||
|
||||
test -z "$DLLTOOL" && DLLTOOL=dlltool |
||||
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl |
||||
|
||||
test -z "$OBJDUMP" && OBJDUMP=objdump |
||||
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl |
||||
])# win32-dll |
||||
|
||||
AU_DEFUN([AC_LIBTOOL_WIN32_DLL], |
||||
[AC_REQUIRE([AC_CANONICAL_HOST])dnl |
||||
_LT_SET_OPTION([LT_INIT], [win32-dll]) |
||||
AC_DIAGNOSE([obsolete], |
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you |
||||
put the 'win32-dll' option into LT_INIT's first parameter.]) |
||||
]) |
||||
|
||||
dnl aclocal-1.4 backwards compatibility: |
||||
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) |
||||
|
||||
|
||||
# _LT_ENABLE_SHARED([DEFAULT]) |
||||
# ---------------------------- |
||||
# implement the --enable-shared flag, and supports the 'shared' and |
||||
# 'disable-shared' LT_INIT options. |
||||
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. |
||||
m4_define([_LT_ENABLE_SHARED], |
||||
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl |
||||
AC_ARG_ENABLE([shared], |
||||
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], |
||||
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], |
||||
[p=${PACKAGE-default} |
||||
case $enableval in |
||||
yes) enable_shared=yes ;; |
||||
no) enable_shared=no ;; |
||||
*) |
||||
enable_shared=no |
||||
# Look at the argument we got. We use all the common list separators. |
||||
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, |
||||
for pkg in $enableval; do |
||||
IFS=$lt_save_ifs |
||||
if test "X$pkg" = "X$p"; then |
||||
enable_shared=yes |
||||
fi |
||||
done |
||||
IFS=$lt_save_ifs |
||||
;; |
||||
esac], |
||||
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT) |
||||
|
||||
_LT_DECL([build_libtool_libs], [enable_shared], [0], |
||||
[Whether or not to build shared libraries]) |
||||
])# _LT_ENABLE_SHARED |
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) |
||||
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) |
||||
|
||||
# Old names: |
||||
AC_DEFUN([AC_ENABLE_SHARED], |
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) |
||||
]) |
||||
|
||||
AC_DEFUN([AC_DISABLE_SHARED], |
||||
[_LT_SET_OPTION([LT_INIT], [disable-shared]) |
||||
]) |
||||
|
||||
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) |
||||
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) |
||||
|
||||
dnl aclocal-1.4 backwards compatibility: |
||||
dnl AC_DEFUN([AM_ENABLE_SHARED], []) |
||||
dnl AC_DEFUN([AM_DISABLE_SHARED], []) |
||||
|
||||
|
||||
|
||||
# _LT_ENABLE_STATIC([DEFAULT]) |
||||
# ---------------------------- |
||||
# implement the --enable-static flag, and support the 'static' and |
||||
# 'disable-static' LT_INIT options. |
||||
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. |
||||
m4_define([_LT_ENABLE_STATIC], |
||||
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl |
||||
AC_ARG_ENABLE([static], |
||||
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], |
||||
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], |
||||
[p=${PACKAGE-default} |
||||
case $enableval in |
||||
yes) enable_static=yes ;; |
||||
no) enable_static=no ;; |
||||
*) |
||||
enable_static=no |
||||
# Look at the argument we got. We use all the common list separators. |
||||
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, |
||||
for pkg in $enableval; do |
||||
IFS=$lt_save_ifs |
||||
if test "X$pkg" = "X$p"; then |
||||
enable_static=yes |
||||
fi |
||||
done |
||||
IFS=$lt_save_ifs |
||||
;; |
||||
esac], |
||||
[enable_static=]_LT_ENABLE_STATIC_DEFAULT) |
||||
|
||||
_LT_DECL([build_old_libs], [enable_static], [0], |
||||
[Whether or not to build static libraries]) |
||||
])# _LT_ENABLE_STATIC |
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) |
||||
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) |
||||
|
||||
# Old names: |
||||
AC_DEFUN([AC_ENABLE_STATIC], |
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) |
||||
]) |
||||
|
||||
AC_DEFUN([AC_DISABLE_STATIC], |
||||
[_LT_SET_OPTION([LT_INIT], [disable-static]) |
||||
]) |
||||
|
||||
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) |
||||
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) |
||||
|
||||
dnl aclocal-1.4 backwards compatibility: |
||||
dnl AC_DEFUN([AM_ENABLE_STATIC], []) |
||||
dnl AC_DEFUN([AM_DISABLE_STATIC], []) |
||||
|
||||
|
||||
|
||||
# _LT_ENABLE_FAST_INSTALL([DEFAULT]) |
||||
# ---------------------------------- |
||||
# implement the --enable-fast-install flag, and support the 'fast-install' |
||||
# and 'disable-fast-install' LT_INIT options. |
||||
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. |
||||
m4_define([_LT_ENABLE_FAST_INSTALL], |
||||
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl |
||||
AC_ARG_ENABLE([fast-install], |
||||
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], |
||||
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], |
||||
[p=${PACKAGE-default} |
||||
case $enableval in |
||||
yes) enable_fast_install=yes ;; |
||||
no) enable_fast_install=no ;; |
||||
*) |
||||
enable_fast_install=no |
||||
# Look at the argument we got. We use all the common list separators. |
||||
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, |
||||
for pkg in $enableval; do |
||||
IFS=$lt_save_ifs |
||||
if test "X$pkg" = "X$p"; then |
||||
enable_fast_install=yes |
||||
fi |
||||
done |
||||
IFS=$lt_save_ifs |
||||
;; |
||||
esac], |
||||
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) |
||||
|
||||
_LT_DECL([fast_install], [enable_fast_install], [0], |
||||
[Whether or not to optimize for fast installation])dnl |
||||
])# _LT_ENABLE_FAST_INSTALL |
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) |
||||
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) |
||||
|
||||
# Old names: |
||||
AU_DEFUN([AC_ENABLE_FAST_INSTALL], |
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) |
||||
AC_DIAGNOSE([obsolete], |
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you put |
||||
the 'fast-install' option into LT_INIT's first parameter.]) |
||||
]) |
||||
|
||||
AU_DEFUN([AC_DISABLE_FAST_INSTALL], |
||||
[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) |
||||
AC_DIAGNOSE([obsolete], |
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you put |
||||
the 'disable-fast-install' option into LT_INIT's first parameter.]) |
||||
]) |
||||
|
||||
dnl aclocal-1.4 backwards compatibility: |
||||
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) |
||||
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) |
||||
|
||||
|
||||
# _LT_WITH_AIX_SONAME([DEFAULT]) |
||||
# ---------------------------------- |
||||
# implement the --with-aix-soname flag, and support the `aix-soname=aix' |
||||
# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT |
||||
# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. |
||||
m4_define([_LT_WITH_AIX_SONAME], |
||||
[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl |
||||
shared_archive_member_spec= |
||||
case $host,$enable_shared in |
||||
power*-*-aix[[5-9]]*,yes) |
||||
AC_MSG_CHECKING([which variant of shared library versioning to provide]) |
||||
AC_ARG_WITH([aix-soname], |
||||
[AS_HELP_STRING([--with-aix-soname=aix|svr4|both], |
||||
[shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], |
||||
[case $withval in |
||||
aix|svr4|both) |
||||
;; |
||||
*) |
||||
AC_MSG_ERROR([Unknown argument to --with-aix-soname]) |
||||
;; |
||||
esac |
||||
lt_cv_with_aix_soname=$with_aix_soname], |
||||
[AC_CACHE_VAL([lt_cv_with_aix_soname], |
||||
[lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) |
||||
with_aix_soname=$lt_cv_with_aix_soname]) |
||||
AC_MSG_RESULT([$with_aix_soname]) |
||||
if test aix != "$with_aix_soname"; then |
||||
# For the AIX way of multilib, we name the shared archive member |
||||
# based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', |
||||
# and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. |
||||
# Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, |
||||
# the AIX toolchain works better with OBJECT_MODE set (default 32). |
||||
if test 64 = "${OBJECT_MODE-32}"; then |
||||
shared_archive_member_spec=shr_64 |
||||
else |
||||
shared_archive_member_spec=shr |
||||
fi |
||||
fi |
||||
;; |
||||
*) |
||||
with_aix_soname=aix |
||||
;; |
||||
esac |
||||
|
||||
_LT_DECL([], [shared_archive_member_spec], [0], |
||||
[Shared archive member basename, for filename based shared library versioning on AIX])dnl |
||||
])# _LT_WITH_AIX_SONAME |
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) |
||||
LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) |
||||
LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) |
||||
|
||||
|
||||
# _LT_WITH_PIC([MODE]) |
||||
# -------------------- |
||||
# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' |
||||
# LT_INIT options. |
||||
# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. |
||||
m4_define([_LT_WITH_PIC], |
||||
[AC_ARG_WITH([pic], |
||||
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], |
||||
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])], |
||||
[lt_p=${PACKAGE-default} |
||||
case $withval in |
||||
yes|no) pic_mode=$withval ;; |
||||
*) |
||||
pic_mode=default |
||||
# Look at the argument we got. We use all the common list separators. |
||||
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, |
||||
for lt_pkg in $withval; do |
||||
IFS=$lt_save_ifs |
||||
if test "X$lt_pkg" = "X$lt_p"; then |
||||
pic_mode=yes |
||||
fi |
||||
done |
||||
IFS=$lt_save_ifs |
||||
;; |
||||
esac], |
||||
[pic_mode=m4_default([$1], [default])]) |
||||
|
||||
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl |
||||
])# _LT_WITH_PIC |
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) |
||||
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) |
||||
|
||||
# Old name: |
||||
AU_DEFUN([AC_LIBTOOL_PICMODE], |
||||
[_LT_SET_OPTION([LT_INIT], [pic-only]) |
||||
AC_DIAGNOSE([obsolete], |
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you |
||||
put the 'pic-only' option into LT_INIT's first parameter.]) |
||||
]) |
||||
|
||||
dnl aclocal-1.4 backwards compatibility: |
||||
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) |
||||
|
||||
## ----------------- ## |
||||
## LTDL_INIT Options ## |
||||
## ----------------- ## |
||||
|
||||
m4_define([_LTDL_MODE], []) |
||||
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], |
||||
[m4_define([_LTDL_MODE], [nonrecursive])]) |
||||
LT_OPTION_DEFINE([LTDL_INIT], [recursive], |
||||
[m4_define([_LTDL_MODE], [recursive])]) |
||||
LT_OPTION_DEFINE([LTDL_INIT], [subproject], |
||||
[m4_define([_LTDL_MODE], [subproject])]) |
||||
|
||||
m4_define([_LTDL_TYPE], []) |
||||
LT_OPTION_DEFINE([LTDL_INIT], [installable], |
||||
[m4_define([_LTDL_TYPE], [installable])]) |
||||
LT_OPTION_DEFINE([LTDL_INIT], [convenience], |
||||
[m4_define([_LTDL_TYPE], [convenience])]) |
||||
@ -0,0 +1,124 @@
|
||||
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- |
||||
# |
||||
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software |
||||
# Foundation, Inc. |
||||
# Written by Gary V. Vaughan, 2004 |
||||
# |
||||
# This file is free software; the Free Software Foundation gives |
||||
# unlimited permission to copy and/or distribute it, with or without |
||||
# modifications, as long as this notice is preserved. |
||||
|
||||
# serial 6 ltsugar.m4 |
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define. |
||||
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) |
||||
|
||||
|
||||
# lt_join(SEP, ARG1, [ARG2...]) |
||||
# ----------------------------- |
||||
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their |
||||
# associated separator. |
||||
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier |
||||
# versions in m4sugar had bugs. |
||||
m4_define([lt_join], |
||||
[m4_if([$#], [1], [], |
||||
[$#], [2], [[$2]], |
||||
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) |
||||
m4_define([_lt_join], |
||||
[m4_if([$#$2], [2], [], |
||||
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) |
||||
|
||||
|
||||
# lt_car(LIST) |
||||
# lt_cdr(LIST) |
||||
# ------------ |
||||
# Manipulate m4 lists. |
||||
# These macros are necessary as long as will still need to support |
||||
# Autoconf-2.59, which quotes differently. |
||||
m4_define([lt_car], [[$1]]) |
||||
m4_define([lt_cdr], |
||||
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], |
||||
[$#], 1, [], |
||||
[m4_dquote(m4_shift($@))])]) |
||||
m4_define([lt_unquote], $1) |
||||
|
||||
|
||||
# lt_append(MACRO-NAME, STRING, [SEPARATOR]) |
||||
# ------------------------------------------ |
||||
# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. |
||||
# Note that neither SEPARATOR nor STRING are expanded; they are appended |
||||
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). |
||||
# No SEPARATOR is output if MACRO-NAME was previously undefined (different |
||||
# than defined and empty). |
||||
# |
||||
# This macro is needed until we can rely on Autoconf 2.62, since earlier |
||||
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. |
||||
m4_define([lt_append], |
||||
[m4_define([$1], |
||||
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) |
||||
|
||||
|
||||
|
||||
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) |
||||
# ---------------------------------------------------------- |
||||
# Produce a SEP delimited list of all paired combinations of elements of |
||||
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list |
||||
# has the form PREFIXmINFIXSUFFIXn. |
||||
# Needed until we can rely on m4_combine added in Autoconf 2.62. |
||||
m4_define([lt_combine], |
||||
[m4_if(m4_eval([$# > 3]), [1], |
||||
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl |
||||
[[m4_foreach([_Lt_prefix], [$2], |
||||
[m4_foreach([_Lt_suffix], |
||||
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, |
||||
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) |
||||
|
||||
|
||||
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) |
||||
# ----------------------------------------------------------------------- |
||||
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited |
||||
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. |
||||
m4_define([lt_if_append_uniq], |
||||
[m4_ifdef([$1], |
||||
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], |
||||
[lt_append([$1], [$2], [$3])$4], |
||||
[$5])], |
||||
[lt_append([$1], [$2], [$3])$4])]) |
||||
|
||||
|
||||
# lt_dict_add(DICT, KEY, VALUE) |
||||
# ----------------------------- |
||||
m4_define([lt_dict_add], |
||||
[m4_define([$1($2)], [$3])]) |
||||
|
||||
|
||||
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) |
||||
# -------------------------------------------- |
||||
m4_define([lt_dict_add_subkey], |
||||
[m4_define([$1($2:$3)], [$4])]) |
||||
|
||||
|
||||
# lt_dict_fetch(DICT, KEY, [SUBKEY]) |
||||
# ---------------------------------- |
||||
m4_define([lt_dict_fetch], |
||||
[m4_ifval([$3], |
||||
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), |
||||
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) |
||||
|
||||
|
||||
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) |
||||
# ----------------------------------------------------------------- |
||||
m4_define([lt_if_dict_fetch], |
||||
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], |
||||
[$5], |
||||
[$6])]) |
||||
|
||||
|
||||
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) |
||||
# -------------------------------------------------------------- |
||||
m4_define([lt_dict_filter], |
||||
[m4_if([$5], [], [], |
||||
[lt_join(m4_quote(m4_default([$4], [[, ]])), |
||||
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), |
||||
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl |
||||
]) |
||||
@ -0,0 +1,23 @@
|
||||
# ltversion.m4 -- version numbers -*- Autoconf -*- |
||||
# |
||||
# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. |
||||
# Written by Scott James Remnant, 2004 |
||||
# |
||||
# This file is free software; the Free Software Foundation gives |
||||
# unlimited permission to copy and/or distribute it, with or without |
||||
# modifications, as long as this notice is preserved. |
||||
|
||||
# @configure_input@ |
||||
|
||||
# serial 4179 ltversion.m4 |
||||
# This file is part of GNU Libtool |
||||
|
||||
m4_define([LT_PACKAGE_VERSION], [2.4.6]) |
||||
m4_define([LT_PACKAGE_REVISION], [2.4.6]) |
||||
|
||||
AC_DEFUN([LTVERSION_VERSION], |
||||
[macro_version='2.4.6' |
||||
macro_revision='2.4.6' |
||||
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) |
||||
_LT_DECL(, macro_revision, 0) |
||||
]) |
||||
@ -0,0 +1,99 @@
|
||||
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- |
||||
# |
||||
# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software |
||||
# Foundation, Inc. |
||||
# Written by Scott James Remnant, 2004. |
||||
# |
||||
# This file is free software; the Free Software Foundation gives |
||||
# unlimited permission to copy and/or distribute it, with or without |
||||
# modifications, as long as this notice is preserved. |
||||
|
||||
# serial 5 lt~obsolete.m4 |
||||
|
||||
# These exist entirely to fool aclocal when bootstrapping libtool. |
||||
# |
||||
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), |
||||
# which have later been changed to m4_define as they aren't part of the |
||||
# exported API, or moved to Autoconf or Automake where they belong. |
||||
# |
||||
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN |
||||
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us |
||||
# using a macro with the same name in our local m4/libtool.m4 it'll |
||||
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define |
||||
# and doesn't know about Autoconf macros at all.) |
||||
# |
||||
# So we provide this file, which has a silly filename so it's always |
||||
# included after everything else. This provides aclocal with the |
||||
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything |
||||
# because those macros already exist, or will be overwritten later. |
||||
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. |
||||
# |
||||
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. |
||||
# Yes, that means every name once taken will need to remain here until |
||||
# we give up compatibility with versions before 1.7, at which point |
||||
# we need to keep only those names which we still refer to. |
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define. |
||||
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) |
||||
|
||||
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) |
||||
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) |
||||
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) |
||||
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) |
||||
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) |
||||
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) |
||||
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) |
||||
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) |
||||
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) |
||||
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) |
||||
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) |
||||
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) |
||||
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) |
||||
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) |
||||
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) |
||||
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) |
||||
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) |
||||
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) |
||||
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) |
||||
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) |
||||
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) |
||||
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) |
||||
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) |
||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) |
||||
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) |
||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) |
||||
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) |
||||
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) |
||||
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) |
||||
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) |
||||
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) |
||||
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) |
||||
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) |
||||
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) |
||||
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) |
||||
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) |
||||
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) |
||||
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) |
||||
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) |
||||
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) |
||||
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) |
||||
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) |
||||
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) |
||||
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) |
||||
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) |
||||
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) |
||||
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) |
||||
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) |
||||
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) |
||||
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) |
||||
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) |
||||
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) |
||||
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) |
||||
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) |
||||
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) |
||||
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) |
||||
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) |
||||
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) |
||||
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) |
||||
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) |
||||
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) |
||||
@ -0,0 +1,215 @@
|
||||
#! /bin/sh |
||||
# Common wrapper for a few potentially missing GNU programs. |
||||
|
||||
scriptversion=2018-03-07.03; # UTC |
||||
|
||||
# Copyright (C) 1996-2021 Free Software Foundation, Inc. |
||||
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 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 <https://www.gnu.org/licenses/>. |
||||
|
||||
# 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 <bug-automake@gnu.org>." |
||||
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: |
||||
@ -0,0 +1,40 @@
|
||||
#! /bin/sh |
||||
# mkinstalldirs --- make directory hierarchy |
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu> |
||||
# Created: 1993-05-16 |
||||
# Public domain |
||||
|
||||
# $Id$ |
||||
|
||||
errstatus=0 |
||||
|
||||
for file |
||||
do |
||||
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` |
||||
shift |
||||
|
||||
pathcomp= |
||||
for d |
||||
do |
||||
pathcomp="$pathcomp$d" |
||||
case "$pathcomp" in |
||||
-* ) pathcomp=./$pathcomp ;; |
||||
esac |
||||
|
||||
if test ! -d "$pathcomp"; then |
||||
echo "mkdir $pathcomp" |
||||
|
||||
mkdir "$pathcomp" || lasterr=$? |
||||
|
||||
if test ! -d "$pathcomp"; then |
||||
errstatus=$lasterr |
||||
fi |
||||
fi |
||||
|
||||
pathcomp="$pathcomp/" |
||||
done |
||||
done |
||||
|
||||
exit $errstatus |
||||
|
||||
# mkinstalldirs ends here |
||||
@ -0,0 +1,26 @@
|
||||
PACKAGE internal autotools |
||||
PACKAGE_BUGREPORT internal autotools |
||||
PACKAGE_NAME internal autotools |
||||
PACKAGE_STRING internal autotools |
||||
PACKAGE_TARNAME internal autotools |
||||
PACKAGE_VERSION internal autotools |
||||
PQXX_HAVE_CHARCONV_INT internal compiler |
||||
PQXX_HAVE_CHARCONV_FLOAT internal compiler |
||||
PQXX_HAVE_CMP public compiler |
||||
PQXX_HAVE_CONCEPTS public compiler |
||||
PQXX_HAVE_CXA_DEMANGLE internal compiler |
||||
PQXX_HAVE_GCC_PURE public compiler |
||||
PQXX_HAVE_GCC_VISIBILITY public compiler |
||||
PQXX_HAVE_LIKELY public compiler |
||||
PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT public compiler |
||||
PQXX_HAVE_PATH public compiler |
||||
PQXX_HAVE_POLL internal compiler |
||||
PQXX_HAVE_PQENCRYPTPASSWORDCONN internal libpq |
||||
PQXX_HAVE_PQ_PIPELINE internal libpq |
||||
PQXX_HAVE_SLEEP_FOR internal compiler |
||||
PQXX_HAVE_SPAN public compiler |
||||
PQXX_HAVE_STRERROR_R internal compiler |
||||
PQXX_HAVE_STRERROR_S internal compiler |
||||
PQXX_HAVE_THREAD_LOCAL internal compiler |
||||
PQXX_HAVE_YEAR_MONTH_DAY public compiler |
||||
VERSION internal autotools |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,738 @@
|
||||
# Generate configure script for libpqxx. This needs the autoconf archive |
||||
# package installed. (The configure script itself does not require it though.) |
||||
|
||||
AC_PREREQ(2.69) |
||||
AC_INIT( |
||||
libpqxx, |
||||
[m4_esyscmd_s([./tools/extract_version])], |
||||
[Jeroen T. Vermeulen]) |
||||
AC_LANG(C++) |
||||
|
||||
AC_CONFIG_SRCDIR([src/connection.cxx]) |
||||
AC_CONFIG_AUX_DIR(config) |
||||
AC_CONFIG_MACRO_DIR([config/m4]) |
||||
AM_INIT_AUTOMAKE([subdir-objects]) |
||||
|
||||
PQXX_ABI=m4_esyscmd_s([./tools/extract_version --abi]) |
||||
AC_SUBST(PQXXVERSION, $PACKAGE_VERSION) |
||||
AC_SUBST(PQXX_ABI) |
||||
|
||||
AC_CONFIG_HEADER([include/pqxx/config.h]) |
||||
|
||||
# Default prefix for installs. |
||||
AC_PREFIX_DEFAULT(/usr/local) |
||||
|
||||
|
||||
# Read test programme from config-test. |
||||
AC_DEFUN([read_test], [AC_LANG_SOURCE( |
||||
esyscmd(tools/m4esc.py --input=config-tests/$1))]) |
||||
|
||||
|
||||
# Checks for programs. |
||||
AC_PROG_CXX |
||||
AC_PROG_INSTALL |
||||
AC_DISABLE_SHARED |
||||
AC_PROG_LIBTOOL |
||||
AC_PROG_MAKE_SET |
||||
AC_PATH_PROG([MKDIR], [mkdir]) |
||||
|
||||
# Documentation. |
||||
AC_ARG_ENABLE( |
||||
documentation, |
||||
[AS_HELP_STRING([--enable-documentation], [Generate documentation])], |
||||
[], |
||||
[enable_documentation=auto]) |
||||
AC_ARG_VAR([DOXYGEN], |
||||
[Path to doxygen needed to build reference documentation]) |
||||
AC_PATH_TOOL([DOXYGEN], [doxygen], [nodoxygen]) |
||||
AC_ARG_VAR([HAVE_DOT], |
||||
[Variable used by doxygen to declare availibility of dot]) |
||||
AC_CHECK_TOOL([HAVE_DOT], [dot], [YES], [NO]) |
||||
AS_IF([test "$enable_documentation" = "yes" && test "$DOXYGEN" = "nodoxygen"], |
||||
[AC_MSG_ERROR([could not find tools necessary to build documentation])]) |
||||
AM_CONDITIONAL([BUILD_REFERENCE], |
||||
[test "$enable_documentation" != "no" -a "$DOXYGEN" != "nodoxygen"]) |
||||
|
||||
AM_MAINTAINER_MODE |
||||
|
||||
# See if we want stricter compiler warnings. |
||||
AC_MSG_CHECKING([maintainer mode]) |
||||
AC_ARG_ENABLE(maintainer-mode) |
||||
AC_MSG_RESULT(${enable_maintainer_mode}) |
||||
|
||||
# See if we want runtime debug checking. |
||||
AC_MSG_CHECKING([audit]) |
||||
AC_ARG_ENABLE(audit) |
||||
AC_MSG_RESULT(${enable_audit}) |
||||
|
||||
# See if we want "suggestions," such as "this class could be final." |
||||
# (The suggestions are often useful, but can also easily be wrong.) |
||||
AC_MSG_CHECKING([suggest]) |
||||
AC_ARG_ENABLE(suggest) |
||||
AC_MSG_RESULT(${enable_suggest}) |
||||
|
||||
|
||||
AC_ARG_ENABLE(shared) |
||||
AS_IF( |
||||
[test "${shared}" = "yes" ], |
||||
[CPPFLAGS="$CPPFLAGS -DPQXX_SHARED"]) |
||||
|
||||
|
||||
# Add options to compiler command line, if compiler accepts them. |
||||
add_compiler_opts_if_ok() { |
||||
for option in $* |
||||
do |
||||
ACO_SAVE_CXXFLAGS="$CXXFLAGS" |
||||
CXXFLAGS="$CXXFLAGS $option" |
||||
AC_MSG_CHECKING([whether $CXX accepts $option]) |
||||
AC_COMPILE_IFELSE( |
||||
[AC_LANG_PROGRAM([], [])], |
||||
has_option=yes, |
||||
has_option=no) |
||||
AC_MSG_RESULT($has_option) |
||||
AS_IF( |
||||
[test "$has_option" = "no" ], |
||||
[CXXFLAGS="$ACO_SAVE_CXXFLAGS"]) |
||||
done |
||||
} |
||||
|
||||
|
||||
# Add options to compiler command line, unconditionally. |
||||
add_compiler_opts() { |
||||
CXXFLAGS="$CXXFLAGS $*" |
||||
} |
||||
|
||||
|
||||
# It's tempting to use Autoconf Archive's AX_CXX_COMPILE_STDCXX_17 for this, |
||||
# but it's 2022 and the C++20 equivalent isn't quite ready for use. |
||||
# Seems simpler and more reliable for the user to arrange for the desired |
||||
# language versions by setting the appropriate option for their compiler. |
||||
AC_MSG_CHECKING([for sufficient C++ language/library level]) |
||||
sufficient_cxx=yes |
||||
AC_COMPILE_IFELSE( |
||||
[AC_LANG_SOURCE([ |
||||
#if __cplusplus < 201611L |
||||
#error "Need C++17 or better." |
||||
#endif |
||||
])], |
||||
sufficient_cxx=yes, |
||||
sufficient_cxx=no) |
||||
AC_MSG_RESULT($sufficient_cxx) |
||||
if test "$sufficient_cxx" != "yes" |
||||
then |
||||
AC_MSG_ERROR([This libpqxx version needs at least C++17.]) |
||||
fi |
||||
|
||||
|
||||
# Let's try to get the compiler to be helpful. |
||||
# |
||||
# (Omit options -Weffc++ and -Wabi because they currently yield too many |
||||
# warnings in gcc's standard headers; omit -Wunreachable-code because it isn't |
||||
# always right) |
||||
if test "$GCC" = "yes" |
||||
then |
||||
# In maintainer mode, enable all the warning options we can. |
||||
if test "$enable_maintainer_mode" = "yes" |
||||
then |
||||
# "Eternal" (FLW) g++ options. These have been around for |
||||
# ages, and both g++ and clang++ support them. Don't bother |
||||
# checking for support; just add them to the compiler options. |
||||
add_compiler_opts \ |
||||
-fstrict-enums \ |
||||
-Werror \ |
||||
-Wall \ |
||||
-pedantic \ |
||||
-Wcast-align \ |
||||
-Wcast-qual \ |
||||
-Wconversion \ |
||||
-Wctor-dtor-privacy \ |
||||
-Wendif-labels \ |
||||
-Wextra \ |
||||
-Wfloat-equal \ |
||||
-Wformat=2 \ |
||||
-Wformat-security \ |
||||
-Wmissing-include-dirs \ |
||||
-Wno-div-by-zero \ |
||||
-Wnon-virtual-dtor \ |
||||
-Wold-style-cast \ |
||||
-Woverlength-strings \ |
||||
-Woverloaded-virtual \ |
||||
-Wpointer-arith \ |
||||
-Wredundant-decls \ |
||||
-Wshadow \ |
||||
-Wsign-promo \ |
||||
-Wundef \ |
||||
-Wunused \ |
||||
-Wwrite-strings |
||||
|
||||
# "Iffy" g++ options. Some reasonably current g++-like |
||||
# compilers may not support these. |
||||
add_compiler_opts_if_ok \ |
||||
-fnothrow-opt \ |
||||
-Wattribute-alias=2 \ |
||||
-Wextra-semi \ |
||||
-Wlogical-op \ |
||||
-Wmismatched-tags \ |
||||
-Wnoexcept \ |
||||
-Wredundant-tags \ |
||||
-Wrestrict \ |
||||
-Wstringop-overflow \ |
||||
-Wzero-as-null-pointer-constant \ |
||||
-Warray-bounds=2 \ |
||||
-Wduplicated-branches \ |
||||
-Wduplicated-cond \ |
||||
-Wsuggest-attribute=noreturn \ |
||||
-Wsuggest-override \ |
||||
-Wtrampolines |
||||
fi |
||||
|
||||
# In "audit," enable all runtime checks we can. |
||||
if test "$enable_audit" = "yes" |
||||
then |
||||
add_compiler_opts_if_ok \ |
||||
-D_FORTIFY_SOURCE=2 \ |
||||
-fsanitize=address \ |
||||
-fsanitize-address-use-after-scope \ |
||||
-fsanitize=alignment \ |
||||
-fsanitize=bool \ |
||||
-fsanitize=bounds \ |
||||
-fsanitize=bounds-strict \ |
||||
-fsanitize=builtin \ |
||||
-fsanitize=enum \ |
||||
-fsanitize=float-cast-overflow \ |
||||
-fsanitize=float-divide-by-zero \ |
||||
-fsanitize=integer-divide-by-zero \ |
||||
-fsanitize=leak \ |
||||
-fsanitize=nonnull-attribute \ |
||||
-fsanitize=null \ |
||||
-fsanitize=object-size \ |
||||
-fsanitize=pointer-compare \ |
||||
-fsanitize=pointer-overflow \ |
||||
-fsanitize=pointer-subtract \ |
||||
-fsanitize=return \ |
||||
-fsanitize=returns-nonnull-attribute \ |
||||
-fsanitize=shift \ |
||||
-fsanitize=shift-base \ |
||||
-fsanitize=shift-exponent \ |
||||
-fsanitize=signed-integer-overflow \ |
||||
-fsanitize=undefined \ |
||||
-fsanitize=unreachable \ |
||||
-fsanitize=vla-bound \ |
||||
-fsanitize=vptr \ |
||||
-fstack-protector-all |
||||
fi |
||||
|
||||
# In "suggest" mode, enable a bunch of code suggestions. |
||||
if test "$enable_suggest" = "yes" |
||||
then |
||||
add_compiler_opts_if_ok \ |
||||
-Wsuggest-attribute=cold \ |
||||
-Wsuggest-attribute=const \ |
||||
-Wsuggest-attribute=malloc \ |
||||
-Wsuggest-attribute=pure \ |
||||
-Wsuggest-final-types \ |
||||
-Wsuggest-final-methods |
||||
fi |
||||
|
||||
AC_MSG_CHECKING([g++ visibility attribute]) |
||||
gcc_visibility=yes |
||||
SAVE_CXXFLAGS="$CXXFLAGS" |
||||
CXXFLAGS="$CXXFLAGS -Werror" |
||||
AC_COMPILE_IFELSE( |
||||
[read_test(gcc_visibility.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_GCC_VISIBILITY], |
||||
1, |
||||
[Define if g++ supports visibility attribute.]), |
||||
gcc_visibility=no) |
||||
AC_MSG_RESULT($gcc_visibility) |
||||
CXXFLAGS="$SAVE_CXXFLAGS" |
||||
if test "$gcc_visibility" = "yes" |
||||
then |
||||
# Make internal definitions accessible only to the library itself. |
||||
# Only definitions marked PQXX_LIBEXPORT will be accessible. |
||||
add_compiler_opts -fvisibility=hidden |
||||
add_compiler_opts -fvisibility-inlines-hidden |
||||
fi |
||||
|
||||
AC_MSG_CHECKING([g++ pure attribute]) |
||||
gcc_pure=yes |
||||
AC_COMPILE_IFELSE( |
||||
[read_test(gcc_pure.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_GCC_PURE], |
||||
1, |
||||
[Define if g++ supports pure attribute]), |
||||
gcc_pure=no) |
||||
AC_MSG_RESULT($gcc_pure) |
||||
|
||||
fi # End of gcc-specific part. |
||||
|
||||
|
||||
# Check for __cxa_demangle. |
||||
AC_MSG_CHECKING([__cxa_demangle]) |
||||
cxa_demangle=yes |
||||
AC_COMPILE_IFELSE( |
||||
[read_test(cxa_demangle.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_CXA_DEMANGLE], |
||||
1, |
||||
[Define if compiler supports __cxa_demangle]), |
||||
cxa_demangle=no) |
||||
AC_MSG_RESULT($cxa_demangle) |
||||
|
||||
|
||||
# Check for sufficient Concepts support, introduced with C++20. |
||||
AC_MSG_CHECKING([concepts]) |
||||
concepts=yes |
||||
AC_COMPILE_IFELSE( |
||||
[read_test(concepts.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_CONCEPTS], |
||||
1, |
||||
[Define if compiler supports Concepts and <ranges> header.]), |
||||
concepts=no) |
||||
AC_MSG_RESULT($concepts) |
||||
|
||||
|
||||
# Check for C++20 std::span. |
||||
AC_MSG_CHECKING([std::span]) |
||||
span=yes |
||||
AC_COMPILE_IFELSE( |
||||
[read_test(span.cxx)], |
||||
AC_DEFINE([PQXX_HAVE_SPAN], 1, [Define if compiler has std::span.]), |
||||
span=no) |
||||
AC_MSG_RESULT($span) |
||||
|
||||
|
||||
# Check for multidimensional subscript operator support. Proposed for C++23. |
||||
AC_MSG_CHECKING([for multidimensional subscript operator support]) |
||||
multidim_subscript=yes |
||||
AC_COMPILE_IFELSE( |
||||
[read_test(multidim-subscript.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT], 1, |
||||
[Define if operator[] can take multiple arguments.]), |
||||
multidim_subscript=no) |
||||
AC_MSG_RESULT($multidim_subscript) |
||||
|
||||
|
||||
AC_MSG_CHECKING([for strerror_r()]) |
||||
strerror_r=yes |
||||
AC_LINK_IFELSE( |
||||
[read_test(strerror_r.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_STRERROR_R], |
||||
1, |
||||
[Define if strerror_r() is available.]), |
||||
strerror_r=no) |
||||
AC_MSG_RESULT($strerror_r) |
||||
|
||||
|
||||
|
||||
AC_MSG_CHECKING([for strerror_s()]) |
||||
strerror_s=yes |
||||
AC_LINK_IFELSE( |
||||
[read_test(strerror_s.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_STRERROR_S], |
||||
1, |
||||
[Define if strerror_s() is available.]), |
||||
strerror_s=no) |
||||
AC_MSG_RESULT($strerror_s) |
||||
|
||||
|
||||
AC_MSG_CHECKING([for std::chrono::year_month_day etc]) |
||||
year_month_day=yes |
||||
AC_LINK_IFELSE( |
||||
[read_test(year_month_day.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_YEAR_MONTH_DAY], |
||||
1, |
||||
[Define if std::chrono has year_month_day etc.]), |
||||
year_month_day=no) |
||||
AC_MSG_RESULT($year_month_day) |
||||
|
||||
|
||||
# Check for [[likely]] and [[unlikely]] attributes. |
||||
AC_MSG_CHECKING([attributes "likely" and "unlikely".]) |
||||
likely=yes |
||||
AC_COMPILE_IFELSE( |
||||
[read_test(likely.cxx)], |
||||
AC_DEFINE([PQXX_HAVE_LIKELY], 1, [Define if likely & unlikely work.]), |
||||
likely=no) |
||||
AC_MSG_RESULT($likely) |
||||
|
||||
|
||||
# It's mid-2019, and gcc's charconv supports integers but not yet floats. |
||||
# So for now, we test for int and float conversion... separately. |
||||
# |
||||
# It's worse for older clang versions, which compile the integer conversions |
||||
# but then fail at link time because of a missing symbol "__muloti4" with the |
||||
# "long long" version. I couldn't resolve that symbol by adding -lm either. |
||||
# So don't just compile these tests; link them as well. |
||||
AC_MSG_CHECKING([for C++17 charconv integer conversion]) |
||||
have_charconv_int=yes |
||||
AC_LINK_IFELSE( |
||||
[read_test(charconv_int.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_CHARCONV_INT], |
||||
1, |
||||
[Define if <charconv> supports integer conversion.]), |
||||
have_charconv_int=no) |
||||
AC_MSG_RESULT($have_charconv_int) |
||||
|
||||
AC_MSG_CHECKING([for C++17 charconv floating-point conversion]) |
||||
have_charconv_float=yes |
||||
AC_LINK_IFELSE( |
||||
[read_test(charconv_float.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_CHARCONV_FLOAT], |
||||
1, |
||||
[Define if <charconv> supports floating-point conversion.]), |
||||
have_charconv_float=no) |
||||
AC_MSG_RESULT($have_charconv_float) |
||||
|
||||
# As per #262, clang with libcxxrt does not support thread_local on non-POD |
||||
# objects. Luckily we can live without those, it's just less efficient. |
||||
AC_MSG_CHECKING([for full thread_local support]) |
||||
have_thread_local=yes |
||||
AC_LINK_IFELSE( |
||||
[read_test(thread_local.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_THREAD_LOCAL], |
||||
1, |
||||
[Define if thread_local is fully supported.]), |
||||
have_thread_local=no) |
||||
AC_MSG_RESULT($have_thread_local) |
||||
|
||||
AC_MSG_CHECKING([for std::this_thread::sleep_for]) |
||||
have_sleep_for=yes |
||||
AC_LINK_IFELSE( |
||||
[read_test(sleep_for.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_SLEEP_FOR], |
||||
1, |
||||
[Define if std::this_thread::sleep_for works.]), |
||||
have_sleep_for=no) |
||||
AC_MSG_RESULT($have_sleep_for) |
||||
|
||||
|
||||
AC_MSG_CHECKING([for std::cmp_greater, std::cmp_less_equal, etc]) |
||||
have_cmp=yes |
||||
AC_COMPILE_IFELSE( |
||||
[read_test(cmp.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_CMP], |
||||
1, |
||||
[Define if compiler has C++20 std::cmp_greater etc.]), |
||||
have_cmp=no) |
||||
AC_MSG_RESULT($have_cmp) |
||||
|
||||
|
||||
# Doing my own check for poll(). There's one built into autoconf-archive, but |
||||
# it produces warnings in C++ (about unnecessarily using "struct", and using 0 |
||||
# as a null pointer constant). In maintainer mode, those warnings turn into |
||||
# errors. |
||||
AC_MSG_CHECKING([for poll()]) |
||||
ax_cv_have_poll=yes |
||||
AC_LINK_IFELSE( |
||||
[read_test(poll.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_POLL], |
||||
1, |
||||
[Define if poll() is available.]), |
||||
ax_cv_have_poll=no) |
||||
AC_MSG_RESULT($ax_cv_have_poll) |
||||
|
||||
if test "$ax_cv_have_poll" != "yes" |
||||
then |
||||
# No poll(); we'll fall back to select(). |
||||
|
||||
# Some systems keep select() in a separate library which is not linked by |
||||
# default. See if we need one of those. |
||||
socklibok=no |
||||
AC_SEARCH_LIBS(select, socket nsl ws2_32 wsock32 winsock, [socklibok=yes]) |
||||
|
||||
# Microsoft proprietary libraries do not work with code that is generated with |
||||
# autoconf's SEARCH_LIBS macro, so we need to check manually and just use the |
||||
# first socket library available. |
||||
# We only do this if select() is not available by other means, to avoid picking |
||||
# up an unnecessary Windows compatibility library on a non-Windows system. |
||||
for l in ws2_32 wsock32 winsock |
||||
do |
||||
if test "${socklibok}" != "yes" |
||||
then |
||||
AC_CHECK_LIB($l,main,LIBS="$LIBS -l$l";[socklibok=yes]) |
||||
fi |
||||
done |
||||
|
||||
if test "${socklibok}" != "yes" |
||||
then |
||||
AC_MSG_ERROR([ |
||||
Could not figure out how to link a simple sockets-based program. Please read |
||||
the config.log file for more clues as to why this failed. |
||||
]) |
||||
fi |
||||
|
||||
fi # No poll() |
||||
|
||||
|
||||
# Find PostgreSQL includes and libraries |
||||
AC_PATH_PROG([PKG_CONFIG], [pkg-config]) |
||||
AC_PATH_PROGS(PG_CONFIG, pg_config) |
||||
|
||||
AC_ARG_WITH( |
||||
[postgres-include], |
||||
[AS_HELP_STRING( |
||||
[--with-postgres-include=DIR], |
||||
[Use PostgreSQL includes from DIR. Defaults to querying pg_config or pkg-config, whichever is available.])], |
||||
AS_IF( |
||||
[test "x$with_postgres_include" = "xyes"], |
||||
[with_postgres_include=""])) |
||||
|
||||
if test -n "$with_postgres_include" |
||||
then |
||||
POSTGRES_INCLUDE="-I$with_postgres_include" |
||||
else |
||||
if test -x "$PKG_CONFIG" || test -x "$PG_CONFIG" |
||||
then |
||||
# We should prefer pkg-config over pg_config, but there seems to be a |
||||
# problem in pkg-config 1.6.3. Until that's been resolved (#291), go |
||||
# with pg_config if we can. |
||||
if test -x "$PG_CONFIG" |
||||
then |
||||
# From pg_config we can either get the C compiler options used to |
||||
# compile postgres, which isn't quite what we want; or we can get |
||||
# the headers directory, without the full option. That's something |
||||
# we can work with. The compiler must support the "-I" option for |
||||
# that, but both scripts assume that anyway. |
||||
POSTGRES_INCLUDE="-I$($PG_CONFIG --includedir)" |
||||
else |
||||
# From pkg-config we can get the compiler options to extend the |
||||
# include path. We use that. |
||||
POSTGRES_INCLUDE=$($PKG_CONFIG libpq --cflags-only-I) |
||||
fi |
||||
AC_MSG_NOTICE([finding PostgreSQL headers using $POSTGRES_INCLUDE]) |
||||
else |
||||
POSTGRES_INCLUDE="" |
||||
|
||||
# We have nothing to tell us where the libpq headers are. That's fine |
||||
# if the compiler can find it, but if not, fail here. |
||||
AC_CHECK_HEADER( |
||||
[libpq-fe.h], |
||||
[], |
||||
[AC_MSG_ERROR([ |
||||
Can't find the main PostgreSQL client header, libpq-fe.h. Make sure that it |
||||
is installed, and either use the --with-postgres-include option or install |
||||
pkg-config. |
||||
])]) |
||||
fi |
||||
fi |
||||
AC_SUBST(POSTGRES_INCLUDE) |
||||
|
||||
# Add the compiler option so we can compile configure tests which rely on the |
||||
# libpq headers. |
||||
CPPFLAGS="$CPPFLAGS $POSTGRES_INCLUDE" |
||||
|
||||
|
||||
AC_ARG_WITH( |
||||
[postgres-lib], |
||||
[AS_HELP_STRING( |
||||
[--with-postgres-lib=DIR], |
||||
[Use PostgreSQL libraries from DIR. Defaults to querying pg_config.])], |
||||
AS_IF( |
||||
[test "x$with_postgres_lib" = "xyes"], |
||||
[with_postgres_lib=""])) |
||||
|
||||
# If no --with-postgres-lib was given, and we have pkg-config, use that. |
||||
AS_IF( |
||||
[test -z "$with_postgres_lib" -a -x "$PKG_CONFIG"], |
||||
[with_postgres_lib=$($PKG_CONFIG libpq --libs-only-L | sed 's/^-L//')]) |
||||
|
||||
# pg_config is deprecated, but for some users it may still provide the only |
||||
# right answer. For instance, `pkg-config` may not know where `libpq` is |
||||
# installed. |
||||
AS_IF( |
||||
[test -z "$with_postgres_lib" -a -x "$PG_CONFIG"], |
||||
[with_postgres_lib=$($PG_CONFIG --libdir)]) |
||||
|
||||
AS_IF( |
||||
[test -n "$with_postgres_lib"], |
||||
[AC_MSG_NOTICE([using PostgreSQL libraries at $with_postgres_lib])], |
||||
[AC_MSG_NOTICE([using PostgreSQL libraries in default location])]) |
||||
|
||||
AC_SUBST(with_postgres_lib) |
||||
|
||||
|
||||
AC_CHECK_HEADER( |
||||
[libpq-fe.h], |
||||
[], |
||||
[AC_MSG_ERROR([ |
||||
Can't find the main PostgreSQL client header, libpq-fe.h. Are you sure the |
||||
libpq headers are installed correctly, and that we've got the right path? |
||||
])]) |
||||
|
||||
|
||||
AC_MSG_CHECKING([for ability to compile source files using libpq]) |
||||
AC_COMPILE_IFELSE( |
||||
[AC_LANG_PROGRAM( |
||||
[[#include<libpq-fe.h>]], |
||||
[[PQexec(nullptr,"")]] |
||||
)], |
||||
[], |
||||
[AC_MSG_ERROR([ |
||||
Could not compile a call to a basic libpq function. There must be something |
||||
seriously wrong with the headers that "pg_config --includedir" or "pkg-config |
||||
libpq --cflags" pointed to; the contents of config.log may give you a clue |
||||
about the nature of the failure. |
||||
Source including the libpq header libpq-fe.h can be compiled, but a call to the |
||||
most basic libpq function PQexec() failed to compile successfully. This is the |
||||
litmus test for a working libpq. |
||||
])]) |
||||
AC_MSG_RESULT(yes) |
||||
|
||||
|
||||
if test "x${with_postgres_lib}" = "x"; then |
||||
with_postgres_libpath="" |
||||
else |
||||
with_postgres_libpath="-L${with_postgres_lib}" |
||||
fi |
||||
LDFLAGS="$LDFLAGS ${with_postgres_libpath}" |
||||
|
||||
AC_CHECK_LIB( |
||||
[pq], |
||||
[PQexec], |
||||
[], |
||||
[AC_MSG_ERROR([ |
||||
Did not find the PQexec() function in libpq. This is the litmus test for a |
||||
working libpq installation. |
||||
|
||||
A source file using the PQexec() function did compile without problems, and the |
||||
libpq library is available for linking, but for some reason a call to PQexec() |
||||
failed to link properly to the libpq library. This may be because the libpq |
||||
library file is damaged, or in some incorrect format, or if your libpq is much |
||||
more recent than libpqxx version $PQXX_ABI, perhaps libpq has undergone a |
||||
radical ABI change. |
||||
|
||||
The last parts of config.log may give you a clue as to what really went wrong, |
||||
but be warned that this is no easy reading. Look for the last error message |
||||
occurring in the file. |
||||
])], |
||||
${with_postgres_libpath}) |
||||
|
||||
|
||||
# PQencryptPasswordConn was added in postgres 10. |
||||
AC_MSG_CHECKING([for PQencryptPasswordConn]) |
||||
have_pqencryptpasswordconn=yes |
||||
AC_COMPILE_IFELSE( |
||||
[AC_LANG_PROGRAM( |
||||
[#include<libpq-fe.h>], |
||||
[ |
||||
extern PGconn *conn; |
||||
PQencryptPasswordConn( |
||||
conn, "pwd", "user", "scram-sha-256") |
||||
] |
||||
)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_PQENCRYPTPASSWORDCONN], |
||||
1, |
||||
[Define if libpq has PQencryptPasswordConn (since pg 10).]), |
||||
[have_pqencryptpasswordconn=no]) |
||||
AC_MSG_RESULT($have_pqencryptpasswordconn) |
||||
|
||||
|
||||
# "Pipeline mode" was introduced in libpq 14. |
||||
AC_MSG_CHECKING([for libpq pipeline mode]) |
||||
have_pq_pipeline=yes |
||||
AC_COMPILE_IFELSE( |
||||
[AC_LANG_PROGRAM( |
||||
[#include<libpq-fe.h>], |
||||
[ |
||||
extern PGconn *conn; |
||||
PQenterPipelineMode(conn) |
||||
] |
||||
)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_PQ_PIPELINE], |
||||
1, |
||||
[Define if libpq has pipeline mode (since pg 14).]), |
||||
[have_pq_pipeline=no]) |
||||
AC_MSG_RESULT($have_pq_pipeline) |
||||
|
||||
|
||||
AC_MSG_CHECKING([for usable std::filesystem::path]) |
||||
have_path=yes |
||||
AC_COMPILE_IFELSE( |
||||
[read_test(fs.cxx)], |
||||
AC_DEFINE( |
||||
[PQXX_HAVE_PATH], |
||||
1, |
||||
[Define if compiler has usable std::filesystem::path.]), |
||||
have_path=no) |
||||
AC_MSG_RESULT($have_path) |
||||
|
||||
|
||||
AC_MSG_CHECKING([whether we need a link option for <filesystem> support]) |
||||
LIBS_SAVE="$LIBS" |
||||
found_fslib=no |
||||
for l in '' '-lstdc++fs' '-lc++fs' |
||||
do |
||||
if test "$found_fslib" != "yes" |
||||
then |
||||
LIBS="$LIBS $l" |
||||
AC_LINK_IFELSE( |
||||
[read_test(need_fslib.cxx)], |
||||
[found_fslib=yes], |
||||
[LIBS="$LIBS_SAVE"]) |
||||
if test "$found_fslib" = "yes" |
||||
then |
||||
result_msg="$l" |
||||
# (And keep our current value of $LIBS.) |
||||
fi |
||||
fi |
||||
done |
||||
|
||||
if test "$found_fslib" != "yes" |
||||
then |
||||
AC_MSG_ERROR([ |
||||
There seems to be <filesystem> support, but I could not figure out now to make |
||||
it work. You'll have to add set your own build options for this. |
||||
]) |
||||
fi |
||||
AC_MSG_RESULT($result_msg) |
||||
|
||||
|
||||
# Remove redundant occurrances of -lpq |
||||
LIBS=[$(echo "$LIBS" | sed -e 's/-lpq * -lpq\>/-lpq/g')] |
||||
|
||||
|
||||
AC_MSG_CHECKING([that type of libpq's Oid is as expected]) |
||||
AC_COMPILE_IFELSE( |
||||
[AC_LANG_PROGRAM( |
||||
[ |
||||
#include<libpq-fe.h> |
||||
#include"${srcdir}/include/pqxx/internal/libpq-forward.hxx" |
||||
extern void f(pqxx::oid&); |
||||
], |
||||
[Oid o;f(o)], |
||||
)], |
||||
[], |
||||
[AC_MSG_ERROR([ |
||||
The Oid typedef in libpq has changed. Please notify the libpqxx authors of the |
||||
change! |
||||
])]) |
||||
AC_MSG_RESULT(yes) |
||||
|
||||
|
||||
AC_PROG_MAKE_SET |
||||
|
||||
AC_CONFIG_FILES([ |
||||
Makefile config/Makefile doc/Makefile doc/Doxyfile src/Makefile |
||||
test/Makefile tools/Makefile include/Makefile include/pqxx/Makefile |
||||
libpqxx.pc]) |
||||
|
||||
|
||||
AC_CONFIG_COMMANDS([configitems], ["${srcdir}/tools/splitconfig" "${srcdir}"]) |
||||
|
||||
AC_OUTPUT(compile_flags) |
||||
@ -0,0 +1,50 @@
|
||||
find_program(HAVE_DOXYGEN doxygen) |
||||
|
||||
if(NOT HAVE_DOXYGEN) |
||||
message(FATAL_ERROR "***************************************************** |
||||
Doxygen not found. |
||||
Install it, or configure with -DBUILD_DOC=OFF |
||||
*****************************************************" |
||||
) |
||||
endif() |
||||
|
||||
set(PQXXVERSION "${CMAKE_PROJECT_VERSION}") |
||||
set(top_srcdir "${PROJECT_SOURCE_DIR}") |
||||
set(PQXX_ABI "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") |
||||
set(PQXX_MAJOR "${PROJECT_VERSION_MAJOR}") |
||||
set(PQXX_MINOR "${PROJECT_VERSION_MINOR}") |
||||
|
||||
find_program(HAVE_DOT dot) |
||||
if(HAVE_DOT) |
||||
set(HAVE_DOT YES) |
||||
else() |
||||
set(HAVE_DOT NO) |
||||
endif() |
||||
|
||||
configure_file(Doxyfile.in Doxyfile) |
||||
|
||||
if(HAVE_DOXYGEN) |
||||
file( |
||||
GLOB DOXYGEN_SOURCES |
||||
"${PROJECT_SOURCE_DIR}/include/pqxx/*.hxx" |
||||
"${PROJECT_SOURCE_DIR}/include/pqxx/doc/*.md" |
||||
"${PROJECT_SOURCE_DIR}/*.cxx" |
||||
) |
||||
set(DOXYGEN_STAMP_FILE "${CMAKE_CURRENT_BINARY_DIR}/doxygen.stamp") |
||||
add_custom_command(OUTPUT ${DOXYGEN_STAMP_FILE} |
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/html |
||||
COMMAND doxygen Doxyfile |
||||
COMMAND ${CMAKE_COMMAND} -E touch ${DOXYGEN_STAMP_FILE} |
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile ${DOXYGEN_SOURCES} |
||||
COMMENT "Generate API documentation" |
||||
VERBATIM |
||||
) |
||||
add_custom_target(doxygen ALL |
||||
DEPENDS ${DOXYGEN_STAMP_FILE} |
||||
SOURCES ${DOXYGEN_SOURCES} |
||||
) |
||||
install( |
||||
DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html |
||||
DESTINATION ${CMAKE_INSTALL_DOCDIR}/html |
||||
) |
||||
endif() |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,51 @@
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
maintainer-clean-local: |
||||
$(RM) -rf html
|
||||
$(RM) reference-stamp
|
||||
$(MKDIR) html
|
||||
|
||||
EXTRA_DIST= Doxyfile.in libpqxx.xml reference-stamp
|
||||
|
||||
all-local: docs |
||||
|
||||
if BUILD_REFERENCE |
||||
DOCS = reference
|
||||
else |
||||
DOCS =
|
||||
endif |
||||
|
||||
if MAINTAINER_MODE |
||||
REFERENCE_STAMP_DEP = ../src/libpqxx.la
|
||||
else |
||||
REFERENCE_STAMP_DEP =
|
||||
endif |
||||
|
||||
docs: $(DOCS) |
||||
|
||||
reference: reference-stamp |
||||
reference-stamp: Doxyfile.in $(REFERENCE_STAMP_DEP) |
||||
if [ -x "$(DOXYGEN)" ]; then \
|
||||
$(MKDIR_P) html; \
|
||||
$(DOXYGEN) Doxyfile; \
|
||||
touch $@; \
|
||||
else \
|
||||
echo >&2; \
|
||||
echo >&2 "*****************************************************"; \
|
||||
echo >&2; \
|
||||
echo >&2 "Doxygen not found."; \
|
||||
echo >&2 "Install it, or configure with --disable-documentation"; \
|
||||
echo >&2; \
|
||||
echo >&2 "*****************************************************"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
../src/libpqxx.la: |
||||
cd ../src; \
|
||||
$(MAKE) libpqxx.la
|
||||
|
||||
|
||||
dist-hook: reference |
||||
if [ -d $(srcdir)/html ]; then \
|
||||
cp -pR html $(distdir)/ ; \
|
||||
fi
|
||||
@ -0,0 +1,507 @@
|
||||
# Makefile.in generated by automake 1.16.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@ |
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
} |
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
subdir = doc
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \
|
||||
$(top_srcdir)/config/m4/ltoptions.m4 \
|
||||
$(top_srcdir)/config/m4/ltsugar.m4 \
|
||||
$(top_srcdir)/config/m4/ltversion.m4 \
|
||||
$(top_srcdir)/config/m4/lt~obsolete.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/include/pqxx/config.h
|
||||
CONFIG_CLEAN_FILES = Doxyfile
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
am__DIST_COMMON = $(srcdir)/Doxyfile.in $(srcdir)/Makefile.in \
|
||||
$(top_srcdir)/config/mkinstalldirs
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CSCOPE = @CSCOPE@
|
||||
CTAGS = @CTAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DOXYGEN = @DOXYGEN@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
HAVE_DOT = @HAVE_DOT@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR = @MKDIR@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PG_CONFIG = @PG_CONFIG@
|
||||
PKG_CONFIG = @PKG_CONFIG@
|
||||
POSTGRES_INCLUDE = @POSTGRES_INCLUDE@
|
||||
PQXXVERSION = @PQXXVERSION@
|
||||
PQXX_ABI = @PQXX_ABI@
|
||||
RANLIB = @RANLIB@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
runstatedir = @runstatedir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
with_postgres_lib = @with_postgres_lib@
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
EXTRA_DIST = Doxyfile.in libpqxx.xml reference-stamp
|
||||
@BUILD_REFERENCE_FALSE@DOCS =
|
||||
@BUILD_REFERENCE_TRUE@DOCS = reference
|
||||
@MAINTAINER_MODE_FALSE@REFERENCE_STAMP_DEP =
|
||||
@MAINTAINER_MODE_TRUE@REFERENCE_STAMP_DEP = ../src/libpqxx.la
|
||||
all: all-am |
||||
|
||||
.SUFFIXES: |
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) |
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu doc/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status |
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) |
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) |
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) |
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps): |
||||
Doxyfile: $(top_builddir)/config.status $(srcdir)/Doxyfile.in |
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||||
|
||||
mostlyclean-libtool: |
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool: |
||||
-rm -rf .libs _libs
|
||||
tags TAGS: |
||||
|
||||
ctags CTAGS: |
||||
|
||||
cscope cscopelist: |
||||
|
||||
distdir: $(BUILT_SOURCES) |
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
distdir-am: $(DISTFILES) |
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$(top_distdir)" distdir="$(distdir)" \
|
||||
dist-hook
|
||||
check-am: all-am |
||||
check: check-am |
||||
all-am: Makefile all-local |
||||
installdirs: |
||||
install: install-am |
||||
install-exec: install-exec-am |
||||
install-data: install-data-am |
||||
uninstall: uninstall-am |
||||
|
||||
install-am: all-am |
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am |
||||
install-strip: |
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic: |
||||
|
||||
clean-generic: |
||||
|
||||
distclean-generic: |
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic: |
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
clean: clean-am |
||||
|
||||
clean-am: clean-generic clean-libtool mostlyclean-am |
||||
|
||||
distclean: distclean-am |
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic |
||||
|
||||
dvi: dvi-am |
||||
|
||||
dvi-am: |
||||
|
||||
html: html-am |
||||
|
||||
html-am: |
||||
|
||||
info: info-am |
||||
|
||||
info-am: |
||||
|
||||
install-data-am: |
||||
|
||||
install-dvi: install-dvi-am |
||||
|
||||
install-dvi-am: |
||||
|
||||
install-exec-am: |
||||
|
||||
install-html: install-html-am |
||||
|
||||
install-html-am: |
||||
|
||||
install-info: install-info-am |
||||
|
||||
install-info-am: |
||||
|
||||
install-man: |
||||
|
||||
install-pdf: install-pdf-am |
||||
|
||||
install-pdf-am: |
||||
|
||||
install-ps: install-ps-am |
||||
|
||||
install-ps-am: |
||||
|
||||
installcheck-am: |
||||
|
||||
maintainer-clean: maintainer-clean-am |
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic \
|
||||
maintainer-clean-local
|
||||
|
||||
mostlyclean: mostlyclean-am |
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool |
||||
|
||||
pdf: pdf-am |
||||
|
||||
pdf-am: |
||||
|
||||
ps: ps-am |
||||
|
||||
ps-am: |
||||
|
||||
uninstall-am: |
||||
|
||||
.MAKE: install-am install-strip |
||||
|
||||
.PHONY: all all-am all-local check check-am clean clean-generic \
|
||||
clean-libtool cscopelist-am ctags-am dist-hook distclean \
|
||||
distclean-generic distclean-libtool distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-html install-html-am install-info \
|
||||
install-info-am install-man install-pdf install-pdf-am \
|
||||
install-ps install-ps-am install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic maintainer-clean-local mostlyclean \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags-am uninstall uninstall-am
|
||||
|
||||
.PRECIOUS: Makefile |
||||
|
||||
|
||||
maintainer-clean-local: |
||||
$(RM) -rf html
|
||||
$(RM) reference-stamp
|
||||
$(MKDIR) html
|
||||
|
||||
all-local: docs |
||||
|
||||
docs: $(DOCS) |
||||
|
||||
reference: reference-stamp |
||||
reference-stamp: Doxyfile.in $(REFERENCE_STAMP_DEP) |
||||
if [ -x "$(DOXYGEN)" ]; then \
|
||||
$(MKDIR_P) html; \
|
||||
$(DOXYGEN) Doxyfile; \
|
||||
touch $@; \
|
||||
else \
|
||||
echo >&2; \
|
||||
echo >&2 "*****************************************************"; \
|
||||
echo >&2; \
|
||||
echo >&2 "Doxygen not found."; \
|
||||
echo >&2 "Install it, or configure with --disable-documentation"; \
|
||||
echo >&2; \
|
||||
echo >&2 "*****************************************************"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
../src/libpqxx.la: |
||||
cd ../src; \
|
||||
$(MAKE) libpqxx.la
|
||||
|
||||
dist-hook: reference |
||||
if [ -d $(srcdir)/html ]; then \
|
||||
cp -pR html $(distdir)/ ; \
|
||||
fi
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT: |
||||
@ -0,0 +1,199 @@
|
||||
# -*- coding: utf-8 -*- |
||||
""" |
||||
libpqxx documentation build configuration file, created by |
||||
sphinx-quickstart on Sun Dec 3 00:43:33 2017. |
||||
|
||||
This file is execfile()d with the current directory set to its containing dir. |
||||
|
||||
All configuration values have a default; values that are commented out serve |
||||
to show the default. |
||||
""" |
||||
|
||||
import codecs |
||||
import os |
||||
from subprocess import check_call |
||||
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory, |
||||
# add these directories to sys.path here. If the directory is relative to the |
||||
# documentation root, use os.path.abspath to make it absolute, like shown here. |
||||
# |
||||
# import sys |
||||
# sys.path.insert(0, os.path.abspath(os.path.curdir)) |
||||
|
||||
|
||||
read_the_docs_build = os.environ.get('READTHEDOCS') == 'True' |
||||
|
||||
if read_the_docs_build: |
||||
check_call( |
||||
[os.path.join(os.path.curdir, 'configure'), 'CXXFLAGS=-std=c++17 -O0'], |
||||
cwd=os.path.pardir) |
||||
check_call('doxygen', cwd=os.path.join(os.path.pardir, 'doc')) |
||||
|
||||
# -- General configuration ------------------------------------------------ |
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here. |
||||
# |
||||
# needs_sphinx = '1.0' |
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be |
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom |
||||
# ones. |
||||
extensions = [ |
||||
'sphinx.ext.autodoc', |
||||
'sphinx.ext.doctest', |
||||
] |
||||
|
||||
# Add any paths that contain templates here, relative to this directory. |
||||
templates_path = ['_templates'] |
||||
|
||||
# The suffix(es) of source filenames. |
||||
# You can specify multiple suffix as a list of string: |
||||
# |
||||
# source_suffix = ['.rst', '.md'] |
||||
source_suffix = '.rst' |
||||
|
||||
# The master toctree document. |
||||
master_doc = 'index' |
||||
|
||||
# General information about the project. |
||||
project = u'libpqxx' |
||||
copyright = u'2000-2022, Jeroen T. Vermeulen' |
||||
author = u'Jeroen T. Vermeulen' |
||||
|
||||
|
||||
def read_version(): |
||||
"""Return version number as specified in the VERSION file.""" |
||||
version_file = os.path.join( |
||||
os.path.dirname(__file__), os.path.pardir, 'VERSION') |
||||
with codecs.open(version_file, encoding='ascii') as stream: |
||||
return stream.read().strip() |
||||
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for |
||||
# |version| and |release|, also used in various other places throughout the |
||||
# built documents. |
||||
# |
||||
# The full version, including alpha/beta/rc tags. |
||||
release = read_version() |
||||
|
||||
# The short X.Y version. |
||||
version = '.'.join(release.split('.')[:2]) |
||||
|
||||
html_title = "libpqxx %s" % release |
||||
html_short_title = "libpqxx" |
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation |
||||
# for a list of supported languages. |
||||
# |
||||
# This is also used if you do content translation via gettext catalogs. |
||||
# Usually you set "language" from the command line for these cases. |
||||
language = None |
||||
|
||||
# List of patterns, relative to source directory, that match files and |
||||
# directories to ignore when looking for source files. |
||||
# This patterns also effect to html_static_path and html_extra_path |
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] |
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use. |
||||
pygments_style = 'sphinx' |
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing. |
||||
todo_include_todos = False |
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------- |
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for |
||||
# a list of builtin themes. |
||||
# |
||||
html_theme = 'alabaster' |
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme |
||||
# further. For a list of options available for each theme, see the |
||||
# documentation. |
||||
# |
||||
# html_theme_options = {} |
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here, |
||||
# relative to this directory. They are copied after the builtin static files, |
||||
# so a file named "default.css" will overwrite the builtin "default.css". |
||||
html_static_path = ['_static'] |
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names |
||||
# to template names. |
||||
# |
||||
# This is required for the alabaster theme |
||||
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars |
||||
html_sidebars = { |
||||
'**': [ |
||||
'relations.html', # needs 'show_related': True theme option to display |
||||
'searchbox.html', |
||||
] |
||||
} |
||||
|
||||
# Looks like the setup is that our build generates the HTML itself, and then |
||||
# has readthedocs copy the full generated HTML tree to the output directory. |
||||
# |
||||
# Problem is, that doesn't seem to be working now. This needs debugging. |
||||
html_extra_path = ["html"] |
||||
|
||||
# -- Options for HTMLHelp output ------------------------------------------ |
||||
|
||||
# Output file base name for HTML help builder. |
||||
htmlhelp_basename = 'libpqxxdoc' |
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------- |
||||
|
||||
latex_elements = { |
||||
# The paper size ('letterpaper' or 'a4paper'). |
||||
# |
||||
# 'papersize': 'letterpaper', |
||||
|
||||
# The font size ('10pt', '11pt' or '12pt'). |
||||
# |
||||
# 'pointsize': '10pt', |
||||
|
||||
# Additional stuff for the LaTeX preamble. |
||||
# |
||||
# 'preamble': '', |
||||
|
||||
# Latex figure (float) alignment |
||||
# |
||||
# 'figure_align': 'htbp', |
||||
} |
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples |
||||
# (source start file, target name, title, |
||||
# author, documentclass [howto, manual, or own class]). |
||||
latex_documents = [ |
||||
( |
||||
master_doc, |
||||
'libpqxx.tex', |
||||
u'libpqxx Documentation', |
||||
u'Jeroen T. Vermeulen', |
||||
'manual', |
||||
), |
||||
] |
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------- |
||||
|
||||
# One entry per manual page. List of tuples |
||||
# (source start file, name, description, authors, manual section). |
||||
man_pages = [ |
||||
(master_doc, 'libpqxx', u'libpqxx Documentation', [author], 1) |
||||
] |
||||
|
||||
|
||||
# -- Options for Texinfo output ------------------------------------------- |
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples |
||||
# (source start file, target name, title, author, |
||||
# dir menu entry, description, category) |
||||
texinfo_documents = [ |
||||
(master_doc, 'libpqxx', u'libpqxx Documentation', |
||||
author, 'libpqxx', "C++ client API for PostgreSQL.", |
||||
'Miscellaneous'), |
||||
] |
||||
@ -0,0 +1,20 @@
|
||||
.. x documentation master file, created by |
||||
sphinx-quickstart on Sun Dec 3 01:30:12 2017. |
||||
You can adapt this file completely to your liking, but it should at least |
||||
contain the root `toctree` directive. |
||||
|
||||
libpqxx |
||||
======= |
||||
|
||||
.. toctree:: |
||||
:maxdepth: 2 |
||||
:caption: Contents: |
||||
|
||||
|
||||
|
||||
Indices and tables |
||||
================== |
||||
|
||||
* :ref:`genindex` |
||||
* :ref:`modindex` |
||||
* :ref:`search` |
||||
@ -0,0 +1,68 @@
|
||||
# ############################################################################## |
||||
# AUTOMATICALLY GENERATED FILE -- DO NOT EDIT. |
||||
# |
||||
# This file is generated automatically by libpqxx's template2mak.py script, and |
||||
# will be rewritten from time to time. |
||||
# |
||||
# If you modify this file, chances are your modifications will be lost. |
||||
# |
||||
# The template2mak.py script should be available in the tools directory of the |
||||
# libpqxx source archive. |
||||
# |
||||
# Generated from template './include/CMakeLists.txt.template'. |
||||
# ############################################################################## |
||||
install( |
||||
DIRECTORY pqxx "${PROJECT_BINARY_DIR}/include/pqxx" |
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} |
||||
FILES_MATCHING |
||||
# For each X.hxx, install both X.hxx itself and plain X. |
||||
PATTERN *.hxx |
||||
# TODO: Is there any way to do this with CMake's globbing? |
||||
PATTERN array |
||||
PATTERN binarystring |
||||
PATTERN blob |
||||
PATTERN composite |
||||
PATTERN connection |
||||
PATTERN cursor |
||||
PATTERN dbtransaction |
||||
PATTERN errorhandler |
||||
PATTERN except |
||||
PATTERN field |
||||
PATTERN isolation |
||||
PATTERN largeobject |
||||
PATTERN nontransaction |
||||
PATTERN notification |
||||
PATTERN params |
||||
PATTERN pipeline |
||||
PATTERN prepared_statement |
||||
PATTERN range |
||||
PATTERN result |
||||
PATTERN robusttransaction |
||||
PATTERN row |
||||
PATTERN separated_list |
||||
PATTERN strconv |
||||
PATTERN stream_from |
||||
PATTERN stream_to |
||||
PATTERN subtransaction |
||||
PATTERN time |
||||
PATTERN transaction |
||||
PATTERN transaction_base |
||||
PATTERN transaction_focus |
||||
PATTERN transactor |
||||
PATTERN types |
||||
PATTERN util |
||||
PATTERN version |
||||
PATTERN zview |
||||
PATTERN internal/*.hxx |
||||
PATTERN internal/gates/*.hxx |
||||
PATTERN config-public-compiler.h |
||||
PATTERN pqxx |
||||
PATTERN doc EXCLUDE |
||||
) |
||||
|
||||
install( |
||||
DIRECTORY pqxx/doc/ |
||||
DESTINATION ${CMAKE_INSTALL_DOCDIR} |
||||
FILES_MATCHING |
||||
PATTERN *.md |
||||
) |
||||
@ -0,0 +1,23 @@
|
||||
install( |
||||
DIRECTORY pqxx "${PROJECT_BINARY_DIR}/include/pqxx" |
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} |
||||
FILES_MATCHING |
||||
# For each X.hxx, install both X.hxx itself and plain X. |
||||
PATTERN *.hxx |
||||
# TODO: Is there any way to do this with CMake's globbing? |
||||
###MAKTEMPLATE:FOREACH include/pqxx/*.hxx |
||||
PATTERN ###BASENAME### |
||||
###MAKTEMPLATE:ENDFOREACH |
||||
PATTERN internal/*.hxx |
||||
PATTERN internal/gates/*.hxx |
||||
PATTERN config-public-compiler.h |
||||
PATTERN pqxx |
||||
PATTERN doc EXCLUDE |
||||
) |
||||
|
||||
install( |
||||
DIRECTORY pqxx/doc/ |
||||
DESTINATION ${CMAKE_INSTALL_DOCDIR} |
||||
FILES_MATCHING |
||||
PATTERN *.md |
||||
) |
||||
@ -0,0 +1,79 @@
|
||||
SUBDIRS = pqxx
|
||||
|
||||
nobase_include_HEADERS= pqxx/pqxx \
|
||||
pqxx/array pqxx/array.hxx \
|
||||
pqxx/binarystring pqxx/binarystring.hxx \
|
||||
pqxx/blob pqxx/blob.hxx \
|
||||
pqxx/composite pqxx/composite.hxx \
|
||||
pqxx/connection pqxx/connection.hxx \
|
||||
pqxx/cursor pqxx/cursor.hxx \
|
||||
pqxx/dbtransaction pqxx/dbtransaction.hxx \
|
||||
pqxx/errorhandler pqxx/errorhandler.hxx \
|
||||
pqxx/except pqxx/except.hxx \
|
||||
pqxx/field pqxx/field.hxx \
|
||||
pqxx/isolation pqxx/isolation.hxx \
|
||||
pqxx/largeobject pqxx/largeobject.hxx \
|
||||
pqxx/nontransaction pqxx/nontransaction.hxx \
|
||||
pqxx/notification pqxx/notification.hxx \
|
||||
pqxx/params pqxx/params.hxx \
|
||||
pqxx/pipeline pqxx/pipeline.hxx \
|
||||
pqxx/prepared_statement pqxx/prepared_statement.hxx \
|
||||
pqxx/range pqxx/range.hxx \
|
||||
pqxx/result pqxx/result.hxx \
|
||||
pqxx/robusttransaction pqxx/robusttransaction.hxx \
|
||||
pqxx/separated_list pqxx/separated_list.hxx \
|
||||
pqxx/strconv pqxx/strconv.hxx \
|
||||
pqxx/stream_from pqxx/stream_from.hxx \
|
||||
pqxx/stream_to pqxx/stream_to.hxx \
|
||||
pqxx/subtransaction pqxx/subtransaction.hxx \
|
||||
pqxx/time pqxx/time.hxx \
|
||||
pqxx/transaction pqxx/transaction.hxx \
|
||||
pqxx/transaction_base pqxx/transaction_base.hxx \
|
||||
pqxx/transaction_focus pqxx/transaction_focus.hxx \
|
||||
pqxx/transactor pqxx/transactor.hxx \
|
||||
pqxx/row pqxx/row.hxx \
|
||||
pqxx/util pqxx/util.hxx \
|
||||
pqxx/types pqxx/types.hxx \
|
||||
pqxx/zview pqxx/zview.hxx \
|
||||
pqxx/version pqxx/version.hxx \
|
||||
pqxx/internal/array-composite.hxx \
|
||||
pqxx/internal/callgate.hxx \
|
||||
pqxx/internal/concat.hxx \
|
||||
pqxx/internal/conversions.hxx \
|
||||
pqxx/internal/encoding_group.hxx \
|
||||
pqxx/internal/encodings.hxx \
|
||||
pqxx/internal/header-pre.hxx \
|
||||
pqxx/internal/header-post.hxx \
|
||||
pqxx/internal/ignore-deprecated-post.hxx \
|
||||
pqxx/internal/ignore-deprecated-pre.hxx \
|
||||
pqxx/internal/libpq-forward.hxx \
|
||||
pqxx/internal/result_iter.hxx \
|
||||
pqxx/internal/result_iterator.hxx \
|
||||
pqxx/internal/sql_cursor.hxx \
|
||||
pqxx/internal/statement_parameters.hxx \
|
||||
pqxx/internal/stream_iterator.hxx \
|
||||
pqxx/internal/wait.hxx \
|
||||
pqxx/internal/gates/connection-errorhandler.hxx \
|
||||
pqxx/internal/gates/connection-largeobject.hxx \
|
||||
pqxx/internal/gates/connection-notification_receiver.hxx \
|
||||
pqxx/internal/gates/connection-pipeline.hxx \
|
||||
pqxx/internal/gates/connection-sql_cursor.hxx \
|
||||
pqxx/internal/gates/connection-transaction.hxx \
|
||||
pqxx/internal/gates/errorhandler-connection.hxx \
|
||||
pqxx/internal/gates/icursorstream-icursor_iterator.hxx \
|
||||
pqxx/internal/gates/icursor_iterator-icursorstream.hxx \
|
||||
pqxx/internal/gates/result-connection.hxx \
|
||||
pqxx/internal/gates/result-creation.hxx \
|
||||
pqxx/internal/gates/result-pipeline.hxx \
|
||||
pqxx/internal/gates/result-sql_cursor.hxx \
|
||||
pqxx/internal/gates/transaction-sql_cursor.hxx \
|
||||
pqxx/internal/gates/transaction-transaction_focus.hxx
|
||||
|
||||
|
||||
nobase_nodist_include_HEADERS = \
|
||||
pqxx/config-public-compiler.h
|
||||
|
||||
EXTRA_DIST = \
|
||||
pqxx/doc/*.md \
|
||||
pqxx/doc/mainpage.md.template \
|
||||
pqxx/version.hxx.template
|
||||
@ -0,0 +1,802 @@
|
||||
# Makefile.in generated by automake 1.16.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@ |
||||
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
} |
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
subdir = include
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \
|
||||
$(top_srcdir)/config/m4/ltoptions.m4 \
|
||||
$(top_srcdir)/config/m4/ltsugar.m4 \
|
||||
$(top_srcdir)/config/m4/ltversion.m4 \
|
||||
$(top_srcdir)/config/m4/lt~obsolete.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(nobase_include_HEADERS) \
|
||||
$(am__DIST_COMMON)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/include/pqxx/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
|
||||
ctags-recursive dvi-recursive html-recursive info-recursive \
|
||||
install-data-recursive install-dvi-recursive \
|
||||
install-exec-recursive install-html-recursive \
|
||||
install-info-recursive install-pdf-recursive \
|
||||
install-ps-recursive install-recursive installcheck-recursive \
|
||||
installdirs-recursive pdf-recursive ps-recursive \
|
||||
tags-recursive uninstall-recursive
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
test -z "$$files" \
|
||||
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
am__installdirs = "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"
|
||||
HEADERS = $(nobase_include_HEADERS) $(nobase_nodist_include_HEADERS)
|
||||
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
|
||||
distclean-recursive maintainer-clean-recursive
|
||||
am__recursive_targets = \
|
||||
$(RECURSIVE_TARGETS) \
|
||||
$(RECURSIVE_CLEAN_TARGETS) \
|
||||
$(am__extra_recursive_targets)
|
||||
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
|
||||
distdir distdir-am
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
am__uniquify_input = $(AWK) '\
|
||||
BEGIN { nonempty = 0; } \
|
||||
{ items[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in items) print i; }; } \
|
||||
' |
||||
# Make sure the list of sources is unique. This is necessary because,
|
||||
# e.g., the same source file might be shared among _SOURCES variables
|
||||
# for different programs/libraries.
|
||||
am__define_uniq_tagged_files = \
|
||||
list='$(am__tagged_files)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
DIST_SUBDIRS = $(SUBDIRS)
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in \
|
||||
$(top_srcdir)/config/mkinstalldirs
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
am__relativize = \
|
||||
dir0=`pwd`; \
|
||||
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
|
||||
sed_rest='s,^[^/]*/*,,'; \
|
||||
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
|
||||
sed_butlast='s,/*[^/]*$$,,'; \
|
||||
while test -n "$$dir1"; do \
|
||||
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
|
||||
if test "$$first" != "."; then \
|
||||
if test "$$first" = ".."; then \
|
||||
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
|
||||
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
|
||||
else \
|
||||
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
|
||||
if test "$$first2" = "$$first"; then \
|
||||
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
|
||||
else \
|
||||
dir2="../$$dir2"; \
|
||||
fi; \
|
||||
dir0="$$dir0"/"$$first"; \
|
||||
fi; \
|
||||
fi; \
|
||||
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
|
||||
done; \
|
||||
reldir="$$dir2"
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CSCOPE = @CSCOPE@
|
||||
CTAGS = @CTAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DOXYGEN = @DOXYGEN@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
HAVE_DOT = @HAVE_DOT@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR = @MKDIR@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PG_CONFIG = @PG_CONFIG@
|
||||
PKG_CONFIG = @PKG_CONFIG@
|
||||
POSTGRES_INCLUDE = @POSTGRES_INCLUDE@
|
||||
PQXXVERSION = @PQXXVERSION@
|
||||
PQXX_ABI = @PQXX_ABI@
|
||||
RANLIB = @RANLIB@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
runstatedir = @runstatedir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
with_postgres_lib = @with_postgres_lib@
|
||||
SUBDIRS = pqxx
|
||||
nobase_include_HEADERS = pqxx/pqxx \
|
||||
pqxx/array pqxx/array.hxx \
|
||||
pqxx/binarystring pqxx/binarystring.hxx \
|
||||
pqxx/blob pqxx/blob.hxx \
|
||||
pqxx/composite pqxx/composite.hxx \
|
||||
pqxx/connection pqxx/connection.hxx \
|
||||
pqxx/cursor pqxx/cursor.hxx \
|
||||
pqxx/dbtransaction pqxx/dbtransaction.hxx \
|
||||
pqxx/errorhandler pqxx/errorhandler.hxx \
|
||||
pqxx/except pqxx/except.hxx \
|
||||
pqxx/field pqxx/field.hxx \
|
||||
pqxx/isolation pqxx/isolation.hxx \
|
||||
pqxx/largeobject pqxx/largeobject.hxx \
|
||||
pqxx/nontransaction pqxx/nontransaction.hxx \
|
||||
pqxx/notification pqxx/notification.hxx \
|
||||
pqxx/params pqxx/params.hxx \
|
||||
pqxx/pipeline pqxx/pipeline.hxx \
|
||||
pqxx/prepared_statement pqxx/prepared_statement.hxx \
|
||||
pqxx/range pqxx/range.hxx \
|
||||
pqxx/result pqxx/result.hxx \
|
||||
pqxx/robusttransaction pqxx/robusttransaction.hxx \
|
||||
pqxx/separated_list pqxx/separated_list.hxx \
|
||||
pqxx/strconv pqxx/strconv.hxx \
|
||||
pqxx/stream_from pqxx/stream_from.hxx \
|
||||
pqxx/stream_to pqxx/stream_to.hxx \
|
||||
pqxx/subtransaction pqxx/subtransaction.hxx \
|
||||
pqxx/time pqxx/time.hxx \
|
||||
pqxx/transaction pqxx/transaction.hxx \
|
||||
pqxx/transaction_base pqxx/transaction_base.hxx \
|
||||
pqxx/transaction_focus pqxx/transaction_focus.hxx \
|
||||
pqxx/transactor pqxx/transactor.hxx \
|
||||
pqxx/row pqxx/row.hxx \
|
||||
pqxx/util pqxx/util.hxx \
|
||||
pqxx/types pqxx/types.hxx \
|
||||
pqxx/zview pqxx/zview.hxx \
|
||||
pqxx/version pqxx/version.hxx \
|
||||
pqxx/internal/array-composite.hxx \
|
||||
pqxx/internal/callgate.hxx \
|
||||
pqxx/internal/concat.hxx \
|
||||
pqxx/internal/conversions.hxx \
|
||||
pqxx/internal/encoding_group.hxx \
|
||||
pqxx/internal/encodings.hxx \
|
||||
pqxx/internal/header-pre.hxx \
|
||||
pqxx/internal/header-post.hxx \
|
||||
pqxx/internal/ignore-deprecated-post.hxx \
|
||||
pqxx/internal/ignore-deprecated-pre.hxx \
|
||||
pqxx/internal/libpq-forward.hxx \
|
||||
pqxx/internal/result_iter.hxx \
|
||||
pqxx/internal/result_iterator.hxx \
|
||||
pqxx/internal/sql_cursor.hxx \
|
||||
pqxx/internal/statement_parameters.hxx \
|
||||
pqxx/internal/stream_iterator.hxx \
|
||||
pqxx/internal/wait.hxx \
|
||||
pqxx/internal/gates/connection-errorhandler.hxx \
|
||||
pqxx/internal/gates/connection-largeobject.hxx \
|
||||
pqxx/internal/gates/connection-notification_receiver.hxx \
|
||||
pqxx/internal/gates/connection-pipeline.hxx \
|
||||
pqxx/internal/gates/connection-sql_cursor.hxx \
|
||||
pqxx/internal/gates/connection-transaction.hxx \
|
||||
pqxx/internal/gates/errorhandler-connection.hxx \
|
||||
pqxx/internal/gates/icursorstream-icursor_iterator.hxx \
|
||||
pqxx/internal/gates/icursor_iterator-icursorstream.hxx \
|
||||
pqxx/internal/gates/result-connection.hxx \
|
||||
pqxx/internal/gates/result-creation.hxx \
|
||||
pqxx/internal/gates/result-pipeline.hxx \
|
||||
pqxx/internal/gates/result-sql_cursor.hxx \
|
||||
pqxx/internal/gates/transaction-sql_cursor.hxx \
|
||||
pqxx/internal/gates/transaction-transaction_focus.hxx
|
||||
|
||||
nobase_nodist_include_HEADERS = \
|
||||
pqxx/config-public-compiler.h
|
||||
|
||||
EXTRA_DIST = \
|
||||
pqxx/doc/*.md \
|
||||
pqxx/doc/mainpage.md.template \
|
||||
pqxx/version.hxx.template
|
||||
|
||||
all: all-recursive |
||||
|
||||
.SUFFIXES: |
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) |
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu include/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status |
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) |
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) |
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) |
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps): |
||||
|
||||
mostlyclean-libtool: |
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool: |
||||
-rm -rf .libs _libs
|
||||
install-nobase_includeHEADERS: $(nobase_include_HEADERS) |
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
|
||||
fi; \
|
||||
$(am__nobase_list) | while read dir files; do \
|
||||
xfiles=; for file in $$files; do \
|
||||
if test -f "$$file"; then xfiles="$$xfiles $$file"; \
|
||||
else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
|
||||
test -z "$$xfiles" || { \
|
||||
test "x$$dir" = x. || { \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \
|
||||
echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \
|
||||
$(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \
|
||||
done
|
||||
|
||||
uninstall-nobase_includeHEADERS: |
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
|
||||
$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
|
||||
dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
|
||||
install-nobase_nodist_includeHEADERS: $(nobase_nodist_include_HEADERS) |
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(nobase_nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
|
||||
fi; \
|
||||
$(am__nobase_list) | while read dir files; do \
|
||||
xfiles=; for file in $$files; do \
|
||||
if test -f "$$file"; then xfiles="$$xfiles $$file"; \
|
||||
else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
|
||||
test -z "$$xfiles" || { \
|
||||
test "x$$dir" = x. || { \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \
|
||||
echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \
|
||||
$(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \
|
||||
done
|
||||
|
||||
uninstall-nobase_nodist_includeHEADERS: |
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(nobase_nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \
|
||||
$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
|
||||
dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
|
||||
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
# into them and run 'make' without going through this Makefile.
|
||||
# To change the values of 'make' variables: instead of editing Makefiles,
|
||||
# (1) if the variable is set in 'config.status', edit 'config.status'
|
||||
# (which will cause the Makefiles to be regenerated when you run 'make');
|
||||
# (2) otherwise, pass the desired values on the 'make' command line.
|
||||
$(am__recursive_targets): |
||||
@fail=; \
|
||||
if $(am__make_keepgoing); then \
|
||||
failcom='fail=yes'; \
|
||||
else \
|
||||
failcom='exit 1'; \
|
||||
fi; \
|
||||
dot_seen=no; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
case "$@" in \
|
||||
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||
*) list='$(SUBDIRS)' ;; \
|
||||
esac; \
|
||||
for subdir in $$list; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
dot_seen=yes; \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| eval $$failcom; \
|
||||
done; \
|
||||
if test "$$dot_seen" = "no"; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||
fi; test -z "$$fail"
|
||||
|
||||
ID: $(am__tagged_files) |
||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||
tags: tags-recursive |
||||
TAGS: tags |
||||
|
||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) |
||||
set x; \
|
||||
here=`pwd`; \
|
||||
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
|
||||
include_option=--etags-include; \
|
||||
empty_fix=.; \
|
||||
else \
|
||||
include_option=--include; \
|
||||
empty_fix=; \
|
||||
fi; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test ! -f $$subdir/TAGS || \
|
||||
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
|
||||
fi; \
|
||||
done; \
|
||||
$(am__define_uniq_tagged_files); \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: ctags-recursive |
||||
|
||||
CTAGS: ctags |
||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) |
||||
$(am__define_uniq_tagged_files); \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS: |
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
cscopelist: cscopelist-recursive |
||||
|
||||
cscopelist-am: $(am__tagged_files) |
||||
list='$(am__tagged_files)'; \
|
||||
case "$(srcdir)" in \
|
||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||
esac; \
|
||||
for i in $$list; do \
|
||||
if test -f "$$i"; then \
|
||||
echo "$(subdir)/$$i"; \
|
||||
else \
|
||||
echo "$$sdir/$$i"; \
|
||||
fi; \
|
||||
done >> $(top_builddir)/cscope.files
|
||||
|
||||
distclean-tags: |
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
distdir: $(BUILT_SOURCES) |
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
distdir-am: $(DISTFILES) |
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
$(am__make_dryrun) \
|
||||
|| test -d "$(distdir)/$$subdir" \
|
||||
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|
||||
|| exit 1; \
|
||||
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
|
||||
$(am__relativize); \
|
||||
new_distdir=$$reldir; \
|
||||
dir1=$$subdir; dir2="$(top_distdir)"; \
|
||||
$(am__relativize); \
|
||||
new_top_distdir=$$reldir; \
|
||||
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
|
||||
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
|
||||
($(am__cd) $$subdir && \
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$$new_top_distdir" \
|
||||
distdir="$$new_distdir" \
|
||||
am__remove_distdir=: \
|
||||
am__skip_length_check=: \
|
||||
am__skip_mode_fix=: \
|
||||
distdir) \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am |
||||
check: check-recursive |
||||
all-am: Makefile $(HEADERS) |
||||
installdirs: installdirs-recursive |
||||
installdirs-am: |
||||
for dir in "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-recursive |
||||
install-exec: install-exec-recursive |
||||
install-data: install-data-recursive |
||||
uninstall: uninstall-recursive |
||||
|
||||
install-am: all-am |
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-recursive |
||||
install-strip: |
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic: |
||||
|
||||
clean-generic: |
||||
|
||||
distclean-generic: |
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic: |
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-recursive |
||||
|
||||
clean-am: clean-generic clean-libtool mostlyclean-am |
||||
|
||||
distclean: distclean-recursive |
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic distclean-tags |
||||
|
||||
dvi: dvi-recursive |
||||
|
||||
dvi-am: |
||||
|
||||
html: html-recursive |
||||
|
||||
html-am: |
||||
|
||||
info: info-recursive |
||||
|
||||
info-am: |
||||
|
||||
install-data-am: install-nobase_includeHEADERS \
|
||||
install-nobase_nodist_includeHEADERS
|
||||
|
||||
install-dvi: install-dvi-recursive |
||||
|
||||
install-dvi-am: |
||||
|
||||
install-exec-am: |
||||
|
||||
install-html: install-html-recursive |
||||
|
||||
install-html-am: |
||||
|
||||
install-info: install-info-recursive |
||||
|
||||
install-info-am: |
||||
|
||||
install-man: |
||||
|
||||
install-pdf: install-pdf-recursive |
||||
|
||||
install-pdf-am: |
||||
|
||||
install-ps: install-ps-recursive |
||||
|
||||
install-ps-am: |
||||
|
||||
installcheck-am: |
||||
|
||||
maintainer-clean: maintainer-clean-recursive |
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic |
||||
|
||||
mostlyclean: mostlyclean-recursive |
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool |
||||
|
||||
pdf: pdf-recursive |
||||
|
||||
pdf-am: |
||||
|
||||
ps: ps-recursive |
||||
|
||||
ps-am: |
||||
|
||||
uninstall-am: uninstall-nobase_includeHEADERS \
|
||||
uninstall-nobase_nodist_includeHEADERS
|
||||
|
||||
.MAKE: $(am__recursive_targets) install-am install-strip |
||||
|
||||
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
|
||||
check-am clean clean-generic clean-libtool cscopelist-am ctags \
|
||||
ctags-am distclean distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-nobase_includeHEADERS \
|
||||
install-nobase_nodist_includeHEADERS install-pdf \
|
||||
install-pdf-am install-ps install-ps-am install-strip \
|
||||
installcheck installcheck-am installdirs installdirs-am \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags tags-am uninstall uninstall-am \
|
||||
uninstall-nobase_includeHEADERS \
|
||||
uninstall-nobase_nodist_includeHEADERS
|
||||
|
||||
.PRECIOUS: Makefile |
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT: |
||||
@ -0,0 +1,13 @@
|
||||
MAINTAINERCLEANFILES=Makefile.in stamp-h.in
|
||||
|
||||
noinst_HEADERS = \
|
||||
config-internal-autotools.h
|
||||
|
||||
nodist_noinst_HEADERS = \
|
||||
config.h \
|
||||
config-internal-compiler.h
|
||||
|
||||
DISTCLEANFILES = \
|
||||
config-internal-autotools.h \
|
||||
config-internal-compiler.h \
|
||||
config-public-compiler.h
|
||||
@ -0,0 +1,556 @@
|
||||
# Makefile.in generated by automake 1.16.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@ |
||||
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
} |
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
subdir = include/pqxx
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \
|
||||
$(top_srcdir)/config/m4/ltoptions.m4 \
|
||||
$(top_srcdir)/config/m4/ltsugar.m4 \
|
||||
$(top_srcdir)/config/m4/ltversion.m4 \
|
||||
$(top_srcdir)/config/m4/lt~obsolete.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \
|
||||
$(am__DIST_COMMON)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
|
||||
CONFIG_HEADER = config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
HEADERS = $(nodist_noinst_HEADERS) $(noinst_HEADERS)
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
|
||||
config.h.in
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
am__uniquify_input = $(AWK) '\
|
||||
BEGIN { nonempty = 0; } \
|
||||
{ items[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in items) print i; }; } \
|
||||
' |
||||
# Make sure the list of sources is unique. This is necessary because,
|
||||
# e.g., the same source file might be shared among _SOURCES variables
|
||||
# for different programs/libraries.
|
||||
am__define_uniq_tagged_files = \
|
||||
list='$(am__tagged_files)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
|
||||
$(top_srcdir)/config/mkinstalldirs
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CSCOPE = @CSCOPE@
|
||||
CTAGS = @CTAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DOXYGEN = @DOXYGEN@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
HAVE_DOT = @HAVE_DOT@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR = @MKDIR@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PG_CONFIG = @PG_CONFIG@
|
||||
PKG_CONFIG = @PKG_CONFIG@
|
||||
POSTGRES_INCLUDE = @POSTGRES_INCLUDE@
|
||||
PQXXVERSION = @PQXXVERSION@
|
||||
PQXX_ABI = @PQXX_ABI@
|
||||
RANLIB = @RANLIB@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
runstatedir = @runstatedir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
with_postgres_lib = @with_postgres_lib@
|
||||
MAINTAINERCLEANFILES = Makefile.in stamp-h.in
|
||||
noinst_HEADERS = \
|
||||
config-internal-autotools.h
|
||||
|
||||
nodist_noinst_HEADERS = \
|
||||
config.h \
|
||||
config-internal-compiler.h
|
||||
|
||||
DISTCLEANFILES = \
|
||||
config-internal-autotools.h \
|
||||
config-internal-compiler.h \
|
||||
config-public-compiler.h
|
||||
|
||||
all: config.h |
||||
$(MAKE) $(AM_MAKEFLAGS) all-am
|
||||
|
||||
.SUFFIXES: |
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) |
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/pqxx/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu include/pqxx/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status |
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) |
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) |
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) |
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps): |
||||
|
||||
config.h: stamp-h1 |
||||
@test -f $@ || rm -f stamp-h1
|
||||
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
|
||||
|
||||
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status |
||||
@rm -f stamp-h1
|
||||
cd $(top_builddir) && $(SHELL) ./config.status include/pqxx/config.h
|
||||
$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) |
||||
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
|
||||
rm -f stamp-h1
|
||||
touch $@
|
||||
|
||||
distclean-hdr: |
||||
-rm -f config.h stamp-h1
|
||||
|
||||
mostlyclean-libtool: |
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool: |
||||
-rm -rf .libs _libs
|
||||
|
||||
ID: $(am__tagged_files) |
||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||
tags: tags-am |
||||
TAGS: tags |
||||
|
||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) |
||||
set x; \
|
||||
here=`pwd`; \
|
||||
$(am__define_uniq_tagged_files); \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: ctags-am |
||||
|
||||
CTAGS: ctags |
||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) |
||||
$(am__define_uniq_tagged_files); \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS: |
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
cscopelist: cscopelist-am |
||||
|
||||
cscopelist-am: $(am__tagged_files) |
||||
list='$(am__tagged_files)'; \
|
||||
case "$(srcdir)" in \
|
||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||
esac; \
|
||||
for i in $$list; do \
|
||||
if test -f "$$i"; then \
|
||||
echo "$(subdir)/$$i"; \
|
||||
else \
|
||||
echo "$$sdir/$$i"; \
|
||||
fi; \
|
||||
done >> $(top_builddir)/cscope.files
|
||||
|
||||
distclean-tags: |
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
distdir: $(BUILT_SOURCES) |
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
distdir-am: $(DISTFILES) |
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am |
||||
check: check-am |
||||
all-am: Makefile $(HEADERS) config.h |
||||
installdirs: |
||||
install: install-am |
||||
install-exec: install-exec-am |
||||
install-data: install-data-am |
||||
uninstall: uninstall-am |
||||
|
||||
install-am: all-am |
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am |
||||
install-strip: |
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic: |
||||
|
||||
clean-generic: |
||||
|
||||
distclean-generic: |
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
|
||||
|
||||
maintainer-clean-generic: |
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
clean: clean-am |
||||
|
||||
clean-am: clean-generic clean-libtool mostlyclean-am |
||||
|
||||
distclean: distclean-am |
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic distclean-hdr distclean-tags |
||||
|
||||
dvi: dvi-am |
||||
|
||||
dvi-am: |
||||
|
||||
html: html-am |
||||
|
||||
html-am: |
||||
|
||||
info: info-am |
||||
|
||||
info-am: |
||||
|
||||
install-data-am: |
||||
|
||||
install-dvi: install-dvi-am |
||||
|
||||
install-dvi-am: |
||||
|
||||
install-exec-am: |
||||
|
||||
install-html: install-html-am |
||||
|
||||
install-html-am: |
||||
|
||||
install-info: install-info-am |
||||
|
||||
install-info-am: |
||||
|
||||
install-man: |
||||
|
||||
install-pdf: install-pdf-am |
||||
|
||||
install-pdf-am: |
||||
|
||||
install-ps: install-ps-am |
||||
|
||||
install-ps-am: |
||||
|
||||
installcheck-am: |
||||
|
||||
maintainer-clean: maintainer-clean-am |
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic |
||||
|
||||
mostlyclean: mostlyclean-am |
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool |
||||
|
||||
pdf: pdf-am |
||||
|
||||
pdf-am: |
||||
|
||||
ps: ps-am |
||||
|
||||
ps-am: |
||||
|
||||
uninstall-am: |
||||
|
||||
.MAKE: all install-am install-strip |
||||
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
|
||||
clean-libtool cscopelist-am ctags ctags-am distclean \
|
||||
distclean-generic distclean-hdr distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags tags-am uninstall uninstall-am
|
||||
|
||||
.PRECIOUS: Makefile |
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT: |
||||
@ -0,0 +1,6 @@
|
||||
/** Handling of SQL arrays. |
||||
*/ |
||||
// Actual definitions in .hxx file so editors and such recognize file type. |
||||
#include "pqxx/internal/header-pre.hxx" |
||||
#include "pqxx/array.hxx" |
||||
#include "pqxx/internal/header-post.hxx" |
||||
@ -0,0 +1,103 @@
|
||||
/* Handling of SQL arrays.
|
||||
* |
||||
* DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead. |
||||
* |
||||
* Copyright (c) 2000-2022, Jeroen T. Vermeulen. |
||||
* |
||||
* See COPYING for copyright license. If you did not receive a file called |
||||
* COPYING with this source code, please notify the distributor of this |
||||
* mistake, or contact the author. |
||||
*/ |
||||
#ifndef PQXX_H_ARRAY |
||||
#define PQXX_H_ARRAY |
||||
|
||||
#if !defined(PQXX_HEADER_PRE) |
||||
# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>." |
||||
#endif |
||||
|
||||
#include <stdexcept> |
||||
#include <string> |
||||
#include <utility> |
||||
|
||||
#include "pqxx/internal/encoding_group.hxx" |
||||
#include "pqxx/internal/encodings.hxx" |
||||
|
||||
|
||||
namespace pqxx |
||||
{ |
||||
/// Low-level array parser.
|
||||
/** Use this to read an array field retrieved from the database.
|
||||
* |
||||
* This parser will only work reliably if your client encoding is UTF-8, ASCII, |
||||
* or a single-byte encoding which is a superset of ASCII (such as Latin-1). |
||||
* |
||||
* Also, the parser only supports array element types which use either a comma |
||||
* or a semicolon ("," or ";") as the separator between array elements. All |
||||
* built-in types use comma, except for one which uses semicolon, but some |
||||
* custom types may not work. |
||||
* |
||||
* The input is a C-style string containing the textual representation of an |
||||
* array, as returned by the database. The parser reads this representation |
||||
* on the fly. The string must remain in memory until parsing is done. |
||||
* |
||||
* Parse the array by making calls to @ref get_next until it returns a |
||||
* @ref juncture of "done". The @ref juncture tells you what the parser found |
||||
* in that step: did the array "nest" to a deeper level, or "un-nest" back up? |
||||
*/ |
||||
class PQXX_LIBEXPORT array_parser |
||||
{ |
||||
public: |
||||
/// What's the latest thing found in the array?
|
||||
enum class juncture |
||||
{ |
||||
/// Starting a new row.
|
||||
row_start, |
||||
/// Ending the current row.
|
||||
row_end, |
||||
/// Found a NULL value.
|
||||
null_value, |
||||
/// Found a string value.
|
||||
string_value, |
||||
/// Parsing has completed.
|
||||
done, |
||||
}; |
||||
|
||||
// TODO: constexpr noexcept. Breaks ABI.
|
||||
/// Constructor. You don't need this; use @ref field::as_array instead.
|
||||
/** The parser only remains valid while the data underlying the @ref result
|
||||
* remains valid. Once all `result` objects referring to that data have been |
||||
* destroyed, the parser will no longer refer to valid memory. |
||||
*/ |
||||
explicit array_parser( |
||||
std::string_view input, |
||||
internal::encoding_group = internal::encoding_group::MONOBYTE); |
||||
|
||||
/// Parse the next step in the array.
|
||||
/** Returns what it found. If the juncture is @ref juncture::string_value,
|
||||
* the string will contain the value. Otherwise, it will be empty. |
||||
* |
||||
* Call this until the @ref array_parser::juncture it returns is |
||||
* @ref juncture::done. |
||||
*/ |
||||
std::pair<juncture, std::string> get_next(); |
||||
|
||||
private: |
||||
std::string_view m_input; |
||||
internal::glyph_scanner_func *const m_scan; |
||||
|
||||
/// Current parsing position in the input.
|
||||
std::string::size_type m_pos = 0u; |
||||
|
||||
std::string::size_type scan_single_quoted_string() const; |
||||
std::string parse_single_quoted_string(std::string::size_type end) const; |
||||
std::string::size_type scan_double_quoted_string() const; |
||||
std::string parse_double_quoted_string(std::string::size_type end) const; |
||||
std::string::size_type scan_unquoted_string() const; |
||||
std::string parse_unquoted_string(std::string::size_type end) const; |
||||
|
||||
std::string::size_type scan_glyph(std::string::size_type pos) const; |
||||
std::string::size_type |
||||
scan_glyph(std::string::size_type pos, std::string::size_type end) const; |
||||
}; |
||||
} // namespace pqxx
|
||||
#endif |
||||
@ -0,0 +1,6 @@
|
||||
/** BYTEA (binary string) conversions. |
||||
*/ |
||||
// Actual definitions in .hxx file so editors and such recognize file type. |
||||
#include "pqxx/internal/header-pre.hxx" |
||||
#include "pqxx/binarystring.hxx" |
||||
#include "pqxx/internal/header-post.hxx" |
||||
@ -0,0 +1,236 @@
|
||||
/* Deprecated representation for raw, binary data.
|
||||
* |
||||
* DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/binarystring instead. |
||||
* |
||||
* Copyright (c) 2000-2022, Jeroen T. Vermeulen. |
||||
* |
||||
* See COPYING for copyright license. If you did not receive a file called |
||||
* COPYING with this source code, please notify the distributor of this |
||||
* mistake, or contact the author. |
||||
*/ |
||||
#ifndef PQXX_H_BINARYSTRING |
||||
#define PQXX_H_BINARYSTRING |
||||
|
||||
#if !defined(PQXX_HEADER_PRE) |
||||
# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>." |
||||
#endif |
||||
|
||||
#include <memory> |
||||
#include <string> |
||||
#include <string_view> |
||||
|
||||
#include "pqxx/result.hxx" |
||||
#include "pqxx/strconv.hxx" |
||||
|
||||
namespace pqxx |
||||
{ |
||||
class binarystring; |
||||
template<> struct string_traits<binarystring>; |
||||
|
||||
|
||||
/// Binary data corresponding to PostgreSQL's "BYTEA" binary-string type.
|
||||
/** @ingroup escaping-functions
|
||||
* @deprecated Use @c std::basic_string<std::byte> and |
||||
* @c std::basic_string_view<std::byte> 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 <em>not thread-safe</em>. If you wish to pass |
||||
* binarystrings around between threads, make sure that each of these |
||||
* operations is protected against concurrency with similar operations on the |
||||
* same object, or other objects pointing to the same data block. |
||||
*/ |
||||
class PQXX_LIBEXPORT binarystring |
||||
{ |
||||
public: |
||||
using char_type = unsigned char; |
||||
using value_type = std::char_traits<char_type>::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<const_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<value_type> 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<char const *>(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<std::byte const *>(get()); |
||||
} |
||||
|
||||
/// Read data as a @c std::basic_string_view<std::byte>.
|
||||
[[nodiscard]] std::basic_string_view<std::byte> bytes_view() const |
||||
{ |
||||
return std::basic_string_view<std::byte>{bytes(), size()}; |
||||
} |
||||
|
||||
private: |
||||
std::shared_ptr<value_type> m_buf; |
||||
size_type m_size{0}; |
||||
}; |
||||
|
||||
|
||||
template<> struct nullness<binarystring> : no_null<binarystring> |
||||
{}; |
||||
|
||||
|
||||
/// 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<binarystring> |
||||
{ |
||||
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<unsigned char> buf{ |
||||
new unsigned char[size], [](unsigned char const *x) { delete[] x; }}; |
||||
pqxx::internal::unesc_bin(text, reinterpret_cast<std::byte *>(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 |
||||
@ -0,0 +1,6 @@
|
||||
/** Binary Large Objects interface. |
||||
*/ |
||||
// Actual definitions in .hxx file so editors and such recognize file type. |
||||
#include "pqxx/internal/header-pre.hxx" |
||||
#include "pqxx/blob.hxx" |
||||
#include "pqxx/internal/header-post.hxx" |
||||
@ -0,0 +1,351 @@
|
||||
/* Binary Large Objects interface.
|
||||
* |
||||
* Read or write large objects, stored in their own storage on the server. |
||||
* |
||||
* DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead. |
||||
* |
||||
* Copyright (c) 2000-2022, Jeroen T. Vermeulen. |
||||
* |
||||
* See COPYING for copyright license. If you did not receive a file called |
||||
* COPYING with this source code, please notify the distributor of this |
||||
* mistake, or contact the author. |
||||
*/ |
||||
#ifndef PQXX_H_BLOB |
||||
#define PQXX_H_BLOB |
||||
|
||||
#if !defined(PQXX_HEADER_PRE) |
||||
# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>." |
||||
#endif |
||||
|
||||
#include <cstdint> |
||||
|
||||
#if defined(PQXX_HAVE_PATH) |
||||
# include <filesystem> |
||||
#endif |
||||
|
||||
#if defined(PQXX_HAVE_RANGES) && __has_include(<ranges>) |
||||
# include <ranges> |
||||
#endif |
||||
|
||||
#if defined(PQXX_HAVE_SPAN) && __has_include(<span>) |
||||
# include <span> |
||||
#endif |
||||
|
||||
#include "pqxx/dbtransaction.hxx" |
||||
|
||||
|
||||
namespace pqxx |
||||
{ |
||||
/** Binary large object.
|
||||
* |
||||
* This is how you store data that may be too large for the `BYTEA` type. |
||||
* Access operations are similar to those for a file: you can read, write, |
||||
* query or set the current reading/writing position, and so on. |
||||
* |
||||
* These large objects live in their own storage on the server, indexed by an |
||||
* integer object identifier ("oid"). |
||||
* |
||||
* Two `blob` objects may refer to the same actual large object in the |
||||
* database at the same time. Each will have its own reading/writing position, |
||||
* but writes to the one will of course affect what the other sees. |
||||
*/ |
||||
class PQXX_LIBEXPORT blob |
||||
{ |
||||
public: |
||||
/// Create a new, empty large object.
|
||||
/** You may optionally specify an oid for the new blob. If you do, then
|
||||
* the new object will have that oid -- or creation will fail if there |
||||
* already is an object with that oid. |
||||
*/ |
||||
[[nodiscard]] static oid create(dbtransaction &, oid = 0); |
||||
|
||||
/// Delete a large object, or fail if it does not exist.
|
||||
static void remove(dbtransaction &, oid); |
||||
|
||||
/// Open blob for reading. Any attempt to write to it will fail.
|
||||
[[nodiscard]] static blob open_r(dbtransaction &, oid); |
||||
// Open blob for writing. Any attempt to read from it will fail.
|
||||
[[nodiscard]] static blob open_w(dbtransaction &, oid); |
||||
// Open blob for reading and/or writing.
|
||||
[[nodiscard]] static blob open_rw(dbtransaction &, oid); |
||||
|
||||
/// You can default-construct a blob, but it won't do anything useful.
|
||||
/** Most operations on a default-constructed blob will throw @ref
|
||||
* usage_error. |
||||
*/ |
||||
blob() = default; |
||||
|
||||
/// You can move a blob, but not copy it. The original becomes unusable.
|
||||
blob(blob &&); |
||||
/// You can move a blob, but not copy it. The original becomes unusable.
|
||||
blob &operator=(blob &&); |
||||
|
||||
blob(blob const &) = delete; |
||||
blob &operator=(blob const &) = delete; |
||||
~blob(); |
||||
|
||||
/// Maximum number of bytes that can be read or written at a time.
|
||||
/** The underlying protocol only supports reads and writes up to 2 GB
|
||||
* exclusive. |
||||
* |
||||
* If you need to read or write more data to or from a binary large object, |
||||
* you'll have to break it up into chunks. |
||||
*/ |
||||
static constexpr std::size_t chunk_limit = 0x7fffffff; |
||||
|
||||
/// Read up to `size` bytes of the object into `buf`.
|
||||
/** Uses a buffer that you provide, resizing it as needed. If it suits you,
|
||||
* this lets you allocate the buffer once and then re-use it multiple times. |
||||
* |
||||
* Resizes `buf` as needed. |
||||
* |
||||
* @warning The underlying protocol only supports reads up to 2GB at a time. |
||||
* If you need to read more, try making repeated calls to @ref append_to_buf. |
||||
*/ |
||||
std::size_t read(std::basic_string<std::byte> &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::size_t extent = std::dynamic_extent> |
||||
std::span<std::byte> read(std::span<std::byte, extent> 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<binary DATA> std::span<std::byte> 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<std::byte>`. |
||||
* |
||||
* 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<typename ALLOC> |
||||
std::basic_string_view<std::byte> read(std::vector<std::byte, ALLOC> &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<binary DATA> 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<typename DATA> void write(DATA const &data) |
||||
{ |
||||
raw_write(std::data(data), std::size(data)); |
||||
} |
||||
#endif |
||||
|
||||
/// Resize large object to `size` bytes.
|
||||
/** If the blob is more than `size` bytes long, this removes the end so as
|
||||
* to make the blob the desired length. |
||||
* |
||||
* If the blob is less than `size` bytes long, it adds enough zero bytes to |
||||
* make it the desired length. |
||||
*/ |
||||
void resize(std::int64_t size); |
||||
|
||||
/// Return the current reading/writing position in the large object.
|
||||
[[nodiscard]] std::int64_t tell() const; |
||||
|
||||
/// Set the current reading/writing position to an absolute offset.
|
||||
/** Returns the new file offset. */ |
||||
std::int64_t seek_abs(std::int64_t offset = 0); |
||||
/// Move the current reading/writing position forwards by an offset.
|
||||
/** To move backwards, pass a negative offset.
|
||||
* |
||||
* Returns the new file offset. |
||||
*/ |
||||
std::int64_t seek_rel(std::int64_t offset = 0); |
||||
/// Set the current position to an offset relative to the end of the blob.
|
||||
/** You'll probably want an offset of zero or less.
|
||||
* |
||||
* Returns the new file offset. |
||||
*/ |
||||
std::int64_t seek_end(std::int64_t offset = 0); |
||||
|
||||
/// Create a binary large object containing given `data`.
|
||||
/** You may optionally specify an oid for the new object. If you do, and an
|
||||
* object with that oid already exists, creation will fail. |
||||
*/ |
||||
static oid from_buf( |
||||
dbtransaction &tx, std::basic_string_view<std::byte> data, oid id = 0); |
||||
|
||||
/// Append `data` to binary large object.
|
||||
/** The underlying protocol only supports appending blocks up to 2 GB.
|
||||
*/ |
||||
static void append_from_buf( |
||||
dbtransaction &tx, std::basic_string_view<std::byte> data, oid id); |
||||
|
||||
/// Read client-side file and store it server-side as a binary large object.
|
||||
[[nodiscard]] static oid from_file(dbtransaction &, char const path[]); |
||||
|
||||
#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) |
||||
/// Read client-side file and store it server-side as a binary large object.
|
||||
/** This overload is not available on Windows, where `std::filesystem::path`
|
||||
* converts to a `wchar_t` string rather than a `char` string. |
||||
*/ |
||||
[[nodiscard]] static oid |
||||
from_file(dbtransaction &tx, std::filesystem::path const &path) |
||||
{ |
||||
return from_file(tx, path.c_str()); |
||||
} |
||||
#endif |
||||
|
||||
/// Read client-side file and store it server-side as a binary large object.
|
||||
/** In this version, you specify the binary large object's oid. If that oid
|
||||
* is already in use, the operation will fail. |
||||
*/ |
||||
static oid from_file(dbtransaction &, char const path[], oid); |
||||
|
||||
#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) |
||||
/// Read client-side file and store it server-side as a binary large object.
|
||||
/** In this version, you specify the binary large object's oid. If that oid
|
||||
* is already in use, the operation will fail. |
||||
* |
||||
* This overload is not available on Windows, where `std::filesystem::path` |
||||
* converts to a `wchar_t` string rather than a `char` string. |
||||
*/ |
||||
static oid |
||||
from_file(dbtransaction &tx, std::filesystem::path const &path, oid id) |
||||
{ |
||||
return from_file(tx, path.c_str(), id); |
||||
} |
||||
#endif |
||||
|
||||
/// Convenience function: Read up to `max_size` bytes from blob with `id`.
|
||||
/** You could easily do this yourself using the @ref open_r and @ref read
|
||||
* functions, but it can save you a bit of code to do it this way. |
||||
*/ |
||||
static void to_buf( |
||||
dbtransaction &, oid, std::basic_string<std::byte> &, |
||||
std::size_t max_size); |
||||
|
||||
/// Read part of the binary large object with `id`, and append it to `buf`.
|
||||
/** Use this to break up a large read from one binary large object into one
|
||||
* massive buffer. Just keep calling this function until it returns zero. |
||||
* |
||||
* The `offset` is how far into the large object your desired chunk is, and |
||||
* `append_max` says how much to try and read in one go. |
||||
*/ |
||||
static std::size_t append_to_buf( |
||||
dbtransaction &tx, oid id, std::int64_t offset, |
||||
std::basic_string<std::byte> &buf, std::size_t append_max); |
||||
|
||||
/// Write a binary large object's contents to a client-side file.
|
||||
static void to_file(dbtransaction &, oid, char const path[]); |
||||
|
||||
#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) |
||||
/// Write a binary large object's contents to a client-side file.
|
||||
/** This overload is not available on Windows, where `std::filesystem::path`
|
||||
* converts to a `wchar_t` string rather than a `char` string. |
||||
*/ |
||||
static void |
||||
to_file(dbtransaction &tx, oid id, std::filesystem::path const &path) |
||||
{ |
||||
to_file(tx, id, path.c_str()); |
||||
} |
||||
#endif |
||||
|
||||
/// Close this blob.
|
||||
/** This does not delete the blob from the database; it only terminates your
|
||||
* local object for accessing the blob. |
||||
* |
||||
* Resets the blob to a useless state similar to one that was |
||||
* default-constructed. |
||||
* |
||||
* The destructor will do this for you automatically. Still, there is a |
||||
* reason to `close()` objects explicitly where possible: if an error should |
||||
* occur while closing, `close()` can throw an exception. A destructor |
||||
* cannot. |
||||
*/ |
||||
void close(); |
||||
|
||||
private: |
||||
PQXX_PRIVATE blob(connection &conn, int fd) noexcept : |
||||
m_conn{&conn}, m_fd{fd} |
||||
{} |
||||
static PQXX_PRIVATE blob open_internal(dbtransaction &, oid, int); |
||||
static PQXX_PRIVATE pqxx::internal::pq::PGconn * |
||||
raw_conn(pqxx::connection *) noexcept; |
||||
static PQXX_PRIVATE pqxx::internal::pq::PGconn * |
||||
raw_conn(pqxx::dbtransaction const &) noexcept; |
||||
static PQXX_PRIVATE std::string errmsg(connection const *); |
||||
static PQXX_PRIVATE std::string errmsg(dbtransaction const &tx) |
||||
{ |
||||
return errmsg(&tx.conn()); |
||||
} |
||||
PQXX_PRIVATE std::string errmsg() const { return errmsg(m_conn); } |
||||
PQXX_PRIVATE std::int64_t seek(std::int64_t offset, int whence); |
||||
std::size_t raw_read(std::byte buf[], std::size_t size); |
||||
void raw_write(std::byte const buf[], std::size_t size); |
||||
|
||||
connection *m_conn = nullptr; |
||||
int m_fd = -1; |
||||
}; |
||||
} // namespace pqxx
|
||||
#endif |
||||
@ -0,0 +1,6 @@
|
||||
/** Handling of SQL "composite types." |
||||
*/ |
||||
// Actual definitions in .hxx file so editors and such recognize file type. |
||||
#include "pqxx/internal/header-pre.hxx" |
||||
#include "pqxx/composite.hxx" |
||||
#include "pqxx/internal/header-post.hxx" |
||||
@ -0,0 +1,149 @@
|
||||
#ifndef PQXX_H_COMPOSITE |
||||
#define PQXX_H_COMPOSITE |
||||
|
||||
#if !defined(PQXX_HEADER_PRE) |
||||
# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>." |
||||
#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<typename... T> |
||||
inline void parse_composite( |
||||
pqxx::internal::encoding_group enc, std::string_view text, T &...fields) |
||||
{ |
||||
static_assert(sizeof...(fields) > 0); |
||||
|
||||
auto const scan{pqxx::internal::get_glyph_scanner(enc)}; |
||||
auto const data{std::data(text)}; |
||||
auto const size{std::size(text)}; |
||||
if (size == 0) |
||||
throw conversion_error{"Cannot parse composite value from empty string."}; |
||||
|
||||
std::size_t here{0}, next{scan(data, size, here)}; |
||||
if (next != 1 or data[here] != '(') |
||||
throw conversion_error{ |
||||
internal::concat("Invalid composite value string: ", text)}; |
||||
|
||||
here = next; |
||||
|
||||
constexpr auto num_fields{sizeof...(fields)}; |
||||
std::size_t index{0}; |
||||
(pqxx::internal::parse_composite_field( |
||||
index, text, here, fields, scan, num_fields - 1), |
||||
...); |
||||
if (here != std::size(text)) |
||||
throw conversion_error{internal::concat( |
||||
"Composite value did not end at the closing parenthesis: '", text, |
||||
"'.")}; |
||||
if (text[here - 1] != ')') |
||||
throw conversion_error{internal::concat( |
||||
"Composive value did not end in parenthesis: '", text, "'")}; |
||||
} |
||||
|
||||
|
||||
/// Parse a string representation of a value of a composite type.
|
||||
/** @warning This version only works for UTF-8 and single-byte encodings.
|
||||
* |
||||
* For proper encoding support, use the composite-type support in the |
||||
* `field` class. |
||||
*/ |
||||
template<typename... T> |
||||
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<typename... T> |
||||
[[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<typename... T> |
||||
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<T>(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 |
||||
@ -0,0 +1,121 @@
|
||||
/* include/pqxx/config.h.in. Generated from configure.ac by autoheader. */ |
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */ |
||||
#undef HAVE_DLFCN_H |
||||
|
||||
/* Define to 1 if you have the <inttypes.h> 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 <memory.h> header file. */ |
||||
#undef HAVE_MEMORY_H |
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */ |
||||
#undef HAVE_STDINT_H |
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */ |
||||
#undef HAVE_STDLIB_H |
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */ |
||||
#undef HAVE_STRINGS_H |
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */ |
||||
#undef HAVE_STRING_H |
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */ |
||||
#undef HAVE_SYS_STAT_H |
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */ |
||||
#undef HAVE_SYS_TYPES_H |
||||
|
||||
/* Define to 1 if you have the <unistd.h> 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 <charconv> supports floating-point conversion. */ |
||||
#undef PQXX_HAVE_CHARCONV_FLOAT |
||||
|
||||
/* Define if <charconv> supports integer conversion. */ |
||||
#undef PQXX_HAVE_CHARCONV_INT |
||||
|
||||
/* Define if compiler has C++20 std::cmp_greater etc. */ |
||||
#undef PQXX_HAVE_CMP |
||||
|
||||
/* Define if compiler supports Concepts and <ranges> header. */ |
||||
#undef PQXX_HAVE_CONCEPTS |
||||
|
||||
/* Define if compiler supports __cxa_demangle */ |
||||
#undef PQXX_HAVE_CXA_DEMANGLE |
||||
|
||||
/* Define if g++ supports pure attribute */ |
||||
#undef PQXX_HAVE_GCC_PURE |
||||
|
||||
/* Define if g++ supports visibility attribute. */ |
||||
#undef PQXX_HAVE_GCC_VISIBILITY |
||||
|
||||
/* Define if likely & unlikely work. */ |
||||
#undef PQXX_HAVE_LIKELY |
||||
|
||||
/* Define if operator[] can take multiple arguments. */ |
||||
#undef PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT |
||||
|
||||
/* Define if compiler has usable std::filesystem::path. */ |
||||
#undef PQXX_HAVE_PATH |
||||
|
||||
/* Define if poll() is available. */ |
||||
#undef PQXX_HAVE_POLL |
||||
|
||||
/* Define if libpq has PQencryptPasswordConn (since pg 10). */ |
||||
#undef PQXX_HAVE_PQENCRYPTPASSWORDCONN |
||||
|
||||
/* Define if libpq has pipeline mode (since pg 14). */ |
||||
#undef PQXX_HAVE_PQ_PIPELINE |
||||
|
||||
/* Define if std::this_thread::sleep_for works. */ |
||||
#undef PQXX_HAVE_SLEEP_FOR |
||||
|
||||
/* Define if compiler has std::span. */ |
||||
#undef PQXX_HAVE_SPAN |
||||
|
||||
/* Define if strerror_r() is available. */ |
||||
#undef PQXX_HAVE_STRERROR_R |
||||
|
||||
/* Define if strerror_s() is available. */ |
||||
#undef PQXX_HAVE_STRERROR_S |
||||
|
||||
/* Define if thread_local is fully supported. */ |
||||
#undef PQXX_HAVE_THREAD_LOCAL |
||||
|
||||
/* Define if std::chrono has year_month_day etc. */ |
||||
#undef PQXX_HAVE_YEAR_MONTH_DAY |
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */ |
||||
#undef STDC_HEADERS |
||||
|
||||
/* Version number of package */ |
||||
#undef VERSION |
||||
@ -0,0 +1,8 @@
|
||||
/** pqxx::connection class. |
||||
* |
||||
* pqxx::connection encapsulates a connection to a database. |
||||
*/ |
||||
// Actual definitions in .hxx file so editors and such recognize file type. |
||||
#include "pqxx/internal/header-pre.hxx" |
||||
#include "pqxx/connection.hxx" |
||||
#include "pqxx/internal/header-post.hxx" |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@
|
||||
/** Definition of the iterator/container-style cursor classes. |
||||
* |
||||
* C++-style wrappers for SQL cursors |
||||
*/ |
||||
// Actual definitions in .hxx file so editors and such recognize file type. |
||||
#include "pqxx/internal/header-pre.hxx" |
||||
#include "pqxx/cursor.hxx" |
||||
#include "pqxx/internal/header-post.hxx" |
||||
@ -0,0 +1,483 @@
|
||||
/* Definition of the iterator/container-style cursor classes.
|
||||
* |
||||
* C++-style wrappers for SQL cursors. |
||||
* |
||||
* DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/cursor instead. |
||||
* |
||||
* Copyright (c) 2000-2022, Jeroen T. Vermeulen. |
||||
* |
||||
* See COPYING for copyright license. If you did not receive a file called |
||||
* COPYING with this source code, please notify the distributor of this |
||||
* mistake, or contact the author. |
||||
*/ |
||||
#ifndef PQXX_H_CURSOR |
||||
#define PQXX_H_CURSOR |
||||
|
||||
#if !defined(PQXX_HEADER_PRE) |
||||
# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>." |
||||
#endif |
||||
|
||||
#include <limits> |
||||
#include <stdexcept> |
||||
|
||||
#include "pqxx/result.hxx" |
||||
#include "pqxx/transaction_base.hxx" |
||||
|
||||
|
||||
namespace pqxx |
||||
{ |
||||
/// Common definitions for cursor types
|
||||
/** In C++ terms, fetches are always done in pre-increment or pre-decrement
|
||||
* fashion--i.e. the result does not include the row the cursor is on at the |
||||
* beginning of the fetch, and the cursor ends up being positioned on the last |
||||
* row in the result. |
||||
* |
||||
* There are singular positions akin to `end()` at both the beginning and the |
||||
* end of the cursor's range of movement, although these fit in so naturally |
||||
* with the semantics that one rarely notices them. The cursor begins at the |
||||
* first of these, but any fetch in the forward direction will move the cursor |
||||
* off this position and onto the first row before returning anything. |
||||
*/ |
||||
class PQXX_LIBEXPORT cursor_base |
||||
{ |
||||
public: |
||||
using size_type = result_size_type; |
||||
using difference_type = result_difference_type; |
||||
|
||||
/// Cursor access-pattern policy
|
||||
/** Allowing a cursor to move forward only can result in better performance,
|
||||
* so use this access policy whenever possible. |
||||
*/ |
||||
enum access_policy |
||||
{ |
||||
/// Cursor can move forward only
|
||||
forward_only, |
||||
/// Cursor can move back and forth
|
||||
random_access |
||||
}; |
||||
|
||||
/// Cursor update policy
|
||||
/**
|
||||
* @warning Not all PostgreSQL versions support updatable cursors. |
||||
*/ |
||||
enum update_policy |
||||
{ |
||||
/// Cursor can be used to read data but not to write
|
||||
read_only, |
||||
/// Cursor can be used to update data as well as read it
|
||||
update |
||||
}; |
||||
|
||||
/// Cursor destruction policy
|
||||
/** The normal thing to do is to make a cursor object the owner of the SQL
|
||||
* cursor it represents. There may be cases, however, where a cursor needs |
||||
* to persist beyond the end of the current transaction (and thus also beyond |
||||
* the lifetime of the cursor object that created it!), where it can be |
||||
* "adopted" into a new cursor object. See the basic_cursor documentation |
||||
* for an explanation of cursor adoption. |
||||
* |
||||
* If a cursor is created with "loose" ownership policy, the object |
||||
* representing the underlying SQL cursor will not take the latter with it |
||||
* when its own lifetime ends, nor will its originating transaction. |
||||
* |
||||
* @warning Use this feature with care and moderation. Only one cursor |
||||
* object should be responsible for any one underlying SQL cursor at any |
||||
* given time. |
||||
*/ |
||||
enum ownership_policy |
||||
{ |
||||
/// Destroy SQL cursor when cursor object is closed at end of transaction
|
||||
owned, |
||||
/// Leave SQL cursor in existence after close of object and transaction
|
||||
loose |
||||
}; |
||||
|
||||
cursor_base() = delete; |
||||
cursor_base(cursor_base const &) = delete; |
||||
cursor_base &operator=(cursor_base const &) = delete; |
||||
|
||||
/**
|
||||
* @name Special movement distances. |
||||
*/ |
||||
//@{
|
||||
|
||||
// TODO: Make constexpr inline (but breaks ABI).
|
||||
/// Special value: read until end.
|
||||
/** @return Maximum value for result::difference_type, so the cursor will
|
||||
* attempt to read the largest possible result set. |
||||
*/ |
||||
[[nodiscard]] static difference_type all() noexcept; |
||||
|
||||
/// Special value: read one row only.
|
||||
/** @return Unsurprisingly, 1.
|
||||
*/ |
||||
[[nodiscard]] static constexpr difference_type next() noexcept { return 1; } |
||||
|
||||
/// Special value: read backwards, one row only.
|
||||
/** @return Unsurprisingly, -1.
|
||||
*/ |
||||
[[nodiscard]] static constexpr difference_type prior() noexcept |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
// TODO: Make constexpr inline (but breaks ABI).
|
||||
/// Special value: read backwards from current position back to origin.
|
||||
/** @return Minimum value for result::difference_type.
|
||||
*/ |
||||
[[nodiscard]] static difference_type backward_all() noexcept; |
||||
|
||||
//@}
|
||||
|
||||
/// Name of underlying SQL cursor
|
||||
/**
|
||||
* @returns Name of SQL cursor, which may differ from original given name. |
||||
* @warning Don't use this to access the SQL cursor directly without going |
||||
* through the provided wrapper classes! |
||||
*/ |
||||
[[nodiscard]] constexpr std::string const &name() const noexcept |
||||
{ |
||||
return m_name; |
||||
} |
||||
|
||||
protected: |
||||
cursor_base(connection &, std::string_view Name, bool embellish_name = true); |
||||
|
||||
std::string const m_name; |
||||
}; |
||||
} // namespace pqxx
|
||||
|
||||
|
||||
#include <pqxx/internal/sql_cursor.hxx> |
||||
|
||||
|
||||
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<cursor_base::update_policy up, cursor_base::ownership_policy op> |
||||
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 <em>not thread-safe</em>. 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 |
||||
@ -0,0 +1,8 @@
|
||||
/** pqxx::dbtransaction abstract base class. |
||||
* |
||||
* pqxx::dbransaction defines a real transaction on the database. |
||||
*/ |
||||
// Actual definitions in .hxx file so editors and such recognize file type. |
||||
#include "pqxx/internal/header-pre.hxx" |
||||
#include "pqxx/dbtransaction.hxx" |
||||
#include "pqxx/internal/header-post.hxx" |
||||
@ -0,0 +1,70 @@
|
||||
/* Definition of the pqxx::dbtransaction abstract base class.
|
||||
* |
||||
* pqxx::dbransaction defines a real transaction on the database. |
||||
* |
||||
* DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/dbtransaction instead. |
||||
* |
||||
* Copyright (c) 2000-2022, Jeroen T. Vermeulen. |
||||
* |
||||
* See COPYING for copyright license. If you did not receive a file called |
||||
* COPYING with this source code, please notify the distributor of this |
||||
* mistake, or contact the author. |
||||
*/ |
||||
#ifndef PQXX_H_DBTRANSACTION |
||||
#define PQXX_H_DBTRANSACTION |
||||
|
||||
#if !defined(PQXX_HEADER_PRE) |
||||
# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>." |
||||
#endif |
||||
|
||||
#include "pqxx/transaction_base.hxx" |
||||
|
||||
namespace pqxx |
||||
{ |
||||
/// Abstract transaction base class: bracket transactions on the database.
|
||||
/**
|
||||
* @ingroup transactions |
||||
* |
||||
* Use a dbtransaction-derived object such as "work" (transaction<>) to enclose |
||||
* operations on a database in a single "unit of work." This ensures that the |
||||
* whole series of operations either succeeds as a whole or fails completely. |
||||
* In no case will it leave half-finished work behind in the database. |
||||
* |
||||
* Once processing on a transaction has succeeded and any changes should be |
||||
* allowed to become permanent in the database, call commit(). If something |
||||
* has gone wrong and the changes should be forgotten, call abort() instead. |
||||
* If you do neither, an implicit abort() is executed at destruction time. |
||||
* |
||||
* It is an error to abort a transaction that has already been committed, or to |
||||
* commit a transaction that has already been aborted. Aborting an already |
||||
* aborted transaction or committing an already committed one is allowed, to |
||||
* make error handling easier. Repeated aborts or commits have no effect after |
||||
* the first one. |
||||
* |
||||
* Database transactions are not suitable for guarding long-running processes. |
||||
* If your transaction code becomes too long or too complex, consider ways to |
||||
* break it up into smaller ones. Unfortunately there is no universal recipe |
||||
* for this. |
||||
* |
||||
* The actual operations for committing/aborting the backend transaction are |
||||
* implemented by a derived class. The implementing concrete class must also |
||||
* call @ref close from its destructor. |
||||
*/ |
||||
class PQXX_LIBEXPORT PQXX_NOVTABLE dbtransaction : public transaction_base |
||||
{ |
||||
protected: |
||||
/// Begin transaction.
|
||||
explicit dbtransaction(connection &c) : transaction_base{c} {} |
||||
/// Begin transaction.
|
||||
dbtransaction(connection &c, std::string_view tname) : |
||||
transaction_base{c, tname} |
||||
{} |
||||
/// Begin transaction.
|
||||
dbtransaction( |
||||
connection &c, std::string_view tname, |
||||
std::shared_ptr<std::string> rollback_cmd) : |
||||
transaction_base{c, tname, rollback_cmd} |
||||
{} |
||||
}; |
||||
} // namespace pqxx
|
||||
#endif |
||||
@ -0,0 +1,157 @@
|
||||
Accessing results and result rows {#accessing-results} |
||||
--------------------------------- |
||||
|
||||
When you execute a query using one of the transaction `exec` functions, you |
||||
normally get a `result` object back. A `result` is a container of `row`s. |
||||
|
||||
(There are exceptions. The `exec1` functions expect exactly one row of data, |
||||
so they return just a `row`, not a full `result`.) |
||||
|
||||
Result objects are an all-or-nothing affair. The `exec` function waits until |
||||
it's received all the result data, and then gives it to you in the form of the |
||||
`result`. _(There is a faster, easier way of executing simple queries, so see |
||||
"streaming rows" below as well.)_ |
||||
|
||||
For example, your code might do: |
||||
|
||||
```cxx |
||||
pqxx::result r = tx.exec("SELECT * FROM mytable"); |
||||
``` |
||||
|
||||
Now, how do you access the data inside `r`? |
||||
|
||||
Result sets act as standard C++ containers of rows. Rows act as standard |
||||
C++ containers of fields. So the easiest way to go through them is: |
||||
|
||||
```cxx |
||||
for (auto const &row: r) |
||||
{ |
||||
for (auto const &field: row) std::cout << field.c_str() << '\t'; |
||||
std::cout << '\n'; |
||||
} |
||||
``` |
||||
|
||||
But results and rows also support other kinds of access. Array-style |
||||
indexing, for instance, such as `r[rownum]`: |
||||
|
||||
```cxx |
||||
std::size_t const num_rows = std::size(r); |
||||
for (std::size_t rownum=0u; rownum < num_rows; ++rownum) |
||||
{ |
||||
pqxx::row const row = r[rownum]; |
||||
std::size_t const num_cols = std::size(row); |
||||
for (std::size_t colnum=0u; colnum < num_cols; ++colnum) |
||||
{ |
||||
pqxx::field const field = row[colnum]; |
||||
std::cout << field.c_str() << '\t'; |
||||
} |
||||
|
||||
std::cout << '\n'; |
||||
} |
||||
``` |
||||
|
||||
Every row in the result has the same number of columns, so you don't need to |
||||
look up the number of fields again for each one: |
||||
|
||||
```cxx |
||||
std::size_t const num_rows = std::size(r); |
||||
std::size_t const num_cols = r.columns(); |
||||
for (std::size_t rownum=0u; rownum < num_rows; ++rownum) |
||||
{ |
||||
pqxx::row const row = r[rownum]; |
||||
for (std::size_t colnum=0u; colnum < num_cols; ++colnum) |
||||
{ |
||||
pqxx::field const field = row[colnum]; |
||||
std::cout << field.c_str() << '\t'; |
||||
} |
||||
|
||||
std::cout << '\n'; |
||||
} |
||||
``` |
||||
|
||||
You can even address a field by indexing the `row` using the field's _name:_ |
||||
|
||||
```cxx |
||||
std::cout << row["salary"] << '\n'; |
||||
``` |
||||
|
||||
But try not to do that if speed matters, because looking up the column by name |
||||
takes time. At least you'd want to look up the column index before your loop |
||||
and then use numerical indexes inside the loop. |
||||
|
||||
For C++23 or better, there's also a two-dimensional array access operator: |
||||
|
||||
```cxx |
||||
for (std::size_t rownum=0u; rownum < num_rows; ++rownum) |
||||
{ |
||||
for (std::size_t colnum=0u; colnum < num_cols; ++colnum) |
||||
std::cout result[rownum, colnum].c_str() << '\t'; |
||||
std::cout << '\n'; |
||||
} |
||||
``` |
||||
|
||||
And of course you can use classic "begin/end" loops: |
||||
|
||||
```cxx |
||||
for (auto row = std::begin(r); row != std::end(r); row++) |
||||
{ |
||||
for (auto field = std::begin(row); field != std::end(row); field++) |
||||
std::cout << field->c_str() << '\t'; |
||||
std::cout << '\n'; |
||||
} |
||||
``` |
||||
|
||||
Result sets are immutable, so all iterators on results and rows are actually |
||||
`const_iterator`s. There are also `const_reverse_iterator` types, which |
||||
iterate backwards from `rbegin()` to `rend()` exclusive. |
||||
|
||||
All these iterator types provide one extra bit of convenience that you won't |
||||
normally find in C++ iterators: referential transparency. You don't need to |
||||
dereference them to get to the row or field they refer to. That is, instead |
||||
of `row->end()` you can also choose to say `row.end()`. Similarly, you |
||||
may prefer `field.c_str()` over `field->c_str()`. |
||||
|
||||
This becomes really helpful with the array-indexing operator. With regular |
||||
C++ iterators you would need ugly expressions like `(*row)[0]` or |
||||
`row->operator[](0)`. With the iterator types defined by the result and |
||||
row classes you can simply say `row[0]`. |
||||
|
||||
|
||||
Streaming rows |
||||
-------------- |
||||
|
||||
There's another way to go through the rows coming out of a query. It's |
||||
usually easier and faster, but there are drawbacks. |
||||
|
||||
**One,** you start getting rows before all the data has come in from the |
||||
database. That speeds things up, but what happens if you lose your network |
||||
connection while transferring the data? Your application may already have |
||||
processed some of the data before finding out that the rest isn't coming. If |
||||
that is a problem for your application, streaming may not be the right choice. |
||||
|
||||
**Two,** streaming only works for some types of query. The `stream()` function |
||||
wraps your query in a PostgreSQL `COPY` command, and `COPY` only supports a few |
||||
commands: `SELECT`, `VALUES`, `or an `INSERT`, `UPDATE`, or `DELETE` with a |
||||
`RETURNING` clause. See the `COPY` documentation here: |
||||
https://www.postgresql.org/docs/current/sql-copy.html |
||||
|
||||
**Three,** when you convert a field to a "view" type (such as |
||||
`std::string_view` or `std::basic_string_view<std::byte>`), the view points to |
||||
underlying data which only stays valid until you iterate to the next row or |
||||
exit the loop. So if you want to use that data for longer than a single |
||||
iteration of the streaming loop, you'll have to store it somewhere yourself. |
||||
|
||||
Now for the good news. Streaming does make it very easy to query data and loop |
||||
over it: |
||||
|
||||
```cxx |
||||
for (auto [id, name, x, y] : |
||||
tx.stream<int, std::string_view, float, float>( |
||||
"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. |
||||
@ -0,0 +1,56 @@
|
||||
Binary data {#binary} |
||||
=========== |
||||
|
||||
The database has two ways of storing binary data: `BYTEA` is like a string, but |
||||
containing bytes rather than text characters. And _large objects_ are more |
||||
like a separate table containing binary objects. |
||||
|
||||
Generally you'll want to use `BYTEA` for reasonably-sized values, and large |
||||
objects for very large values. |
||||
|
||||
That's the database side. On the C++ side, in libpqxx, all binary data must be |
||||
either `std::basic_string<std::byte>` or `std::basic_string_view<std::byte>`; |
||||
or if you're building in C++20 or better, anything that's a block of |
||||
contiguous `std::byte` in memory. |
||||
|
||||
So for example, if you want to write a large object, you'd create a |
||||
`pqxx::blob` object. And you might use that to write data in the form of |
||||
`std::basic_string_view<std::byte>`. |
||||
|
||||
Your particular binary data may look different though. You may have it in a |
||||
`std::string`, or a `std::vector<unsigned char>`, or a pointer to `char` |
||||
accompanied by a size (which could be signed or unsigned, and of any of a few |
||||
different widths). Sometimes that's your choice, or sometimes some other |
||||
library will dictate what form it takes. |
||||
|
||||
So long as it's _basically_ still a block of bytes though, you can use |
||||
`pqxx::binary_cast` to construct a `std::basic_string_view<std::byte>` from it. |
||||
|
||||
There are two forms of `binary_cast`. One takes a single argument that must |
||||
support `std::data()` and `std::size()`: |
||||
|
||||
std::string hi{"Hello binary world"}; |
||||
my_blob.write(pqxx::binary_cast(hi); |
||||
|
||||
The other takes a pointer and a size: |
||||
|
||||
char const greeting[] = "Hello binary world"; |
||||
char const *hi = greeting; |
||||
my_blob.write(pqxx::binary_cast(hi, sizeof(greeting))); |
||||
|
||||
|
||||
Caveats |
||||
------- |
||||
|
||||
There are some restrictions on `binary_cast` that you must be aware of. |
||||
|
||||
First, your data must of a type that gives us _bytes._ So: `char`, |
||||
`unsigned char`, `signed char`, `int8_t`, `uint8_t`, or of course `std::byte`. |
||||
You can't feed in a vector of `double`, or anything like that. |
||||
|
||||
Second, the data must be laid out as a contiguous block in memory. If there's |
||||
no `std::data()` implementation for your type, it's not suitable. |
||||
|
||||
Third, `binary_cast` only constructs something like a `std::string_view`. It |
||||
does not make a copy of your actual data. So, make sure that your data remains |
||||
alive and in the same place while you're using it. |
||||
@ -0,0 +1,373 @@
|
||||
Supporting additional data types {#datatypes} |
||||
================================ |
||||
|
||||
Communication with the database mostly happens in a text format. When you |
||||
include an integer value in a query, you use `to_string` to convert it to that |
||||
text format. When you get a query result field "as a float," it converts from |
||||
the text format to a floating-point type. These conversions are everywhere in |
||||
libpqxx. |
||||
|
||||
The conversion sydstem supports many built-in types, but it is also extensible. |
||||
You can "teach" libpqxx (in the scope of your own application) to convert |
||||
additional types of values to and from PostgreSQL's string format. |
||||
|
||||
This is massively useful, but it's not for the faint of heart. You'll need to |
||||
specialise some templates. And, **the API for doing this can change with any |
||||
major libpqxx release.** |
||||
|
||||
|
||||
Converting types |
||||
---------------- |
||||
|
||||
In your application, a conversion is driven entirely by a C++ type you specify. |
||||
The value's SQL type has nothing to do with it, nor is there anything in the |
||||
string that would identify its type. |
||||
|
||||
So, if you've SELECTed a 64-bit integer from the database, and you try to |
||||
convert it to a C++ "short," one of two things will happen: either the number |
||||
is small enough to fit in your `short` (and it just works), or else it throws a |
||||
conversion exception. |
||||
|
||||
Or, your database table might have a text column, but a given field may contain |
||||
a string that _looks_ just like a number. You can convert that value to an |
||||
integer type just fine. Or to a floating-point type. All that matters to the |
||||
conversion is the actual value, and the type. |
||||
|
||||
In some cases the templates for these conversions can tell the type from the |
||||
arguments you pass them: |
||||
|
||||
auto x = to_string(99); |
||||
|
||||
In other cases you may need to instantiate template explicitly: |
||||
|
||||
auto y = from_string<int>("99"); |
||||
|
||||
|
||||
Supporting a new type |
||||
--------------------- |
||||
|
||||
Let's say you have some other SQL type which you want to be able to store in, |
||||
or retrieve from, the database. What would it take to support that? |
||||
|
||||
Sometimes you do not need _complete_ support. You might need a conversion _to_ |
||||
a string but not _from_ a string, for example. The conversion is defined at |
||||
compile time, so don't be too afraid to be incomplete. If you leave out one of |
||||
these steps, it's not going to crash at run time or mess up your data. The |
||||
worst that can happen is that your code won't build. |
||||
|
||||
So what do you need for a complete conversion? |
||||
|
||||
First off, of course, you need a C++ type. It may be your own, but it |
||||
doesn't have to be. It could be a type from a third-party library, or even one |
||||
from the standard library that libpqxx does not yet support. |
||||
|
||||
You also specialise the `pqxx::type_name` variable to specify the type's name. |
||||
This is important for all code which mentions your type in human-readable text, |
||||
such as error messages. |
||||
|
||||
Then, does your type have a built-in null value? You specialise the |
||||
`pqxx::nullness` template to specify the details. |
||||
|
||||
Finally, you specialise the `pqxx::string_traits` template. This is where you |
||||
define the actual conversions. |
||||
|
||||
Let's go through these steps one by one. |
||||
|
||||
|
||||
Your type |
||||
--------- |
||||
|
||||
You'll need a type for which the conversions are not yet defined, because the |
||||
C++ type is what determines the right conversion. One type, one set of |
||||
conversions. |
||||
|
||||
The type doesn't have to be one that you create. The conversion logic was |
||||
designed such that you can build it around any type. So you can just as |
||||
easily build a conversion for a type that's defined somewhere else. There's |
||||
no need to include any special methods or other members inside it. That's also |
||||
how libpqxx can support converting built-in types like `int`. |
||||
|
||||
By the way, if the type is an enum, you don't need to do any of this. Just |
||||
invoke the preprocessor macro `PQXX_DECLARE_ENUM_CONVERSION`, from the global |
||||
namespace near the top of your translation unit, and pass the type as an |
||||
argument. |
||||
|
||||
The library also provides specialisations for `std::optional<T>`, |
||||
`std::shared_ptr<T>`, and `std::unique_ptr<T>`. If you have conversions for |
||||
`T`, you'll also have conversions for those. |
||||
|
||||
|
||||
Specialise `type_name` |
||||
---------------------- |
||||
|
||||
When errors happen during conversion, libpqxx will compose error messages for |
||||
the user. Sometimes these will include the name of the type that's being |
||||
converted. |
||||
|
||||
To tell libpqxx the name of each type, there's a template variable called |
||||
`pqxx::type_name`. For any given type `T`, it should have a specialisation |
||||
that provides that `T`'s human-readable name: |
||||
|
||||
namespace pqxx |
||||
{ |
||||
template<> std::string const type_name<T>{"T"}; |
||||
} |
||||
|
||||
(Yes, this means that you need to define something inside the pqxx namespace. |
||||
Future versions of libpqxx may move this into a separate namespace.) |
||||
|
||||
Define this early on in your translation unit, before any code that might cause |
||||
libpqxx to need the name. That way, the libpqxx code which needs to know the |
||||
type's name can see your definition. |
||||
|
||||
|
||||
Specialise `nullness` |
||||
--------------------- |
||||
|
||||
A struct template `pqxx::nullness` defines whether your type has a natural |
||||
"null value" built in. If so, it also provides member functions for producing |
||||
and recognising null values. |
||||
|
||||
The simplest scenario is also the most common: most types don't have a null |
||||
value built in. In that case, derive your nullness traits from |
||||
`pqxx::no_null`: |
||||
|
||||
namespace pqxx |
||||
{ |
||||
template<> struct nullness<T> : pqxx::no_null<T> {}; |
||||
} |
||||
|
||||
(Here again you're defining this in the pqxx namespace.) |
||||
|
||||
If your type does have a natural null value, the definition gets a little more |
||||
complex: |
||||
|
||||
namespace pqxx |
||||
{ |
||||
template<> struct nullness<T> |
||||
{ |
||||
static constexpr bool has_null{true}; |
||||
static constexpr bool always_null{false}; |
||||
|
||||
static bool is_null(T const &value) |
||||
{ |
||||
// Return whether "value" is null. |
||||
return ...; |
||||
} |
||||
|
||||
[[nodiscard]] static T null() |
||||
{ |
||||
// Return a null value. |
||||
return ...; |
||||
} |
||||
}; |
||||
} |
||||
|
||||
You may be wondering why there's a function to produce a null value, but also a |
||||
function to check whether a value is null. Why not just compare the value to |
||||
the result of `null()`? Because two null values may not be equal. `T` may |
||||
have several different null values. Or it may override the comparison |
||||
operator, similar to SQL where NULL is not equal to NULL. |
||||
|
||||
As a third case, your type may be one that _always_ represents a null value. |
||||
This is the case for `std::nullptr_t` and `std::nullopt_t`. In that case, you |
||||
set `nullness<TYPE>::always_null` to `true` (as well as `has_null` of course), |
||||
and you won't need to define any actual conversions. |
||||
|
||||
|
||||
Specialise `string_traits` |
||||
------------------------- |
||||
|
||||
This part is more work. (You can skip it for types that are _always_ null, |
||||
but those will be rare.) Specialise the `pqxx::string_traits` template: |
||||
|
||||
namespace pqxx |
||||
{ |
||||
template<> struct string_traits<T> |
||||
{ |
||||
static T from_string(std::string_view text); |
||||
static zview to_buf(char *begin, char *end, T const &value); |
||||
static char *into_buf(char *begin, char *end, T const &value); |
||||
static std::size_t size_buffer(T const &value) noexcept; |
||||
}; |
||||
} |
||||
|
||||
You'll also need to write those member functions, or as many of them as needed |
||||
to get your code to build. |
||||
|
||||
|
||||
### `from_string` |
||||
|
||||
We start off simple: `from_string` parses a string as a value of `T`, and |
||||
returns that value. |
||||
|
||||
The string may not be zero-terminated; it's just the `string_view` from |
||||
beginning to end (exclusive). In your tests, cover cases where the string |
||||
does not end in a zero byte. |
||||
|
||||
It's perfectly possible that the string isn't actually a `T` value. Mistakes |
||||
happen. In that case, throw a `pqxx::conversion_error`. |
||||
|
||||
(Of course it's also possible that you run into some other error, so it's fine |
||||
to throw different exceptions as well. But when it's definitely "this is not |
||||
the right format for a `T`," throw `conversion_error`.) |
||||
|
||||
|
||||
### `to_buf` |
||||
|
||||
In this function, you convert a value of `T` into a string that the postgres |
||||
server will understand. |
||||
|
||||
The caller will provide you with a buffer where you can write the string, if |
||||
you need it: from `begin` to `end` exclusive. It's a half-open interval, so |
||||
don't access `*end`. |
||||
|
||||
If the buffer is insufficient for you to do the conversion, throw a |
||||
`pqxx::conversion_overrun`. It doesn't have to be exact: you can be a little |
||||
pessimistic and demand a bit more space than you need. Just be sure to throw |
||||
the exception if there's any risk of overrunning the buffer. |
||||
|
||||
You don't _have_ to use the buffer for this function though. For example, |
||||
`pqxx::string_traits<bool>::to_buf` returns a compile-time constant string and |
||||
ignores the buffer. |
||||
|
||||
Even if you do use the buffer, your string does not _have_ to start at the |
||||
beginning of the buffer. For example, the integer conversions start by writing |
||||
the _least_ significant digit to the _end_ of the buffer, and then writes the |
||||
more significant digits before it. It was just more convenient. |
||||
|
||||
Return a `pqxx::zview`. This is basically a `std::string_view`, but with one |
||||
difference: a `zview` guarantees that there will be a valid zero byte right |
||||
after the `string_view`. The zero byte is not counted as part of its size, but |
||||
it will be there. |
||||
|
||||
Expressed in code, this rule must hold: |
||||
|
||||
void invariant(zview z) |
||||
{ |
||||
assert(z[std::size(z)] == 0); |
||||
} |
||||
|
||||
Make sure you write your trailing zero _before_ the `end`. If the trailing |
||||
zero doesn't fit in the buffer, then there's just not enough room to perform |
||||
the conversion. |
||||
|
||||
Beware of locales when converting. If you use standard library features like |
||||
`sprintf`, they may obey whatever locale is currently set on the system. That |
||||
means that a simple integer like 1000000 may come out as "1000000" on your |
||||
system, but as "1,000,000" on mine, or as "1.000.000" for somebody else, and on |
||||
an Indian system it may be "1,00,000". Values coming from or going to the |
||||
database should be in non-localised formats. You can use libpqxx functions for |
||||
those conversions: `pqxx::from_string`, `pqxx::to_string`, `pqxx::to_buf`. |
||||
|
||||
|
||||
### `into_buf` |
||||
|
||||
This is a stricter version of `to_buf`. All the same requirements apply, but |
||||
in addition you must write your string into the buffer provided, starting |
||||
_exactly_ at `begin`. |
||||
|
||||
That's why this function returns just a simple pointer: the address right |
||||
behind the trailing zero. If the caller wants to use the string, they can |
||||
find it at `begin`. If they want to write a different value into the rest of |
||||
the buffer, they can start at the location you returned. |
||||
|
||||
|
||||
### `size_buffer` |
||||
|
||||
Here you estimate how much buffer space you need for converting a `T` to a |
||||
string. Be precise if you can, but pessimistic if you must. It's usually |
||||
better to waste a few unnecessary bytes than to spend a lot of time computing |
||||
the exact buffer space you need. And failing the conversion because you |
||||
under-budgeted the buffer is worst of all. |
||||
|
||||
Include the trailing zero in the buffer size. If your `to_buf` takes more |
||||
space than just what's needed to store the result, include that too. |
||||
|
||||
Make `size_buffer` a `constexpr` function if you can. It can allow the caller |
||||
to allocate the buffer on the stack, with a size known at compile time. |
||||
|
||||
|
||||
Optional: Specialise `is_unquoted_safe` |
||||
--------------------------------------- |
||||
|
||||
When converting arrays or composite values to strings, libpqxx may need to |
||||
quote values and escape any special characters. This takes time. |
||||
|
||||
Some types though, such as integral or floating-point types, can never have |
||||
any special characters such as quotes, commas, or backslashes in their string |
||||
representations. In such cases, there's no need to quote or escape such values |
||||
in arrays or composite types. |
||||
|
||||
If your type is like that, you can tell libpqxx about this by defining: |
||||
|
||||
namespace pqxx |
||||
{ |
||||
template<> inline constexpr bool is_unquoted_safe<MY_TYPE>{true}; |
||||
} |
||||
|
||||
The code that converts this type of field to strings in an array or a composite |
||||
type can then use a simpler, more efficient variant of the code. It's always |
||||
safe to leave this out; it's _just_ an optimisation for when you're completely |
||||
sure that it's safe. |
||||
|
||||
Do not do this if a string representation of your type may contain a comma; |
||||
semicolon; parenthesis; brace; quote; backslash; newline; or any other |
||||
character that might need escaping. |
||||
|
||||
|
||||
Optional: Specialise `param_format` |
||||
----------------------------------- |
||||
|
||||
This one you don't generally need to worry about. Read on if you're writing a |
||||
type which represents raw binary data, or if you're writing a template where |
||||
_some specialisations_ may contain raw binary data. |
||||
|
||||
When you call parameterised statements, or prepared statements with parameters, |
||||
libpqxx needs to your parameters on to libpq, the underlying C-level PostgreSQL |
||||
client library. |
||||
|
||||
There are two formats for doing that: _text_ and _binary._ In the first, we |
||||
represent all values as strings, and the server then converts them into its own |
||||
internal binary representation. That's what the string conversions are all |
||||
about, and it's what we do for almost all types of parameters. |
||||
|
||||
But we do it differently when the parameter is a contiguous series of raw bytes |
||||
and the corresponding SQL type is `BYTEA`. There is a text format for those, |
||||
but we bypass it for efficiency. The server can use the binary data in the |
||||
exact same form, without any conversion or extra processing. The binary data |
||||
is also twice as compact during transport. |
||||
|
||||
(People sometimes ask why we can't just treat all types as binary. However the |
||||
general case isn't so clear-cut. The binary formats are not documented, there |
||||
are no guarantees that they will be platform-independent or that they will |
||||
remain stable, and there's no really solid way to detect when we might get the |
||||
format wrong. But also, the conversions aren't necessarily as straightforward |
||||
and efficient as they sound. So, for the general case, libpqxx sticks with the |
||||
text formats. Raw binary data alone stands out as a clear win.) |
||||
|
||||
Long story short, the machinery for passing parameters needs to know: is this |
||||
parameter a binary string, or not? In the normal case it can assume "no," and |
||||
that's what it does. The text format is always a safe choice; we just try to |
||||
use the binary format where it's faster. |
||||
|
||||
The `param_format` function template is what makes the decision. We specialise |
||||
it for types which may be binary strings, and use the default for all other |
||||
types. |
||||
|
||||
"Types which _may_ be binary"? You might think we know whether a type is a |
||||
binary type or not. But there are some complications with generic types. |
||||
|
||||
Templates like `std::shared_ptr`, `std::optional`, and so on act like |
||||
"wrappers" for another type. A `std::optional<T>` 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<T>` 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. |
||||
@ -0,0 +1,74 @@
|
||||
String escaping {#escaping} |
||||
=============== |
||||
|
||||
Writing queries as strings is easy. But sometimes you need a variable in |
||||
there: `"SELECT id FROM user WHERE name = '" + name + "'"`. |
||||
|
||||
This is dangerous. See the bug? If `name` can contain quotes, you may have |
||||
an SQL injection vulnerability there, where users can enter nasty stuff like |
||||
"`.'; DROP TABLE user`". Or if you're lucky, it's just a nasty bug that you |
||||
discover when `name` happens to be "d'Arcy". |
||||
|
||||
So, you'll need to _escape_ the `name` before you insert it. This is where |
||||
quotes and other problematic characters are marked as "this is just a character |
||||
in the string, not the end of the string." There are |
||||
[several functions](@ref escaping-functions) in libpqxx to do this for you. |
||||
|
||||
|
||||
SQL injection |
||||
------------- |
||||
|
||||
To understand what SQL injection vulnerabilities are and why they should be |
||||
prevented, imagine you use the following SQL statement somewhere in your |
||||
program: |
||||
|
||||
TX.exec( |
||||
"SELECT number,amount " |
||||
"FROM accounts " |
||||
"WHERE allowed_to_see('" + userid + "','" + password + "')"); |
||||
|
||||
This shows a logged-in user important information on all accounts he is |
||||
authorized to view. The userid and password strings are variables entered |
||||
by the user himself. |
||||
|
||||
Now, if the user is actually an attacker who knows (or can guess) the |
||||
general shape of this SQL statement, imagine he enters the following |
||||
password: |
||||
|
||||
x') OR ('x' = 'x |
||||
|
||||
Does that make sense to you? Probably not. But if this is inserted into |
||||
the SQL string by the C++ code above, the query becomes: |
||||
|
||||
SELECT number,amount |
||||
FROM accounts |
||||
WHERE allowed_to_see('user','x') OR ('x' = 'x') |
||||
|
||||
Is this what you wanted to happen? Probably not! The neat `allowed_to_see()` |
||||
clause is completely circumvented by the "`OR ('x' = 'x')`" clause, which is |
||||
always `true`. Therefore, the attacker will get to see all accounts in the |
||||
database! |
||||
|
||||
|
||||
Using the esc functions |
||||
----------------------- |
||||
|
||||
Here's how you can fix the problem in the example above: |
||||
|
||||
TX.exec( |
||||
"SELECT number,amount " |
||||
"FROM accounts " |
||||
"WHERE allowed_to_see('" + TX.esc(userid) + "', " |
||||
"'" + TX.esc(password) + "')"); |
||||
|
||||
Now, the quotes embedded in the attacker's string will be neatly escaped so |
||||
they can't "break out" of the quoted SQL string they were meant to go into: |
||||
|
||||
SELECT number,amount |
||||
FROM accounts |
||||
WHERE allowed_to_see('user', 'x'') OR (''x'' = ''x') |
||||
|
||||
If you look carefully, you'll see that thanks to the added escape characters |
||||
(a single-quote is escaped in SQL by doubling it) all we get is a very |
||||
strange-looking password string--but not a change in the SQL statement. |
||||
|
||||
@ -0,0 +1,142 @@
|
||||
Getting started {#getting-started} |
||||
=============== |
||||
|
||||
The most basic three types in libpqxx are the _connection_, the _transaction_, |
||||
and the _result_. |
||||
|
||||
They fit together as follows: |
||||
* You connect to the database by creating a `pqxx::connection` object (see |
||||
@ref connections). |
||||
|
||||
* You create a transaction object (see @ref transactions) operating on that |
||||
connection. You'll usually want the `pqxx::work` variety. |
||||
|
||||
Once you're done you call the transaction's `commit` function to make its |
||||
work final. If you don't call this, the work will be rolled back when the |
||||
transaction object is destroyed. |
||||
|
||||
* Until then, use the transaction's `exec`, `query_value`, and `stream` |
||||
functions (and variants) to execute SQL statements. You pass the statements |
||||
themselves in as simple strings. (See @ref streams for more about data |
||||
streaming). |
||||
|
||||
* Most of the `exec` functions return a `pqxx::result` object, which acts |
||||
as a standard container of rows: `pqxx::row`. |
||||
|
||||
Each row in a result, in turn, acts as a container of fields: `pqxx::field`. |
||||
See @ref accessing-results for more about results, rows, and fields. |
||||
|
||||
* Each field's data is stored internally as a text string, in a format defined |
||||
by PostgreSQL. You can convert field or row values using their `as()` and |
||||
`to()` member functions. |
||||
|
||||
* After you've closed the transaction, the connection is free to run a next |
||||
transaction. |
||||
|
||||
Here's a very basic example. It connects to the default database (you'll |
||||
need to have one set up), queries it for a very simple result, converts it to |
||||
an `int`, and prints it out. It also contains some basic error handling. |
||||
|
||||
#include <iostream> |
||||
#include <pqxx/pqxx> |
||||
|
||||
int main() |
||||
{ |
||||
try |
||||
{ |
||||
// Connect to the database. In practice we may have to pass some |
||||
// arguments to say where the database server is, and so on. |
||||
// The constructor parses options exactly like libpq's |
||||
// PQconnectdb/PQconnect, see: |
||||
// https://www.postgresql.org/docs/10/static/libpq-connect.html |
||||
pqxx::connection c; |
||||
|
||||
// Start a transaction. In libpqxx, you always work in one. |
||||
pqxx::work w(c); |
||||
|
||||
// work::exec1() executes a query returning a single row of data. |
||||
// We'll just ask the database to return the number 1 to us. |
||||
pqxx::row r = w.exec1("SELECT 1"); |
||||
|
||||
// Commit your transaction. If an exception occurred before this |
||||
// point, execution will have left the block, and the transaction will |
||||
// have been destroyed along the way. In that case, the failed |
||||
// transaction would implicitly abort instead of getting to this point. |
||||
w.commit(); |
||||
|
||||
// Look at the first and only field in the row, parse it as an integer, |
||||
// and print it. |
||||
// |
||||
// "r[0]" returns the first field, which has an "as<...>()" member |
||||
// function template to convert its contents from their string format |
||||
// to a type of your choice. |
||||
std::cout << r[0].as<int>() << std::endl; |
||||
} |
||||
catch (std::exception const &e) |
||||
{ |
||||
std::cerr << e.what() << std::endl; |
||||
return 1; |
||||
} |
||||
} |
||||
|
||||
This prints the number 1. Notice that you can keep the result object around |
||||
after you've closed the transaction or even the connection. There are |
||||
situations where you can't do it, but generally it's fine. If you're |
||||
interested: you can install your own callbacks for receiving error messages |
||||
from the database, and in that case you'll have to keep the connection object |
||||
alive. But otherwise, it's nice to be able to "fire and forget" your |
||||
connection and deal with the data. |
||||
|
||||
You can also convert an entire row to a series of C++-side types in one go, |
||||
using the @c as member function on the row: |
||||
|
||||
pqxx::connection c; |
||||
pqxx::work w(c); |
||||
pqxx::row r = w.exec1("SELECT 1, 2, 'Hello'"); |
||||
auto [one, two, hello] = r.as<int, int, std::string>(); |
||||
std::cout << (one + two) << ' ' << std::strlen(hello) << std::endl; |
||||
|
||||
Here's a slightly more complicated example. It takes an argument from the |
||||
command line and retrieves a string with that value. The interesting part is |
||||
that it uses the escaping-and-quoting function `quote` to embed this |
||||
string value in SQL safely. It also reads the result field's value as a |
||||
plain C-style string using its `c_str` function. |
||||
|
||||
#include <iostream> |
||||
#include <stdexcept> |
||||
#include <pqxx/pqxx> |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
try |
||||
{ |
||||
if (!argv[1]) throw std::runtime_error("Give me a string!"); |
||||
|
||||
pqxx::connection c; |
||||
pqxx::work w(c); |
||||
|
||||
// work::exec() returns a full result set, which can consist of any |
||||
// number of rows. |
||||
pqxx::result r = w.exec("SELECT " + w.quote(argv[1])); |
||||
|
||||
// End our transaction here. We can still use the result afterwards. |
||||
w.commit(); |
||||
|
||||
// Print the first field of the first row. Read it as a C string, |
||||
// just like std::string::c_str() does. |
||||
std::cout << r[0][0].c_str() << std::endl; |
||||
} |
||||
catch (std::exception const &e) |
||||
{ |
||||
std::cerr << e.what() << std::endl; |
||||
return 1; |
||||
} |
||||
} |
||||
|
||||
You can find more about converting field values to native types, or |
||||
converting values to strings for use with libpqxx, under |
||||
@ref stringconversion. More about getting to the rows and fields of a |
||||
result is under @ref accessing-results. |
||||
|
||||
If you want to handle exceptions thrown by libpqxx in more detail, for |
||||
example to print the SQL contents of a query that failed, see @ref exception. |
||||
@ -0,0 +1,28 @@
|
||||
libpqxx {#mainpage} |
||||
======= |
||||
|
||||
@version 7.7.3 |
||||
@author Jeroen T. Vermeulen |
||||
@see http://pqxx.org |
||||
@see https://github.com/jtv/libpqxx |
||||
|
||||
Welcome to libpqxx, the C++ API to the PostgreSQL database management system. |
||||
|
||||
Compiling this package requires PostgreSQL to be installed -- including the |
||||
C headers for client development. The library builds on top of PostgreSQL's |
||||
standard C API, libpq. The libpq headers are not needed to compile client |
||||
programs, however. |
||||
|
||||
For a quick introduction to installing and using libpqxx, see the README.md |
||||
file. The latest information can be found at http://pqxx.org/ |
||||
|
||||
|
||||
Some links that should help you find your bearings: |
||||
* @ref getting-started |
||||
* @ref thread-safety |
||||
* @ref connections |
||||
* @ref transactions |
||||
* @ref escaping |
||||
* @ref performance |
||||
* @ref transactor |
||||
* @ref datatypes |
||||
@ -0,0 +1,28 @@
|
||||
libpqxx {#mainpage} |
||||
======= |
||||
|
||||
@version @PQXXVERSION@ |
||||
@author Jeroen T. Vermeulen |
||||
@see http://pqxx.org |
||||
@see https://github.com/jtv/libpqxx |
||||
|
||||
Welcome to libpqxx, the C++ API to the PostgreSQL database management system. |
||||
|
||||
Compiling this package requires PostgreSQL to be installed -- including the |
||||
C headers for client development. The library builds on top of PostgreSQL's |
||||
standard C API, libpq. The libpq headers are not needed to compile client |
||||
programs, however. |
||||
|
||||
For a quick introduction to installing and using libpqxx, see the README.md |
||||
file. The latest information can be found at http://pqxx.org/ |
||||
|
||||
|
||||
Some links that should help you find your bearings: |
||||
* @ref getting-started |
||||
* @ref thread-safety |
||||
* @ref connections |
||||
* @ref transactions |
||||
* @ref escaping |
||||
* @ref performance |
||||
* @ref transactor |
||||
* @ref datatypes |
||||
@ -0,0 +1,90 @@
|
||||
Statement parameters {#parameters} |
||||
==================== |
||||
|
||||
When you execute a prepared statement (see @ref prepared), or a parameterised |
||||
statement (using functions like `pqxx::connection::exec_params`), you may write |
||||
special _placeholders_ in the query text. They look like `$1`, `$2`, and so |
||||
on. |
||||
|
||||
If you execute the query and pass parameter values, the call will respectively |
||||
substitute the first where it finds `$1`, the second where it finds `$2`, et |
||||
cetera. |
||||
|
||||
Doing this saves you work. If you don't use statement parameters, you'll need |
||||
to quote and escape your values (see `connection::quote()` and friends) as you |
||||
insert them into your query as literal values. |
||||
|
||||
Or if you forget to do that, you leave yourself open to horrible |
||||
[SQL injection attacks](https://xkcd.com/327/). Trust me, I was born in a town |
||||
whose name started with an apostrophe! |
||||
|
||||
Statement parameters save you this work. With these parameters you can pass |
||||
your values as-is, and they will go across the wire to the database in a safe |
||||
format. |
||||
|
||||
In some cases it may even be faster! When a parameter represents binary data |
||||
(as in the SQL `BYTEA` type), libpqxx will send it directly as binary, which is |
||||
a bit more efficient. If you insert the binary data directly in your query |
||||
text, your CPU will have some extra work to do, converting the data into a text |
||||
format, escaping it, and adding quotes. |
||||
|
||||
|
||||
Dynamic parameter lists |
||||
----------------------- |
||||
|
||||
In rare cases you may just not know how many parameters you'll pass into your |
||||
statement when you call it. |
||||
|
||||
For these situations, have a look at `params`. It lets you compose your |
||||
parameters list on the fly, even add whole ranges of parameters at a time. |
||||
|
||||
You can pass a `params` into your statement as a normal parameter. It will |
||||
fill in all the parameter values it contains into that position of the |
||||
statement's overall parameter list. |
||||
|
||||
So if you call your statement passing a regular parameter `a`, a |
||||
`params` containing just a parameter `b`, and another regular parameter `c`, |
||||
then your call will pass parameters `a`, `b`, and `c`. Or if the params object |
||||
is empty, it will pass just `a` and `c`. If the params object contains `x` and |
||||
`y`, your call will pass `a, x, y, c`. |
||||
|
||||
You can mix static and dynamic parameters freely. Don't go overboard though: |
||||
complexity is where bugs happen! |
||||
|
||||
|
||||
Generating placeholders |
||||
----------------------- |
||||
|
||||
If your code gets particularly complex, it may sometimes happen that it becomes |
||||
hard to track which parameter value belongs with which placeholder. Did you |
||||
intend to pass this numeric value as `$7`, or as `$8`? The answer may depend |
||||
on an `if` that happened earlier in a different function. |
||||
|
||||
(Generally if things get that complex, it's a good idea to look for simpler |
||||
solutions. But especially when performance matters, sometimes you can't avoid |
||||
complexity like that.) |
||||
|
||||
There's a little helper class called `placeholders`. You can use it as a |
||||
counter which produces those placeholder strings, `$1`, `$2`, `$3`, et cetera. |
||||
When you start generating a complex statement, you can create both a `params` |
||||
and a `placeholders`: |
||||
|
||||
pqxx::params values; |
||||
pqxx::placeholders name; |
||||
|
||||
Let's say you've got some complex code to generate the conditions for an SQL |
||||
"WHERE" clause. You'll generally want to do these things close together in |
||||
your, so that you don't accidentally update one part and forget another: |
||||
|
||||
if (extra_clause) |
||||
{ |
||||
// Extend the query text, using the current placeholder. |
||||
query += " AND x = " + name.get(); |
||||
// Add the parameter value. |
||||
values.append(my_x); |
||||
// Move on to the next placeholder value. |
||||
name.next(); |
||||
} |
||||
|
||||
Depending on the starting value of `name`, this might add to `query` a fragment |
||||
like "` AND x = $3`" or "` AND x = $5`". |
||||
@ -0,0 +1,24 @@
|
||||
Performance features {#performance} |
||||
==================== |
||||
|
||||
If your program's database interaction is not as efficient as it needs to be, |
||||
the first place to look is usually the SQL you're executing. But libpqxx |
||||
has a few specialized features to help you squeeze more performance out |
||||
of how you issue commands and retrieve data: |
||||
|
||||
* @ref streams. Use these as a faster way to transfer data between your |
||||
code and the database. |
||||
* `std::string_view` and `pqxx::zview`. In places where traditional C++ worked |
||||
with `std::string`, see whether `std::string_view` or `pqxx::zview` will |
||||
do. Of course that means that you'll have to look at the data's lifetime |
||||
more carefully, but it'll save the computer a lot of copying. |
||||
* @ref prepared. These can be executed many times without the server |
||||
parsing and planning them anew each time. They also save you having to |
||||
escape string parameters. |
||||
* `pqxx::pipeline` lets you send queries to the database in batches, and |
||||
continue other processing while they are executing. |
||||
* `pqxx::connecting` lets you start setting up a database connection, but |
||||
without blocking the thread. |
||||
|
||||
As always of course, don't risk the quality of your code for optimizations |
||||
that you don't need! |
||||
@ -0,0 +1,125 @@
|
||||
Prepared statements {#prepared} |
||||
=================== |
||||
|
||||
Prepared statements are SQL queries that you define once and then invoke |
||||
as many times as you like, typically with varying parameters. It's basically |
||||
a function that you can define ad hoc. |
||||
|
||||
If you have an SQL statement that you're going to execute many times in |
||||
quick succession, it may be more efficient to prepare it once and reuse it. |
||||
This saves the database backend the effort of parsing complex SQL and |
||||
figuring out an efficient execution plan. Another nice side effect is that |
||||
you don't need to worry about escaping parameters. Some corporate coding |
||||
standards require all SQL parameters to be passed in this way, to reduce the |
||||
risk of programmer mistakes leaving room for SQL injections. |
||||
|
||||
|
||||
Preparing a statement |
||||
--------------------- |
||||
|
||||
You create a prepared statement by preparing it on the connection (using the |
||||
`pqxx::connection::prepare` functions), passing an identifier and its SQL text. |
||||
|
||||
The identifier is the name by which the prepared statement will be known; it |
||||
should consist of ASCII letters, digits, and underscores only, and start with |
||||
an ASCII letter. The name is case-sensitive. |
||||
|
||||
```cxx |
||||
void prepare_my_statement(pqxx::connection &c) |
||||
{ |
||||
c.prepare( |
||||
"my_statement", |
||||
"SELECT * FROM Employee WHERE name = 'Xavier'"); |
||||
} |
||||
``` |
||||
|
||||
Once you've done this, you'll be able to call `my_statement` from any |
||||
transaction you execute on the same connection. For this, use the |
||||
`pqxx::transaction_base::exec_prepared` functions. |
||||
|
||||
```cxx |
||||
pqxx::result execute_my_statement(pqxx::transaction_base &t) |
||||
{ |
||||
return t.exec_prepared("my_statement"); |
||||
} |
||||
``` |
||||
|
||||
|
||||
Parameters |
||||
---------- |
||||
|
||||
Did I mention that prepared statements can have parameters? The query text |
||||
can contain `$1`, `$2` etc. as placeholders for parameter values that you |
||||
will provide when you invoke the prepared satement. |
||||
|
||||
See @ref parameters for more about this. And here's a simple example of |
||||
preparing a statement and invoking it with parameters: |
||||
|
||||
```cxx |
||||
void prepare_find(pqxx::connection &c) |
||||
{ |
||||
// Prepare a statement called "find" that looks for employees with a |
||||
// given name (parameter 1) whose salary exceeds a given number |
||||
// (parameter 2). |
||||
c.prepare( |
||||
"find", |
||||
"SELECT * FROM Employee WHERE name = $1 AND salary > $2"); |
||||
} |
||||
``` |
||||
|
||||
This example looks up the prepared statement "find," passes `name` and |
||||
`min_salary` as parameters, and invokes the statement with those values: |
||||
|
||||
```cxx |
||||
pqxx::result execute_find( |
||||
pqxx::transaction_base &t, std::string name, int min_salary) |
||||
{ |
||||
return t.exec_prepared("find", name, min_salary); |
||||
} |
||||
``` |
||||
|
||||
|
||||
A special prepared statement |
||||
---------------------------- |
||||
|
||||
There is one special case: the _nameless_ prepared statement. You may prepare |
||||
a statement without a name, i.e. whose name is an empty string. The unnamed |
||||
statement can be redefined at any time, without un-preparing it first. |
||||
|
||||
|
||||
Performance note |
||||
---------------- |
||||
|
||||
Don't assume that using prepared statements will speed up your application. |
||||
There are cases where prepared statements are actually slower than plain SQL. |
||||
|
||||
The reason is that the backend can often produce a better execution plan when |
||||
it knows the statement's actual parameter values. |
||||
|
||||
For example, say you've got a web application and you're querying for users |
||||
with status "inactive" who have email addresses in a given domain name X. If |
||||
X is a very popular provider, the best way for the database engine to plan the |
||||
query may be to list the inactive users first and then filter for the email |
||||
addresses you're looking for. But in other cases, it may be much faster to |
||||
find matching email addresses first and then see which of their owners are |
||||
"inactive." A prepared statement must be planned to fit either case, but a |
||||
direct query will be optimised based on table statistics, partial indexes, etc. |
||||
|
||||
|
||||
Zero bytes |
||||
---------- |
||||
|
||||
@warning Beware of "nul" bytes! |
||||
|
||||
Any string you pass as a parameter will end at the _first char with value |
||||
zero._ If you pass a string that contains a zero byte, the last byte in the |
||||
value will be the one just before the zero. |
||||
|
||||
So, if you need a zero byte in a string, consider that it's really a _binary |
||||
string,_ which is not the same thing as a text string. SQL represents binary |
||||
data as the `BYTEA` type, or in binary large objects ("blobs"). |
||||
|
||||
In libpqxx, you represent binary data as a range of `std::byte`. They must be |
||||
contiguous in memory, so that libpqxx can pass pointers to the underlying C |
||||
library. So you might use `std::basic_string<std::byte>`, or |
||||
`std::basic_string_view<std::byte>`, or `std::vector<std::byte>`. |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue