mirror of
https://github.com/postgres/postgres.git
synced 2025-07-31 22:04:40 +03:00
Always use our own versions of *printf().
We've spent an awful lot of effort over the years in coping with platform-specific vagaries of the *printf family of functions. Let's just forget all that mess and standardize on always using src/port/snprintf.c. This gets rid of a lot of configure logic, and it will allow a saner approach to dealing with %m (though actually changing that is left for a follow-on patch). Preliminary performance testing suggests that as it stands, snprintf.c is faster than the native printf functions for some tasks on some platforms, and slower for other cases. A pending patch will improve that, though cases with floating-point conversions will doubtless remain slower unless we want to put a *lot* of effort into that. Still, we've not observed that *printf is really a performance bottleneck for most workloads, so I doubt this matters much. Patch by me, reviewed by Michael Paquier Discussion: https://postgr.es/m/2975.1526862605@sss.pgh.pa.us
This commit is contained in:
@ -171,106 +171,6 @@ AC_DEFUN([PGAC_STRUCT_ADDRINFO],
|
||||
])])# PGAC_STRUCT_ADDRINFO
|
||||
|
||||
|
||||
# PGAC_FUNC_SNPRINTF_ARG_CONTROL
|
||||
# ---------------------------------------
|
||||
# Determine if snprintf supports %1$ argument selection, e.g. %5$ selects
|
||||
# the fifth argument after the printf format string.
|
||||
# This is not in the C99 standard, but in the Single Unix Specification (SUS).
|
||||
# It is used in our language translation strings.
|
||||
#
|
||||
AC_DEFUN([PGAC_FUNC_SNPRINTF_ARG_CONTROL],
|
||||
[AC_MSG_CHECKING([whether snprintf supports argument control])
|
||||
AC_CACHE_VAL(pgac_cv_snprintf_arg_control,
|
||||
[AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char buf[100];
|
||||
|
||||
/* can it swap arguments? */
|
||||
snprintf(buf, 100, "%2\$d %1\$d", 3, 4);
|
||||
if (strcmp(buf, "4 3") != 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}]])],
|
||||
[pgac_cv_snprintf_arg_control=yes],
|
||||
[pgac_cv_snprintf_arg_control=no],
|
||||
[pgac_cv_snprintf_arg_control=cross])
|
||||
])dnl AC_CACHE_VAL
|
||||
AC_MSG_RESULT([$pgac_cv_snprintf_arg_control])
|
||||
])# PGAC_FUNC_SNPRINTF_ARG_CONTROL
|
||||
|
||||
# PGAC_FUNC_SNPRINTF_SIZE_T_SUPPORT
|
||||
# ---------------------------------
|
||||
# Determine if snprintf supports the z length modifier for printing
|
||||
# size_t-sized variables. That's supported by C99 and POSIX but not
|
||||
# all platforms play ball, so we must test whether it's working.
|
||||
#
|
||||
AC_DEFUN([PGAC_FUNC_SNPRINTF_SIZE_T_SUPPORT],
|
||||
[AC_MSG_CHECKING([whether snprintf supports the %z modifier])
|
||||
AC_CACHE_VAL(pgac_cv_snprintf_size_t_support,
|
||||
[AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char bufz[100];
|
||||
char buf64[100];
|
||||
|
||||
/*
|
||||
* Print the largest unsigned number fitting in a size_t using both %zu
|
||||
* and the previously-determined format for 64-bit integers. Note that
|
||||
* we don't run this code unless we know snprintf handles 64-bit ints.
|
||||
*/
|
||||
bufz[0] = '\0'; /* in case snprintf fails to emit anything */
|
||||
snprintf(bufz, sizeof(bufz), "%zu", ~((size_t) 0));
|
||||
snprintf(buf64, sizeof(buf64), "%" INT64_MODIFIER "u",
|
||||
(unsigned PG_INT64_TYPE) ~((size_t) 0));
|
||||
if (strcmp(bufz, buf64) != 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}]])],
|
||||
[pgac_cv_snprintf_size_t_support=yes],
|
||||
[pgac_cv_snprintf_size_t_support=no],
|
||||
[pgac_cv_snprintf_size_t_support=cross])
|
||||
])dnl AC_CACHE_VAL
|
||||
AC_MSG_RESULT([$pgac_cv_snprintf_size_t_support])
|
||||
])# PGAC_FUNC_SNPRINTF_SIZE_T_SUPPORT
|
||||
|
||||
# PGAC_FUNC_SNPRINTF_C99_RESULT
|
||||
# -----------------------------
|
||||
# Determine whether snprintf returns the desired buffer length when
|
||||
# it overruns the actual buffer length. That's required by C99 and POSIX
|
||||
# but ancient platforms don't behave that way, so we must test.
|
||||
# While we're at it, let's just verify that it doesn't physically overrun
|
||||
# the buffer.
|
||||
#
|
||||
AC_DEFUN([PGAC_FUNC_SNPRINTF_C99_RESULT],
|
||||
[AC_MSG_CHECKING([whether snprintf handles buffer overrun per C99])
|
||||
AC_CACHE_VAL(pgac_cv_snprintf_c99_result,
|
||||
[AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char buf[10];
|
||||
|
||||
strcpy(buf, "abcdefghi");
|
||||
if (snprintf(buf, 4, "%d", 123456) != 6)
|
||||
return 1;
|
||||
if (strcmp(buf, "123") != 0 || buf[4] != 'e')
|
||||
return 1;
|
||||
return 0;
|
||||
}]])],
|
||||
[pgac_cv_snprintf_c99_result=yes],
|
||||
[pgac_cv_snprintf_c99_result=no],
|
||||
[pgac_cv_snprintf_c99_result=cross])
|
||||
])dnl AC_CACHE_VAL
|
||||
AC_MSG_RESULT([$pgac_cv_snprintf_c99_result])
|
||||
])# PGAC_FUNC_SNPRINTF_C99_RESULT
|
||||
|
||||
|
||||
# PGAC_TYPE_LOCALE_T
|
||||
# ------------------
|
||||
# Check for the locale_t type and find the right header file. macOS
|
||||
|
Reference in New Issue
Block a user