PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
snprintf.c File Reference
#include "c.h"
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <sys/ioctl.h>
#include <sys/param.h>
Include dependency graph for snprintf.c:

Go to the source code of this file.

Data Structures

struct  PrintfTarget
 
union  PrintfArgValue
 

Macros

#define NL_ARGMAX   16
 

Enumerations

enum  PrintfArgType {
  ATYPE_NONE = 0, ATYPE_INT, ATYPE_LONG, ATYPE_LONGLONG,
  ATYPE_DOUBLE, ATYPE_CHARPTR
}
 

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,...)
 
static 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_printf (const char *fmt,...)
 
static void fmtstr (char *value, int leftjust, int minlen, int maxwidth, int pointflag, PrintfTarget *target)
 
static void fmtptr (void *value, PrintfTarget *target)
 
static void fmtint (int64 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 int adjust_sign (int is_negative, int forcesign, int *signvalue)
 
static void adjust_padlen (int minlen, int vallen, int leftjust, int *padlen)
 
static void leading_pad (int zpad, int *signvalue, int *padlen, PrintfTarget *target)
 
static void trailing_pad (int *padlen, PrintfTarget *target)
 
static size_t pg_strnlen (const char *str, size_t maxlen)
 

Macro Definition Documentation

#define NL_ARGMAX   16

Definition at line 47 of file snprintf.c.

Referenced by dopr().

Enumeration Type Documentation

Enumerator
ATYPE_NONE 
ATYPE_INT 
ATYPE_LONG 
ATYPE_LONGLONG 
ATYPE_DOUBLE 
ATYPE_CHARPTR 

Definition at line 125 of file snprintf.c.

Function Documentation

static void adjust_padlen ( int  minlen,
int  vallen,
int  leftjust,
int *  padlen 
)
static

Definition at line 1090 of file snprintf.c.

Referenced by fmtchar(), fmtfloat(), fmtint(), and fmtstr().

1091 {
1092  *padlen = minlen - vallen;
1093  if (*padlen < 0)
1094  *padlen = 0;
1095  if (leftjust)
1096  *padlen = -(*padlen);
1097 }
static int adjust_sign ( int  is_negative,
int  forcesign,
int *  signvalue 
)
static

Definition at line 1076 of file snprintf.c.

Referenced by fmtfloat(), and fmtint().

1077 {
1078  if (is_negative)
1079  {
1080  *signvalue = '-';
1081  return true;
1082  }
1083  else if (forcesign)
1084  *signvalue = '+';
1085  return false;
1086 }
static void dopr ( PrintfTarget target,
const char *  format,
va_list  args 
)
static

Definition at line 298 of file snprintf.c.

References ATYPE_CHARPTR, ATYPE_DOUBLE, ATYPE_INT, ATYPE_LONG, ATYPE_LONGLONG, ATYPE_NONE, PrintfArgValue::cptr, PrintfArgValue::d, dopr_outch(), PrintfTarget::failed, fmtchar(), fmtfloat(), fmtint(), fmtptr(), fmtstr(), format, i, PrintfArgValue::i, PrintfArgValue::l, PrintfArgValue::ll, Max, MemSet, and NL_ARGMAX.

Referenced by pg_vfprintf(), pg_vsnprintf(), and pg_vsprintf().

299 {
300  const char *format_start = format;
301  int ch;
302  bool have_dollar;
303  bool have_non_dollar;
304  bool have_star;
305  bool afterstar;
306  int accum;
307  int longlongflag;
308  int longflag;
309  int pointflag;
310  int leftjust;
311  int fieldwidth;
312  int precision;
313  int zpad;
314  int forcesign;
315  int last_dollar;
316  int fmtpos;
317  int cvalue;
318  int64 numvalue;
319  double fvalue;
320  char *strvalue;
321  int i;
322  PrintfArgType argtypes[NL_ARGMAX + 1];
323  PrintfArgValue argvalues[NL_ARGMAX + 1];
324 
325  /*
326  * Parse the format string to determine whether there are %n$ format
327  * specs, and identify the types and order of the format parameters.
328  */
329  have_dollar = have_non_dollar = false;
330  last_dollar = 0;
331  MemSet(argtypes, 0, sizeof(argtypes));
332 
333  while ((ch = *format++) != '\0')
334  {
335  if (ch != '%')
336  continue;
337  longflag = longlongflag = pointflag = 0;
338  fmtpos = accum = 0;
339  afterstar = false;
340 nextch1:
341  ch = *format++;
342  if (ch == '\0')
343  break; /* illegal, but we don't complain */
344  switch (ch)
345  {
346  case '-':
347  case '+':
348  goto nextch1;
349  case '0':
350  case '1':
351  case '2':
352  case '3':
353  case '4':
354  case '5':
355  case '6':
356  case '7':
357  case '8':
358  case '9':
359  accum = accum * 10 + (ch - '0');
360  goto nextch1;
361  case '.':
362  pointflag = 1;
363  accum = 0;
364  goto nextch1;
365  case '*':
366  if (afterstar)
367  have_non_dollar = true; /* multiple stars */
368  afterstar = true;
369  accum = 0;
370  goto nextch1;
371  case '$':
372  have_dollar = true;
373  if (accum <= 0 || accum > NL_ARGMAX)
374  goto bad_format;
375  if (afterstar)
376  {
377  if (argtypes[accum] &&
378  argtypes[accum] != ATYPE_INT)
379  goto bad_format;
380  argtypes[accum] = ATYPE_INT;
381  last_dollar = Max(last_dollar, accum);
382  afterstar = false;
383  }
384  else
385  fmtpos = accum;
386  accum = 0;
387  goto nextch1;
388  case 'l':
389  if (longflag)
390  longlongflag = 1;
391  else
392  longflag = 1;
393  goto nextch1;
394  case 'z':
395 #if SIZEOF_SIZE_T == 8
396 #ifdef HAVE_LONG_INT_64
397  longflag = 1;
398 #elif defined(HAVE_LONG_LONG_INT_64)
399  longlongflag = 1;
400 #else
401 #error "Don't know how to print 64bit integers"
402 #endif
403 #else
404  /* assume size_t is same size as int */
405 #endif
406  goto nextch1;
407  case 'h':
408  case '\'':
409  /* ignore these */
410  goto nextch1;
411  case 'd':
412  case 'i':
413  case 'o':
414  case 'u':
415  case 'x':
416  case 'X':
417  if (fmtpos)
418  {
419  PrintfArgType atype;
420 
421  if (longlongflag)
422  atype = ATYPE_LONGLONG;
423  else if (longflag)
424  atype = ATYPE_LONG;
425  else
426  atype = ATYPE_INT;
427  if (argtypes[fmtpos] &&
428  argtypes[fmtpos] != atype)
429  goto bad_format;
430  argtypes[fmtpos] = atype;
431  last_dollar = Max(last_dollar, fmtpos);
432  }
433  else
434  have_non_dollar = true;
435  break;
436  case 'c':
437  if (fmtpos)
438  {
439  if (argtypes[fmtpos] &&
440  argtypes[fmtpos] != ATYPE_INT)
441  goto bad_format;
442  argtypes[fmtpos] = ATYPE_INT;
443  last_dollar = Max(last_dollar, fmtpos);
444  }
445  else
446  have_non_dollar = true;
447  break;
448  case 's':
449  case 'p':
450  if (fmtpos)
451  {
452  if (argtypes[fmtpos] &&
453  argtypes[fmtpos] != ATYPE_CHARPTR)
454  goto bad_format;
455  argtypes[fmtpos] = ATYPE_CHARPTR;
456  last_dollar = Max(last_dollar, fmtpos);
457  }
458  else
459  have_non_dollar = true;
460  break;
461  case 'e':
462  case 'E':
463  case 'f':
464  case 'g':
465  case 'G':
466  if (fmtpos)
467  {
468  if (argtypes[fmtpos] &&
469  argtypes[fmtpos] != ATYPE_DOUBLE)
470  goto bad_format;
471  argtypes[fmtpos] = ATYPE_DOUBLE;
472  last_dollar = Max(last_dollar, fmtpos);
473  }
474  else
475  have_non_dollar = true;
476  break;
477  case '%':
478  break;
479  }
480 
481  /*
482  * If we finish the spec with afterstar still set, there's a
483  * non-dollar star in there.
484  */
485  if (afterstar)
486  have_non_dollar = true;
487  }
488 
489  /* Per spec, you use either all dollar or all not. */
490  if (have_dollar && have_non_dollar)
491  goto bad_format;
492 
493  /*
494  * In dollar mode, collect the arguments in physical order.
495  */
496  for (i = 1; i <= last_dollar; i++)
497  {
498  switch (argtypes[i])
499  {
500  case ATYPE_NONE:
501  goto bad_format;
502  case ATYPE_INT:
503  argvalues[i].i = va_arg(args, int);
504  break;
505  case ATYPE_LONG:
506  argvalues[i].l = va_arg(args, long);
507  break;
508  case ATYPE_LONGLONG:
509  argvalues[i].ll = va_arg(args, int64);
510  break;
511  case ATYPE_DOUBLE:
512  argvalues[i].d = va_arg(args, double);
513  break;
514  case ATYPE_CHARPTR:
515  argvalues[i].cptr = va_arg(args, char *);
516  break;
517  }
518  }
519 
520  /*
521  * At last we can parse the format for real.
522  */
523  format = format_start;
524  while ((ch = *format++) != '\0')
525  {
526  if (target->failed)
527  break;
528 
529  if (ch != '%')
530  {
531  dopr_outch(ch, target);
532  continue;
533  }
534  fieldwidth = precision = zpad = leftjust = forcesign = 0;
535  longflag = longlongflag = pointflag = 0;
536  fmtpos = accum = 0;
537  have_star = afterstar = false;
538 nextch2:
539  ch = *format++;
540  if (ch == '\0')
541  break; /* illegal, but we don't complain */
542  switch (ch)
543  {
544  case '-':
545  leftjust = 1;
546  goto nextch2;
547  case '+':
548  forcesign = 1;
549  goto nextch2;
550  case '0':
551  /* set zero padding if no nonzero digits yet */
552  if (accum == 0 && !pointflag)
553  zpad = '0';
554  /* FALL THRU */
555  case '1':
556  case '2':
557  case '3':
558  case '4':
559  case '5':
560  case '6':
561  case '7':
562  case '8':
563  case '9':
564  accum = accum * 10 + (ch - '0');
565  goto nextch2;
566  case '.':
567  if (have_star)
568  have_star = false;
569  else
570  fieldwidth = accum;
571  pointflag = 1;
572  accum = 0;
573  goto nextch2;
574  case '*':
575  if (have_dollar)
576  {
577  /* process value after reading n$ */
578  afterstar = true;
579  }
580  else
581  {
582  /* fetch and process value now */
583  int starval = va_arg(args, int);
584 
585  if (pointflag)
586  {
587  precision = starval;
588  if (precision < 0)
589  {
590  precision = 0;
591  pointflag = 0;
592  }
593  }
594  else
595  {
596  fieldwidth = starval;
597  if (fieldwidth < 0)
598  {
599  leftjust = 1;
600  fieldwidth = -fieldwidth;
601  }
602  }
603  }
604  have_star = true;
605  accum = 0;
606  goto nextch2;
607  case '$':
608  if (afterstar)
609  {
610  /* fetch and process star value */
611  int starval = argvalues[accum].i;
612 
613  if (pointflag)
614  {
615  precision = starval;
616  if (precision < 0)
617  {
618  precision = 0;
619  pointflag = 0;
620  }
621  }
622  else
623  {
624  fieldwidth = starval;
625  if (fieldwidth < 0)
626  {
627  leftjust = 1;
628  fieldwidth = -fieldwidth;
629  }
630  }
631  afterstar = false;
632  }
633  else
634  fmtpos = accum;
635  accum = 0;
636  goto nextch2;
637  case 'l':
638  if (longflag)
639  longlongflag = 1;
640  else
641  longflag = 1;
642  goto nextch2;
643  case 'z':
644 #if SIZEOF_SIZE_T == 8
645 #ifdef HAVE_LONG_INT_64
646  longflag = 1;
647 #elif defined(HAVE_LONG_LONG_INT_64)
648  longlongflag = 1;
649 #else
650 #error "Don't know how to print 64bit integers"
651 #endif
652 #else
653  /* assume size_t is same size as int */
654 #endif
655  goto nextch2;
656  case 'h':
657  case '\'':
658  /* ignore these */
659  goto nextch2;
660  case 'd':
661  case 'i':
662  if (!have_star)
663  {
664  if (pointflag)
665  precision = accum;
666  else
667  fieldwidth = accum;
668  }
669  if (have_dollar)
670  {
671  if (longlongflag)
672  numvalue = argvalues[fmtpos].ll;
673  else if (longflag)
674  numvalue = argvalues[fmtpos].l;
675  else
676  numvalue = argvalues[fmtpos].i;
677  }
678  else
679  {
680  if (longlongflag)
681  numvalue = va_arg(args, int64);
682  else if (longflag)
683  numvalue = va_arg(args, long);
684  else
685  numvalue = va_arg(args, int);
686  }
687  fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad,
688  precision, pointflag, target);
689  break;
690  case 'o':
691  case 'u':
692  case 'x':
693  case 'X':
694  if (!have_star)
695  {
696  if (pointflag)
697  precision = accum;
698  else
699  fieldwidth = accum;
700  }
701  if (have_dollar)
702  {
703  if (longlongflag)
704  numvalue = (uint64) argvalues[fmtpos].ll;
705  else if (longflag)
706  numvalue = (unsigned long) argvalues[fmtpos].l;
707  else
708  numvalue = (unsigned int) argvalues[fmtpos].i;
709  }
710  else
711  {
712  if (longlongflag)
713  numvalue = (uint64) va_arg(args, int64);
714  else if (longflag)
715  numvalue = (unsigned long) va_arg(args, long);
716  else
717  numvalue = (unsigned int) va_arg(args, int);
718  }
719  fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad,
720  precision, pointflag, target);
721  break;
722  case 'c':
723  if (!have_star)
724  {
725  if (pointflag)
726  precision = accum;
727  else
728  fieldwidth = accum;
729  }
730  if (have_dollar)
731  cvalue = (unsigned char) argvalues[fmtpos].i;
732  else
733  cvalue = (unsigned char) va_arg(args, int);
734  fmtchar(cvalue, leftjust, fieldwidth, target);
735  break;
736  case 's':
737  if (!have_star)
738  {
739  if (pointflag)
740  precision = accum;
741  else
742  fieldwidth = accum;
743  }
744  if (have_dollar)
745  strvalue = argvalues[fmtpos].cptr;
746  else
747  strvalue = va_arg(args, char *);
748  fmtstr(strvalue, leftjust, fieldwidth, precision, pointflag,
749  target);
750  break;
751  case 'p':
752  /* fieldwidth/leftjust are ignored ... */
753  if (have_dollar)
754  strvalue = argvalues[fmtpos].cptr;
755  else
756  strvalue = va_arg(args, char *);
757  fmtptr((void *) strvalue, target);
758  break;
759  case 'e':
760  case 'E':
761  case 'f':
762  case 'g':
763  case 'G':
764  if (!have_star)
765  {
766  if (pointflag)
767  precision = accum;
768  else
769  fieldwidth = accum;
770  }
771  if (have_dollar)
772  fvalue = argvalues[fmtpos].d;
773  else
774  fvalue = va_arg(args, double);
775  fmtfloat(fvalue, ch, forcesign, leftjust,
776  fieldwidth, zpad,
777  precision, pointflag,
778  target);
779  break;
780  case '%':
781  dopr_outch('%', target);
782  break;
783  }
784  }
785 
786  return;
787 
788 bad_format:
789  errno = EINVAL;
790  target->failed = true;
791 }
static void dopr_outch(int c, PrintfTarget *target)
Definition: snprintf.c:1062
static void fmtptr(void *value, PrintfTarget *target)
Definition: snprintf.c:833
static void fmtint(int64 value, char type, int forcesign, int leftjust, int minlen, int zpad, int precision, int pointflag, PrintfTarget *target)
Definition: snprintf.c:847
static void fmtchar(int value, int leftjust, int minlen, PrintfTarget *target)
Definition: snprintf.c:926
#define MemSet(start, val, len)
Definition: c.h:853
char * cptr
Definition: snprintf.c:141
bool failed
Definition: snprintf.c:116
static void fmtstr(char *value, int leftjust, int minlen, int maxwidth, int pointflag, PrintfTarget *target)
Definition: snprintf.c:804
#define Max(x, y)
Definition: c.h:796
PrintfArgType
Definition: snprintf.c:125
#define NL_ARGMAX
Definition: snprintf.c:47
int i
static char format
Definition: pg_basebackup.c:83
static void fmtfloat(double value, char type, int forcesign, int leftjust, int minlen, int zpad, int precision, int pointflag, PrintfTarget *target)
Definition: snprintf.c:944
static void dopr_outch ( int  c,
PrintfTarget target 
)
static

