All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
snprintf.c
Go to the documentation of this file.
1 
2 /*
3  Unix snprintf implementation.
4  Version 1.4
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU Library General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 
20  Revision History:
21 
22  1.4:
23  * integrate in FreeRADIUS's libradius:
24  * Fetched from: http://savannah.gnu.org/cgi-bin/viewcvs/mailutils/mailutils/lib/snprintf.c?rev=1.4
25  * Fetched from: http://savannah.gnu.org/cgi-bin/viewcvs/mailutils/mailutils/lib/snprintf.h?rev=1.4
26  * Replace config.h with autoconf.h
27  * Protect with HAVE_SNPRINTF and HAVE_VSNPRINTF
28  1.3:
29  * add #include <config.h> ifdef HAVE_CONFIG_H
30  * cosmetic change, when exponent is 0 print xxxE+00
31  instead of xxxE-00
32  1.2:
33  * put the program under LGPL.
34  1.1:
35  * added changes from Miles Bader
36  * corrected a bug with %f
37  * added support for %#g
38  * added more comments :-)
39  1.0:
40  * supporting must ANSI syntaxic_sugars
41  0.0:
42  * suppot %s %c %d
43 
44  THANKS(for the patches and ideas):
45  Miles Bader
46  Cyrille Rustom
47  Jacek Slabocewiz
48  Mike Parker(mouse)
49 
50 */
51 
52 RCSID("$Id: 4f79a32d64a0ac1388012f7f060347b6d79acddf $")
53 
54 #include "snprintf.h"
55 
56 #ifndef HAVE_VSNPRINTF
57 
58 /*
59  * Find the nth power of 10
60  */
61 PRIVATE double
62 #ifdef __STDC__
63 pow_10(int n)
64 #else
66 int n;
67 #endif
68 {
69  int i;
70  double P;
71 
72  if (n < 0)
73  for (i = 1, P = 1., n = -n ; i <= n ; i++) {P *= .1;}
74  else
75  for (i = 1, P = 1. ; i <= n ; i++) {P *= 10.0;}
76  return P;
77 }
78 
79 /*
80  * Find the integral part of the log in base 10
81  * Note: this not a real log10()
82  I just need and approximation(integerpart) of x in:
83  10^x ~= r
84  * log_10(200) = 2;
85  * log_10(250) = 2;
86  */
87 PRIVATE int
88 #ifdef __STDC__
89 log_10(double r)
90 #else
92 double r;
93 #endif
94 {
95  int i = 0;
96  double result = 1.;
97 
98  if (r < 0.)
99  r = -r;
100 
101  if (r < 1.) {
102  while (result >= r) {result *= .1; i++;}
103  return (-i);
104  } else {
105  while (result <= r) {result *= 10.; i++;}
106  return (i - 1);
107  }
108 }
109 
110 /*
111  * This function return the fraction part of a double
112  * and set in ip the integral part.
113  * In many ways it resemble the modf() found on most Un*x
114  */
115 PRIVATE double
116 #ifdef __STDC__
117 integral(double real, double * ip)
118 #else
119 integral(real, ip)
120 double real;
121 double * ip;
122 #endif
123 {
124  int j;
125  double i, s, p;
126  double real_integral = 0.;
127 
128 /* take care of the obvious */
129 /* equal to zero ? */
130  if (real == 0.) {
131  *ip = 0.;
132  return (0.);
133  }
134 
135 /* negative number ? */
136  if (real < 0.)
137  real = -real;
138 
139 /* a fraction ? */
140  if ( real < 1.) {
141  *ip = 0.;
142  return real;
143  }
144 /* the real work :-) */
145  for (j = log_10(real); j >= 0; j--) {
146  p = pow_10(j);
147  s = (real - real_integral)/p;
148  i = 0.;
149  while (i + 1. <= s) {i++;}
150  real_integral += i*p;
151  }
152  *ip = real_integral;
153  return (real - real_integral);
154 }
155 
156 #define PRECISION 1.e-6
157 /*
158  * return an ascii representation of the integral part of the number
159  * and set fract to be an ascii representation of the fraction part
160  * the container for the fraction and the integral part or staticly
161  * declare with fix size
162  */
163 PRIVATE char *
164 #ifdef __STDC__
165 numtoa(double number, int base, int precision, char ** fract)
166 #else
167 numtoa(number, base, precision, fract)
168 double number;
169 int base;
170 int precision;
171 char ** fract;
172 #endif
173 {
174  register int i, j;
175  double ip, fp; /* integer and fraction part */
176  double fraction;
177  int digits = MAX_INT - 1;
178  static char integral_part[MAX_INT];
179  static char fraction_part[MAX_FRACT];
180  double sign;
181  int ch;
182 
183 /* taking care of the obvious case: 0.0 */
184  if (number == 0.) {
185  integral_part[0] = '0';
186  integral_part[1] = '\0';
187  fraction_part[0] = '0';
188  fraction_part[1] = '\0';
189  return integral_part;
190  }
191 
192 /* for negative numbers */
193  if ((sign = number) < 0.) {
194  number = -number;
195  digits--; /* sign consume one digit */
196  }
197 
198  fraction = integral(number, &ip);
199  number = ip;
200 /* do the integral part */
201  if ( ip == 0.) {
202  integral_part[0] = '0';
203  i = 1;
204  } else {
205  for ( i = 0; i < digits && number != 0.; ++i) {
206  number /= base;
207  fp = integral(number, &ip);
208  ch = (int)((fp + PRECISION)*base); /* force to round */
209  integral_part[i] = (ch <= 9) ? ch + '0' : ch + 'a' - 10;
210  if (! isxdigit(integral_part[i])) /* bail out overflow !! */
211  break;
212  number = ip;
213  }
214  }
215 
216 /* Oh No !! out of bound, ho well fill it up ! */
217  if (number != 0.)
218  for (i = 0; i < digits; ++i)
219  integral_part[i] = '9';
220 
221 /* put the sign ? */
222  if (sign < 0.)
223  integral_part[i++] = '-';
224 
225  integral_part[i] = '\0';
226 
227 /* reverse every thing */
228  for ( i--, j = 0; j < i; j++, i--)
229  SWAP_INT(integral_part[i], integral_part[j]);
230 
231 /* the fractionnal part */
232  for (i=0, fp=fraction; precision > 0 && i < MAX_FRACT ; i++, precision-- ) {
233  fraction_part[i] = (int)((fp + PRECISION)*10. + '0');
234  if (! isdigit(fraction_part[i])) /* underflow ? */
235  break;
236  fp = (fp*10.0) - (double)(long)((fp + PRECISION)*10.);
237  }
238  fraction_part[i] = '\0';
239 
240  if (fract != (char **)0)
241  *fract = fraction_part;
242 
243  return integral_part;
244 
245 }
246 
247 /* for %d and friends, it puts in holder
248  * the representation with the right padding
249  */
250 PRIVATE void
251 #ifdef __STDC__
252 decimal(struct DATA *p, double d)
253 #else
254 decimal(p, d)
255 struct DATA *p;
256 double d;
257 #endif
258 {
259  char *tmp;
260 
261  tmp = itoa(d);
262  p->width -= strlen(tmp);
263  PAD_RIGHT(p);
264  PUT_PLUS(d, p);
265  PUT_SPACE(d, p);
266  while (*tmp) { /* the integral */
267  PUT_CHAR(*tmp, p);
268  tmp++;
269  }
270  PAD_LEFT(p);
271 }
272 
273 /* for %o octal representation */
274 PRIVATE void
275 #ifdef __STDC__
276 octal(struct DATA *p, double d)
277 #else
278 octal(p, d)
279 struct DATA *p;
280 double d;
281 #endif
282 {
283  char *tmp;
284 
285  tmp = otoa(d);
286  p->width -= strlen(tmp);
287  PAD_RIGHT(p);
288  if (p->square == FOUND) /* had prefix '0' for octal */
289  PUT_CHAR('0', p);
290  while (*tmp) { /* octal */
291  PUT_CHAR(*tmp, p);
292  tmp++;
293  }
294  PAD_LEFT(p);
295 }
296 
297 /* for %x %X hexadecimal representation */
298 PRIVATE void
299 #ifdef __STDC__
300 hexa(struct DATA *p, double d)
301 #else
302 hexa(p, d)
303 struct DATA *p;
304 double d;
305 #endif
306 {
307  char *tmp;
308 
309  tmp = htoa(d);
310  p->width -= strlen(tmp);
311  PAD_RIGHT(p);
312  if (p->square == FOUND) { /* prefix '0x' for hexa */
313  PUT_CHAR('0', p); PUT_CHAR(*p->pf, p);
314  }
315  while (*tmp) { /* hexa */
316  PUT_CHAR((*p->pf == 'X' ? toupper(*tmp) : *tmp), p);
317  tmp++;
318  }
319  PAD_LEFT(p);
320 }
321 
322 /* %s strings */
323 PRIVATE void
324 #ifdef __STDC__
325 strings(struct DATA *p, char *tmp)
326 #else
327 strings(p, tmp)
328 struct DATA *p;
329 char *tmp;
330 #endif
331 {
332  int i;
333 
334  i = strlen(tmp);
335  if (p->precision != NOT_FOUND) /* the smallest number */
336  i = (i < p->precision ? i : p->precision);
337  p->width -= i;
338  PAD_RIGHT(p);
339  while (i-- > 0) { /* put the sting */
340  PUT_CHAR(*tmp, p);
341  tmp++;
342  }
343  PAD_LEFT(p);
344 }
345 
346 /* %f or %g floating point representation */
347 PRIVATE void
348 #ifdef __STDC__
349 floating(struct DATA *p, double d)
350 #else
351 floating(p, d)
352 struct DATA *p;
353 double d;
354 #endif
355 {
356  char *tmp, *tmp2;
357  int i;
358 
359  DEF_PREC(p);
360  d = ROUND(d, p);
361  tmp = dtoa(d, p->precision, &tmp2);
362  /* calculate the padding. 1 for the dot */
363  p->width = p->width -
364  ((d > 0. && p->justify == RIGHT) ? 1:0) -
365  ((p->space == FOUND) ? 1:0) -
366  strlen(tmp) - p->precision - 1;
367  PAD_RIGHT(p);
368  PUT_PLUS(d, p);
369  PUT_SPACE(d, p);
370  while (*tmp) { /* the integral */
371  PUT_CHAR(*tmp, p);
372  tmp++;
373  }
374  if (p->precision != 0 || p->square == FOUND)
375  PUT_CHAR('.', p); /* put the '.' */
376  if (*p->pf == 'g' || *p->pf == 'G') /* smash the trailing zeros */
377  for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
378  tmp2[i] = '\0';
379  for (; *tmp2; tmp2++)
380  PUT_CHAR(*tmp2, p); /* the fraction */
381 
382  PAD_LEFT(p);
383 }
384 
385 /* %e %E %g exponent representation */
386 PRIVATE void
387 #ifdef __STDC__
388 exponent(struct DATA *p, double d)
389 #else
390 exponent(p, d)
391 struct DATA *p;
392 double d;
393 #endif
394 {
395  char *tmp, *tmp2;
396  int j, i;
397 
398  DEF_PREC(p);
399  j = log_10(d);
400  d = d / pow_10(j); /* get the Mantissa */
401  d = ROUND(d, p);
402  tmp = dtoa(d, p->precision, &tmp2);
403  /* 1 for unit, 1 for the '.', 1 for 'e|E',
404  * 1 for '+|-', 3 for 'exp' */
405  /* calculate how much padding need */
406  p->width = p->width -
407  ((d > 0. && p->justify == RIGHT) ? 1:0) -
408  ((p->space == FOUND) ? 1:0) - p->precision - 7;
409  PAD_RIGHT(p);
410  PUT_PLUS(d, p);
411  PUT_SPACE(d, p);
412  while (*tmp) {/* the integral */
413  PUT_CHAR(*tmp, p);
414  tmp++;
415  }
416  if (p->precision != 0 || p->square == FOUND)
417  PUT_CHAR('.', p); /* the '.' */
418  if (*p->pf == 'g' || *p->pf == 'G') /* smash the trailing zeros */
419  for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
420  tmp2[i] = '\0';
421  for (; *tmp2; tmp2++)
422  PUT_CHAR(*tmp2, p); /* the fraction */
423 
424  if (*p->pf == 'g' || *p->pf == 'e') { /* the exponent put the 'e|E' */
425  PUT_CHAR('e', p);
426  } else
427  PUT_CHAR('E', p);
428  if (j >= 0) { /* the sign of the exp */
429  PUT_CHAR('+', p);
430  } else {
431  PUT_CHAR('-', p);
432  j = -j;
433  }
434  tmp = itoa((double)j);
435  if (j < 9) { /* need to pad the exponent with 0 '000' */
436  PUT_CHAR('0', p); PUT_CHAR('0', p);
437  } else if (j < 99)
438  PUT_CHAR('0', p);
439  while (*tmp) { /* the exponent */
440  PUT_CHAR(*tmp, p);
441  tmp++;
442  }
443  PAD_LEFT(p);
444 }
445 
446 /* initialize the conversion specifiers */
447 PRIVATE void
448 #ifdef __STDC__
449 conv_flag(char * s, struct DATA * p)
450 #else
452 char * s;
453 struct DATA * p;
454 #endif
455 {
456  char number[MAX_FIELD/2];
457  int i;
458 
459  /* reset the flags. */
460  p->precision = p->width = NOT_FOUND;
461  p->star_w = p->star_p = NOT_FOUND;
462  p->square = p->space = NOT_FOUND;
463  p->a_long = p->justify = NOT_FOUND;
464  p->a_longlong = NOT_FOUND;
465  p->pad = ' ';
466 
467  for(;s && *s ;s++) {
468  switch (*s) {
469  case ' ': p->space = FOUND; break;
470  case '#': p->square = FOUND; break;
471  case '*': if (p->width == NOT_FOUND)
472  p->width = p->star_w = FOUND;
473  else
474  p->precision = p->star_p = FOUND;
475  break;
476  case '+': p->justify = RIGHT; break;
477  case '-': p->justify = LEFT; break;
478  case '.': if (p->width == NOT_FOUND)
479  p->width = 0;
480  break;
481  case '0': p->pad = '0'; break;
482  case '1': case '2': case '3':
483  case '4': case '5': case '6':
484  case '7': case '8': case '9': /* gob all the digits */
485  for (i = 0; isdigit(*s); i++, s++)
486  if (i < MAX_FIELD/2 - 1)
487  number[i] = *s;
488  number[i] = '\0';
489  if (p->width == NOT_FOUND)
490  p->width = atoi(number);
491  else
492  p->precision = atoi(number);
493  s--; /* went to far go back */
494  break;
495  }
496  }
497 }
498 
499 PUBLIC int
500 #ifdef __STDC__
501 vsnprintf(char *string, size_t length, char const * format, va_list args)
502 #else
503 vsnprintf(string, length, format, args)
504 char *string;
505 size_t length;
506 char * format;
507 va_list args;
508 #endif
509 {
510  struct DATA data;
511  char conv_field[MAX_FIELD];
512  double d; /* temporary holder */
513  int state;
514  int i;
515 
516  data.length = length - 1; /* leave room for '\0' */
517  data.holder = string;
518  data.pf = format;
519  data.counter = 0;
520 
521 
522 /* sanity check, the string must be > 1 */
523  if (length < 1)
524  return -1;
525 
526 
527  for (; *data.pf && (data.counter < data.length); data.pf++) {
528  if ( *data.pf == '%' ) { /* we got a magic % cookie */
529  conv_flag((char *)0, &data); /* initialise format flags */
530  for (state = 1; *data.pf && state;) {
531  switch (*(++data.pf)) {
532  case '\0': /* a NULL here ? ? bail out */
533  *data.holder = '\0';
534  return data.counter;
535  break;
536  case 'f': /* float, double */
537  STAR_ARGS(&data);
538  if (data.a_long == FOUND)
539  d = va_arg(args, LONG_DOUBLE);
540  else
541  d = va_arg(args, double);
542  floating(&data, d);
543  state = 0;
544  break;
545  case 'g':
546  case 'G':
547  STAR_ARGS(&data);
548  DEF_PREC(&data);
549  if (data.a_long == FOUND)
550  d = va_arg(args, LONG_DOUBLE);
551  else
552  d = va_arg(args, double);
553  i = log_10(d);
554  /*
555  * for '%g|%G' ANSI: use f if exponent
556  * is in the range or [-4,p] exclusively
557  * else use %e|%E
558  */
559  if (-4 < i && i < data.precision)
560  floating(&data, d);
561  else
562  exponent(&data, d);
563  state = 0;
564  break;
565  case 'e':
566  case 'E': /* Exponent double */
567  STAR_ARGS(&data);
568  if (data.a_long == FOUND)
569  d = va_arg(args, LONG_DOUBLE);
570  else
571  d = va_arg(args, double);
572  exponent(&data, d);
573  state = 0;
574  break;
575  case 'u': /* unsigned decimal */
576  STAR_ARGS(&data);
577  if (data.a_longlong == FOUND)
578  d = va_arg(args, unsigned LONG_LONG);
579  else if (data.a_long == FOUND)
580  d = va_arg(args, unsigned long);
581  else
582  d = va_arg(args, unsigned int);
583  decimal(&data, d);
584  state = 0;
585  break;
586  case 'd': /* decimal */
587  STAR_ARGS(&data);
588  if (data.a_longlong == FOUND)
589  d = va_arg(args, LONG_LONG);
590  else if (data.a_long == FOUND)
591  d = va_arg(args, long);
592  else
593  d = va_arg(args, int);
594  decimal(&data, d);
595  state = 0;
596  break;
597  case 'o': /* octal */
598  STAR_ARGS(&data);
599  if (data.a_longlong == FOUND)
600  d = va_arg(args, LONG_LONG);
601  else if (data.a_long == FOUND)
602  d = va_arg(args, long);
603  else
604  d = va_arg(args, int);
605  octal(&data, d);
606  state = 0;
607  break;
608  case 'x':
609  case 'X': /* hexadecimal */
610  STAR_ARGS(&data);
611  if (data.a_longlong == FOUND)
612  d = va_arg(args, LONG_LONG);
613  else if (data.a_long == FOUND)
614  d = va_arg(args, long);
615  else
616  d = va_arg(args, int);
617  hexa(&data, d);
618  state = 0;
619  break;
620  case 'c': /* character */
621  d = va_arg(args, int);
622  PUT_CHAR(d, &data);
623  state = 0;
624  break;
625  case 's': /* string */
626  STAR_ARGS(&data);
627  strings(&data, va_arg(args, char *));
628  state = 0;
629  break;
630  case 'n':
631  *(va_arg(args, int *)) = data.counter; /* what's the count ? */
632  state = 0;
633  break;
634  case 'q':
635  data.a_longlong = FOUND;
636  break;
637  case 'L':
638  case 'l':
639  if (data.a_long == FOUND)
640  data.a_longlong = FOUND;
641  else
642  data.a_long = FOUND;
643  break;
644  case 'h':
645  break;
646  case '%': /* nothing just % */
647  PUT_CHAR('%', &data);
648  state = 0;
649  break;
650  case '#': case ' ': case '+': case '*':
651  case '-': case '.': case '0': case '1':
652  case '2': case '3': case '4': case '5':
653  case '6': case '7': case '8': case '9':
654  /* initialize width and precision */
655  for (i = 0; isflag(*data.pf); i++, data.pf++)
656  if (i < MAX_FIELD - 1)
657  conv_field[i] = *data.pf;
658  conv_field[i] = '\0';
659  conv_flag(conv_field, &data);
660  data.pf--; /* went to far go back */
661  break;
662  default:
663  /* is this an error ? maybe bail out */
664  state = 0;
665  break;
666  } /* end switch */
667  } /* end of for state */
668  } else { /* not % */
669  PUT_CHAR(*data.pf, &data); /* add the char the string */
670  }
671  }
672 
673  *data.holder = '\0'; /* the end ye ! */
674 
675  return data.counter;
676 }
677 
678 #endif /* HAVE_VSNPRINTF */
679 
680 #ifndef HAVE_SNPRINTF
681 
682 PUBLIC int
683 #if __STDC__
684 snprintf(char *string, size_t length, char const * format, ...)
685 #else
686 snprintf(string, length, format, va_alist)
687 char *string;
688 size_t length;
689 char * format;
690 va_dcl
691 #endif
692 {
693  int rval;
694  va_list args;
695 
696 #if __STDC__
697  va_start(args, format);
698 #else
699  va_start(args);
700 #endif
701 
702  rval = vsnprintf (string, length, format, args);
703 
704  va_end(args);
705 
706  return rval;
707 }
708 
709 #endif /* HAVE_SNPRINTF */
710 
711 
712 #ifdef DRIVER
713 
714 #include <stdio.h>
715 
716 /* set of small tests for snprintf() */
717 int main()
718 {
719  char holder[100];
720  int i;
721 
722 /*
723  printf("Suite of test for snprintf:\n");
724  printf("a_format\n");
725  printf("printf() format\n");
726  printf("snprintf() format\n\n");
727 */
728 /* Checking the field widths */
729 
730  printf("/%%d/, 336\n");
731  snprintf(holder, sizeof holder, "/%d/\n", 336);
732  printf("/%d/\n", 336);
733  printf("%s\n", holder);
734 
735  printf("/%%2d/, 336\n");
736  snprintf(holder, sizeof holder, "/%2d/\n", 336);
737  printf("/%2d/\n", 336);
738  printf("%s\n", holder);
739 
740  printf("/%%10d/, 336\n");
741  snprintf(holder, sizeof holder, "/%10d/\n", 336);
742  printf("/%10d/\n", 336);
743  printf("%s\n", holder);
744 
745  printf("/%%-10d/, 336\n");
746  snprintf(holder, sizeof holder, "/%-10d/\n", 336);
747  printf("/%-10d/\n", 336);
748  printf("%s\n", holder);
749 
750 /* long long */
751 
752  printf("/%%lld/, 336\n");
753  snprintf(holder, sizeof holder, "/%lld/\n", (LONG_LONG)336);
754  printf("/%lld/\n", (LONG_LONG)336);
755  printf("%s\n", holder);
756 
757  printf("/%%2qd/, 336\n");
758  snprintf(holder, sizeof holder, "/%2qd/\n", (LONG_LONG)336);
759  printf("/%2qd/\n", (LONG_LONG)336);
760  printf("%s\n", holder);
761 
762 /* floating points */
763 
764  printf("/%%f/, 1234.56\n");
765  snprintf(holder, sizeof holder, "/%f/\n", 1234.56);
766  printf("/%f/\n", 1234.56);
767  printf("%s\n", holder);
768 
769  printf("/%%e/, 1234.56\n");
770  snprintf(holder, sizeof holder, "/%e/\n", 1234.56);
771  printf("/%e/\n", 1234.56);
772  printf("%s\n", holder);
773 
774  printf("/%%4.2f/, 1234.56\n");
775  snprintf(holder, sizeof holder, "/%4.2f/\n", 1234.56);
776  printf("/%4.2f/\n", 1234.56);
777  printf("%s\n", holder);
778 
779  printf("/%%3.1f/, 1234.56\n");
780  snprintf(holder, sizeof holder, "/%3.1f/\n", 1234.56);
781  printf("/%3.1f/\n", 1234.56);
782  printf("%s\n", holder);
783 
784  printf("/%%10.3f/, 1234.56\n");
785  snprintf(holder, sizeof holder, "/%10.3f/\n", 1234.56);
786  printf("/%10.3f/\n", 1234.56);
787  printf("%s\n", holder);
788 
789  printf("/%%10.3e/, 1234.56\n");
790  snprintf(holder, sizeof holder, "/%10.3e/\n", 1234.56);
791  printf("/%10.3e/\n", 1234.56);
792  printf("%s\n", holder);
793 
794  printf("/%%+4.2f/, 1234.56\n");
795  snprintf(holder, sizeof holder, "/%+4.2f/\n", 1234.56);
796  printf("/%+4.2f/\n", 1234.56);
797  printf("%s\n", holder);
798 
799  printf("/%%010.2f/, 1234.56\n");
800  snprintf(holder, sizeof holder, "/%010.2f/\n", 1234.56);
801  printf("/%010.2f/\n", 1234.56);
802  printf("%s\n", holder);
803 
804 #define BLURB "Outstanding acting !"
805 /* strings precisions */
806 
807  printf("/%%2s/, \"%s\"\n", BLURB);
808  snprintf(holder, sizeof holder, "/%2s/\n", BLURB);
809  printf("/%2s/\n", BLURB);
810  printf("%s\n", holder);
811 
812  printf("/%%22s/ %s\n", BLURB);
813  snprintf(holder, sizeof holder, "/%22s/\n", BLURB);
814  printf("/%22s/\n", BLURB);
815  printf("%s\n", holder);
816 
817  printf("/%%22.5s/ %s\n", BLURB);
818  snprintf(holder, sizeof holder, "/%22.5s/\n", BLURB);
819  printf("/%22.5s/\n", BLURB);
820  printf("%s\n", holder);
821 
822  printf("/%%-22.5s/ %s\n", BLURB);
823  snprintf(holder, sizeof holder, "/%-22.5s/\n", BLURB);
824  printf("/%-22.5s/\n", BLURB);
825  printf("%s\n", holder);
826 
827 /* see some flags */
828 
829  printf("%%x %%X %%#x, 31, 31, 31\n");
830  snprintf(holder, sizeof holder, "%x %X %#x\n", 31, 31, 31);
831  printf("%x %X %#x\n", 31, 31, 31);
832  printf("%s\n", holder);
833 
834  printf("**%%d**%% d**%% d**, 42, 42, -42\n");
835  snprintf(holder, sizeof holder, "**%d**% d**% d**\n", 42, 42, -42);
836  printf("**%d**% d**% d**\n", 42, 42, -42);
837  printf("%s\n", holder);
838 
839 /* other flags */
840 
841  printf("/%%g/, 31.4\n");
842  snprintf(holder, sizeof holder, "/%g/\n", 31.4);
843  printf("/%g/\n", 31.4);
844  printf("%s\n", holder);
845 
846  printf("/%%.6g/, 31.4\n");
847  snprintf(holder, sizeof holder, "/%.6g/\n", 31.4);
848  printf("/%.6g/\n", 31.4);
849  printf("%s\n", holder);
850 
851  printf("/%%.1G/, 31.4\n");
852  snprintf(holder, sizeof holder, "/%.1G/\n", 31.4);
853  printf("/%.1G/\n", 31.4);
854  printf("%s\n", holder);
855 
856  printf("abc%%n\n");
857  printf("abc%n", &i); printf("%d\n", i);
858  snprintf(holder, sizeof holder, "abc%n", &i);
859  printf("%s", holder); printf("%d\n\n", i);
860 
861  printf("%%*.*s --> 10.10\n");
862  snprintf(holder, sizeof holder, "%*.*s\n", 10, 10, BLURB);
863  printf("%*.*s\n", 10, 10, BLURB);
864  printf("%s\n", holder);
865 
866  printf("%%%%%%%%\n");
867  snprintf(holder, sizeof holder, "%%%%\n");
868  printf("%%%%\n");
869  printf("%s\n", holder);
870 
871 #define BIG "Hello this is a too big string for the buffer"
872 /* printf("A buffer to small of 10, trying to put this:\n");*/
873  printf("<%%>, %s\n", BIG);
874  i = snprintf(holder, 10, "%s\n", BIG);
875  printf("<%s>\n", BIG);
876  printf("<%s>\n", holder);
877 
878  return 0;
879 }
880 #endif /* !DRIVER */
int length
Definition: snprintf.h:112
PUBLIC int vsnprintf(char *string, size_t length, char *format, va_list args)
Definition: snprintf.c:503
PRIVATE void strings(struct DATA *p, char *tmp)
Definition: snprintf.c:327
#define LEFT
Definition: snprintf.h:164
#define MAX_FIELD
Definition: snprintf.h:167
PRIVATE void exponent(struct DATA *p, double d)
Definition: snprintf.c:390
#define PUT_CHAR(c, p)
Definition: snprintf.h:187
#define SWAP_INT(a, b)
Definition: snprintf.h:108
int star_w
Definition: snprintf.h:123
#define isflag(c)
Definition: snprintf.h:170
#define otoa(n)
Definition: snprintf.h:104
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:686
PRIVATE char * numtoa(double number, int base, int precision, char **fract)
Definition: snprintf.c:167
uint8_t length
Definition: proto_bfd.c:203
PRIVATE void octal(struct DATA *p, double d)
Definition: snprintf.c:278
char * pf
Definition: snprintf.h:118
PRIVATE void conv_flag(char *s, struct DATA *p)
Definition: snprintf.c:451
#define htoa(n)
Definition: snprintf.h:105
#define PAD_LEFT(p)
Definition: snprintf.h:208
int a_long
Definition: snprintf.h:123
#define LONG_DOUBLE
Definition: snprintf.h:95
int a_longlong
Definition: snprintf.h:123
int space
Definition: snprintf.h:123
PRIVATE void hexa(struct DATA *p, double d)
Definition: snprintf.c:302
#define LONG_LONG
Definition: snprintf.h:87
#define MAX_INT
Definition: snprintf.h:80
#define PUT_PLUS(d, p)
Definition: snprintf.h:193
#define PAD_RIGHT(p)
Definition: snprintf.h:202
PRIVATE int log_10(double r)
Definition: snprintf.c:91
int width
Definition: snprintf.h:121
char pad
Definition: snprintf.h:122
#define DEF_PREC(p)
Definition: snprintf.h:182
#define PRIVATE
Definition: snprintf.h:51
#define MAX_FRACT
Definition: snprintf.h:81
#define FOUND
Definition: snprintf.h:166
int justify
Definition: snprintf.h:122
#define PUT_SPACE(d, p)
Definition: snprintf.h:197
int square
Definition: snprintf.h:123
unsigned int state
Definition: proto_bfd.c:200
char * holder
Definition: snprintf.h:113
#define NOT_FOUND
Definition: snprintf.h:165
int counter
Definition: snprintf.h:114
#define STAR_ARGS(p)
Definition: snprintf.h:214
PRIVATE void decimal(struct DATA *p, double d)
Definition: snprintf.c:254
#define PRECISION
Definition: snprintf.c:156
#define RIGHT
Definition: snprintf.h:163
PRIVATE double integral(double real, double *ip)
Definition: snprintf.c:119
#define dtoa(n, p, f)
Definition: snprintf.h:106
int main(int argc, char *argv[])
Definition: radattr.c:959
int precision
Definition: snprintf.h:121
int star_p
Definition: snprintf.h:123
#define PUBLIC
Definition: snprintf.h:52
PRIVATE double pow_10(int n)
Definition: snprintf.c:65
Definition: snprintf.h:111
#define RCSID(id)
Definition: build.h:135
static int r
Definition: rbmonkey.c:66
#define ROUND(d, p)
Definition: snprintf.h:176
PRIVATE void floating(struct DATA *p, double d)
Definition: snprintf.c:351
#define itoa(n)
Definition: snprintf.h:103