PostgreSQL Source Code: src/port/snprintf.c File Reference (original) (raw)
#include "[c.h](c%5F8h%5Fsource.html)"#include <math.h>

Go to the source code of this file.
◆ PG_NL_ARGMAX
◆ strchrnul
◆ PrintfArgType
| Enumerator |
|---|
| ATYPE_NONE |
| ATYPE_INT |
| ATYPE_LONG |
| ATYPE_LONGLONG |
| ATYPE_DOUBLE |
| ATYPE_CHARPTR |
Definition at line 142 of file snprintf.c.
◆ adjust_sign()
◆ compute_padlen()
◆ dopr()
Definition at line 373 of file snprintf.c.
374{
377 int ch;
381 int accum;
387 int precision;
393 double fvalue;
396
397
398
399
400
401
402
404
405 while (*format != '\0')
406 {
407
409 {
410
412
413
416 break;
417
419 break;
421 }
422
423
424
425
426
427
430
431
433
434
436 {
443 break;
444 continue;
445 }
446
453 switch (ch)
454 {
455 case '-':
458 case '+':
461 case '0':
462
466 case '1':
467 case '2':
468 case '3':
469 case '4':
470 case '5':
471 case '6':
472 case '7':
473 case '8':
474 case '9':
475 accum = accum * 10 + (ch - '0');
477 case '.':
480 else
483 accum = 0;
485 case '*':
487 {
488
489
490
491
492
494 }
495 else
496 {
497
499
501 {
503 if (precision < 0)
504 {
505 precision = 0;
507 }
508 }
509 else
510 {
513 {
516 }
517 }
518 }
520 accum = 0;
522 case '$':
523
525 {
526
530 }
532 {
533
535
537 {
539 if (precision < 0)
540 {
541 precision = 0;
543 }
544 }
545 else
546 {
549 {
552 }
553 }
555 }
556 else
558 accum = 0;
560 case 'l':
563 else
566 case 'j':
567#if SIZEOF_INTMAX_T == SIZEOF_LONG
569#elif SIZEOF_INTMAX_T == SIZEOF_LONG_LONG
571#else
572#error "cannot find integer type of the same size as intmax_t"
573#endif
575 case 'z':
576#if SIZEOF_SIZE_T == SIZEOF_LONG
578#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
580#else
581#error "cannot find integer type of the same size as size_t"
582#endif
584 case 'h':
585 case '\'':
586
588 case 'd':
589 case 'i':
591 {
593 precision = accum;
594 else
596 }
598 {
603 else
605 }
606 else
607 {
612 else
614 }
617 break;
618 case 'o':
619 case 'u':
620 case 'x':
621 case 'X':
623 {
625 precision = accum;
626 else
628 }
630 {
635 else
637 }
638 else
639 {
644 else
646 }
649 break;
650 case 'c':
652 {
654 precision = accum;
655 else
657 }
660 else
663 break;
664 case 's':
666 {
668 precision = accum;
669 else
671 }
674 else
676
680 target);
681 break;
682 case 'p':
683
686 else
689 break;
690 case 'e':
691 case 'E':
692 case 'f':
693 case 'g':
694 case 'G':
696 {
698 precision = accum;
699 else
701 }
704 else
705 fvalue = va_arg(args, double);
709 target);
710 break;
711 case 'm':
712 {
715 errbuf, sizeof(errbuf));
716
718 }
719 break;
720 case '%':
722 break;
723 default:
724
725
726
727
728
730 }
731
732
734 break;
735 }
736
737 return;
738
741 target->failed = true;
742}
#define PG_STRERROR_R_BUFLEN
static void dostr(const char *str, int slen, PrintfTarget *target)
static void dopr_outch(int c, PrintfTarget *target)
static void fmtint(long long value, char type, int forcesign, int leftjust, int minlen, int zpad, int precision, int pointflag, PrintfTarget *target)
static void fmtptr(const void *value, PrintfTarget *target)
static void fmtchar(int value, int leftjust, int minlen, PrintfTarget *target)
static void fmtstr(const char *value, int leftjust, int minlen, int maxwidth, int pointflag, PrintfTarget *target)
static void fmtfloat(double value, char type, int forcesign, int leftjust, int minlen, int zpad, int precision, int pointflag, PrintfTarget *target)
static bool find_arguments(const char *format, va_list args, PrintfArgValue *argvalues)
References dopr_outch(), dostr(), PrintfTarget::failed, fb(), find_arguments(), fmtchar(), fmtfloat(), fmtint(), fmtptr(), fmtstr(), format, i, pg_fallthrough, PG_NL_ARGMAX, PG_STRERROR_R_BUFLEN, strchrnul, and strerror_r.
Referenced by pg_vfprintf(), pg_vsnprintf(), and pg_vsprintf().
◆ dopr_outch()
Definition at line 1394 of file snprintf.c.
1395{
1397 {
1398
1400 {
1401 target->nchars++;
1402 return;
1403 }
1405 }
1407}
static void flushbuffer(PrintfTarget *target)
References PrintfTarget::bufend, PrintfTarget::bufptr, fb(), flushbuffer(), PrintfTarget::nchars, and PrintfTarget::stream.
Referenced by dopr(), dopr_outchmulti(), dostr(), fmtchar(), leading_pad(), and pg_strfromd().
◆ dopr_outchmulti()
Definition at line 1410 of file snprintf.c.
1411{
1412
1413 if (slen == 1)
1414 {
1416 return;
1417 }
1418
1419 while (slen > 0)
1420 {
1421 int avail;
1422
1425 else
1426 avail = slen;
1427 if (avail <= 0)
1428 {
1429
1431 {
1433 return;
1434 }
1436 continue;
1437 }
1438 avail = Min(avail, slen);
1440 target->bufptr += avail;
1441 slen -= avail;
1442 }
1443}
References PrintfTarget::bufend, PrintfTarget::bufptr, dopr_outch(), fb(), flushbuffer(), Min, PrintfTarget::nchars, and PrintfTarget::stream.
Referenced by fmtchar(), fmtfloat(), fmtint(), fmtstr(), leading_pad(), and trailing_pad().
◆ dostr()
Definition at line 1357 of file snprintf.c.
1358{
1359
1360 if (slen == 1)
1361 {
1363 return;
1364 }
1365
1366 while (slen > 0)
1367 {
1368 int avail;
1369
1372 else
1373 avail = slen;
1374 if (avail <= 0)
1375 {
1376
1378 {
1380 return;
1381 }
1383 continue;
1384 }
1385 avail = Min(avail, slen);
1387 target->bufptr += avail;
1388 str += avail;
1389 slen -= avail;
1390 }
1391}
References PrintfTarget::bufend, PrintfTarget::bufptr, dopr_outch(), fb(), flushbuffer(), Min, PrintfTarget::nchars, str, and PrintfTarget::stream.
Referenced by dopr(), fmtfloat(), fmtint(), fmtptr(), fmtstr(), and pg_strfromd().
◆ find_arguments()
Definition at line 751 of file snprintf.c.
753{
754 int ch;
756 int accum;
760 int i;
761 int last_dollar = 0;
763
764
765
766
767
768
769
770
771
772 while (*format != '\0')
773 {
774
776 {
777
780 break;
781 }
782
783
790 switch (ch)
791 {
792 case '-':
793 case '+':
795 case '0':
796 case '1':
797 case '2':
798 case '3':
799 case '4':
800 case '5':
801 case '6':
802 case '7':
803 case '8':
804 case '9':
805 accum = accum * 10 + (ch - '0');
807 case '.':
808 accum = 0;
810 case '*':
812 return false;
814 accum = 0;
816 case '$':
818 return false;
820 {
821 if (argtypes[accum] &&
823 return false;
827 }
828 else
830 accum = 0;
832 case 'l':
835 else
838 case 'j':
839#if SIZEOF_INTMAX_T == SIZEOF_LONG
841#elif SIZEOF_INTMAX_T == SIZEOF_LONG_LONG
843#else
844#error "cannot find integer type of the same size as intmax_t"
845#endif
847 case 'z':
848#if SIZEOF_SIZE_T == SIZEOF_LONG
850#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
852#else
853#error "cannot find integer type of the same size as size_t"
854#endif
856 case 'h':
857 case '\'':
858
860 case 'd':
861 case 'i':
862 case 'o':
863 case 'u':
864 case 'x':
865 case 'X':
867 {
869
874 else
876 if (argtypes[fmtpos] &&
878 return false;
881 }
882 else
883 return false;
884 break;
885 case 'c':
887 {
888 if (argtypes[fmtpos] &&
890 return false;
893 }
894 else
895 return false;
896 break;
897 case 's':
898 case 'p':
900 {
901 if (argtypes[fmtpos] &&
903 return false;
906 }
907 else
908 return false;
909 break;
910 case 'e':
911 case 'E':
912 case 'f':
913 case 'g':
914 case 'G':
916 {
917 if (argtypes[fmtpos] &&
919 return false;
922 }
923 else
924 return false;
925 break;
926 case 'm':
927 case '%':
928 break;
929 default:
930 return false;
931 }
932
933
934
935
936
938 return false;
939 }
940
941
942
943
944
945
947 {
948 switch (argtypes[i])
949 {
951 return false;
954 break;
957 break;
960 break;
963 break;
966 break;
967 }
968 }
969
970 return true;
971}
References ATYPE_CHARPTR, ATYPE_DOUBLE, ATYPE_INT, ATYPE_LONG, ATYPE_LONGLONG, ATYPE_NONE, fb(), format, i, Max, and PG_NL_ARGMAX.
Referenced by dopr().
◆ flushbuffer()
◆ fmtchar()
Definition at line 1128 of file snprintf.c.
1129{
1130 int padlen;
1131
1133
1135 {
1138 }
1139
1141
1143}
static int compute_padlen(int minlen, int vallen, int leftjust)
static void trailing_pad(int padlen, PrintfTarget *target)
static void dopr_outchmulti(int c, int slen, PrintfTarget *target)
References compute_padlen(), dopr_outch(), dopr_outchmulti(), fb(), trailing_pad(), and value.
Referenced by dopr(), and rfmtlong().
◆ fmtfloat()
Definition at line 1146 of file snprintf.c.
1149{
1152 int vallen;
1153 char fmt[8];
1155 int zeropadlen = 0;
1156 int padlen;
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175 if (precision < 0)
1176 precision = 0;
1177 prec = Min(precision, 350);
1178
1180 {
1182 vallen = 3;
1183
1184 }
1185 else
1186 {
1187
1188
1189
1190
1191
1192
1193 static const double dzero = 0.0;
1194
1196 (value == 0.0 &&
1200
1202 {
1204 vallen = 8;
1205
1206 }
1208 {
1210 fmt[0] = '%';
1211 fmt[1] = '.';
1212 fmt[2] = '*';
1214 fmt[4] = '\0';
1216 }
1217 else
1218 {
1219 fmt[0] = '%';
1221 fmt[2] = '\0';
1223 }
1224 if (vallen < 0)
1226 }
1227
1229
1231
1233 {
1234
1236
1240 {
1241
1245 }
1246 else
1247 {
1248
1251 }
1252 }
1253 else
1254 {
1255
1257 }
1258
1260 return;
1261
1263 target->failed = true;
1264}
static void leading_pad(int zpad, int signvalue, int *padlen, PrintfTarget *target)
static int adjust_sign(int is_negative, int forcesign, int *signvalue)
static void convert(const int_fast32_t val, char *const buf)
References adjust_sign(), compute_padlen(), convert(), dopr_outchmulti(), dostr(), PrintfTarget::failed, fb(), leading_pad(), Min, snprintf, trailing_pad(), type, and value.
Referenced by dopr().
◆ fmtint()
Definition at line 1017 of file snprintf.c.
1020{
1021 unsigned long long uvalue;
1022 int base;
1024 const char *cvt = "0123456789abcdef";
1027 int vallen = 0;
1028 int padlen;
1029 int zeropad;
1030
1031 switch (type)
1032 {
1033 case 'd':
1034 case 'i':
1035 base = 10;
1037 break;
1038 case 'o':
1039 base = 8;
1041 break;
1042 case 'u':
1043 base = 10;
1045 break;
1046 case 'x':
1047 base = 16;
1049 break;
1050 case 'X':
1051 cvt = "0123456789ABCDEF";
1052 base = 16;
1054 break;
1055 default:
1056 return;
1057 }
1058
1059
1060#ifdef _MSC_VER
1061#pragma warning(push)
1062#pragma warning(disable: 4146)
1063#endif
1064
1067 else
1069#ifdef _MSC_VER
1070#pragma warning(pop)
1071#endif
1072
1073
1074
1075
1076
1078 vallen = 0;
1079 else
1080 {
1081
1082
1083
1084
1085
1086
1087 if (base == 10)
1088 {
1089 do
1090 {
1094 }
1095 else if (base == 16)
1096 {
1097 do
1098 {
1102 }
1103 else
1104 {
1105 do
1106 {
1110 }
1111 }
1112
1113 zeropad = Max(0, precision - vallen);
1114
1116
1118
1121
1123
1125}
References adjust_sign(), compute_padlen(), convert(), dopr_outchmulti(), dostr(), fb(), leading_pad(), Max, trailing_pad(), type, and value.
Referenced by dopr().
◆ fmtptr()
◆ fmtstr()
◆ leading_pad()
◆ pg_fprintf()
◆ pg_printf()
◆ pg_snprintf()
◆ pg_sprintf()
◆ pg_strfromd()
Definition at line 1276 of file snprintf.c.
1277{
1280 int vallen;
1281 char fmt[8];
1283
1284
1287 target.bufend = str + count - 1;
1290 target.failed = false;
1291
1292
1293
1294
1295
1296
1297 if (precision < 1)
1298 precision = 1;
1299 else if (precision > 32)
1300 precision = 32;
1301
1302
1303
1304
1305
1307 {
1309 vallen = 3;
1310 }
1311 else
1312 {
1313 static const double dzero = 0.0;
1314
1315 if (value < 0.0 ||
1316 (value == 0.0 &&
1318 {
1321 }
1322
1324 {
1326 vallen = 8;
1327 }
1328 else
1329 {
1330 fmt[0] = '%';
1331 fmt[1] = '.';
1332 fmt[2] = '*';
1333 fmt[3] = 'g';
1334 fmt[4] = '\0';
1336 if (vallen < 0)
1337 {
1338 target.failed = true;
1340 }
1341 }
1342 }
1343
1346
1348
1350 *(target.bufptr) = '\0';
1353}
#define Assert(condition)
References Assert, PrintfTarget::bufend, PrintfTarget::bufptr, PrintfTarget::bufstart, convert(), dopr_outch(), dostr(), PrintfTarget::failed, fb(), PrintfTarget::nchars, snprintf, str, PrintfTarget::stream, and value.
Referenced by float4out(), and float8out_internal().
◆ pg_vfprintf()
Definition at line 242 of file snprintf.c.
243{
245 char buffer[1024];
246
247 if (stream == NULL)
248 {
250 return -1;
251 }
253 target.bufend = buffer + sizeof(buffer);
254 target.stream = stream;
256 target.failed = false;
258
261}
static void dopr(PrintfTarget *target, const char *format, va_list args)
References PrintfTarget::bufend, PrintfTarget::bufptr, PrintfTarget::bufstart, dopr(), PrintfTarget::failed, fb(), flushbuffer(), PrintfTarget::nchars, and PrintfTarget::stream.
Referenced by pg_fprintf(), pg_printf(), and pg_vprintf().
◆ pg_vprintf()
◆ pg_vsnprintf()
Definition at line 174 of file snprintf.c.
175{
178
179
180
181
182
183
184
185 if (count == 0)
186 {
188 count = 1;
189 }
194 target.failed = false;
196 *(target.bufptr) = '\0';
199}
References PrintfTarget::bufend, PrintfTarget::bufptr, PrintfTarget::bufstart, dopr(), PrintfTarget::failed, fb(), PrintfTarget::nchars, str, and PrintfTarget::stream.
Referenced by pg_snprintf().
◆ pg_vsprintf()
◆ strchrnul()
Definition at line 359 of file snprintf.c.
360{
361 while (*s != '\0' && *s != c)
362 s++;
363 return s;
364}