Definition at line 1062 of file snprintf.c.

References PrintfTarget::bufend, PrintfTarget::bufptr, flushbuffer(), NULL, and PrintfTarget::stream.

Referenced by dopr(), fmtchar(), fmtfloat(), fmtint(), fmtstr(), leading_pad(), and trailing_pad().

1063 {
1064  if (target->bufend != NULL && target->bufptr >= target->bufend)
1065  {
1066  /* buffer full, can we dump to stream? */
1067  if (target->stream == NULL)
1068  return; /* no, lose the data */
1069  flushbuffer(target);
1070  }
1071  *(target->bufptr++) = c;
1072 }
char * bufend
Definition: snprintf.c:112
static void flushbuffer(PrintfTarget *target)
Definition: snprintf.c:258
char * c
FILE * stream
Definition: snprintf.c:114
#define NULL
Definition: c.h:226
char * bufptr
Definition: snprintf.c:110
static void dostr ( const char *  str,
int  slen,
PrintfTarget target 
)
static

Definition at line 1035 of file snprintf.c.

References PrintfTarget::bufend, PrintfTarget::bufptr, flushbuffer(), memmove, Min, NULL, and PrintfTarget::stream.

Referenced by fmtfloat(), fmtptr(), and fmtstr().

1036 {
1037  while (slen > 0)
1038  {
1039  int avail;
1040 
1041  if (target->bufend != NULL)
1042  avail = target->bufend - target->bufptr;
1043  else
1044  avail = slen;
1045  if (avail <= 0)
1046  {
1047  /* buffer full, can we dump to stream? */
1048  if (target->stream == NULL)
1049  return; /* no, lose the data */
1050  flushbuffer(target);
1051  continue;
1052  }
1053  avail = Min(avail, slen);
1054  memmove(target->bufptr, str, avail);
1055  target->bufptr += avail;
1056  str += avail;
1057  slen -= avail;
1058  }
1059 }
char * bufend
Definition: snprintf.c:112
#define Min(x, y)
Definition: c.h:802
static void flushbuffer(PrintfTarget *target)
Definition: snprintf.c:258
#define memmove(d, s, c)
Definition: c.h:1058
FILE * stream
Definition: snprintf.c:114
#define NULL
Definition: c.h:226
char * bufptr
Definition: snprintf.c:110
static void flushbuffer ( PrintfTarget target)
static

