Clean up *printf macros to avoid conflict with format archetypes.
We must define the macro "printf" with arguments, else it can mess
up format archetype attributes in builds where PG_PRINTF_ATTRIBUTE
is just "printf". Fortunately, that's easy to do now that we're
requiring C99; we can use __VA_ARGS__.
On the other hand, it's better not to use __VA_ARGS__ for the rest
of the *printf crew, so that one can take the addresses of those
functions without surprises.
I'd proposed doing this some time ago, but forgot to make it happen;
buildfarm failures subsequent to 96bf88d52
reminded me.
Discussion: https://postgr.es/m/22709.1535135640@sss.pgh.pa.us
Discussion: https://postgr.es/m/20180926190934.ea4xvzhkayuw7gkx@alap3.anarazel.de
This commit is contained in:
parent
a6b88d682c
commit
8b91d25884
@ -173,25 +173,19 @@ extern int pg_fprintf(FILE *stream, const char *fmt,...) pg_attribute_printf(2,
|
||||
extern int pg_printf(const char *fmt,...) pg_attribute_printf(1, 2);
|
||||
|
||||
/*
|
||||
* The GCC-specific code below prevents the pg_attribute_printf above from
|
||||
* being replaced, and this is required because gcc doesn't know anything
|
||||
* about pg_printf.
|
||||
* We use __VA_ARGS__ for printf to prevent replacing references to
|
||||
* the "printf" format archetype in format() attribute declarations.
|
||||
* That unfortunately means that taking a function pointer to printf
|
||||
* will not do what we'd wish. (If you need to do that, you must name
|
||||
* pg_printf explicitly.) For printf's sibling functions, use
|
||||
* parameterless macros so that function pointers will work unsurprisingly.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
#define vsnprintf(...) pg_vsnprintf(__VA_ARGS__)
|
||||
#define snprintf(...) pg_snprintf(__VA_ARGS__)
|
||||
#define sprintf(...) pg_sprintf(__VA_ARGS__)
|
||||
#define vfprintf(...) pg_vfprintf(__VA_ARGS__)
|
||||
#define fprintf(...) pg_fprintf(__VA_ARGS__)
|
||||
#define printf(...) pg_printf(__VA_ARGS__)
|
||||
#else
|
||||
#define vsnprintf pg_vsnprintf
|
||||
#define snprintf pg_snprintf
|
||||
#define sprintf pg_sprintf
|
||||
#define vfprintf pg_vfprintf
|
||||
#define fprintf pg_fprintf
|
||||
#define printf pg_printf
|
||||
#endif
|
||||
#define printf(...) pg_printf(__VA_ARGS__)
|
||||
|
||||
/* Replace strerror() with our own, somewhat more robust wrapper */
|
||||
extern char *pg_strerror(int errnum);
|
||||
|
@ -102,13 +102,8 @@
|
||||
#ifdef vsnprintf
|
||||
#undef vsnprintf
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
#define vsnprintf(...) pg_vsnprintf(__VA_ARGS__)
|
||||
#define snprintf(...) pg_snprintf(__VA_ARGS__)
|
||||
#else
|
||||
#define vsnprintf pg_vsnprintf
|
||||
#define snprintf pg_snprintf
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
/* perl version and platform portability */
|
||||
#define NEED_eval_pv
|
||||
|
@ -127,13 +127,8 @@ typedef int Py_ssize_t;
|
||||
#ifdef vsnprintf
|
||||
#undef vsnprintf
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
#define vsnprintf(...) pg_vsnprintf(__VA_ARGS__)
|
||||
#define snprintf(...) pg_snprintf(__VA_ARGS__)
|
||||
#else
|
||||
#define vsnprintf pg_vsnprintf
|
||||
#define snprintf pg_snprintf
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
/*
|
||||
* Used throughout, and also by the Python 2/3 porting layer, so it's easier to
|
||||
|
Loading…
Reference in New Issue
Block a user