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#ifdef WIN32

561 case 'I':

562

565 else if (format[0] == '6' && format[1] == '4')

566 {

568 longlongflag = 1;

569 }

570 else

571 {

572#if SIZEOF_VOID_P == SIZEOF_LONG

573 longflag = 1;

574#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG

575 longlongflag = 1;

576#else

577#error "cannot find integer type of the same size as intptr_t"

578#endif

579 }

580 goto nextch2;

581#endif

582 case 'l':

583 if (longflag)

584 longlongflag = 1;

585 else

586 longflag = 1;

587 goto nextch2;

588 case 'z':

589#if SIZEOF_SIZE_T == SIZEOF_LONG

590 longflag = 1;

591#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG

592 longlongflag = 1;

593#else

594#error "cannot find integer type of the same size as size_t"

595#endif

596 goto nextch2;

597 case 'h':

598 case '\'':

599

600 goto nextch2;

601 case 'd':

602 case 'i':

603 if (!have_star)

604 {

605 if (pointflag)

606 precision = accum;

607 else

608 fieldwidth = accum;

609 }

610 if (have_dollar)

611 {

612 if (longlongflag)

613 numvalue = argvalues[fmtpos].ll;

614 else if (longflag)

615 numvalue = argvalues[fmtpos].l;

616 else

617 numvalue = argvalues[fmtpos].i;

618 }

619 else

620 {

621 if (longlongflag)

622 numvalue = va_arg(args, long long);

623 else if (longflag)

624 numvalue = va_arg(args, long);

625 else

626 numvalue = va_arg(args, int);

627 }

628 fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad,

629 precision, pointflag, target);

630 break;

631 case 'o':

632 case 'u':

633 case 'x':

634 case 'X':

635 if (!have_star)

636 {

637 if (pointflag)

638 precision = accum;

639 else

640 fieldwidth = accum;

641 }

642 if (have_dollar)

643 {

644 if (longlongflag)

645 numvalue = (unsigned long long) argvalues[fmtpos].ll;

646 else if (longflag)

647 numvalue = (unsigned long) argvalues[fmtpos].l;

648 else

649 numvalue = (unsigned int) argvalues[fmtpos].i;

650 }

651 else

652 {

653 if (longlongflag)

654 numvalue = (unsigned long long) va_arg(args, long long);

655 else if (longflag)

656 numvalue = (unsigned long) va_arg(args, long);

657 else

658 numvalue = (unsigned int) va_arg(args, int);

659 }

660 fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad,

661 precision, pointflag, target);

662 break;

663 case 'c':

664 if (!have_star)

665 {

666 if (pointflag)

667 precision = accum;

668 else

669 fieldwidth = accum;

670 }

671 if (have_dollar)

672 cvalue = (unsigned char) argvalues[fmtpos].i;

673 else

674 cvalue = (unsigned char) va_arg(args, int);

675 fmtchar(cvalue, leftjust, fieldwidth, target);

676 break;

677 case 's':

678 if (!have_star)

679 {

680 if (pointflag)

681 precision = accum;

682 else

683 fieldwidth = accum;

684 }

685 if (have_dollar)

686 strvalue = argvalues[fmtpos].cptr;

687 else

688 strvalue = va_arg(args, char *);

689

690 if (strvalue == NULL)

691 strvalue = "(null)";

692 fmtstr(strvalue, leftjust, fieldwidth, precision, pointflag,

693 target);

694 break;

695 case 'p':

696

697 if (have_dollar)

698 strvalue = argvalues[fmtpos].cptr;

699 else

700 strvalue = va_arg(args, char *);

701 fmtptr((const void *) strvalue, target);

702 break;

703 case 'e':

704 case 'E':

705 case 'f':

706 case 'g':

707 case 'G':

708 if (!have_star)

709 {

710 if (pointflag)

711 precision = accum;

712 else

713 fieldwidth = accum;

714 }

715 if (have_dollar)

716 fvalue = argvalues[fmtpos].d;

717 else

718 fvalue = va_arg(args, double);

719 fmtfloat(fvalue, ch, forcesign, leftjust,

720 fieldwidth, zpad,

721 precision, pointflag,

722 target);

723 break;

724 case 'm':

725 {

727 const char *errm = strerror_r(save_errno,

728 errbuf, sizeof(errbuf));

729

730 dostr(errm, strlen(errm), target);

731 }

732 break;

733 case '%':

735 break;

736 default:

737

738

739

740

741

742 goto bad_format;

743 }

744

745

747 break;

748 }

749

750 return;

751

752bad_format:

753 errno = EINVAL;

754 target->failed = true;

755}

756

757

758

759

