">

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.

Functions
static void flushbuffer (PrintfTarget *target)
static void dopr (PrintfTarget *target, const char *format, va_list args)
int pg_vsnprintf (char *str, size_t count, const char *fmt, va_list args)
int pg_snprintf (char *str, size_t count, const char *fmt,...)
int pg_vsprintf (char *str, const char *fmt, va_list args)
int pg_sprintf (char *str, const char *fmt,...)
int pg_vfprintf (FILE *stream, const char *fmt, va_list args)
int pg_fprintf (FILE *stream, const char *fmt,...)
int pg_vprintf (const char *fmt, va_list args)
int pg_printf (const char *fmt,...)
static bool find_arguments (const char *format, va_list args, PrintfArgValue *argvalues)
static void fmtstr (const char *value, int leftjust, int minlen, int maxwidth, int pointflag, PrintfTarget *target)
static void fmtptr (const void *value, 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 fmtchar (int value, int leftjust, int minlen, PrintfTarget *target)
static void fmtfloat (double value, char type, int forcesign, int leftjust, int minlen, int zpad, int precision, int pointflag, PrintfTarget *target)
static void dostr (const char *str, int slen, PrintfTarget *target)
static void dopr_outch (int c, PrintfTarget *target)
static void dopr_outchmulti (int c, int slen, PrintfTarget *target)
static int adjust_sign (int is_negative, int forcesign, int *signvalue)
static int compute_padlen (int minlen, int vallen, int leftjust)
static void leading_pad (int zpad, int signvalue, int *padlen, PrintfTarget *target)
static void trailing_pad (int padlen, PrintfTarget *target)
static const char * strchrnul (const char *s, int c)
int pg_strfromd (char *str, size_t count, int precision, double value)

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 }

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

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 {

1432 target->nchars += slen;

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 {

1379 target->nchars += slen;

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;

257 dopr(&target, fmt, args);

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;

195 dopr(&target, fmt, args);

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}

trailing_pad()