Contiki 2.6

_SP_sprintf.c

00001 /*
00002  * Copyright (c) 1990 The Regents of the University of California.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms are permitted
00006  * provided that the above copyright notice and this paragraph are
00007  * duplicated in all such forms and that any documentation,
00008  * advertising materials, and other materials related to such
00009  * distribution and use acknowledge that the software was developed
00010  * by the University of California, Berkeley.  The name of the
00011  * University may not be used to endorse or promote products derived
00012  * from this software without specific prior written permission.
00013  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
00014  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00015  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00016  */
00017 
00018 /*
00019 
00020 FUNCTION
00021         <<printf>>, <<fprintf>>, <<asprintf>>, <<sprintf>>, <<snprintf>>---format output
00022 INDEX
00023         fprintf
00024 INDEX
00025         printf
00026 INDEX
00027         asprintf
00028 INDEX
00029         sprintf
00030 INDEX
00031         snprintf
00032 
00033 ANSI_SYNOPSIS
00034         #include <stdio.h>
00035 
00036         int printf(const char *<[format]> [, <[arg]>, ...]);
00037         int fprintf(FILE *<[fd]>, const char *<[format]> [, <[arg]>, ...]);
00038         int sprintf(char *<[str]>, const char *<[format]> [, <[arg]>, ...]);
00039         int asprintf(char **<[strp]>, const char *<[format]> [, <[arg]>, ...]);
00040         int snprintf(char *<[str]>, size_t <[size]>, const char *<[format]> [, <[arg]>, ...]);
00041 
00042 TRAD_SYNOPSIS
00043         #include <stdio.h>
00044 
00045         int printf(<[format]> [, <[arg]>, ...])
00046         char *<[format]>;
00047 
00048         int fprintf(<[fd]>, <[format]> [, <[arg]>, ...]);
00049         FILE *<[fd]>;
00050         char *<[format]>;
00051 
00052         int asprintf(<[strp]>, <[format]> [, <[arg]>, ...]);
00053         char **<[strp]>;
00054         char *<[format]>;
00055 
00056         int sprintf(<[str]>, <[format]> [, <[arg]>, ...]);
00057         char *<[str]>;
00058         char *<[format]>;
00059 
00060         int snprintf(<[str]>, size_t <[size]>, <[format]> [, <[arg]>, ...]);
00061         char *<[str]>;
00062         size_t <[size]>;
00063         char *<[format]>;
00064 
00065 DESCRIPTION
00066         <<printf>> accepts a series of arguments, applies to each a
00067         format specifier from <<*<[format]>>>, and writes the
00068         formatted data to <<stdout>>, terminated with a null character.
00069         The behavior of <<printf>> is undefined if there are not enough
00070         arguments for the format.
00071         <<printf>> returns when it reaches the end of the format string.
00072         If there are more arguments than the format requires, excess
00073         arguments are ignored.
00074 
00075         <<fprintf>>, <<asprintf>>, <<sprintf>> and <<snprintf>> are identical 
00076         to <<printf>>, other than the destination of the formatted output: 
00077         <<fprintf>> sends the output to a specified file <[fd]>, while 
00078         <<asprintf>> stores the output in a dynamically allocated buffer,
00079         while <<sprintf>> stores the output in the specified char array 
00080         <[str]> and <<snprintf>> limits number of characters written to 
00081         <[str]> to at most <[size]> (including terminating <<0>>).  For 
00082         <<sprintf>> and <<snprintf>>, the behavior is undefined if the 
00083         output <<*<[str]>>> overlaps with one of the arguments. For
00084         <<asprintf>>, <[strp]> points to a pointer to char which is filled
00085         in with the dynamically allocated buffer.  <[format]> is a pointer 
00086         to a charater string containing two types of objects: ordinary 
00087         characters (other than <<%>>), which are copied unchanged to the 
00088         output, and conversion specifications, each of which is introduced 
00089         by <<%>>. (To include <<%>> in the output, use <<%%>> in the format 
00090         string.) A conversion specification has the following form:
00091 
00092 .       %[<[flags]>][<[width]>][.<[prec]>][<[size]>][<[type]>]
00093 
00094         The fields of the conversion specification have the following meanings:
00095 
00096         O+
00097         o <[flags]>
00098 
00099         an optional sequence of characters which control
00100         output justification, numeric signs, decimal points,
00101         trailing zeroes, and octal and hex prefixes.
00102         The flag characters are minus (<<->>), plus (<<+>>),
00103         space ( ), zero (<<0>>), and sharp (<<#>>).  They can
00104         appear in any combination.
00105 
00106         o+
00107         o -
00108                 The result of the conversion is left justified, and the right is
00109                 padded with blanks.  If you do not use this flag, the result is right
00110                 justified, and padded on the left.
00111 
00112         o +
00113                 The result of a signed conversion (as determined by <[type]>)
00114                 will always begin with a plus or minus sign.  (If you do not use
00115         this flag, positive values do not begin with a plus sign.)
00116 
00117         o " " (space)
00118                 If the first character of a signed conversion specification
00119         is not a sign, or if a signed conversion results in no
00120                 characters, the result will begin with a space.  If the
00121         space ( ) flag and the plus (<<+>>) flag both appear,
00122                 the space flag is ignored.
00123 
00124         o 0
00125                 If the <[type]> character is <<d>>, <<i>>, <<o>>, <<u>>,
00126                 <<x>>, <<X>>, <<e>>, <<E>>, <<f>>, <<g>>, or <<G>>: leading zeroes,
00127                 are used to pad the field width (following any indication of sign or
00128                 base); no spaces are used for padding.  If the zero (<<0>>) and
00129                 minus (<<->>) flags both appear, the zero (<<0>>) flag will
00130                 be ignored.  For <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, and <<X>>
00131                 conversions, if a precision <[prec]> is specified, the zero (<<0>>)
00132         flag is ignored.
00133                 
00134                 Note that <<0>> is interpreted as a flag, not as the beginning
00135         of a field width.
00136 
00137         o #
00138                 The result is to be converted to an alternative form, according
00139                 to the next character:
00140 
00141             o+
00142                     o 0
00143                         increases precision to force the first digit
00144                         of the result to be a zero.
00145 
00146                         o x
00147                         a non-zero result will have a <<0x>> prefix.
00148 
00149                         o X
00150                         a non-zero result will have a <<0X>> prefix.
00151 
00152                         o e, E or f
00153                         The result will always contain a decimal point
00154                         even if no digits follow the point.
00155                         (Normally, a decimal point appears only if a
00156                         digit follows it.)  Trailing zeroes are removed.
00157 
00158                         o g or G
00159                         same as <<e>> or <<E>>, but trailing zeroes
00160                         are not removed.
00161 
00162                         o all others
00163                         undefined.
00164 
00165                         o-
00166       o-
00167 
00168       o <[width]>
00169 
00170           <[width]> is an optional minimum field width.  You can either
00171           specify it directly as a decimal integer, or indirectly by
00172           using instead an asterisk (<<*>>), in which case an <<int>>
00173           argument is used as the field width.  Negative field widths
00174           are not supported; if you attempt to specify a negative field
00175           width, it is interpreted as a minus (<<->>) flag followed by a
00176           positive field width.
00177 
00178       o <[prec]>
00179 
00180           an optional field; if present, it is introduced with `<<.>>'
00181           (a period). This field gives the maximum number of
00182           characters to print in a conversion; the minimum number of
00183           digits of an integer to print, for conversions with <[type]>
00184           <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, and <<X>>; the maximum number of
00185           significant digits, for the <<g>> and <<G>> conversions;
00186           or the number of digits to print after the decimal
00187           point, for <<e>>, <<E>>, and <<f>> conversions.  You can specify
00188           the precision either directly as a decimal integer or
00189           indirectly by using an asterisk (<<*>>), in which case
00190           an <<int>> argument is used as the precision.  Supplying a negative
00191       precision is equivalent to omitting the precision.
00192           If only a period is specified the precision is zero.
00193           If a precision appears with any other conversion <[type]>
00194           than those listed here, the behavior is undefined.
00195 
00196       o  <[size]>
00197 
00198                 <<h>>, <<l>>, and <<L>> are optional size characters which
00199                 override the default way that <<printf>> interprets the
00200                 data type of the corresponding argument.  <<h>> forces
00201                 the following <<d>>, <<i>>, <<o>>, <<u>>, <<x>> or <<X>> conversion
00202                 <[type]> to apply to a <<short>> or <<unsigned short>>. <<h>> also
00203                 forces a following <<n>> <[type]> to apply to
00204                 a pointer to a <<short>>. Similarily, an
00205                 <<l>> forces the following <<d>>, <<i>>, <<o>>, <<u>>,
00206                 <<x>> or <<X>> conversion <[type]> to apply to a <<long>> or
00207                 <<unsigned long>>.  <<l>> also forces a following <<n>> <[type]> to
00208                 apply to a pointer to a <<long>>.  <<l>> with <<c>>, <<s>> is
00209                 equivalent to <<C>>, <<S>> respectively.  If an <<h>>
00210                 or an <<l>> appears with another conversion
00211                 specifier, the behavior is undefined.  <<L>> forces a
00212                 following <<e>>, <<E>>, <<f>>, <<g>> or <<G>> conversion <[type]> to
00213                 apply to a <<long double>> argument.  If <<L>> appears with
00214                 any other conversion <[type]>, the behavior is undefined.
00215 
00216      o   <[type]>
00217 
00218                 <[type]> specifies what kind of conversion <<printf>> performs.
00219                 Here is a table of these:
00220 
00221         o+
00222                 o %
00223                 prints the percent character (<<%>>)
00224 
00225                 o c
00226                 prints <[arg]> as single character
00227                 
00228                 o C
00229                 prints wchar_t <[arg]> as single multibyte character
00230                 
00231                 o s
00232                 prints characters until precision is reached or a null terminator
00233                 is encountered; takes a string pointer
00234 
00235                 o S
00236                 converts wchar_t characters to multibyte output characters until
00237                 precision is reached or a null wchar_t terminator
00238                 is encountered; takes a wchar_t pointer
00239 
00240                 o d
00241                 prints a signed decimal integer; takes an <<int>> (same as <<i>>)
00242 
00243                 o i
00244                 prints a signed decimal integer; takes an <<int>> (same as <<d>>)
00245 
00246                 o o
00247                 prints a signed octal integer; takes an <<int>>
00248 
00249                 o u
00250                 prints an unsigned decimal integer; takes an <<int>>
00251 
00252                 o x
00253                 prints an unsigned hexadecimal integer (using <<abcdef>> as
00254                 digits beyond <<9>>); takes an <<int>>
00255 
00256                 o X
00257                 prints an unsigned hexadecimal integer (using <<ABCDEF>> as
00258                 digits beyond <<9>>); takes an <<int>>
00259 
00260                 o f
00261                 prints a signed value of the form <<[-]9999.9999>>; takes
00262                 a floating-point number
00263         
00264                 o e
00265                 prints a signed value of the form <<[-]9.9999e[+|-]999>>; takes a
00266                 floating-point number
00267 
00268                 o E
00269                 prints the same way as <<e>>, but using <<E>> to introduce the
00270                 exponent; takes a floating-point number
00271 
00272                 o g
00273                 prints a signed value in either <<f>> or <<e>> form, based on given
00274                 value and precision---trailing zeros and the decimal point are
00275                 printed only if necessary; takes a floating-point number
00276         
00277                 o G
00278                 prints the same way as <<g>>, but using <<E>> for the exponent if an
00279                 exponent is needed; takes a floating-point number
00280 
00281                 o n
00282                 stores (in the same object) a count of the characters written;
00283                 takes a pointer to <<int>>
00284 
00285                 o p
00286                 prints a pointer in an implementation-defined format.
00287                 This implementation treats the pointer as an
00288                 <<unsigned long>> (same as <<Lu>>).
00289         o-
00290 O-
00291 
00292 
00293 RETURNS
00294 <<sprintf>> and <<asprintf>> return the number of bytes in the output string,
00295 save that the concluding <<NULL>> is not counted.
00296 <<printf>> and <<fprintf>> return the number of characters transmitted.
00297 If an error occurs, <<printf>> and <<fprintf>> return <<EOF>> and
00298 <<asprintf>> returns -1.  No error returns occur for <<sprintf>>.
00299 
00300 PORTABILITY
00301         The  ANSI C standard specifies that implementations must
00302         support at least formatted output of up to 509 characters.
00303 
00304 Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
00305 <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
00306 */
00307 
00308 
00309 #include <stdio.h>
00310 #ifdef _HAVE_STDC
00311 #include <stdarg.h>
00312 #else
00313 #include <varargs.h>
00314 #endif
00315 #include <limits.h>
00316 #include <_ansi.h>
00317 
00318 #ifndef _SMALL_PRINTF
00319                 #include "local.h"
00320 #else
00321         #ifdef INTEGER_ONLY
00322                 #define _vfprintf_r  _vfiprintf_r 
00323         #endif
00324 #endif
00325 
00326 
00327 
00328 
00329 
00330 #ifndef _SMALL_PRINTF
00331         int
00332         #ifdef _HAVE_STDC
00333         _DEFUN (_sprintf_r, (ptr, str, fmt), struct _reent *ptr _AND char *str _AND _CONST char *fmt _DOTS)
00334         #else
00335         _sprintf_r (ptr, str, fmt, va_alist)
00336              struct _reent *ptr;
00337              char *str;
00338              _CONST char *fmt;
00339              va_dcl
00340         #endif
00341         {
00342           int ret;
00343           va_list ap;
00344           FILE f;
00345         
00346           f._flags = __SWR | __SSTR;
00347           f._bf._base = f._p = (unsigned char *) str;
00348           f._bf._size = f._w = INT_MAX;
00349           f._file = -1;  /* No file. */
00350         #ifdef _HAVE_STDC
00351           va_start (ap, fmt);
00352         #else
00353           va_start (ap);
00354         #endif
00355           ret = _vfprintf_r (ptr, &f, fmt, ap);
00356           va_end (ap);
00357           *f._p = 0;
00358           return (ret);
00359         }
00360 #endif
00361 
00362 #ifndef _REENT_ONLY
00363 int
00364 #ifdef _HAVE_STDC
00365 _DEFUN (sprintf, (str, fmt), char *str _AND _CONST char *fmt _DOTS)
00366 #else
00367 sprintf (str, fmt, va_alist)
00368      char *str;
00369      _CONST char *fmt;
00370      va_dcl
00371 #endif
00372 {
00373   int ret;
00374   va_list ap;
00375   FILE f;
00376 
00377   f._flags = __SWR | __SSTR;
00378   f._bf._base = f._p = (unsigned char *) str;
00379   f._bf._size = f._w = INT_MAX;
00380   f._file = -1;  /* No file. */
00381 #ifdef _HAVE_STDC
00382   va_start (ap, fmt);
00383 #else
00384   va_start (ap);
00385 #endif
00386   ret = _vfprintf_r (_REENT, &f, fmt, ap);
00387   va_end (ap);
00388   *f._p = 0;
00389   return (ret);
00390 }
00391 #endif
00392 
00393