sl@0: /* SPRINTF.C sl@0: * sl@0: * Portions Copyright (c) 1990-2006 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: */ sl@0: sl@0: /* sl@0: * Copyright (c) 1990 The Regents of the University of California. sl@0: * All rights reserved. sl@0: * sl@0: * Redistribution and use in source and binary forms are permitted sl@0: * provided that the above copyright notice and this paragraph are sl@0: * duplicated in all such forms and that any documentation, sl@0: * advertising materials, and other materials related to such sl@0: * distribution and use acknowledge that the software was developed sl@0: * by the University of California, Berkeley. The name of the sl@0: * University may not be used to endorse or promote products derived sl@0: * from this software without specific prior written permission. sl@0: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR sl@0: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED sl@0: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. sl@0: */ sl@0: sl@0: /* sl@0: sl@0: FUNCTION sl@0: <>, <>, <>---format output sl@0: INDEX sl@0: fprintf sl@0: INDEX sl@0: printf sl@0: INDEX sl@0: sprintf sl@0: sl@0: ANSI_SYNOPSIS sl@0: #include sl@0: sl@0: int printf(const char *<[format]> [, <[arg]>, ...]); sl@0: int fprintf(FILE *<[fd]>, const char *<[format]> [, <[arg]>, ...]); sl@0: int sprintf(char *<[str]>, const char *<[format]> [, <[arg]>, ...]); sl@0: sl@0: TRAD_SYNOPSIS sl@0: #include sl@0: sl@0: int printf(<[format]> [, <[arg]>, ...]) sl@0: char *<[format]>; sl@0: sl@0: int fprintf(<[fd]>, <[format]> [, <[arg]>, ...]); sl@0: FILE *<[fd]>; sl@0: char *<[format]>; sl@0: sl@0: int sprintf(<[str]>, <[format]> [, <[arg]>, ...]); sl@0: char *<[str]>; sl@0: char *<[format]>; sl@0: sl@0: DESCRIPTION sl@0: <> accepts a series of arguments, applies to each a sl@0: format specifier from <<*<[format]>>>, and writes the sl@0: formatted data to <>, terminated with a null character. sl@0: The behavior of <> is undefined if there are not enough sl@0: arguments for the format. sl@0: <> returns when it reaches the end of the format string. sl@0: If there are more arguments than the format requires, excess sl@0: arguments are ignored. sl@0: sl@0: <> and <> are identical to <>, other than the sl@0: destination of the formatted output: <> sends the sl@0: output to a specified file <[fd]>, while <> stores the sl@0: output in the specified char array <[str]>. For <>, sl@0: the behavior is also undefined if the output <<*<[str]>>> sl@0: overlaps with one of the arguments. sl@0: <[format]> is a pointer to a charater string containing two types of sl@0: objects: ordinary characters (other than <<%>>), which are sl@0: copied unchanged to the output, and conversion sl@0: specifications, each of which is introduced by <<%>>. sl@0: (To include <<%>> in the output, use <<%%>> in the format string.) sl@0: A conversion specification has the following form: sl@0: sl@0: . %[<[flags]>][<[width]>][.<[prec]>][<[size]>][<[type]>] sl@0: sl@0: The fields of the conversion specification have the following meanings: sl@0: sl@0: O+ sl@0: o <[flags]> sl@0: sl@0: an optional sequence of characters which control sl@0: output justification, numeric signs, decimal points, sl@0: trailing zeroes, and octal and hex prefixes. sl@0: The flag characters are minus (<<->>), plus (<<+>>), sl@0: space ( ), zero (<<0>>), and sharp (<<#>>). They can sl@0: appear in any combination. sl@0: sl@0: o+ sl@0: o - sl@0: The result of the conversion is left justified, and the right is sl@0: padded with blanks. If you do not use this flag, the result is right sl@0: justified, and padded on the left. sl@0: sl@0: o + sl@0: The result of a signed conversion (as determined by <[type]>) sl@0: will always begin with a plus or minus sign. (If you do not use sl@0: this flag, positive values do not begin with a plus sign.) sl@0: sl@0: o " " (space) sl@0: If the first character of a signed conversion specification sl@0: is not a sign, or if a signed conversion results in no sl@0: characters, the result will begin with a space. If the sl@0: space ( ) flag and the plus (<<+>>) flag both appear, sl@0: the space flag is ignored. sl@0: sl@0: o 0 sl@0: If the <[type]> character is <>, <>, <>, <>, sl@0: <>, <>, <>, <>, <>, <>, or <>: leading zeroes, sl@0: are used to pad the field width (following any indication of sign or sl@0: base); no spaces are used for padding. If the zero (<<0>>) and sl@0: minus (<<->>) flags both appear, the zero (<<0>>) flag will sl@0: be ignored. For <>, <>, <>, <>, <>, and <> sl@0: conversions, if a precision <[prec]> is specified, the zero (<<0>>) sl@0: flag is ignored. sl@0: sl@0: Note that <<0>> is interpreted as a flag, not as the beginning sl@0: of a field width. sl@0: sl@0: o # sl@0: The result is to be converted to an alternative form, according sl@0: to the next character: sl@0: sl@0: o+ sl@0: o 0 sl@0: increases precision to force the first digit sl@0: of the result to be a zero. sl@0: sl@0: o x sl@0: a non-zero result will have a <<0x>> prefix. sl@0: sl@0: o X sl@0: a non-zero result will have a <<0X>> prefix. sl@0: sl@0: o e, E or f sl@0: The result will always contain a decimal point sl@0: even if no digits follow the point. sl@0: (Normally, a decimal point appears only if a sl@0: digit follows it.) Trailing zeroes are removed. sl@0: sl@0: o g or G sl@0: same as <> or <>, but trailing zeroes sl@0: are not removed. sl@0: sl@0: o all others sl@0: undefined. sl@0: sl@0: o- sl@0: o- sl@0: sl@0: o <[width]> sl@0: sl@0: <[width]> is an optional minimum field width. You can either sl@0: specify it directly as a decimal integer, or indirectly by sl@0: using instead an asterisk (<<*>>), in which case an <> sl@0: argument is used as the field width. Negative field widths sl@0: are not supported; if you attempt to specify a negative field sl@0: width, it is interpreted as a minus (<<->>) flag followed by a sl@0: positive field width. sl@0: sl@0: o <[prec]> sl@0: sl@0: an optional field; if present, it is introduced with `<<.>>' sl@0: (a period). This field gives the maximum number of sl@0: characters to print in a conversion; the minimum number of sl@0: digits of an integer to print, for conversions with <[type]> sl@0: <>, <>, <>, <>, <>, and <>; the maximum number of sl@0: significant digits, for the <> and <> conversions; sl@0: or the number of digits to print after the decimal sl@0: point, for <>, <>, and <> conversions. You can specify sl@0: the precision either directly as a decimal integer or sl@0: indirectly by using an asterisk (<<*>>), in which case sl@0: an <> argument is used as the precision. Supplying a negative sl@0: precision is equivalent to omitting the precision. sl@0: If only a period is specified the precision is zero. sl@0: If a precision appears with any other conversion <[type]> sl@0: than those listed here, the behavior is undefined. sl@0: sl@0: o <[size]> sl@0: sl@0: <>, <>, and <> are optional size characters which sl@0: override the default way that <> interprets the sl@0: data type of the corresponding argument. <> forces sl@0: the following <>, <>, <>, <>, <> or <> conversion sl@0: <[type]> to apply to a <> or <>. <> also sl@0: forces a following <> <[type]> to apply to sl@0: a pointer to a <>. Similarily, an sl@0: <> forces the following <>, <>, <>, <>, sl@0: <> or <> conversion <[type]> to apply to a <> or sl@0: <>. <> also forces a following <> <[type]> to sl@0: apply to a pointer to a <>. If an <> sl@0: or an <> appears with another conversion sl@0: specifier, the behavior is undefined. <> forces a sl@0: following <>, <>, <>, <> or <> conversion <[type]> to sl@0: apply to a <> argument. If <> appears with sl@0: any other conversion <[type]>, the behavior is undefined. sl@0: sl@0: o <[type]> sl@0: sl@0: <[type]> specifies what kind of conversion <> performs. sl@0: Here is a table of these: sl@0: sl@0: o+ sl@0: o % sl@0: prints the percent character (<<%>>) sl@0: sl@0: o c sl@0: prints <[arg]> as single character sl@0: sl@0: o s sl@0: prints characters until precision is reached or a null terminator sl@0: is encountered; takes a string pointer sl@0: sl@0: o d sl@0: prints a signed decimal integer; takes an <> (same as <>) sl@0: sl@0: o i sl@0: prints a signed decimal integer; takes an <> (same as <>) sl@0: sl@0: o o sl@0: prints a signed octal integer; takes an <> sl@0: sl@0: o u sl@0: prints an unsigned decimal integer; takes an <> sl@0: sl@0: o x sl@0: prints an unsigned hexadecimal integer (using <> as sl@0: digits beyond <<9>>); takes an <> sl@0: sl@0: o X sl@0: prints an unsigned hexadecimal integer (using <> as sl@0: digits beyond <<9>>); takes an <> sl@0: sl@0: o f sl@0: prints a signed value of the form <<[-]9999.9999>>; takes sl@0: a floating point number sl@0: sl@0: o e sl@0: prints a signed value of the form <<[-]9.9999e[+|-]999>>; takes a sl@0: floating point number sl@0: sl@0: o E sl@0: prints the same way as <>, but using <> to introduce the sl@0: exponent; takes a floating point number sl@0: sl@0: o g sl@0: prints a signed value in either <> or <> form, based on given sl@0: value and precision---trailing zeros and the decimal point are sl@0: printed only if necessary; takes a floating point number sl@0: sl@0: o G sl@0: prints the same way as <>, but using <> for the exponent if an sl@0: exponent is needed; takes a floating point number sl@0: sl@0: o n sl@0: stores (in the same object) a count of the characters written; sl@0: takes a pointer to <> sl@0: sl@0: o p sl@0: prints a pointer in an implementation-defined format. sl@0: This implementation treats the pointer as an sl@0: <> (same as <>). sl@0: o- sl@0: O- sl@0: sl@0: sl@0: RETURNS sl@0: <> returns the number of bytes in the output string, sl@0: save that the concluding <> is not counted. sl@0: <> and <> return the number of characters transmitted. sl@0: If an error occurs, <> and <> return <>. sl@0: Error returns occur for <>. sl@0: sl@0: PORTABILITY sl@0: The ANSI C standard specifies that implementations must sl@0: support at least formatted output of up to 509 characters. sl@0: sl@0: Supporting OS subroutines required: <>, <>, <>, sl@0: <>, <>, <>, <>. sl@0: */ sl@0: sl@0: #include <_ansi.h> sl@0: #include sl@0: #include sl@0: #include sl@0: #include "LOCAL.H" sl@0: sl@0: /** sl@0: A reentrant version of sprintf(). sl@0: */ sl@0: EXPORT_C int _sprintf_r (struct _reent *ptr, char *str, const char *fmt, ...) sl@0: { sl@0: int ret; sl@0: va_list ap; sl@0: FILE f; sl@0: sl@0: f._flags = __SWR | __SSTR; sl@0: f._bf._base = f._p = (unsigned char *) str; sl@0: f._bf._size = f._w = INT_MAX; sl@0: f._data = ptr; sl@0: va_start (ap, fmt); sl@0: ret = vfprintf (&f, fmt, ap); sl@0: va_end (ap); sl@0: *f._p = 0; sl@0: return (ret); sl@0: } sl@0: sl@0: #ifndef _REENT_ONLY sl@0: sl@0: /** sl@0: Print formatted data to a string. sl@0: Writes a sequence of arguments to the given buffer formatted as the format argument specifies. sl@0: sl@0: @param str Buffer where to store the resulting formatted string. sl@0: @param fmt String that contains the text to be printed. sl@0: sl@0: @return On Success, the total number of characters printed is returned. sl@0: On Failure, a negative number is returned. sl@0: */ sl@0: EXPORT_C int sprintf (char *str, const char *fmt, ...) sl@0: { sl@0: int ret; sl@0: va_list ap; sl@0: FILE f; sl@0: sl@0: f._flags = __SWR | __SSTR; sl@0: f._bf._base = f._p = (unsigned char *) str; sl@0: f._bf._size = f._w = INT_MAX; sl@0: f._data = _REENT2; sl@0: if (!f._data) sl@0: return EOF; // Memory for library globals is not allocated (errno not set). sl@0: va_start (ap, fmt); sl@0: ret = vfprintf (&f, fmt, ap); sl@0: va_end (ap); sl@0: *f._p = 0; sl@0: return (ret); sl@0: } sl@0: sl@0: sl@0: /** sl@0: @param str Buffer where to store the resulting formatted string. sl@0: @param fmt String that contains the text to be printed. sl@0: @param ap sl@0: sl@0: @return On Success, the total number of characters printed is returned. sl@0: On Failure, a negative number is returned. sl@0: */ sl@0: EXPORT_C int vsprintf (char *str,char const *fmt, va_list ap) sl@0: { sl@0: int ret; sl@0: FILE f; sl@0: sl@0: f._flags = __SWR | __SSTR; sl@0: f._bf._base = f._p = (unsigned char *) str; sl@0: f._bf._size = f._w = INT_MAX; sl@0: f._data = _REENT2; sl@0: if (!f._data) sl@0: return EOF; // Memory for library globals is not allocated (errno not set). sl@0: ret = vfprintf (&f, fmt, ap); sl@0: *f._p = 0; sl@0: return ret; sl@0: } sl@0: sl@0: #endif