Definition at line 258 of file snprintf.c.

References PrintfTarget::bufptr, PrintfTarget::bufstart, PrintfTarget::failed, PrintfTarget::nchars, and PrintfTarget::stream.

Referenced by dopr_outch(), dostr(), and pg_vfprintf().

259 {
260  size_t nc = target->bufptr - target->bufstart;
261 
262  if (!target->failed && nc > 0)
263  {
264  size_t written;
265 
266  written = fwrite(target->bufstart, 1, nc, target->stream);
267  target->nchars += written;
268  if (written != nc)
269  target->failed = true;
270  }
271  target->bufptr = target->bufstart;
272 }
char * bufstart
Definition: snprintf.c:111
FILE * stream
Definition: snprintf.c:114
bool failed
Definition: snprintf.c:116
char * bufptr
Definition: snprintf.c:110
static void fmtchar ( int  value,
int  leftjust,
int  minlen,
PrintfTarget target 
)
static

Definition at line 926 of file snprintf.c.

References adjust_padlen(), dopr_outch(), and trailing_pad().

Referenced by dopr(), and rfmtlong().

927 {
928  int padlen = 0; /* amount to pad */
929 
930  adjust_padlen(minlen, 1, leftjust, &padlen);
931 
932  while (padlen > 0)
933  {
934  dopr_outch(' ', target);
935  --padlen;
936  }
937 
938  dopr_outch(value, target);
939 
940  trailing_pad(&padlen, target);
941 }
static struct @76 value
static void dopr_outch(int c, PrintfTarget *target)
Definition: snprintf.c:1062
static void adjust_padlen(int minlen, int vallen, int leftjust, int *padlen)
Definition: snprintf.c:1090
static void trailing_pad(int *padlen, PrintfTarget *target)
Definition: snprintf.c:1134
static void fmtfloat ( double  value,
char  type,
int  forcesign,
int  leftjust,
int  minlen,
int  zpad,
int  precision,
int  pointflag,
PrintfTarget target 
)
static

