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