1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cstdlib/LSTDIO/SPRINTF.C Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,368 @@
1.4 +/* SPRINTF.C
1.5 + *
1.6 + * Portions Copyright (c) 1990-2006 Nokia Corporation and/or its subsidiary(-ies).
1.7 + * All rights reserved.
1.8 + */
1.9 +
1.10 +/*
1.11 + * Copyright (c) 1990 The Regents of the University of California.
1.12 + * All rights reserved.
1.13 + *
1.14 + * Redistribution and use in source and binary forms are permitted
1.15 + * provided that the above copyright notice and this paragraph are
1.16 + * duplicated in all such forms and that any documentation,
1.17 + * advertising materials, and other materials related to such
1.18 + * distribution and use acknowledge that the software was developed
1.19 + * by the University of California, Berkeley. The name of the
1.20 + * University may not be used to endorse or promote products derived
1.21 + * from this software without specific prior written permission.
1.22 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1.23 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1.24 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1.25 + */
1.26 +
1.27 +/*
1.28 +
1.29 +FUNCTION
1.30 + <<printf>>, <<fprintf>>, <<sprintf>>---format output
1.31 +INDEX
1.32 + fprintf
1.33 +INDEX
1.34 + printf
1.35 +INDEX
1.36 + sprintf
1.37 +
1.38 +ANSI_SYNOPSIS
1.39 + #include <stdio.h>
1.40 +
1.41 + int printf(const char *<[format]> [, <[arg]>, ...]);
1.42 + int fprintf(FILE *<[fd]>, const char *<[format]> [, <[arg]>, ...]);
1.43 + int sprintf(char *<[str]>, const char *<[format]> [, <[arg]>, ...]);
1.44 +
1.45 +TRAD_SYNOPSIS
1.46 + #include <stdio.h>
1.47 +
1.48 + int printf(<[format]> [, <[arg]>, ...])
1.49 + char *<[format]>;
1.50 +
1.51 + int fprintf(<[fd]>, <[format]> [, <[arg]>, ...]);
1.52 + FILE *<[fd]>;
1.53 + char *<[format]>;
1.54 +
1.55 + int sprintf(<[str]>, <[format]> [, <[arg]>, ...]);
1.56 + char *<[str]>;
1.57 + char *<[format]>;
1.58 +
1.59 +DESCRIPTION
1.60 + <<printf>> accepts a series of arguments, applies to each a
1.61 + format specifier from <<*<[format]>>>, and writes the
1.62 + formatted data to <<stdout>>, terminated with a null character.
1.63 + The behavior of <<printf>> is undefined if there are not enough
1.64 + arguments for the format.
1.65 + <<printf>> returns when it reaches the end of the format string.
1.66 + If there are more arguments than the format requires, excess
1.67 + arguments are ignored.
1.68 +
1.69 + <<fprintf>> and <<sprintf>> are identical to <<printf>>, other than the
1.70 + destination of the formatted output: <<fprintf>> sends the
1.71 + output to a specified file <[fd]>, while <<sprintf>> stores the
1.72 + output in the specified char array <[str]>. For <<sprintf>>,
1.73 + the behavior is also undefined if the output <<*<[str]>>>
1.74 + overlaps with one of the arguments.
1.75 + <[format]> is a pointer to a charater string containing two types of
1.76 + objects: ordinary characters (other than <<%>>), which are
1.77 + copied unchanged to the output, and conversion
1.78 + specifications, each of which is introduced by <<%>>.
1.79 + (To include <<%>> in the output, use <<%%>> in the format string.)
1.80 + A conversion specification has the following form:
1.81 +
1.82 +. %[<[flags]>][<[width]>][.<[prec]>][<[size]>][<[type]>]
1.83 +
1.84 + The fields of the conversion specification have the following meanings:
1.85 +
1.86 + O+
1.87 + o <[flags]>
1.88 +
1.89 + an optional sequence of characters which control
1.90 + output justification, numeric signs, decimal points,
1.91 + trailing zeroes, and octal and hex prefixes.
1.92 + The flag characters are minus (<<->>), plus (<<+>>),
1.93 + space ( ), zero (<<0>>), and sharp (<<#>>). They can
1.94 + appear in any combination.
1.95 +
1.96 + o+
1.97 + o -
1.98 + The result of the conversion is left justified, and the right is
1.99 + padded with blanks. If you do not use this flag, the result is right
1.100 + justified, and padded on the left.
1.101 +
1.102 + o +
1.103 + The result of a signed conversion (as determined by <[type]>)
1.104 + will always begin with a plus or minus sign. (If you do not use
1.105 + this flag, positive values do not begin with a plus sign.)
1.106 +
1.107 + o " " (space)
1.108 + If the first character of a signed conversion specification
1.109 + is not a sign, or if a signed conversion results in no
1.110 + characters, the result will begin with a space. If the
1.111 + space ( ) flag and the plus (<<+>>) flag both appear,
1.112 + the space flag is ignored.
1.113 +
1.114 + o 0
1.115 + If the <[type]> character is <<d>>, <<i>>, <<o>>, <<u>>,
1.116 + <<x>>, <<X>>, <<e>>, <<E>>, <<f>>, <<g>>, or <<G>>: leading zeroes,
1.117 + are used to pad the field width (following any indication of sign or
1.118 + base); no spaces are used for padding. If the zero (<<0>>) and
1.119 + minus (<<->>) flags both appear, the zero (<<0>>) flag will
1.120 + be ignored. For <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, and <<X>>
1.121 + conversions, if a precision <[prec]> is specified, the zero (<<0>>)
1.122 + flag is ignored.
1.123 +
1.124 + Note that <<0>> is interpreted as a flag, not as the beginning
1.125 + of a field width.
1.126 +
1.127 + o #
1.128 + The result is to be converted to an alternative form, according
1.129 + to the next character:
1.130 +
1.131 + o+
1.132 + o 0
1.133 + increases precision to force the first digit
1.134 + of the result to be a zero.
1.135 +
1.136 + o x
1.137 + a non-zero result will have a <<0x>> prefix.
1.138 +
1.139 + o X
1.140 + a non-zero result will have a <<0X>> prefix.
1.141 +
1.142 + o e, E or f
1.143 + The result will always contain a decimal point
1.144 + even if no digits follow the point.
1.145 + (Normally, a decimal point appears only if a
1.146 + digit follows it.) Trailing zeroes are removed.
1.147 +
1.148 + o g or G
1.149 + same as <<e>> or <<E>>, but trailing zeroes
1.150 + are not removed.
1.151 +
1.152 + o all others
1.153 + undefined.
1.154 +
1.155 + o-
1.156 + o-
1.157 +
1.158 + o <[width]>
1.159 +
1.160 + <[width]> is an optional minimum field width. You can either
1.161 + specify it directly as a decimal integer, or indirectly by
1.162 + using instead an asterisk (<<*>>), in which case an <<int>>
1.163 + argument is used as the field width. Negative field widths
1.164 + are not supported; if you attempt to specify a negative field
1.165 + width, it is interpreted as a minus (<<->>) flag followed by a
1.166 + positive field width.
1.167 +
1.168 + o <[prec]>
1.169 +
1.170 + an optional field; if present, it is introduced with `<<.>>'
1.171 + (a period). This field gives the maximum number of
1.172 + characters to print in a conversion; the minimum number of
1.173 + digits of an integer to print, for conversions with <[type]>
1.174 + <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, and <<X>>; the maximum number of
1.175 + significant digits, for the <<g>> and <<G>> conversions;
1.176 + or the number of digits to print after the decimal
1.177 + point, for <<e>>, <<E>>, and <<f>> conversions. You can specify
1.178 + the precision either directly as a decimal integer or
1.179 + indirectly by using an asterisk (<<*>>), in which case
1.180 + an <<int>> argument is used as the precision. Supplying a negative
1.181 + precision is equivalent to omitting the precision.
1.182 + If only a period is specified the precision is zero.
1.183 + If a precision appears with any other conversion <[type]>
1.184 + than those listed here, the behavior is undefined.
1.185 +
1.186 + o <[size]>
1.187 +
1.188 + <<h>>, <<l>>, and <<L>> are optional size characters which
1.189 + override the default way that <<printf>> interprets the
1.190 + data type of the corresponding argument. <<h>> forces
1.191 + the following <<d>>, <<i>>, <<o>>, <<u>>, <<x>> or <<X>> conversion
1.192 + <[type]> to apply to a <<short>> or <<unsigned short>>. <<h>> also
1.193 + forces a following <<n>> <[type]> to apply to
1.194 + a pointer to a <<short>>. Similarily, an
1.195 + <<l>> forces the following <<d>>, <<i>>, <<o>>, <<u>>,
1.196 + <<x>> or <<X>> conversion <[type]> to apply to a <<long>> or
1.197 + <<unsigned long>>. <<l>> also forces a following <<n>> <[type]> to
1.198 + apply to a pointer to a <<long>>. If an <<h>>
1.199 + or an <<l>> appears with another conversion
1.200 + specifier, the behavior is undefined. <<L>> forces a
1.201 + following <<e>>, <<E>>, <<f>>, <<g>> or <<G>> conversion <[type]> to
1.202 + apply to a <<long double>> argument. If <<L>> appears with
1.203 + any other conversion <[type]>, the behavior is undefined.
1.204 +
1.205 + o <[type]>
1.206 +
1.207 + <[type]> specifies what kind of conversion <<printf>> performs.
1.208 + Here is a table of these:
1.209 +
1.210 + o+
1.211 + o %
1.212 + prints the percent character (<<%>>)
1.213 +
1.214 + o c
1.215 + prints <[arg]> as single character
1.216 +
1.217 + o s
1.218 + prints characters until precision is reached or a null terminator
1.219 + is encountered; takes a string pointer
1.220 +
1.221 + o d
1.222 + prints a signed decimal integer; takes an <<int>> (same as <<i>>)
1.223 +
1.224 + o i
1.225 + prints a signed decimal integer; takes an <<int>> (same as <<d>>)
1.226 +
1.227 + o o
1.228 + prints a signed octal integer; takes an <<int>>
1.229 +
1.230 + o u
1.231 + prints an unsigned decimal integer; takes an <<int>>
1.232 +
1.233 + o x
1.234 + prints an unsigned hexadecimal integer (using <<abcdef>> as
1.235 + digits beyond <<9>>); takes an <<int>>
1.236 +
1.237 + o X
1.238 + prints an unsigned hexadecimal integer (using <<ABCDEF>> as
1.239 + digits beyond <<9>>); takes an <<int>>
1.240 +
1.241 + o f
1.242 + prints a signed value of the form <<[-]9999.9999>>; takes
1.243 + a floating point number
1.244 +
1.245 + o e
1.246 + prints a signed value of the form <<[-]9.9999e[+|-]999>>; takes a
1.247 + floating point number
1.248 +
1.249 + o E
1.250 + prints the same way as <<e>>, but using <<E>> to introduce the
1.251 + exponent; takes a floating point number
1.252 +
1.253 + o g
1.254 + prints a signed value in either <<f>> or <<e>> form, based on given
1.255 + value and precision---trailing zeros and the decimal point are
1.256 + printed only if necessary; takes a floating point number
1.257 +
1.258 + o G
1.259 + prints the same way as <<g>>, but using <<E>> for the exponent if an
1.260 + exponent is needed; takes a floating point number
1.261 +
1.262 + o n
1.263 + stores (in the same object) a count of the characters written;
1.264 + takes a pointer to <<int>>
1.265 +
1.266 + o p
1.267 + prints a pointer in an implementation-defined format.
1.268 + This implementation treats the pointer as an
1.269 + <<unsigned long>> (same as <<Lu>>).
1.270 + o-
1.271 +O-
1.272 +
1.273 +
1.274 +RETURNS
1.275 +<<sprintf>> returns the number of bytes in the output string,
1.276 +save that the concluding <<NULL>> is not counted.
1.277 +<<printf>> and <<fprintf>> return the number of characters transmitted.
1.278 +If an error occurs, <<printf>> and <<fprintf>> return <<EOF>>.
1.279 +Error returns occur for <<sprintf>>.
1.280 +
1.281 +PORTABILITY
1.282 + The ANSI C standard specifies that implementations must
1.283 + support at least formatted output of up to 509 characters.
1.284 +
1.285 +Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
1.286 +<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
1.287 +*/
1.288 +
1.289 +#include <_ansi.h>
1.290 +#include <stdio_r.h>
1.291 +#include <stdarg.h>
1.292 +#include <limits.h>
1.293 +#include "LOCAL.H"
1.294 +
1.295 +/**
1.296 +A reentrant version of sprintf().
1.297 +*/
1.298 +EXPORT_C int _sprintf_r (struct _reent *ptr, char *str, const char *fmt, ...)
1.299 +{
1.300 + int ret;
1.301 + va_list ap;
1.302 + FILE f;
1.303 +
1.304 + f._flags = __SWR | __SSTR;
1.305 + f._bf._base = f._p = (unsigned char *) str;
1.306 + f._bf._size = f._w = INT_MAX;
1.307 + f._data = ptr;
1.308 + va_start (ap, fmt);
1.309 + ret = vfprintf (&f, fmt, ap);
1.310 + va_end (ap);
1.311 + *f._p = 0;
1.312 + return (ret);
1.313 +}
1.314 +
1.315 +#ifndef _REENT_ONLY
1.316 +
1.317 +/**
1.318 +Print formatted data to a string.
1.319 +Writes a sequence of arguments to the given buffer formatted as the format argument specifies.
1.320 +
1.321 +@param str Buffer where to store the resulting formatted string.
1.322 +@param fmt String that contains the text to be printed.
1.323 +
1.324 +@return On Success, the total number of characters printed is returned.
1.325 + On Failure, a negative number is returned.
1.326 +*/
1.327 +EXPORT_C int sprintf (char *str, const char *fmt, ...)
1.328 +{
1.329 + int ret;
1.330 + va_list ap;
1.331 + FILE f;
1.332 +
1.333 + f._flags = __SWR | __SSTR;
1.334 + f._bf._base = f._p = (unsigned char *) str;
1.335 + f._bf._size = f._w = INT_MAX;
1.336 + f._data = _REENT2;
1.337 + if (!f._data)
1.338 + return EOF; // Memory for library globals is not allocated (errno not set).
1.339 + va_start (ap, fmt);
1.340 + ret = vfprintf (&f, fmt, ap);
1.341 + va_end (ap);
1.342 + *f._p = 0;
1.343 + return (ret);
1.344 +}
1.345 +
1.346 +
1.347 +/**
1.348 +@param str Buffer where to store the resulting formatted string.
1.349 +@param fmt String that contains the text to be printed.
1.350 +@param ap
1.351 +
1.352 +@return On Success, the total number of characters printed is returned.
1.353 + On Failure, a negative number is returned.
1.354 +*/
1.355 +EXPORT_C int vsprintf (char *str,char const *fmt, va_list ap)
1.356 +{
1.357 + int ret;
1.358 + FILE f;
1.359 +
1.360 + f._flags = __SWR | __SSTR;
1.361 + f._bf._base = f._p = (unsigned char *) str;
1.362 + f._bf._size = f._w = INT_MAX;
1.363 + f._data = _REENT2;
1.364 + if (!f._data)
1.365 + return EOF; // Memory for library globals is not allocated (errno not set).
1.366 + ret = vfprintf (&f, fmt, ap);
1.367 + *f._p = 0;
1.368 + return ret;
1.369 +}
1.370 +
1.371 +#endif