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