760

761

762

763static bool

766{

767 int ch;

768 bool afterstar;

769 int accum;

770 int longlongflag;

771 int longflag;

772 int fmtpos;

773 int i;

774 int last_dollar = 0;

776

777

778

779

780

781

782

783

784

785 while (*format != '\0')

786 {

787

789 {

790

793 break;

794 }

795

796

798 longflag = longlongflag = 0;

799 fmtpos = accum = 0;

800 afterstar = false;

801nextch1:

803 switch (ch)

804 {

805 case '-':

806 case '+':

807 goto nextch1;

808 case '0':

809 case '1':

810 case '2':

811 case '3':

812 case '4':

813 case '5':

814 case '6':

815 case '7':

816 case '8':

817 case '9':

818 accum = accum * 10 + (ch - '0');

819 goto nextch1;

820 case '.':

821 accum = 0;

822 goto nextch1;

823 case '*':

824 if (afterstar)

825 return false;

826 afterstar = true;

827 accum = 0;

828 goto nextch1;

829 case '$':

831 return false;

832 if (afterstar)

833 {

834 if (argtypes[accum] &&

836 return false;

838 last_dollar = Max(last_dollar, accum);

839 afterstar = false;

840 }

841 else

842 fmtpos = accum;

843 accum = 0;

844 goto nextch1;

845#ifdef WIN32

846 case 'I':

847

850 else if (format[0] == '6' && format[1] == '4')

851 {

853 longlongflag = 1;

854 }

855 else

856 {

857#if SIZEOF_VOID_P == SIZEOF_LONG

858 longflag = 1;

859#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG

860 longlongflag = 1;

861#else

862#error "cannot find integer type of the same size as intptr_t"

863#endif

864 }

865 goto nextch1;

866#endif

867 case 'l':

868 if (longflag)

869 longlongflag = 1;

870 else

871 longflag = 1;

872 goto nextch1;

873 case 'z':

874#if SIZEOF_SIZE_T == SIZEOF_LONG

875 longflag = 1;

876#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG

877 longlongflag = 1;

878#else

879#error "cannot find integer type of the same size as size_t"

880#endif

881 goto nextch1;

882 case 'h':

883 case '\'':

884

885 goto nextch1;

886 case 'd':

887 case 'i':

888 case 'o':

889 case 'u':

890 case 'x':

891 case 'X':

892 if (fmtpos)

893 {

895

896 if (longlongflag)

898 else if (longflag)

900 else

902 if (argtypes[fmtpos] &&

903 argtypes[fmtpos] != atype)

904 return false;

905 argtypes[fmtpos] = atype;

906 last_dollar = Max(last_dollar, fmtpos);

907 }

908 else

909 return false;

910 break;

911 case 'c':

912 if (fmtpos)

913 {

914 if (argtypes[fmtpos] &&

916 return false;

918 last_dollar = Max(last_dollar, fmtpos);

919 }

920 else

921 return false;

922 break;

923 case 's':

924 case 'p':

925 if (fmtpos)

926 {

927 if (argtypes[fmtpos] &&

929 return false;

931 last_dollar = Max(last_dollar, fmtpos);

932 }

933 else

934 return false;

935 break;

936 case 'e':

937 case 'E':

938 case 'f':

939 case 'g':

940 case 'G':

941 if (fmtpos)

942 {

943 if (argtypes[fmtpos] &&

945 return false;

947 last_dollar = Max(last_dollar, fmtpos);

948 }

949 else

950 return false;

951 break;

952 case 'm':

953 case '%':

954 break;

955 default:

956 return false;

957 }

958

959

960

961

962

963 if (afterstar)

964 return false;

965 }

966

967

968

969

970

971

972 for (i = 1; i <= last_dollar; i++)

973 {

974 switch (argtypes[i])

975 {

977 return false;

979 argvalues[i].i = va_arg(args, int);

980 break;

982 argvalues[i].l = va_arg(args, long);

983 break;

985 argvalues[i].ll = va_arg(args, long long);

986 break;

988 argvalues[i].d = va_arg(args, double);

989 break;

991 argvalues[i].cptr = va_arg(args, char *);

992 break;

993 }

994 }

995

996 return true;

997}

998

999static void

1000fmtstr(const char *value, int leftjust, int minlen, int maxwidth,

1002{

1003 int padlen,

1004 vallen;

1005

1006

1007

1008

1009

1010 if (pointflag)

1012 else

1013 vallen = strlen(value);

1014

1016

1017 if (padlen > 0)

1018 {

1020 padlen = 0;

1021 }

1022

1024

1026}

1027

1028static void

1030{

1031 int vallen;

1033

1034

1036 if (vallen < 0)

1037 target->failed = true;

1038 else

1040}

1041

1042static void

1044 int minlen, int zpad, int precision, int pointflag,

1046{

1047 unsigned long long uvalue;

1048 int base;

1049 int dosign;

1050 const char *cvt = "0123456789abcdef";

1051 int signvalue = 0;

1053 int vallen = 0;

1054 int padlen;

1055 int zeropad;

1056

1057 switch (type)

1058 {

1059 case 'd':

1060 case 'i':

1061 base = 10;

1062 dosign = 1;

1063 break;

1064 case 'o':

1065 base = 8;

1066 dosign = 0;

1067 break;

1068 case 'u':

1069 base = 10;

1070 dosign = 0;

1071 break;

1072 case 'x':

1073 base = 16;

1074 dosign = 0;

1075 break;

1076 case 'X':

1077 cvt = "0123456789ABCDEF";

1078 base = 16;

1079 dosign = 0;

1080 break;

1081 default:

1082 return;

1083 }

1084

1085

1086#ifdef _MSC_VER

1087#pragma warning(push)

1088#pragma warning(disable: 4146)

1089#endif

1090

1091 if (dosign && adjust_sign((value < 0), forcesign, &signvalue))

1092 uvalue = -(unsigned long long) value;

1093 else

1094 uvalue = (unsigned long long) value;

1095#ifdef _MSC_VER

1096#pragma warning(pop)

1097#endif

1098

1099

1100

1101

1102

1103 if (value == 0 && pointflag && precision == 0)

1104 vallen = 0;

1105 else

1106 {

1107

1108

1109

1110

1111

1112

1113 if (base == 10)

1114 {

1115 do

1116 {

1117 convert[sizeof(convert) - (++vallen)] = cvt[uvalue % 10];

1118 uvalue = uvalue / 10;

1119 } while (uvalue);

1120 }

1121 else if (base == 16)

1122 {

1123 do

1124 {

1125 convert[sizeof(convert) - (++vallen)] = cvt[uvalue % 16];

1126 uvalue = uvalue / 16;

1127 } while (uvalue);

1128 }

1129 else

1130 {

1131 do

1132 {

1133 convert[sizeof(convert) - (++vallen)] = cvt[uvalue % 8];

1134 uvalue = uvalue / 8;

1135 } while (uvalue);

1136 }

1137 }

1138

1139 zeropad = Max(0, precision - vallen);

1140

1141 padlen = compute_padlen(minlen, vallen + zeropad, leftjust);

1142

1143 leading_pad(zpad, signvalue, &padlen, target);

1144

1145 if (zeropad > 0)

1147

1149

1151}

1152

1153static void

1155{

1156 int padlen;

1157

1159

1160 if (padlen > 0)

1161 {

1163 padlen = 0;

1164 }

1165

1167

1169}

1170

1171static void

1173 int minlen, int zpad, int precision, int pointflag,

1175{

1176 int signvalue = 0;

1177 int prec;

1178 int vallen;

1179 char fmt[8];

1181 int zeropadlen = 0;

1182 int padlen;

1183

1184

1185

1186

1187

1188

1189

1190

1191

1192

1193

1194

1195

1196

1197

1198

1199

1200

1201 if (precision < 0)

1202 precision = 0;

1203 prec = Min(precision, 350);

1204

1205 if (isnan(value))

1206 {

1208 vallen = 3;

1209

1210 }

1211 else

1212 {

1213

1214

1215

1216

1217

1218

1219 static const double dzero = 0.0;

1220

1222 (value == 0.0 &&

1223 memcmp(&value, &dzero, sizeof(double)) != 0)),

1224 forcesign, &signvalue))

1226

1227 if (isinf(value))

1228 {

1229 strcpy(convert, "Infinity");

1230 vallen = 8;

1231

1232 }

1233 else if (pointflag)

1234 {

1235 zeropadlen = precision - prec;

1236 fmt[0] = '%';

1237 fmt[1] = '.';

1238 fmt[2] = '*';

1239 fmt[3] = type;

1240 fmt[4] = '\0';

1242 }

1243 else

1244 {

1245 fmt[0] = '%';

1246 fmt[1] = type;

1247 fmt[2] = '\0';

1249 }

1250 if (vallen < 0)

1251 goto fail;

1252

1253

1254

1255

1256

1257

1258#ifdef WIN32

1259 if (vallen >= 6 &&

1260 convert[vallen - 5] == 'e' &&

1261 convert[vallen - 3] == '0')

1262 {

1265 vallen--;

1266 }

1267#endif

1268 }

1269

1270 padlen = compute_padlen(minlen, vallen + zeropadlen, leftjust);

1271

1272 leading_pad(zpad, signvalue, &padlen, target);

1273

1274 if (zeropadlen > 0)

1275 {

1276

1277 char *epos = strrchr(convert, 'e');

1278

1279 if (!epos)

1280 epos = strrchr(convert, 'E');

1281 if (epos)

1282 {

1283

1286 dostr(epos, vallen - (epos - convert), target);

1287 }

1288 else

1289 {

1290

1293 }

1294 }

1295 else

1296 {

1297

1299 }

1300

1302 return;

1303

1304fail:

1305 target->failed = true;

1306}

1307

1308

1309

1310

1311

1312

1313

1314

1315

1316

1317int

1319{

1321 int signvalue = 0;

1322 int vallen;

1323 char fmt[8];

1325

1326

1329 target.bufend = str + count - 1;

1330 target.stream = NULL;

1332 target.failed = false;

1333

1334

1335

1336

1337

1338

1339 if (precision < 1)

1340 precision = 1;

1341 else if (precision > 32)

1342 precision = 32;

1343

1344

1345

1346

1347

1348 if (isnan(value))

1349 {

1351 vallen = 3;

1352 }

1353 else

1354 {

1355 static const double dzero = 0.0;

1356

1357 if (value < 0.0 ||

1358 (value == 0.0 &&

1359 memcmp(&value, &dzero, sizeof(double)) != 0))

1360 {

1361 signvalue = '-';

1363 }

1364

1365 if (isinf(value))

1366 {

1367 strcpy(convert, "Infinity");

1368 vallen = 8;

1369 }

1370 else

1371 {

1372 fmt[0] = '%';

1373 fmt[1] = '.';

1374 fmt[2] = '*';

1375 fmt[3] = 'g';

1376 fmt[4] = '\0';

1378 if (vallen < 0)

1379 {

1380 target.failed = true;

1381 goto fail;

1382 }

1383

1384#ifdef WIN32

1385 if (vallen >= 6 &&

1386 convert[vallen - 5] == 'e' &&

1387 convert[vallen - 3] == '0')

1388 {

1391 vallen--;

1392 }

1393#endif

1394 }

1395 }

1396

1397 if (signvalue)

1399

1401

1402fail:

1403 *(target.bufptr) = '\0';

1406}

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 memmove(target->bufptr, str, avail);

1440 target->bufptr += avail;

1441 str += avail;

1442 slen -= avail;

1443 }

1444}

