Skip to content

Commit

Permalink
Re-do string conversions.
Browse files Browse the repository at this point in the history
Changes some error conditions to throw `pqxx::conversion_error` instead
of `pqxx::failure` (which is more for problems closer to the actual
database, such as connection failures).

Where available, use C++17 `std::to_chars` and `std::from_chars` for
numeric conversions.  As far as I can see, these work with exactly the
right formats to communicate with postgres.  Eventually my custom code
here will go away, but for now, clang does not support these new
functions and gcc only partially.
  • Loading branch information
jtv committed Feb 17, 2019
1 parent a90f312 commit 00533be
Show file tree
Hide file tree
Showing 8 changed files with 418 additions and 30 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
6.3.2
- Conversion errors no longer throw pqxx::failure; always conversion_error!
- Use C++17's built-in numeric string conversions, if available.
- Query numeric precision in a more sensible, standard way.
- Avoid "dead code" warning.
6.3.1
Expand Down
2 changes: 2 additions & 0 deletions configitems
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ 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_GCC_CONST public compiler
PQXX_HAVE_GCC_DEPRECATED public compiler
PQXX_HAVE_GCC_PURE public compiler
Expand Down
101 changes: 91 additions & 10 deletions configure
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for libpqxx 6.3.0.
# Generated by GNU Autoconf 2.69 for libpqxx 6.3.2.
#
# Report bugs to <Jeroen T. Vermeulen>.
#
Expand Down Expand Up @@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='libpqxx'
PACKAGE_TARNAME='libpqxx'
PACKAGE_VERSION='6.3.0'
PACKAGE_STRING='libpqxx 6.3.0'
PACKAGE_VERSION='6.3.2'
PACKAGE_STRING='libpqxx 6.3.2'
PACKAGE_BUGREPORT='Jeroen T. Vermeulen'
PACKAGE_URL=''