Definition at line 944 of file snprintf.c.

References adjust_padlen(), adjust_sign(), convert(), dopr_outch(), dostr(), PrintfTarget::failed, leading_pad(), Min, trailing_pad(), and value.

Referenced by dopr().

947 {
948  int signvalue = 0;
949  int prec;
950  int vallen;
951  char fmt[32];
952  char convert[1024];
953  int zeropadlen = 0; /* amount to pad with zeroes */
954  int padlen = 0; /* amount to pad with spaces */
955 
956  /*
957  * We rely on the regular C library's sprintf to do the basic conversion,
958  * then handle padding considerations here.
959  *
960  * The dynamic range of "double" is about 1E+-308 for IEEE math, and not
961  * too wildly more than that with other hardware. In "f" format, sprintf
962  * could therefore generate at most 308 characters to the left of the
963  * decimal point; while we need to allow the precision to get as high as
964  * 308+17 to ensure that we don't truncate significant digits from very
965  * small values. To handle both these extremes, we use a buffer of 1024
966  * bytes and limit requested precision to 350 digits; this should prevent
967  * buffer overrun even with non-IEEE math. If the original precision
968  * request was more than 350, separately pad with zeroes.
969  */
970  if (precision < 0) /* cover possible overflow of "accum" */
971  precision = 0;
972  prec = Min(precision, 350);
973 
974  if (pointflag)
975  {
976  if (sprintf(fmt, "%%.%d%c", prec, type) < 0)
977  goto fail;
978  zeropadlen = precision - prec;
979  }
980  else if (sprintf(fmt, "%%%c", type) < 0)
981  goto fail;
982 
983  if (!isnan(value) && adjust_sign((value < 0), forcesign, &signvalue))
984  value = -value;
985 
986  vallen = sprintf(convert, fmt, value);
987  if (vallen < 0)
988  goto fail;
989 
990  /* If it's infinity or NaN, forget about doing any zero-padding */
991  if (zeropadlen > 0 && !isdigit((unsigned char) convert[vallen - 1]))
992  zeropadlen = 0;
993 
994  adjust_padlen(minlen, vallen + zeropadlen, leftjust, &padlen);
995 
996  leading_pad(zpad, &signvalue, &padlen, target);
997 
998  if (zeropadlen > 0)
999  {
1000  /* If 'e' or 'E' format, inject zeroes before the exponent */
1001  char *epos = strrchr(convert, 'e');
1002 
1003  if (!epos)
1004  epos = strrchr(convert, 'E');
1005  if (epos)
1006  {
1007  /* pad after exponent */
1008  dostr(convert, epos - convert, target);
1009  while (zeropadlen-- > 0)
1010  dopr_outch('0', target);
1011  dostr(epos, vallen - (epos - convert), target);
1012  }
1013  else
1014  {
1015  /* no exponent, pad after the digits */
1016  dostr(convert, vallen, target);
1017  while (zeropadlen-- > 0)
1018  dopr_outch('0', target);
1019  }
1020  }
1021  else
1022  {
1023  /* no zero padding, just emit the number as-is */
1024  dostr(convert, vallen, target);
1025  }
1026 
1027  trailing_pad(&padlen, target);
1028  return;
1029 
1030 fail:
1031  target->failed = true;
1032 }
static struct @76 value
static void dopr_outch(int c, PrintfTarget *target)
Definition: snprintf.c:1062
#define Min(x, y)
Definition: c.h:802
static void dostr(const char *str, int slen, PrintfTarget *target)
Definition: snprintf.c:1035
static void convert(const int32 val, char *const buf)
Definition: zic.c:1811
static int adjust_sign(int is_negative, int forcesign, int *signvalue)
Definition: snprintf.c:1076
bool failed
Definition: snprintf.c:116
static void leading_pad(int zpad, int *signvalue, int *padlen, PrintfTarget *target)
Definition: snprintf.c:1101
static void adjust_padlen(int minlen, int vallen, int leftjust, int *padlen)
Definition: snprintf.c:1090
static void trailing_pad(int *padlen, PrintfTarget *target)
Definition: snprintf.c:1134
static void fmtint ( int64  value,
char  type,
int  forcesign,
int  leftjust,
int  minlen,
int  zpad,
int  precision,
int  pointflag,
PrintfTarget target 
)
static

