Rationalize snprintf.c's handling of "ll" formats.

Although all known platforms define "long long" as 64 bits, it still feels
a bit shaky to be using "va_arg(args, int64)" to pull out an argument that
the caller thought was declared "long long".  The reason it was coded like
this, way back in commit 3311c7669, was to work around the possibility that
the compiler had no type named "long long" --- and, at the time, that it
maybe didn't have 64-bit ints at all.  Now that we're requiring compilers
to support C99, those concerns are moot.  Let's make the code clearer and
more bulletproof by writing "long long" where we mean "long long".

This does introduce a hazard that we'd inefficiently use 128-bit arithmetic
to convert plain old integers.  The way to tackle that would be to provide
two versions of fmtint(), one for "long long" and one for narrower types.
Since, as of today, no platforms require that, we won't bother with the
extra code for now.

Discussion: https://postgr.es/m/1680.1538587115@sss.pgh.pa.us
This commit is contained in:
Tom Lane 2018-10-03 14:33:13 -04:00
parent 6d842be6c1
commit 595a0eab7f

View File

@ -157,7 +157,7 @@ typedef union
{
int i;
long l;
int64 ll;
long long ll;
double d;
char *cptr;
} PrintfArgValue;
@ -319,7 +319,7 @@ static bool find_arguments(const char *format, va_list args,
static void fmtstr(const char *value, int leftjust, int minlen, int maxwidth,
int pointflag, PrintfTarget *target);
static void fmtptr(void *value, PrintfTarget *target);
static void fmtint(int64 value, char type, int forcesign,
static void fmtint(long long value, char type, int forcesign,
int leftjust, int minlen, int zpad, int precision, int pointflag,
PrintfTarget *target);
static void fmtchar(int value, int leftjust, int minlen, PrintfTarget *target);
@ -390,7 +390,7 @@ dopr(PrintfTarget *target, const char *format, va_list args)
int forcesign;
int fmtpos;
int cvalue;
int64 numvalue;
long long numvalue;
double fvalue;
char *strvalue;
PrintfArgValue argvalues[PG_NL_ARGMAX + 1];
@ -603,7 +603,7 @@ nextch2:
else
{
if (longlongflag)
numvalue = va_arg(args, int64);
numvalue = va_arg(args, long long);
else if (longflag)
numvalue = va_arg(args, long);
else
@ -626,7 +626,7 @@ nextch2:
if (have_dollar)
{
if (longlongflag)
numvalue = (uint64) argvalues[fmtpos].ll;
numvalue = (unsigned long long) argvalues[fmtpos].ll;
else if (longflag)
numvalue = (unsigned long) argvalues[fmtpos].l;
else
@ -635,7 +635,7 @@ nextch2:
else
{
if (longlongflag)
numvalue = (uint64) va_arg(args, int64);
numvalue = (unsigned long long) va_arg(args, long long);
else if (longflag)
numvalue = (unsigned long) va_arg(args, long);
else
@ -944,7 +944,7 @@ nextch1:
argvalues[i].l = va_arg(args, long);
break;
case ATYPE_LONGLONG:
argvalues[i].ll = va_arg(args, int64);
argvalues[i].ll = va_arg(args, long long);
break;
case ATYPE_DOUBLE:
argvalues[i].d = va_arg(args, double);
@ -1002,11 +1002,11 @@ fmtptr(void *value, PrintfTarget *target)
}
static void
fmtint(int64 value, char type, int forcesign, int leftjust,
fmtint(long long value, char type, int forcesign, int leftjust,
int minlen, int zpad, int precision, int pointflag,
PrintfTarget *target)
{
uint64 base;
unsigned long long base;
int dosign;
const char *cvt = "0123456789abcdef";
int signvalue = 0;
@ -1056,7 +1056,7 @@ fmtint(int64 value, char type, int forcesign, int leftjust,
else
{
/* make integer string */
uint64 uvalue = (uint64) value;
unsigned long long uvalue = (unsigned long long) value;
do
{