Expand Down Expand Up @@ -1364,7 +1364,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures libpqxx 6.3.0 to adapt to many kinds of systems.
\`configure' configures libpqxx 6.3.2 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

Expand Down Expand Up @@ -1435,7 +1435,7 @@ fi

if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of libpqxx 6.3.0:";;
short | recursive ) echo "Configuration of libpqxx 6.3.2:";;
esac
cat <<\_ACEOF

Expand Down Expand Up @@ -1562,7 +1562,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
libpqxx configure 6.3.0
libpqxx configure 6.3.2
generated by GNU Autoconf 2.69

Copyright (C) 2012 Free Software Foundation, Inc.
Expand Down Expand Up @@ -2052,7 +2052,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by libpqxx $as_me 6.3.0, which was
It was created by libpqxx $as_me 6.3.2, which was
generated by GNU Autoconf 2.69. Invocation command line was

$ $0 $@
Expand Down Expand Up @@ -4160,7 +4160,7 @@ fi

# Define the identity of the package.
PACKAGE='libpqxx'
VERSION='6.3.0'
VERSION='6.3.2'


cat >>confdefs.h <<_ACEOF
Expand Down Expand Up @@ -17581,6 +17581,87 @@ $as_echo "$have_exp_optional" >&6; }
fi


# It's early 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 clang, which compiles the integer conversions but then fails
# at link time because of a missing symbol "__muloti4" when compiling
# "long long" code. I couldn't resolve that symbol by adding -lm either. So
# don't just compile these tests; link them as well.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++17 charconv integer conversion" >&5
$as_echo_n "checking for C++17 charconv integer conversion... " >&6; }
have_charconv_int=yes
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <charconv>
int
main ()
{

char z[100];
using ull = unsigned long long;
auto rt = std::to_chars(z, z + sizeof(z), ull{0});
if (rt.ec != std::errc{}) return 1;
ull n;
auto rf = std::from_chars(z, z + sizeof(z), n);
if (rf.ec != std::errc{}) return 2;
return int(n)


;
return 0;
}
_ACEOF
if ac_fn_cxx_try_link "$LINENO"; then :

$as_echo "#define PQXX_HAVE_CHARCONV_INT 1" >>confdefs.h

else
have_charconv_int=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_charconv_int" >&5
$as_echo "$have_charconv_int" >&6; }

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++17 charconv floating-point conversion" >&5
$as_echo_n "checking for C++17 charconv floating-point conversion... " >&6; }
have_charconv_float=yes
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <charconv>
int
main ()
{

char z[100];
using ld = long double;
auto rt = std::to_chars(
z, z + sizeof(z), ld{0.1},
std::chars_format::generic);
if (rt.ec != std::errc{}) return 1;
ld n;
auto rf = std::from_chars(z, z + sizeof(z), n);
if (rf.ec != std::errc{}) return 2;
return int(n)


;
return 0;
}
_ACEOF
if ac_fn_cxx_try_link "$LINENO"; then :

$as_echo "#define PQXX_HAVE_CHARCONV_FLOAT 1" >>confdefs.h

else
have_charconv_float=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_charconv_float" >&5
$as_echo "$have_charconv_float" >&6; }

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for poll(2)" >&5
$as_echo_n "checking for poll(2)... " >&6; }
if ${ax_cv_have_poll+:} false; then :
Expand Down Expand Up @@ -18636,7 +18717,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by libpqxx $as_me 6.3.0, which was
This file was extended by libpqxx $as_me 6.3.2, which was
generated by GNU Autoconf 2.69. Invocation command line was

CONFIG_FILES = $CONFIG_FILES
Expand Down Expand Up @@ -18702,7 +18783,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
libpqxx config.status 6.3.0
libpqxx config.status 6.3.2
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

Expand Down
61 changes: 60 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,69 @@ AC_MSG_RESULT($have_exp_optional)
fi


# It's early 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 clang, which compiles the integer conversions but then fails
# at link time because of a missing symbol "__muloti4" when compiling
# "long long" code. 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(
[AC_LANG_PROGRAM(
[#include <charconv>],
[[
char z[100];
using ull = unsigned long long;
auto rt = std::to_chars(z, z + sizeof(z), ull{0});
if (rt.ec != std::errc{}) return 1;
ull n;
auto rf = std::from_chars(z, z + sizeof(z), n);
if (rf.ec != std::errc{}) return 2;
return int(n)
]]
)],
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(
[AC_LANG_PROGRAM(
[#include <charconv>],
[[
char z[100];
using ld = long double;
auto rt = std::to_chars(
z, z + sizeof(z), ld{0.1},
std::chars_format::generic);
if (rt.ec != std::errc{}) return 1;
ld n;
auto rf = std::from_chars(z, z + sizeof(z), n);
if (rf.ec != std::errc{}) return 2;
return int(n)
]]
)],
AC_DEFINE(
[PQXX_HAVE_CHARCONV_FLOAT],
1,
[Define if <charconv> supports floating-point conversion.]),
have_charconv_float=no)
AC_MSG_RESULT($have_charconv_float)

AX_HAVE_POLL(
[AX_CONFIG_FEATURE_ENABLE(poll)],
[AX_CONFIG_FEATURE_DISABLE(poll)])
AX_CONFIG_FEATURE([poll], [System supports poll().], [HAVE_POLL], [System supports poll().])
AX_CONFIG_FEATURE(
[poll],
[System supports poll().],
[HAVE_POLL],
[System supports poll().])

if test "$ax_cv_have_poll" != "yes"
then
Expand Down
6 changes: 6 additions & 0 deletions include/pqxx/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@
/* 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 supports [[deprecated]] attribute */
#undef PQXX_HAVE_DEPRECATED

Expand Down
2 changes: 1 addition & 1 deletion include/pqxx/version.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include "pqxx/compiler-internal-pre.hxx"

/// Full libpqxx version string.
#define PQXX_VERSION "6.3.0"
#define PQXX_VERSION "6.3.2"
/// Library ABI version.
#define PQXX_ABI "6.3"

Expand Down

0 comments on commit 00533be

Please sign in to comment.