Definition at line 847 of file snprintf.c.

References adjust_padlen(), adjust_sign(), convert(), dopr_outch(), leading_pad(), Max, trailing_pad(), and value.

Referenced by dopr().

850 {
851  uint64 base;
852  int dosign;
853  const char *cvt = "0123456789abcdef";
854  int signvalue = 0;
855  char convert[64];
856  int vallen = 0;
857  int padlen = 0; /* amount to pad */
858  int zeropad; /* extra leading zeroes */
859 
860  switch (type)
861  {
862  case 'd':
863  case 'i':
864  base = 10;
865  dosign = 1;
866  break;
867  case 'o':
868  base = 8;
869  dosign = 0;
870  break;
871  case 'u':
872  base = 10;
873  dosign = 0;
874  break;
875  case 'x':
876  base = 16;
877  dosign = 0;
878  break;
879  case 'X':
880  cvt = "0123456789ABCDEF";
881  base = 16;
882  dosign = 0;
883  break;
884  default:
885  return; /* keep compiler quiet */
886  }
887 
888  /* Handle +/- */
889  if (dosign && adjust_sign((value < 0), forcesign, &signvalue))
890  value = -value;
891 
892  /*
893  * SUS: the result of converting 0 with an explicit precision of 0 is no
894  * characters
895  */
896  if (value == 0 && pointflag && precision == 0)
897  vallen = 0;
898  else
899  {
900  /* make integer string */
901  uint64 uvalue = (uint64) value;
902 
903  do
904  {
905  convert[vallen++] = cvt[uvalue % base];
906  uvalue = uvalue / base;
907  } while (uvalue);
908  }
909 
910  zeropad = Max(0, precision - vallen);
911 
912  adjust_padlen(minlen, vallen + zeropad, leftjust, &padlen);
913 
914  leading_pad(zpad, &signvalue, &padlen, target);
915 
916  while (zeropad-- > 0)
917  dopr_outch('0', target);
918 
919  while (vallen > 0)
920  dopr_outch(convert[--vallen], target);
921 
922  trailing_pad(&padlen, target);
923 }
static struct @76 value
static void dopr_outch(int c, PrintfTarget *target)
Definition: snprintf.c:1062
static void convert(const int32 val, char *const buf)
Definition: zic.c:1811
static int adjust_sign(int is_negative, int forcesign, int *signvalue)
Definition: snprintf.c:1076
#define Max(x, y)
Definition: c.h:796
static void leading_pad(int zpad, int *signvalue, int *padlen, PrintfTarget *target)
Definition: snprintf.c:1101
static void adjust_padlen(int minlen, int vallen, int leftjust, int *padlen)
Definition: snprintf.c:1090
static void trailing_pad(int *padlen, PrintfTarget *target)
Definition: snprintf.c:1134
static void fmtptr ( void *  value,
PrintfTarget target 
)
static