1445

1446static void

1448{

1450 {

1451

1452 if (target->stream == NULL)

1453 {

1454 target->nchars++;

1455 return;

1456 }

1458 }

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

1460}

1461

1462static void

1464{

1465

1466 if (slen == 1)

1467 {

1469 return;

1470 }

1471

1472 while (slen > 0)

1473 {

1474 int avail;

1475

1476 if (target->bufend != NULL)

1478 else

1479 avail = slen;

1480 if (avail <= 0)

1481 {

1482

1483 if (target->stream == NULL)

1484 {

1485 target->nchars += slen;

1486 return;

1487 }

1489 continue;

1490 }

1491 avail = Min(avail, slen);

1492 memset(target->bufptr, c, avail);

1493 target->bufptr += avail;

1494 slen -= avail;

1495 }

1496}

1497

1498

1499static int

1500adjust_sign(int is_negative, int forcesign, int *signvalue)

1501{

1502 if (is_negative)

1503 {

1504 *signvalue = '-';

1505 return true;

1506 }

1507 else if (forcesign)

1508 *signvalue = '+';

1509 return false;

1510}

1511

1512

1513static int

1515{

1516 int padlen;

1517

1518 padlen = minlen - vallen;

1519 if (padlen < 0)

1520 padlen = 0;

1521 if (leftjust)

1522 padlen = -padlen;

1523 return padlen;

1524}

1525

1526

1527static void

1529{

1530 int maxpad;

1531

1532 if (*padlen > 0 && zpad)

1533 {

1534 if (signvalue)

1535 {

1537 --(*padlen);

1538 signvalue = 0;

1539 }

1540 if (*padlen > 0)

1541 {

1543 *padlen = 0;

1544 }

1545 }

1546 maxpad = (signvalue != 0);

1547 if (*padlen > maxpad)

1548 {

1550 *padlen = maxpad;

1551 }

1552 if (signvalue)

1553 {

1555 if (*padlen > 0)

1556 --(*padlen);

1557 else if (*padlen < 0)

1558 ++(*padlen);

1559 }

1560}

1561

1562

1563static void

1565{

1566 if (padlen < 0)

1568}

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 int32 val, char *const buf)