Welcome to mirror list, hosted at ThFree Co, Russian Federation.

sprintf.c « stdio « libc « newlib - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 6e6750145d616ffb3b076d5af7df3a809c0ca7d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
/*
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the University of California, Berkeley.  The name of the
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/*

FUNCTION
        <<printf>>, <<fprintf>>, <<saprintf>>, <<sprintf>>, <<snprintf>>---format output
INDEX
	fprintf
INDEX
	printf
INDEX
	saprintf
INDEX
	sprintf
INDEX
	snprintf

ANSI_SYNOPSIS
        #include <stdio.h>

        int printf(const char *<[format]> [, <[arg]>, ...]);
        int fprintf(FILE *<[fd]>, const char *<[format]> [, <[arg]>, ...]);
        int sprintf(char *<[str]>, const char *<[format]> [, <[arg]>, ...]);
        int saprintf(char **<[strp]>, const char *<[format]> [, <[arg]>, ...]);
        int snprintf(char *<[str]>, size_t <[size]>, const char *<[format]> [, <[arg]>, ...]);

TRAD_SYNOPSIS
	#include <stdio.h>

	int printf(<[format]> [, <[arg]>, ...])
	char *<[format]>;

	int fprintf(<[fd]>, <[format]> [, <[arg]>, ...]);
	FILE *<[fd]>;
	char *<[format]>;

	int saprintf(<[strp]>, <[format]> [, <[arg]>, ...]);
	char **<[strp]>;
	char *<[format]>;

	int sprintf(<[str]>, <[format]> [, <[arg]>, ...]);
	char *<[str]>;
	char *<[format]>;

	int snprintf(<[str]>, size_t <[size]>, <[format]> [, <[arg]>, ...]);
	char *<[str]>;
        size_t <[size]>;
	char *<[format]>;

DESCRIPTION
        <<printf>> accepts a series of arguments, applies to each a
        format specifier from <<*<[format]>>>, and writes the
        formatted data to <<stdout>>, terminated with a null character.
        The behavior of <<printf>> is undefined if there are not enough
        arguments for the format.
        <<printf>> returns when it reaches the end of the format string.
        If there are more arguments than the format requires, excess
        arguments are ignored.

        <<fprintf>>, <<saprintf>>, <<sprintf>> and <<snprintf>> are identical 
	to <<printf>>, other than the destination of the formatted output: 
	<<fprintf>> sends the output to a specified file <[fd]>, while 
	<<saprintf>> stores the output in a dynamically allocated buffer,
	while <<sprintf>> stores the output in the specified char array 
	<[str]> and <<snprintf>> limits number of characters written to 
	<[str]> to at most <[size]> (including terminating <<0>>).  For 
	<<sprintf>> and <<snprintf>>, the behavior is undefined if the 
	output <<*<[str]>>> overlaps with one of the arguments. For
	<<saprintf>>, <[strp]> points to a pointer to char which is filled
	in with the dynamically allocated buffer.  <[format]> is a pointer 
	to a charater string containing two types of objects: ordinary 
	characters (other than <<%>>), which are copied unchanged to the 
	output, and conversion specifications, each of which is introduced 
	by <<%>>. (To include <<%>> in the output, use <<%%>> in the format 
	string.) A conversion specification has the following form:

.       %[<[flags]>][<[width]>][.<[prec]>][<[size]>][<[type]>]

        The fields of the conversion specification have the following meanings:

        O+
	o <[flags]>

	an optional sequence of characters which control
	output justification, numeric signs, decimal points,
	trailing zeroes, and octal and hex prefixes.
	The flag characters are minus (<<->>), plus (<<+>>),
	space ( ), zero (<<0>>), and sharp (<<#>>).  They can
	appear in any combination.

	o+
    	o -
		The result of the conversion is left justified, and the right is
		padded with blanks.  If you do not use this flag, the result is right
		justified, and padded on the left.

        o +
		The result of a signed conversion (as determined by <[type]>)
		will always begin with a plus or minus sign.  (If you do not use
        this flag, positive values do not begin with a plus sign.)

        o " " (space)
		If the first character of a signed conversion specification
        is not a sign, or if a signed conversion results in no
		characters, the result will begin with a space.  If the
        space ( ) flag and the plus (<<+>>) flag both appear,
		the space flag is ignored.

        o 0
		If the <[type]> character is <<d>>, <<i>>, <<o>>, <<u>>,
		<<x>>, <<X>>, <<e>>, <<E>>, <<f>>, <<g>>, or <<G>>: leading zeroes,
		are used to pad the field width (following any indication of sign or
		base); no spaces are used for padding.  If the zero (<<0>>) and
		minus (<<->>) flags both appear, the zero (<<0>>) flag will
		be ignored.  For <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, and <<X>>
		conversions, if a precision <[prec]> is specified, the zero (<<0>>)
        flag is ignored.
		
		Note that <<0>> is interpreted as a flag, not as the beginning
        of a field width.

        o #
		The result is to be converted to an alternative form, according
		to the next character:

	    o+
		    o 0
			increases precision to force the first digit
                        of the result to be a zero.

			o x
			a non-zero result will have a <<0x>> prefix.

			o X
			a non-zero result will have a <<0X>> prefix.

			o e, E or f
			The result will always contain a decimal point
		        even if no digits follow the point.
                        (Normally, a decimal point appears only if a
			digit follows it.)  Trailing zeroes are removed.

			o g or G
			same as <<e>> or <<E>>, but trailing zeroes
                        are not removed.

			o all others
			undefined.

			o-
      o-

      o <[width]>

	  <[width]> is an optional minimum field width.  You can either
	  specify it directly as a decimal integer, or indirectly by
          using instead an asterisk (<<*>>), in which case an <<int>>
          argument is used as the field width.  Negative field widths
          are not supported; if you attempt to specify a negative field
          width, it is interpreted as a minus (<<->>) flag followed by a
          positive field width.

      o <[prec]>

	  an optional field; if present, it is introduced with `<<.>>'
	  (a period). This field gives the maximum number of
	  characters to print in a conversion; the minimum number of
	  digits of an integer to print, for conversions with <[type]>
	  <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, and <<X>>; the maximum number of
	  significant digits, for the <<g>> and <<G>> conversions;
	  or the number of digits to print after the decimal
	  point, for <<e>>, <<E>>, and <<f>> conversions.  You can specify
	  the precision either directly as a decimal integer or
	  indirectly by using an asterisk (<<*>>), in which case
	  an <<int>> argument is used as the precision.  Supplying a negative
      precision is equivalent to omitting the precision.
	  If only a period is specified the precision is zero.
	  If a precision appears with any other conversion <[type]>
	  than those listed here, the behavior is undefined.

      o  <[size]>

		<<h>>, <<l>>, and <<L>> are optional size characters which
		override the default way that <<printf>> interprets the
		data type of the corresponding argument.  <<h>> forces
		the following <<d>>, <<i>>, <<o>>, <<u>>, <<x>> or <<X>> conversion
		<[type]> to apply to a <<short>> or <<unsigned short>>. <<h>> also
		forces a following <<n>> <[type]> to apply to
		a pointer to a <<short>>. Similarily, an
		<<l>> forces the following <<d>>, <<i>>, <<o>>, <<u>>,
		<<x>> or <<X>> conversion <[type]> to apply to a <<long>> or
		<<unsigned long>>.  <<l>> also forces a following <<n>> <[type]> to
		apply to a pointer to a <<long>>. If an <<h>>
		or an <<l>> appears with another conversion
		specifier, the behavior is undefined.  <<L>> forces a
		following <<e>>, <<E>>, <<f>>, <<g>> or <<G>> conversion <[type]> to
		apply to a <<long double>> argument.  If <<L>> appears with
		any other conversion <[type]>, the behavior is undefined.

     o   <[type]>

		<[type]> specifies what kind of conversion <<printf>> performs.
		Here is a table of these:

	o+
		o %
		prints the percent character (<<%>>)

		o c
		prints <[arg]> as single character
		
		o s
		prints characters until precision is reached or a null terminator
		is encountered; takes a string pointer

		o d
		prints a signed decimal integer; takes an <<int>> (same as <<i>>)

		o i
		prints a signed decimal integer; takes an <<int>> (same as <<d>>)

		o o
		prints a signed octal integer; takes an <<int>>

		o u
		prints an unsigned decimal integer; takes an <<int>>

		o x
		prints an unsigned hexadecimal integer (using <<abcdef>> as
		digits beyond <<9>>); takes an <<int>>

		o X
		prints an unsigned hexadecimal integer (using <<ABCDEF>> as
		digits beyond <<9>>); takes an <<int>>

		o f
		prints a signed value of the form <<[-]9999.9999>>; takes
		a floating point number
	
		o e
		prints a signed	value of the form <<[-]9.9999e[+|-]999>>; takes a
		floating point number

		o E
		prints the same way as <<e>>, but using <<E>> to introduce the
		exponent; takes a floating point number

		o g
		prints a signed value in either <<f>> or <<e>> form, based on given
		value and precision---trailing zeros and the decimal point are
		printed only if necessary; takes a floating point number
	
		o G
		prints the same way as <<g>>, but using <<E>> for the exponent if an
		exponent is needed; takes a floating point number

		o n
		stores (in the same object) a count of the characters written;
		takes a pointer to <<int>>

		o p
		prints a pointer in an implementation-defined format.
		This implementation treats the pointer as an
		<<unsigned long>> (same as <<Lu>>).
	o-
O-


RETURNS
<<sprintf>> and <<saprintf>> return the number of bytes in the output string,
save that the concluding <<NULL>> is not counted.
<<printf>> and <<fprintf>> return the number of characters transmitted.
If an error occurs, <<printf>> and <<fprintf>> return <<EOF>> and
<<saprintf>> returns -1.  No error returns occur for <<sprintf>>.

PORTABILITY
        The  ANSI C standard specifies that implementations must
        support at least formatted output of up to 509 characters.

Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/

#include <stdio.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <limits.h>
#include <_ansi.h>
#include "local.h"

int
#ifdef _HAVE_STDC
_DEFUN (_sprintf_r, (ptr, str, fmt), struct _reent *ptr _AND char *str _AND _CONST char *fmt _DOTS)
#else
_sprintf_r (ptr, str, fmt, va_alist)
     struct _reent *ptr;
     char *str;
     _CONST char *fmt;
     va_dcl
#endif
{
  int ret;
  va_list ap;
  FILE f;

  f._flags = __SWR | __SSTR;
  f._bf._base = f._p = (unsigned char *) str;
  f._bf._size = f._w = INT_MAX;
  f._data = ptr;
#ifdef _HAVE_STDC
  va_start (ap, fmt);
#else
  va_start (ap);
#endif
  ret = vfprintf (&f, fmt, ap);
  va_end (ap);
  *f._p = 0;
  return (ret);
}

#ifndef _REENT_ONLY

int
#ifdef _HAVE_STDC
_DEFUN (sprintf, (str, fmt), char *str _AND _CONST char *fmt _DOTS)
#else
sprintf (str, fmt, va_alist)
     char *str;
     _CONST char *fmt;
     va_dcl
#endif
{
  int ret;
  va_list ap;
  FILE f;

  f._flags = __SWR | __SSTR;
  f._bf._base = f._p = (unsigned char *) str;
  f._bf._size = f._w = INT_MAX;
  f._data = _REENT;
#ifdef _HAVE_STDC
  va_start (ap, fmt);
#else
  va_start (ap);
#endif
  ret = vfprintf (&f, fmt, ap);
  va_end (ap);
  *f._p = 0;
  return (ret);
}

#endif