Definition at line 833 of file snprintf.c.

References convert(), dostr(), and PrintfTarget::failed.

Referenced by dopr().

834 {
835  int vallen;
836  char convert[64];
837 
838  /* we rely on regular C library's sprintf to do the basic conversion */
839  vallen = sprintf(convert, "%p", value);
840  if (vallen < 0)
841  target->failed = true;
842  else
843  dostr(convert, vallen, target);
844 }
static struct @76 value
static void dostr(const char *str, int slen, PrintfTarget *target)
Definition: snprintf.c:1035
static void convert(const int32 val, char *const buf)
Definition: zic.c:1811
bool failed
Definition: snprintf.c:116
static void fmtstr ( char *  value,
int  leftjust,
int  minlen,
int  maxwidth,
int  pointflag,
PrintfTarget target 
)
static

Definition at line 804 of file snprintf.c.

References adjust_padlen(), dopr_outch(), dostr(), pg_strnlen(), and trailing_pad().

Referenced by dopr(), and dttofmtasc_replace().

806 {
807  int padlen,
808  vallen; /* amount to pad */
809 
810  /*
811  * If a maxwidth (precision) is specified, we must not fetch more bytes
812  * than that.
813  */
814  if (pointflag)
815  vallen = pg_strnlen(value, maxwidth);
816  else
817  vallen = strlen(value);
818 
819  adjust_padlen(minlen, vallen, leftjust, &padlen);
820 
821  while (padlen > 0)
822  {
823  dopr_outch(' ', target);
824  --padlen;
825  }
826 
827  dostr(value, vallen, target);
828 
829  trailing_pad(&padlen, target);
830 }
static struct @76 value
static void dopr_outch(int c, PrintfTarget *target)
Definition: snprintf.c:1062
static void dostr(const char *str, int slen, PrintfTarget *target)
Definition: snprintf.c:1035
static size_t pg_strnlen(const char *str, size_t maxlen)
Definition: snprintf.c:794
static void adjust_padlen(int minlen, int vallen, int leftjust, int *padlen)
Definition: snprintf.c:1090
static void trailing_pad(int *padlen, PrintfTarget *target)
Definition: snprintf.c:1134
static void leading_pad ( int  zpad,
int *  signvalue,
int *  padlen,
PrintfTarget target 
)
static

