The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
snprintf.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or (at
6  * your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  */
17 
18 /** Unix snprintf implementation
19  *
20  * Version 1.4
21  *
22  * THANKS(for the patches and ideas):
23  * Miles Bader
24  * Cyrille Rustom
25  * Jacek Slabocewiz
26  * Mike Parker(mouse)
27  *
28  * @file src/lib/util/snprintf.h
29  *
30  * @copyright Alain Magloire: alainm@rcsm.ee.mcgill.ca
31  */
32 #ifndef HAVE_VSNPRINTF
33 
34 RCSIDH(snprintf_h, "$Id: 5a86bc9d8e0ceddda1c72bfa441f81a1ff94eba3 $")
35 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
40 #include <freeradius-devel/build.h>
41 #include <freeradius-devel/missing.h>
42 
43 #if __STDC__
44 #include <stdarg.h>
45 #else
46 #include <varargs.h>
47 #endif
48 
49 #include <ctype.h>
50 #include <stdlib.h> /* for atoi() */
51 
52 #define PRIVATE static
53 #define PUBLIC
54 
55 /*
56  * For the FLOATING POINT FORMAT :
57  * the challenge was finding a way to
58  * manipulate the Real numbers without having
59  * to resort to mathematical function(it
60  * would require to link with -lm) and not
61  * going down to the bit pattern(not portable)
62  *
63  * so a number, a real is:
64 
65  real = integral + fraction
66 
67  integral = ... + a(2)*10^2 + a(1)*10^1 + a(0)*10^0
68  fraction = b(1)*10^-1 + b(2)*10^-2 + ...
69 
70  where:
71  0 <= a(i) => 9
72  0 <= b(i) => 9
73 
74  from then it was simple math
75  */
76 
77 /*
78  * size of the buffer for the integral part
79  * and the fraction part
80  */
81 #define MAX_INT 99 + 1 /* 1 for the null */
82 #define MAX_FRACT 29 + 1
83 
84 /*
85  * If the compiler supports (long long)
86  */
87 #ifndef LONG_LONG
88 # define LONG_LONG long long
89 /*# define LONG_LONG int64_t*/
90 #endif
91 
92 /*
93  * If the compiler supports (long double)
94  */
95 #ifndef LONG_DOUBLE
96 # define LONG_DOUBLE long double
97 /*# define LONG_DOUBLE double*/
98 #endif
99 
100 /*
101  * numtoa() uses PRIVATE buffers to store the results,
102  * So this function is not reentrant
103  */
104 #define itoa(n) numtoa(n, 10, 0, (char **)0)
105 #define otoa(n) numtoa(n, 8, 0, (char **)0)
106 #define htoa(n) numtoa(n, 16, 0, (char **)0)
107 #define dtoa(n, p, f) numtoa(n, 10, p, f)
108 
109 #define SWAP_INT(a,b) {int t; t = (a); (a) = (b); (b) = t;}
110 
111 /* this struct holds everything we need */
112 struct DATA {
113  int length;
114  char *holder;
115  int counter;
116 #ifdef __STDC__
117  char const *pf;
118 #else
119  char *pf;
120 #endif
121 /* FLAGS */
123  int justify; char pad;
125 };
126 
127 /* signature of the functions */
128 #ifdef __STDC__
129 /* the floating point stuff */
130  PRIVATE double pow_10(int);
131  PRIVATE int log_10(double);
132  PRIVATE double integral(double, double *);
133  PRIVATE char * numtoa(double, int, int, char **);
134 
135 /* for the format */
136  PRIVATE void conv_flag(char *, struct DATA *);
137  PRIVATE void floating(struct DATA *, double);
138  PRIVATE void exponent(struct DATA *, double);
139  PRIVATE void float64(struct DATA *, double);
140  PRIVATE void octal(struct DATA *, double);
141  PRIVATE void hexa(struct DATA *, double);
142  PRIVATE void strings(struct DATA *, char *);
143 
144 #else
145 /* the floating point stuff */
146  PRIVATE double pow_10();
148  PRIVATE double integral();
149  PRIVATE char * numtoa();
150 
151 /* for the format */
155  PRIVATE void float64();
156  PRIVATE void octal();
157  PRIVATE void hexa();
158  PRIVATE void strings();
159 #endif
160 
161 /* those are defines specific to snprintf to hopefully
162  * make the code clearer :-)
163  */
164 #define RIGHT 1
165 #define LEFT 0
166 #define NOT_FOUND -1
167 #define FOUND 1
168 #define MAX_FIELD 15
169 
170 /* the conversion flags */
171 #define isflag(c) ((c) == '#' || (c) == ' ' || \
172  (c) == '*' || (c) == '+' || \
173  (c) == '-' || (c) == '.' || \
174  isdigit(c))
175 
176 /* round off to the precision */
177 #define ROUND(d, p) \
178  (d < 0.) ? \
179  d - pow_10(-(p)->precision) * 0.5 : \
180  d + pow_10(-(p)->precision) * 0.5
181 
182 /* set default precision */
183 #define DEF_PREC(p) \
184  if ((p)->precision == NOT_FOUND) \
185  (p)->precision = 6
186 
187 /* put a char */
188 #define PUT_CHAR(c, p) \
189  if ((p)->counter < (p)->length) { \
190  *(p)->holder++ = (c); \
191  (p)->counter++; \
192  }
193 
194 #define PUT_PLUS(d, p) \
195  if ((d) > 0. && (p)->justify == RIGHT) \
196  PUT_CHAR('+', p)
197 
198 #define PUT_SPACE(d, p) \
199  if ((p)->space == FOUND && (d) > 0.) \
200  PUT_CHAR(' ', p)
201 
202 /* pad right */
203 #define PAD_RIGHT(p) \
204  if ((p)->width > 0 && (p)->justify != LEFT) \
205  for (; (p)->width > 0; (p)->width--) \
206  PUT_CHAR((p)->pad, p)
207 
208 /* pad left */
209 #define PAD_LEFT(p) \
210  if ((p)->width > 0 && (p)->justify == LEFT) \
211  for (; (p)->width > 0; (p)->width--) \
212  PUT_CHAR((p)->pad, p)
213 
214 /* if width and prec. in the args */
215 #define STAR_ARGS(p) \
216  if ((p)->star_w == FOUND) \
217  (p)->width = va_arg(args, int); \
218  if ((p)->star_p == FOUND) \
219  (p)->precision = va_arg(args, int)
220 
221 #endif /* HAVE_VSNPRINTF */
222 
223 #ifdef __cplusplus
224 }
225 #endif
226 
#define RCSIDH(h, id)
Definition: build.h:445
int length
Definition: snprintf.h:113
PRIVATE void strings()
char * pf
Definition: snprintf.h:119
int star_w
Definition: snprintf.h:124
int star_p
Definition: snprintf.h:124
PRIVATE char * numtoa()
int a_longlong
Definition: snprintf.h:124
PRIVATE double pow_10()
#define PRIVATE
Definition: snprintf.h:52
int square
Definition: snprintf.h:124
int space
Definition: snprintf.h:124
int precision
Definition: snprintf.h:122
PRIVATE void hexa()
PRIVATE double integral()
char * holder
Definition: snprintf.h:114
int a_long
Definition: snprintf.h:124
PRIVATE void floating()
PRIVATE void exponent()
char pad
Definition: snprintf.h:123
int justify
Definition: snprintf.h:123
PRIVATE void conv_flag()
PRIVATE int log_10()
PRIVATE void float64()
int width
Definition: snprintf.h:122
PRIVATE void octal()
int counter
Definition: snprintf.h:115
Definition: snprintf.h:112