22 * Copyright (c) 1983, 1995, 1996 Eric P. Allman
33 * Copyright (c) 1988, 1993
44 * The Regents of the University of California. All rights reserved.
5- * Portions Copyright (c) 1996-2020 , PostgreSQL Global Development Group
5+ * Portions Copyright (c) 1996-2021 , PostgreSQL Global Development Group
66 *
77 * Redistribution and use in source and binary forms, with or without
88 * modification, are permitted provided that the following conditions
@@ -321,7 +321,7 @@ static bool find_arguments(const char *format, va_list args,
321321 PrintfArgValue * argvalues );
322322static void fmtstr (const char * value , int leftjust , int minlen , int maxwidth ,
323323 int pointflag , PrintfTarget * target );
324- static void fmtptr (void * value , PrintfTarget * target );
324+ static void fmtptr (const void * value , PrintfTarget * target );
325325static void fmtint (long long value , char type , int forcesign ,
326326 int leftjust , int minlen , int zpad , int precision , int pointflag ,
327327 PrintfTarget * target );
@@ -377,7 +377,7 @@ dopr(PrintfTarget *target, const char *format, va_list args)
377377 int cvalue ;
378378 long long numvalue ;
379379 double fvalue ;
380- char * strvalue ;
380+ const char * strvalue ;
381381 PrintfArgValue argvalues [PG_NL_ARGMAX + 1 ];
382382
383383 /*
@@ -422,7 +422,8 @@ dopr(PrintfTarget *target, const char *format, va_list args)
422422 {
423423 format ++ ;
424424 strvalue = va_arg (args , char * );
425- Assert (strvalue != NULL );
425+ if (strvalue == NULL )
426+ strvalue = "(null)" ;
426427 dostr (strvalue , strlen (strvalue ), target );
427428 if (target -> failed )
428429 break ;
@@ -653,8 +654,9 @@ dopr(PrintfTarget *target, const char *format, va_list args)
653654 strvalue = argvalues [fmtpos ].cptr ;
654655 else
655656 strvalue = va_arg (args , char * );
656- /* Whine if someone tries to print a NULL string */
657- Assert (strvalue != NULL );
657+ /* If string is NULL, silently substitute "(null)" */
658+ if (strvalue == NULL )
659+ strvalue = "(null)" ;
658660 fmtstr (strvalue , leftjust , fieldwidth , precision , pointflag ,
659661 target );
660662 break ;
@@ -664,7 +666,7 @@ dopr(PrintfTarget *target, const char *format, va_list args)
664666 strvalue = argvalues [fmtpos ].cptr ;
665667 else
666668 strvalue = va_arg (args , char * );
667- fmtptr ((void * ) strvalue , target );
669+ fmtptr ((const void * ) strvalue , target );
668670 break ;
669671 case 'e' :
670672 case 'E' :
@@ -978,7 +980,7 @@ fmtstr(const char *value, int leftjust, int minlen, int maxwidth,
978980}
979981
980982static void
981- fmtptr (void * value , PrintfTarget * target )
983+ fmtptr (const void * value , PrintfTarget * target )
982984{
983985 int vallen ;
984986 char convert [64 ];
@@ -996,8 +998,8 @@ fmtint(long long value, char type, int forcesign, int leftjust,
996998 int minlen , int zpad , int precision , int pointflag ,
997999 PrintfTarget * target )
9981000{
999- unsigned long long base ;
10001001 unsigned long long uvalue ;
1002+ int base ;
10011003 int dosign ;
10021004 const char * cvt = "0123456789abcdef" ;
10031005 int signvalue = 0 ;
@@ -1056,12 +1058,36 @@ fmtint(long long value, char type, int forcesign, int leftjust,
10561058 vallen = 0 ;
10571059 else
10581060 {
1059- /* make integer string */
1060- do
1061+ /*
1062+ * Convert integer to string. We special-case each of the possible
1063+ * base values so as to avoid general-purpose divisions. On most
1064+ * machines, division by a fixed constant can be done much more
1065+ * cheaply than a general divide.
1066+ */
1067+ if (base == 10 )
1068+ {
1069+ do
1070+ {
1071+ convert [sizeof (convert ) - (++ vallen )] = cvt [uvalue % 10 ];
1072+ uvalue = uvalue / 10 ;
1073+ } while (uvalue );
1074+ }
1075+ else if (base == 16 )
10611076 {
1062- convert [sizeof (convert ) - (++ vallen )] = cvt [uvalue % base ];
1063- uvalue = uvalue / base ;
1064- } while (uvalue );
1077+ do
1078+ {
1079+ convert [sizeof (convert ) - (++ vallen )] = cvt [uvalue % 16 ];
1080+ uvalue = uvalue / 16 ;
1081+ } while (uvalue );
1082+ }
1083+ else /* base == 8 */
1084+ {
1085+ do
1086+ {
1087+ convert [sizeof (convert ) - (++ vallen )] = cvt [uvalue % 8 ];
1088+ uvalue = uvalue / 8 ;
1089+ } while (uvalue );
1090+ }
10651091 }
10661092
10671093 zeropad = Max (0 , precision - vallen );
0 commit comments