Definition at line 1101 of file snprintf.c.

References dopr_outch().

Referenced by fmtfloat(), and fmtint().

1102 {
1103  if (*padlen > 0 && zpad)
1104  {
1105  if (*signvalue)
1106  {
1107  dopr_outch(*signvalue, target);
1108  --(*padlen);
1109  *signvalue = 0;
1110  }
1111  while (*padlen > 0)
1112  {
1113  dopr_outch(zpad, target);
1114  --(*padlen);
1115  }
1116  }
1117  while (*padlen > (*signvalue != 0))
1118  {
1119  dopr_outch(' ', target);
1120  --(*padlen);
1121  }
1122  if (*signvalue)
1123  {
1124  dopr_outch(*signvalue, target);
1125  if (*padlen > 0)
1126  --(*padlen);
1127  else if (*padlen < 0)
1128  ++(*padlen);
1129  }
1130 }
static void dopr_outch(int c, PrintfTarget *target)
Definition: snprintf.c:1062
int pg_fprintf ( FILE *  stream,
const char *  fmt,
  ... 
)

Definition at line 230 of file snprintf.c.

References generate_unaccent_rules::args, and pg_vfprintf().

231 {
232  int len;
233  va_list args;
234 
235  va_start(args, fmt);
236  len = pg_vfprintf(stream, fmt, args);
237  va_end(args);
238  return len;
239 }
int pg_vfprintf(FILE *stream, const char *fmt, va_list args)
Definition: snprintf.c:208
int pg_printf ( const char *  fmt,
  ... 
)

Definition at line 242 of file snprintf.c.

References generate_unaccent_rules::args, and pg_vfprintf().

243 {
244  int len;
245  va_list args;
246 
247  va_start(args, fmt);
248  len = pg_vfprintf(stdout, fmt, args);
249  va_end(args);
250  return len;
251 }
int pg_vfprintf(FILE *stream, const char *fmt, va_list args)
Definition: snprintf.c:208
int pg_snprintf ( char *  str,
size_t  count,
const char *  fmt,
  ... 
)

Definition at line 167 of file snprintf.c.

References generate_unaccent_rules::args, and pg_vsnprintf().

168 {
169  int len;
170  va_list args;
171 
172  va_start(args, fmt);
173  len = pg_vsnprintf(str, count, fmt, args);
174  va_end(args);
175  return len;
176 }
int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
Definition: snprintf.c:150
int pg_sprintf ( char *  str,
const char *  fmt,
  ... 
)

Definition at line 196 of file snprintf.c.

References generate_unaccent_rules::args, and pg_vsprintf().

