PostgreSQL Source Code: src/port/snprintf.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#include "c.h"
35
36#include <math.h>
37
38
39
40
41
42
43
44#define PG_NL_ARGMAX 31
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103#undef vsnprintf
104#undef snprintf
105#undef vsprintf
106#undef sprintf
107#undef vfprintf
108#undef fprintf
109#undef vprintf
110#undef printf
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125typedef struct
126{
130
135
136
137
138
139
140
141
142typedef enum
143{
151
152typedef union
153{
160
161
164
165
166
167
168
169
170
171
172
173int
175{
177 char onebyte[1];
178
179
180
181
182
183
184
185 if (count == 0)
186 {
187 str = onebyte;
188 count = 1;
189 }
192 target.stream = NULL;
194 target.failed = false;
196 *(target.bufptr) = '\0';
199}
200
201int
203{
205 va_list args;
206
207 va_start(args, fmt);
209 va_end(args);
210 return len;
211}
212
213int
215{
217
219 target.bufend = NULL;
220 target.stream = NULL;
221 target.nchars = 0;
222 target.failed = false;
224 *(target.bufptr) = '\0';
227}
228
229int
231{
233 va_list args;
234
235 va_start(args, fmt);
237 va_end(args);
238 return len;
239}
240
241int
243{
245 char buffer[1024];
246
247 if (stream == NULL)
248 {
249 errno = EINVAL;
250 return -1;
251 }
253 target.bufend = buffer + sizeof(buffer);
254 target.stream = stream;
256 target.failed = false;
258
261}
262
263int
265{
267 va_list args;
268
269 va_start(args, fmt);
271 va_end(args);
272 return len;
273}
274
275int
277{
279}
280
281int
283{
285 va_list args;
286
287 va_start(args, fmt);
289 va_end(args);
290 return len;
291}
292
293
294
295
296
297static void
299{
301
302
303
304
305
306 if (!target->failed && nc > 0)
307 {
308 size_t written;
309
310 written = fwrite(target->bufstart, 1, nc, target->stream);
311 target->nchars += written;
312 if (written != nc)
313 target->failed = true;
314 }
316}
317
318
321static void fmtstr(const char *value, int leftjust, int minlen, int maxwidth,
324static void fmtint(long long value, char type, int forcesign,
325 int leftjust, int minlen, int zpad, int precision, int pointflag,
329 int leftjust, int minlen, int zpad, int precision, int pointflag,
334static int adjust_sign(int is_negative, int forcesign, int *signvalue);
335static int compute_padlen(int minlen, int vallen, int leftjust);
336static void leading_pad(int zpad, int signvalue, int *padlen,
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354#if !HAVE_DECL_STRCHRNUL
355
356#define strchrnul pg_strchrnul
357
358static inline const char *
360{
361 while (*s != '\0' && *s != c)
362 s++;
363 return s;
364}
365
366#endif
367
368
369
370
371
372static void
374{
375 int save_errno = errno;
376 const char *first_pct = NULL;
377 int ch;
378 bool have_dollar;
379 bool have_star;
380 bool afterstar;
381 int accum;
382 int longlongflag;
383 int longflag;
384 int pointflag;
385 int leftjust;
386 int fieldwidth;
387 int precision;
388 int zpad;
389 int forcesign;
390 int fmtpos;
391 int cvalue;
392 long long numvalue;
393 double fvalue;
394 const char *strvalue;
396
397
398
399
400
401
402
403 have_dollar = false;
404
405 while (*format != '\0')
406 {
407
409 {
410
412
413
416 break;
417
418 if (*next_pct == '\0')
419 break;
421 }
422
423
424
425
426
427
428 if (first_pct == NULL)
430
431
433
434
436 {
438 strvalue = va_arg(args, char *);
439 if (strvalue == NULL)
440 strvalue = "(null)";
441 dostr(strvalue, strlen(strvalue), target);
443 break;
444 continue;
445 }
446
447 fieldwidth = precision = zpad = leftjust = forcesign = 0;
448 longflag = longlongflag = pointflag = 0;
449 fmtpos = accum = 0;
450 have_star = afterstar = false;
451nextch2:
453 switch (ch)
454 {
455 case '-':
456 leftjust = 1;
457 goto nextch2;
458 case '+':
459 forcesign = 1;
460 goto nextch2;
461 case '0':
462
463 if (accum == 0 && !pointflag)
464 zpad = '0';
465
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');
476 goto nextch2;
477 case '.':
478 if (have_star)
479 have_star = false;
480 else
481 fieldwidth = accum;
482 pointflag = 1;
483 accum = 0;
484 goto nextch2;
485 case '*':
486 if (have_dollar)
487 {
488
489
490
491
492
493 afterstar = true;
494 }
495 else
496 {
497
498 int starval = va_arg(args, int);
499
500 if (pointflag)
501 {
502 precision = starval;
503 if (precision < 0)
504 {
505 precision = 0;
506 pointflag = 0;
507 }
508 }
509 else
510 {
511 fieldwidth = starval;
512 if (fieldwidth < 0)
513 {
514 leftjust = 1;
515 fieldwidth = -fieldwidth;
516 }
517 }
518 }
519 have_star = true;
520 accum = 0;
521 goto nextch2;
522 case '$':
523
524 if (!have_dollar)
525 {
526
528 goto bad_format;
529 have_dollar = true;
530 }
531 if (afterstar)
532 {
533
534 int starval = argvalues[accum].i;
535
536 if (pointflag)
537 {
538 precision = starval;
539 if (precision < 0)
540 {
541 precision = 0;
542 pointflag = 0;
543 }
544 }
545 else
546 {
547 fieldwidth = starval;
548 if (fieldwidth < 0)
549 {
550 leftjust = 1;
551 fieldwidth = -fieldwidth;
552 }
553 }
554 afterstar = false;
555 }
556 else
557 fmtpos = accum;
558 accum = 0;
559 goto nextch2;
560 case 'l':
561 if (longflag)
562 longlongflag = 1;
563 else
564 longflag = 1;
565 goto nextch2;
566 case 'j':
567#if SIZEOF_INTMAX_T == SIZEOF_LONG
568 longflag = 1;
569#elif SIZEOF_INTMAX_T == SIZEOF_LONG_LONG
570 longlongflag = 1;
571#else
572#error "cannot find integer type of the same size as intmax_t"
573#endif
574 goto nextch2;
575 case 'z':
576#if SIZEOF_SIZE_T == SIZEOF_LONG
577 longflag = 1;
578#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
579 longlongflag = 1;
580#else
581#error "cannot find integer type of the same size as size_t"
582#endif
583 goto nextch2;
584 case 'h':
585 case '\'':
586
587 goto nextch2;
588 case 'd':
589 case 'i':
590 if (!have_star)
591 {
592 if (pointflag)
593 precision = accum;
594 else
595 fieldwidth = accum;
596 }
597 if (have_dollar)
598 {
599 if (longlongflag)
600 numvalue = argvalues[fmtpos].ll;
601 else if (longflag)
602 numvalue = argvalues[fmtpos].l;
603 else
604 numvalue = argvalues[fmtpos].i;
605 }
606 else
607 {
608 if (longlongflag)
609 numvalue = va_arg(args, long long);
610 else if (longflag)
611 numvalue = va_arg(args, long);
612 else
613 numvalue = va_arg(args, int);
614 }
615 fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad,
616 precision, pointflag, target);
617 break;
618 case 'o':
619 case 'u':
620 case 'x':
621 case 'X':
622 if (!have_star)
623 {
624 if (pointflag)
625 precision = accum;
626 else
627 fieldwidth = accum;
628 }
629 if (have_dollar)
630 {
631 if (longlongflag)
632 numvalue = (unsigned long long) argvalues[fmtpos].ll;
633 else if (longflag)
634 numvalue = (unsigned long) argvalues[fmtpos].l;
635 else
636 numvalue = (unsigned int) argvalues[fmtpos].i;
637 }
638 else
639 {
640 if (longlongflag)
641 numvalue = (unsigned long long) va_arg(args, long long);
642 else if (longflag)
643 numvalue = (unsigned long) va_arg(args, long);
644 else
645 numvalue = (unsigned int) va_arg(args, int);
646 }
647 fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad,
648 precision, pointflag, target);
649 break;
650 case 'c':
651 if (!have_star)
652 {
653 if (pointflag)
654 precision = accum;
655 else
656 fieldwidth = accum;
657 }
658 if (have_dollar)
659 cvalue = (unsigned char) argvalues[fmtpos].i;
660 else
661 cvalue = (unsigned char) va_arg(args, int);
662 fmtchar(cvalue, leftjust, fieldwidth, target);
663 break;
664 case 's':
665 if (!have_star)
666 {
667 if (pointflag)
668 precision = accum;
669 else
670 fieldwidth = accum;
671 }
672 if (have_dollar)
673 strvalue = argvalues[fmtpos].cptr;
674 else
675 strvalue = va_arg(args, char *);
676
677 if (strvalue == NULL)
678 strvalue = "(null)";
679 fmtstr(strvalue, leftjust, fieldwidth, precision, pointflag,
680 target);
681 break;
682 case 'p':
683
684 if (have_dollar)
685 strvalue = argvalues[fmtpos].cptr;
686 else
687 strvalue = va_arg(args, char *);
688 fmtptr((const void *) strvalue, target);
689 break;
690 case 'e':
691 case 'E':
692 case 'f':
693 case 'g':
694 case 'G':
695 if (!have_star)
696 {
697 if (pointflag)
698 precision = accum;
699 else
700 fieldwidth = accum;
701 }
702 if (have_dollar)
703 fvalue = argvalues[fmtpos].d;
704 else
705 fvalue = va_arg(args, double);
706 fmtfloat(fvalue, ch, forcesign, leftjust,
707 fieldwidth, zpad,
708 precision, pointflag,
709 target);
710 break;
711 case 'm':
712 {
714 const char *errm = strerror_r(save_errno,
715 errbuf, sizeof(errbuf));
716
717 dostr(errm, strlen(errm), target);
718 }
719 break;
720 case '%':
722 break;
723 default:
724
725
726
727
728
729 goto bad_format;
730 }
731
732
734 break;
735 }
736
737 return;
738
739bad_format:
740 errno = EINVAL;
741 target->failed = true;
742}
743
744
745
746
747
748
749
750static bool
753{
754 int ch;
755 bool afterstar;
756 int accum;
757 int longlongflag;
758 int longflag;
759 int fmtpos;
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
785 longflag = longlongflag = 0;
786 fmtpos = accum = 0;
787 afterstar = false;
788nextch1:
790 switch (ch)
791 {
792 case '-':
793 case '+':
794 goto nextch1;
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');
806 goto nextch1;
807 case '.':
808 accum = 0;
809 goto nextch1;
810 case '*':
811 if (afterstar)
812 return false;
813 afterstar = true;
814 accum = 0;
815 goto nextch1;
816 case '$':
818 return false;
819 if (afterstar)
820 {
821 if (argtypes[accum] &&
823 return false;
825 last_dollar = Max(last_dollar, accum);
826 afterstar = false;
827 }
828 else
829 fmtpos = accum;
830 accum = 0;
831 goto nextch1;
832 case 'l':
833 if (longflag)
834 longlongflag = 1;
835 else
836 longflag = 1;
837 goto nextch1;
838 case 'j':
839#if SIZEOF_INTMAX_T == SIZEOF_LONG
840 longflag = 1;
841#elif SIZEOF_INTMAX_T == SIZEOF_LONG_LONG
842 longlongflag = 1;
843#else
844#error "cannot find integer type of the same size as intmax_t"
845#endif
846 goto nextch1;
847 case 'z':
848#if SIZEOF_SIZE_T == SIZEOF_LONG
849 longflag = 1;
850#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
851 longlongflag = 1;
852#else
853#error "cannot find integer type of the same size as size_t"
854#endif
855 goto nextch1;
856 case 'h':
857 case '\'':
858
859 goto nextch1;
860 case 'd':
861 case 'i':
862 case 'o':
863 case 'u':
864 case 'x':
865 case 'X':
866 if (fmtpos)
867 {
869
870 if (longlongflag)
872 else if (longflag)
874 else
876 if (argtypes[fmtpos] &&
877 argtypes[fmtpos] != atype)
878 return false;
879 argtypes[fmtpos] = atype;
880 last_dollar = Max(last_dollar, fmtpos);
881 }
882 else
883 return false;
884 break;
885 case 'c':
886 if (fmtpos)
887 {
888 if (argtypes[fmtpos] &&
890 return false;
892 last_dollar = Max(last_dollar, fmtpos);
893 }
894 else
895 return false;
896 break;
897 case 's':
898 case 'p':
899 if (fmtpos)
900 {
901 if (argtypes[fmtpos] &&
903 return false;
905 last_dollar = Max(last_dollar, fmtpos);
906 }
907 else
908 return false;
909 break;
910 case 'e':
911 case 'E':
912 case 'f':
913 case 'g':
914 case 'G':
915 if (fmtpos)
916 {
917 if (argtypes[fmtpos] &&
919 return false;
921 last_dollar = Max(last_dollar, fmtpos);
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
937 if (afterstar)
938 return false;
939 }
940
941
942
943
944
945
946 for (i = 1; i <= last_dollar; i++)
947 {
948 switch (argtypes[i])
949 {
951 return false;
953 argvalues[i].i = va_arg(args, int);
954 break;
956 argvalues[i].l = va_arg(args, long);
957 break;
959 argvalues[i].ll = va_arg(args, long long);
960 break;
962 argvalues[i].d = va_arg(args, double);
963 break;
965 argvalues[i].cptr = va_arg(args, char *);
966 break;
967 }
968 }
969
970 return true;
971}
972
973static void
974fmtstr(const char *value, int leftjust, int minlen, int maxwidth,
976{
977 int padlen,
978 vallen;
979
980
981
982
983
984 if (pointflag)
986 else
987 vallen = strlen(value);
988
990
991 if (padlen > 0)
992 {
994 padlen = 0;
995 }
996
998
1000}
1001
1002static void
1004{
1005 int vallen;
1007
1008
1010 if (vallen < 0)
1011 target->failed = true;
1012 else
1014}
1015
1016static void
1018 int minlen, int zpad, int precision, int pointflag,
1020{
1021 unsigned long long uvalue;
1022 int base;
1023 int dosign;
1024 const char *cvt = "0123456789abcdef";
1025 int signvalue = 0;
1027 int vallen = 0;
1028 int padlen;
1029 int zeropad;
1030
1031 switch (type)
1032 {
1033 case 'd':
1034 case 'i':
1035 base = 10;
1036 dosign = 1;
1037 break;
1038 case 'o':
1039 base = 8;
1040 dosign = 0;
1041 break;
1042 case 'u':
1043 base = 10;
1044 dosign = 0;
1045 break;
1046 case 'x':
1047 base = 16;
1048 dosign = 0;
1049 break;
1050 case 'X':
1051 cvt = "0123456789ABCDEF";
1052 base = 16;
1053 dosign = 0;
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
1065 if (dosign && adjust_sign((value < 0), forcesign, &signvalue))
1066 uvalue = -(unsigned long long) value;
1067 else
1068 uvalue = (unsigned long long) value;
1069#ifdef _MSC_VER
1070#pragma warning(pop)
1071#endif
1072
1073
1074
1075
1076
1077 if (value == 0 && pointflag && precision == 0)
1078 vallen = 0;
1079 else
1080 {
1081
1082
1083
1084
1085
1086
1087 if (base == 10)
1088 {
1089 do
1090 {
1091 convert[sizeof(convert) - (++vallen)] = cvt[uvalue % 10];
1092 uvalue = uvalue / 10;
1093 } while (uvalue);
1094 }
1095 else if (base == 16)
1096 {
1097 do
1098 {
1099 convert[sizeof(convert) - (++vallen)] = cvt[uvalue % 16];
1100 uvalue = uvalue / 16;
1101 } while (uvalue);
1102 }
1103 else
1104 {
1105 do
1106 {
1107 convert[sizeof(convert) - (++vallen)] = cvt[uvalue % 8];
1108 uvalue = uvalue / 8;
1109 } while (uvalue);
1110 }
1111 }
1112
1113 zeropad = Max(0, precision - vallen);
1114
1115 padlen = compute_padlen(minlen, vallen + zeropad, leftjust);
1116
1117 leading_pad(zpad, signvalue, &padlen, target);
1118
1119 if (zeropad > 0)
1121
1123
1125}
1126
1127static void
1129{
1130 int padlen;
1131
1133
1134 if (padlen > 0)
1135 {
1137 padlen = 0;
1138 }
1139
1141
1143}
1144
1145static void
1147 int minlen, int zpad, int precision, int pointflag,
1149{
1150 int signvalue = 0;
1151 int prec;
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
1179 if (isnan(value))
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 &&
1197 memcmp(&value, &dzero, sizeof(double)) != 0)),
1198 forcesign, &signvalue))
1200
1201 if (isinf(value))
1202 {
1203 strcpy(convert, "Infinity");
1204 vallen = 8;
1205
1206 }
1207 else if (pointflag)
1208 {
1209 zeropadlen = precision - prec;
1210 fmt[0] = '%';
1211 fmt[1] = '.';
1212 fmt[2] = '*';
1213 fmt[3] = type;
1214 fmt[4] = '\0';
1216 }
1217 else
1218 {
1219 fmt[0] = '%';
1220 fmt[1] = type;
1221 fmt[2] = '\0';
1223 }
1224 if (vallen < 0)
1225 goto fail;
1226 }
1227
1228 padlen = compute_padlen(minlen, vallen + zeropadlen, leftjust);
1229
1230 leading_pad(zpad, signvalue, &padlen, target);
1231
1232 if (zeropadlen > 0)
1233 {
1234
1235 char *epos = strrchr(convert, 'e');
1236
1237 if (!epos)
1238 epos = strrchr(convert, 'E');
1239 if (epos)
1240 {
1241
1244 dostr(epos, vallen - (epos - convert), target);
1245 }
1246 else
1247 {
1248
1251 }
1252 }
1253 else
1254 {
1255
1257 }
1258
1260 return;
1261
1262fail:
1263 target->failed = true;
1264}
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275int
1277{
1279 int signvalue = 0;
1280 int vallen;
1281 char fmt[8];
1283
1284
1287 target.bufend = str + count - 1;
1288 target.stream = NULL;
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
1306 if (isnan(value))
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 &&
1317 memcmp(&value, &dzero, sizeof(double)) != 0))
1318 {
1319 signvalue = '-';
1321 }
1322
1323 if (isinf(value))
1324 {
1325 strcpy(convert, "Infinity");
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;
1339 goto fail;
1340 }
1341 }
1342 }
1343
1344 if (signvalue)
1346
1348
1349fail:
1350 *(target.bufptr) = '\0';
1353}
1354
1355
1356static void
1358{
1359
1360 if (slen == 1)
1361 {
1363 return;
1364 }
1365
1366 while (slen > 0)
1367 {
1368 int avail;
1369
1370 if (target->bufend != NULL)
1372 else
1373 avail = slen;
1374 if (avail <= 0)
1375 {
1376
1377 if (target->stream == NULL)
1378 {
1379 target->nchars += slen;
1380 return;
1381 }
1383 continue;
1384 }
1385 avail = Min(avail, slen);
1386 memmove(target->bufptr, str, avail);
1387 target->bufptr += avail;
1388 str += avail;
1389 slen -= avail;
1390 }
1391}
1392
1393static void
1395{
1397 {
1398
1399 if (target->stream == NULL)
1400 {
1401 target->nchars++;
1402 return;
1403 }
1405 }
1407}
1408
1409static void
1411{
1412
1413 if (slen == 1)
1414 {
1416 return;
1417 }
1418
1419 while (slen > 0)
1420 {
1421 int avail;
1422
1423 if (target->bufend != NULL)
1425 else
1426 avail = slen;
1427 if (avail <= 0)
1428 {
1429
1430 if (target->stream == NULL)
1431 {
1432 target->nchars += slen;
1433 return;
1434 }
1436 continue;
1437 }
1438 avail = Min(avail, slen);
1439 memset(target->bufptr, c, avail);
1440 target->bufptr += avail;
1441 slen -= avail;
1442 }
1443}
1444
1445
1446static int
1447adjust_sign(int is_negative, int forcesign, int *signvalue)
1448{
1449 if (is_negative)
1450 {
1451 *signvalue = '-';
1452 return true;
1453 }
1454 else if (forcesign)
1455 *signvalue = '+';
1456 return false;
1457}
1458
1459
1460static int
1462{
1463 int padlen;
1464
1465 padlen = minlen - vallen;
1466 if (padlen < 0)
1467 padlen = 0;
1468 if (leftjust)
1469 padlen = -padlen;
1470 return padlen;
1471}
1472
1473
1474static void
1476{
1477 int maxpad;
1478
1479 if (*padlen > 0 && zpad)
1480 {
1481 if (signvalue)
1482 {
1484 --(*padlen);
1485 signvalue = 0;
1486 }
1487 if (*padlen > 0)
1488 {
1490 *padlen = 0;
1491 }
1492 }
1493 maxpad = (signvalue != 0);
1494 if (*padlen > maxpad)
1495 {
1497 *padlen = maxpad;
1498 }
1499 if (signvalue)
1500 {
1502 if (*padlen > 0)
1503 --(*padlen);
1504 else if (*padlen < 0)
1505 ++(*padlen);
1506 }
1507}
1508
1509
1510static void
1512{
1513 if (padlen < 0)
1515}
Assert(PointerIsAligned(start, uint64))
#define PG_STRERROR_R_BUFLEN
size_t strnlen(const char *str, size_t maxlen)
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 leading_pad(int zpad, int signvalue, int *padlen, PrintfTarget *target)
int pg_strfromd(char *str, size_t count, int precision, double value)
static void fmtptr(const void *value, PrintfTarget *target)
static void flushbuffer(PrintfTarget *target)
int pg_printf(const char *fmt,...)
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)
int pg_vprintf(const char *fmt, va_list args)
int pg_snprintf(char *str, size_t count, const char *fmt,...)
static int compute_padlen(int minlen, int vallen, int leftjust)
int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
static void trailing_pad(int padlen, PrintfTarget *target)
static void fmtfloat(double value, char type, int forcesign, int leftjust, int minlen, int zpad, int precision, int pointflag, PrintfTarget *target)
int pg_sprintf(char *str, const char *fmt,...)
static bool find_arguments(const char *format, va_list args, PrintfArgValue *argvalues)
int pg_vsprintf(char *str, const char *fmt, va_list args)
static void dopr(PrintfTarget *target, const char *format, va_list args)
static void dopr_outchmulti(int c, int slen, PrintfTarget *target)
int pg_fprintf(FILE *stream, const char *fmt,...)
int pg_vfprintf(FILE *stream, const char *fmt, va_list args)
static int adjust_sign(int is_negative, int forcesign, int *signvalue)
static void convert(const int_fast32_t val, char *const buf)