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{

127 char *bufptr;

128 char *bufstart;

129 char *bufend;

130

131 FILE *stream;

132 int nchars;

133 bool failed;

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 }

1406 *(target->bufptr++) = c;

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)