197 {
198  int len;
199  va_list args;
200 
201  va_start(args, fmt);
202  len = pg_vsprintf(str, fmt, args);
203  va_end(args);
204  return len;
205 }
static int pg_vsprintf(char *str, const char *fmt, va_list args)
Definition: snprintf.c:179
static size_t pg_strnlen ( const char *  str,
size_t  maxlen 
)
static

Definition at line 794 of file snprintf.c.

Referenced by fmtstr().

795 {
796  const char *p = str;
797 
798  while (maxlen-- > 0 && *p)
799  p++;
800  return p - str;
801 }
int pg_vfprintf ( FILE *  stream,
const char *  fmt,
va_list  args 
)

Definition at line 208 of file snprintf.c.

References PrintfTarget::bufend, PrintfTarget::bufptr, PrintfTarget::bufstart, dopr(), PrintfTarget::failed, flushbuffer(), PrintfTarget::nchars, NULL, and PrintfTarget::stream.

Referenced by pg_fprintf(), and pg_printf().

209 {
210  PrintfTarget target;
211  char buffer[1024]; /* size is arbitrary */
212 
213  if (stream == NULL)
214  {
215  errno = EINVAL;
216  return -1;
217  }
218  target.bufstart = target.bufptr = buffer;
219  target.bufend = buffer + sizeof(buffer) - 1;
220  target.stream = stream;
221  target.nchars = 0;
222  target.failed = false;
223  dopr(&target, fmt, args);
224  /* dump any remaining buffer contents */
225  flushbuffer(&target);
226  return target.failed ? -1 : target.nchars;
227 }
char * bufend
Definition: snprintf.c:112
char * bufstart
Definition: snprintf.c:111
static void flushbuffer(PrintfTarget *target)
Definition: snprintf.c:258
FILE * stream
Definition: snprintf.c:114
bool failed
Definition: snprintf.c:116
#define NULL
Definition: c.h:226
static void dopr(PrintfTarget *target, const char *format, va_list args)
Definition: snprintf.c:298
char * bufptr
Definition: snprintf.c:110
int pg_vsnprintf ( char *  str,
size_t  count,
const char *  fmt,
va_list  args 
)

Definition at line 150 of file snprintf.c.

References PrintfTarget::bufend, PrintfTarget::bufptr, PrintfTarget::bufstart, dopr(), PrintfTarget::failed, NULL, and PrintfTarget::stream.

Referenced by pg_snprintf().

151 {
152  PrintfTarget target;
153 
154  if (str == NULL || count == 0)
155  return 0;
156  target.bufstart = target.bufptr = str;
157  target.bufend = str + count - 1;
158  target.stream = NULL;
159  /* target.nchars is unused in this case */
160  target.failed = false;
161  dopr(&target, fmt, args);
162  *(target.bufptr) = '\0';
163  return target.failed ? -1 : (target.bufptr - target.bufstart);
164 }
char * bufend
Definition: snprintf.c:112
char * bufstart
Definition: snprintf.c:111
FILE * stream
Definition: snprintf.c:114
bool failed
Definition: snprintf.c:116
#define NULL
Definition: c.h:226
static void dopr(PrintfTarget *target, const char *format, va_list args)
Definition: snprintf.c:298
char * bufptr
Definition: snprintf.c:110
static int pg_vsprintf ( char *  str,
const char *  fmt,
va_list  args 
)
static

Definition at line 179 of file snprintf.c.

References PrintfTarget::bufend, PrintfTarget::bufptr, PrintfTarget::bufstart, dopr(), PrintfTarget::failed, NULL, and PrintfTarget::stream.

Referenced by pg_sprintf().

180 {
181  PrintfTarget target;
182 
183  if (str == NULL)
184  return 0;
185  target.bufstart = target.bufptr = str;
186  target.bufend = NULL;
187  target.stream = NULL;
188  /* target.nchars is unused in this case */
189  target.failed = false;
190  dopr(&target, fmt, args);
191  *(target.bufptr) = '\0';
192  return target.failed ? -1 : (target.bufptr - target.bufstart);
193 }
char * bufend
Definition: snprintf.c:112
char * bufstart
Definition: snprintf.c:111
FILE * stream
Definition: snprintf.c:114
bool failed
Definition: snprintf.c:116
#define NULL
Definition: c.h:226
static void dopr(PrintfTarget *target, const char *format, va_list args)
Definition: snprintf.c:298
char * bufptr
Definition: snprintf.c:110
static void trailing_pad ( int *  padlen,
PrintfTarget target 
)
static

Definition at line 1134 of file snprintf.c.

References dopr_outch().

Referenced by fmtchar(), fmtfloat(), fmtint(), and fmtstr().

1135 {
1136  while (*padlen < 0)
1137  {
1138  dopr_outch(' ', target);
1139  ++(*padlen);
1140  }
1141 }
static void dopr_outch(int c, PrintfTarget *target)
Definition: snprintf.c:1062