From b9db5292223d1e716a126b5db8a69391ba4ef73e Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 4 May 2007 02:55:16 +0000 Subject: Add support for asnprintf, and improve *printf documentation. * libc/stdio/Makefile.am (ELIX_SOURCES): Rename... (ELIX_2_SOURCES): ...to this. (ELIX_4_SOURCES): Add new variable. Build asnprintf. (GENERAL_SOURCES): Move dprintf to ELIX_4_SOURCES. (CHEWOUT_FILES): Include diprintf in documentation. * libc/stdio/Makefile.in: Regenerate. * libc/stdio/diprintf.c: Improve documentation. * libc/stdio/dprintf.c: Likewise. * libc/stdio/siprintf.c: Likewise. * libc/stdio/sprintf.c: Likewise. * libc/stdio/vfprintf.c: Likewise. * libc/stdio/viprintf.c: Likewise. * libc/stdio/vsniprintf.c: Consolidate documentation. * libc/stdio/asiprintf.c: Refer to documentation. * libc/stdio/asprintf.c: Likewise. * libc/stdio/fiprintf.c: Likewise. * libc/stdio/fprintf.c: Likewise. * libc/stdio/iprintf.c: Likewise. * libc/stdio/printf.c: Likewise. * libc/stdio/sniprintf.c: Likewise. * libc/stdio/vdiprintf.c: Likewise. * libc/stdio/vdprintf.c: Likewise. * libc/stdio/vsiprintf.c: Likewise. * libc/stdio/fvwrite.c (__sfvwrite_r): Handle asnprintf. * libc/stdio/asniprintf.c (asniprintf, _asniprintf_r): New file. * libc/stdio/asnprintf.c (asnprintf, _asnprintf_r): New file. * libc/stdio/vasniprintf.c (vasniprintf, _vasniprintf_r): New file. * libc/stdio/vasnprintf.c (vasnprintf, _vasnprintf_r): New file. * libc/stdio/vdprintf.c (_vdprintf_r): Rewrite to avoid malloc in typical case. * libc/stdio/vdiprintf.c (_vdiprintf_r): Likewise. * libc/include/stdio.h: Add prototypes for new functions; sort existing functions. --- newlib/libc/stdio/sprintf.c | 661 ++++++++++++++++++++++++++++++-------------- 1 file changed, 450 insertions(+), 211 deletions(-) (limited to 'newlib/libc/stdio/sprintf.c') diff --git a/newlib/libc/stdio/sprintf.c b/newlib/libc/stdio/sprintf.c index 346749a68..d2203fb3c 100644 --- a/newlib/libc/stdio/sprintf.c +++ b/newlib/libc/stdio/sprintf.c @@ -17,7 +17,7 @@ /* FUNCTION - <>, <>, <>, <>, <>---format output +<>, <>, <>, <>, <>, <>---format output INDEX fprintf @@ -29,6 +29,8 @@ INDEX sprintf INDEX snprintf +INDEX + asnprintf ANSI_SYNOPSIS #include @@ -36,271 +38,508 @@ ANSI_SYNOPSIS int printf(const char *<[format]> [, <[arg]>, ...]); int fprintf(FILE *<[fd]>, const char *<[format]> [, <[arg]>, ...]); int sprintf(char *<[str]>, const char *<[format]> [, <[arg]>, ...]); - int asprintf(char **<[strp]>, const char *<[format]> [, <[arg]>, ...]); int snprintf(char *<[str]>, size_t <[size]>, const char *<[format]> [, <[arg]>, ...]); - -TRAD_SYNOPSIS - #include - - int printf(<[format]> [, <[arg]>, ...]) - char *<[format]>; - - int fprintf(<[fd]>, <[format]> [, <[arg]>, ...]); - FILE *<[fd]>; - char *<[format]>; - - int asprintf(<[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]>; + int asprintf(char **<[strp]>, const char *<[format]> [, <[arg]>, ...]); + char *asnprintf(char *<[str]>, size_t *<[size]>, const char *<[format]> + [, <[arg]>, ...]); + + int _printf_r(struct _reent *<[ptr]>, const char *<[format]> + [, <[arg]>, ...]); + int _fprintf_r(struct _reent *<[ptr]>, FILE *<[fd]>, + const char *<[format]> [, <[arg]>, ...]); + int _sprintf_r(struct _reent *<[ptr]>, char *<[str]>, + const char *<[format]> [, <[arg]>, ...]); + int _snprintf_r(struct _reent *<[ptr]>, char *<[str]>, size_t <[size]>, + const char *<[format]> [, <[arg]>, ...]); + int _asprintf_r(struct _reent *<[ptr]>, char **<[strp]>, + const char *<[format]> [, <[arg]>, ...]); + char *_asnprintf_r(struct _reent *<[ptr]>, char *<[str]>, + size_t *<[size]>, const char *<[format]> + [, <[arg]>, ...]); DESCRIPTION <> accepts a series of arguments, applies to each a format specifier from <<*<[format]>>>, and writes the - formatted data to <>, terminated with a null character. - The behavior of <> is undefined if there are not enough - arguments for the format. - <> returns when it reaches the end of the format string. - If there are more arguments than the format requires, excess - arguments are ignored. - - <>, <>, <> and <> are identical - to <>, other than the destination of the formatted output: - <> sends the output to a specified file <[fd]>, while - <> stores the output in a dynamically allocated buffer, - while <> stores the output in the specified char array - <[str]> and <> limits number of characters written to - <[str]> to at most <[size]> (including terminating <<0>>). For - <> and <>, the behavior is undefined if the - output <<*<[str]>>> overlaps with one of the arguments. For - <>, <[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: + formatted data to <>, without a terminating NUL + character. The behavior of <> is undefined if there + are not enough arguments for the format. <> returns + when it reaches the end of the format string. If there are + more arguments than the format requires, excess arguments are + ignored. + + <> is like <>, except that output is directed + to the stream <[fd]> rather than <>. + + <> is like <>, except that output is directed + to the buffer <[str]>, and a terminating NUL is output. + Behavior is undefined if more output is generated than the + buffer can hold. + + <> is like <>, except that output is + limited to at most <[size]> bytes, including the terminating + <>. As a special case, if <[size]> is 0, <[str]> can be + NULL, and <> merely calculates how many bytes would + be printed. + + <> is like <>, except that the output is + stored in a dynamically allocated buffer, <[pstr]>, which + should be freed later with <>. + + <> is like <>, except that the return type + is either the original <[str]> if it was large enough, or a + dynamically allocated string if the output exceeds *<[size]>; + the length of the result is returned in *<[size]>. When + dynamic allocation occurs, the contents of the original + <[str]> may have been modified. + + For <>, <>, and <>, the behavior + is undefined if the output <<*<[str]>>> overlaps with one of + the arguments. Behavior is also undefined if the argument for + <<%n>> within <<*<[format]>>> overlaps another argument. + + <[format]> is a pointer to a character 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: + +. %[<[pos]>][<[flags]>][<[width]>][.<[prec]>][<[size]>]<[type]> + + The fields of the conversion specification have the following + meanings: O+ + o <[pos]> + + Conversions normally consume arguments in the order that they + are presented. However, it is possible to consume arguments + out of order, and reuse an argument for more than one + conversion specification (although the behavior is undefined + if the same argument is requested with different types), by + specifying <[pos]>, which is a decimal integer followed by + '$'. The integer must be between 1 and from + limits.h, and if argument <<%n$>> is requested, all earlier + arguments must be requested somewhere within <[format]>. If + positional parameters are used, then all conversion + specifications except for <<%%>> must specify a position. + 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 <>, <>, <>, <>, - <>, <>, <>, <>, <>, <>, or <>: 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 <>, <>, <>, <>, <>, and <> - 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. + <[flags]> is an optional sequence of characters which control + output justification, numeric signs, decimal points, trailing + zeros, and octal and hex prefixes. The flag characters are + minus (<<->>), plus (<<+>>), space ( ), zero (<<0>>), sharp + (<<#>>), and quote (<<'>>). They can appear in any + combination, although not all flags can be used for all + conversion specification types. + + o+ + o ' + Since newlib only supports the C locale, this + flag has no effect in this implementation. + But in other locales, when <[type]> is <>, + <>, <>, <>, <>, <>, or <>, + the locale-dependent thousand's separator is + inserted prior to zero padding. + + 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]> of <>, <>, <>, + <>, <>, <>, <>, <>, <>, or + <>) 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 <>, <>, + <>, <>, <>, <>, <>, <>, + <>, <>, <>, <>, or <>: leading + zeros 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 + <>, <>, <>, <>, <>, and <> + 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 <[type]> + character: + + o+ + o o + 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. + A non-zero result will have a <<0x>> + prefix. o X - a non-zero result will have a <<0X>> prefix. + 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 a, A, e, E, f, 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 zeros are removed. o g or G - same as <> or <>, but trailing zeroes - are not removed. + The result will always contain a + decimal point even if no digits follow + the point. Trailing zeros are not + removed. o all others - undefined. + 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 <> - 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]> - <>, <>, <>, <>, <>, and <>; the maximum number of - significant digits, for the <> and <> conversions; - or the number of digits to print after the decimal - point, for <>, <>, and <> conversions. You can specify - the precision either directly as a decimal integer or - indirectly by using an asterisk (<<*>>), in which case - an <> 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]> - - <>, <>, and <> are optional size characters which - override the default way that <> interprets the - data type of the corresponding argument. <> forces - the following <>, <>, <>, <>, <> or <> conversion - <[type]> to apply to a <> or <>. <> also - forces a following <> <[type]> to apply to - a pointer to a <>. Similarily, an - <> forces the following <>, <>, <>, <>, - <> or <> conversion <[type]> to apply to a <> or - <>. <> also forces a following <> <[type]> to - apply to a pointer to a <>. <> with <>, <> is - equivalent to <>, <> respectively. If an <> - or an <> appears with another conversion - specifier, the behavior is undefined. <> forces a - following <>, <>, <>, <> or <> conversion <[type]> to - apply to a <> argument. If <> appears with - any other conversion <[type]>, the behavior is undefined. - - o <[type]> - - <[type]> specifies what kind of conversion <> performs. - Here is a table of these: - - 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 <> argument is used as the field + width. If positional arguments are used, then the + width must also be specified positionally as <<*m$>>, + with m as a decimal integer. Negative field widths + are treated as specifying the minus (<<->>) flag for + left justfication, along with a positive field width. + The resulting format may be wider than the specified + width. + + o <[prec]> + + <[prec]> is an optional field; if present, it is + introduced with `<<.>>' (a period). You can specify + the precision either directly as a decimal integer or + indirectly by using an asterisk (<<*>>), in which case + an <> argument is used as the precision. If + positional arguments are used, then the precision must + also be specified positionally as <<*m$>>, with m as a + decimal integer. Supplying a negative precision is + equivalent to omitting the precision. If only a + period is specified the precision is zero. The effect + depends on the conversion <[type]>. + + o+ + o d, i, o, u, x, or X + Minimum number of digits to appear. If no + precision is given, defaults to 1. + + o a or A + Number of digits to appear after the decimal + point. If no precision is given, the + precision defaults to the minimum needed for + an exact representation. + + o e, E, f or F + Number of digits to appear after the decimal + point. If no precision is given, the + precision defaults to 6. + + o g or G + Maximum number of significant digits. A + precision of 0 is treated the same as a + precision of 1. If no precision is given, the + precision defaults to 6. + + o s or S + Maximum number of characters to print from the + string. If no precision is given, the entire + string is printed. + + o all others + undefined. + + o- + + o <[size]> + + <[size]> is an optional modifier that changes the data + type that the corresponding argument has. Behavior is + unspecified if a size is given that does not match the + <[type]>. + + o+ + o hh + With <>, <>, <>, <>, <>, or + <>, specifies that the argument should be + converted to a <> or <> before printing. + + With <>, specifies that the argument is a + pointer to a <>. + + o h + With <>, <>, <>, <>, <>, or + <>, specifies that the argument should be + converted to a <> or <> + before printing. + + With <>, specifies that the argument is a + pointer to a <>. + + o l + With <>, <>, <>, <>, <>, or + <>, specifies that the argument is a + <> or <>. + + With <>, specifies that the argument has + type <>. + + With <>, specifies that the argument is a + pointer to <>. + + With <>, specifies that the argument is a + pointer to a <>. + + With <>, <>, <>, <>, <>, <>, + <>, or <>, has no effect (because of + vararg promotion rules, there is no need to + distinguish between <> and <>). + + o ll + With <>, <>, <>, <>, <>, or + <>, specifies that the argument is a + <> or <>. + + With <>, specifies that the argument is a + pointer to a <>. + + o j + With <>, <>, <>, <>, <>, or + <>, specifies that the argument is an + <> or <>. + + With <>, specifies that the argument is a + pointer to an <>. + + o z + With <>, <>, <>, <>, <>, or + <>, specifies that the argument is a + <> or <>. + + With <>, specifies that the argument is a + pointer to a <>. + + o t + With <>, <>, <>, <>, <>, or + <>, specifies that the argument is a + <>. + + With <>, specifies that the argument is a + pointer to a <>. + + o L + With <>, <>, <>, <>, <>, <>, + <>, or <>, specifies that the argument + is a <>. + + o- + + o <[type]> + + <[type]> specifies what kind of conversion <> + performs. Here is a table of these: + + o+ o % - prints the percent character (<<%>>) + Prints the percent character (<<%>>). o c - prints <[arg]> as single character - + Prints <[arg]> as single character. If the + <> size specifier is in effect, a multibyte + character is printed. + o C - prints wchar_t <[arg]> as single multibyte character - + Short for <<%lc>>. + o s - prints characters until precision is reached or a null terminator - is encountered; takes a string pointer + Prints the elements of a pointer to <> + until the precision or a null character is + reached. If the <> size specifier is in + effect, the pointer is to an array of + <>, and the string is converted to + multibyte characters before printing. o S - converts wchar_t characters to multibyte output characters until - precision is reached or a null wchar_t terminator - is encountered; takes a wchar_t pointer + Short for <<%ls>>. - o d - prints a signed decimal integer; takes an <> (same as <>) + o d or i + Prints a signed decimal integer; takes an + <>. Leading zeros are inserted as + necessary to reach the precision. A precision + of 0 produces an empty string. - o i - prints a signed decimal integer; takes an <> (same as <>) + o D + Newlib extension, short for <<%ld>>. o o - prints a signed octal integer; takes an <> + Prints an unsigned octal integer; takes an + <>. Leading zeros are inserted as + necessary to reach the precision. A precision + of 0 produces an empty string. + + o O + Newlib extension, short for <<%lo>>. o u - prints an unsigned decimal integer; takes an <> + Prints an unsigned decimal integer; takes an + <>. Leading zeros are inserted as + necessary to reach the precision. A precision + of 0 produces an empty string. + + o U + Newlib extension, short for <<%lu>>. o x - prints an unsigned hexadecimal integer (using <> as - digits beyond <<9>>); takes an <> + Prints an unsigned hexadecimal integer (using + <> as digits beyond <<9>>); takes an + <>. Leading zeros are inserted as + necessary to reach the precision. A precision + of 0 produces an empty string. o X - prints an unsigned hexadecimal integer (using <> as - digits beyond <<9>>); takes an <> + Like <>, but uses <> as digits + beyond <<9>>. o f - prints a signed value of the form <<[-]9999.9999>>; takes - a floating-point number - + Prints a signed value of the form + <<[-]9999.9999>>, with the precision + determining how many digits follow the decimal + point; takes a <> (remember that + <> promotes to <> as a vararg). + The low order digit is rounded to even. If + the precision results in at most DECIMAL_DIG + digits, the result is rounded correctly; if + more than DECIMAL_DIG digits are printed, the + result is only guaranteed to round back to the + original value. + + If the value is infinite, the result is + <>, and no zero padding is performed. If + the value is not a number, the result is + <>, and no zero padding is performed. + + o F + Like <>, but uses <> and <> for + non-finite numbers. + o e - prints a signed value of the form <<[-]9.9999e[+|-]999>>; takes a - floating-point number + Prints a signed value of the form + <<[-]9.9999e[+|-]999>>; takes a <>. + The digit before the decimal point is non-zero + if the value is non-zero. The precision + determines how many digits appear between + <<.>> and <>, and the exponent always + contains at least two digits. The value zero + has an exponent of zero. If the value is not + finite, it is printed like <>. o E - prints the same way as <>, but using <> to introduce the - exponent; takes a floating-point number + Like <>, but using <> to introduce the + exponent, and like <> for non-finite + values. o g - prints a signed value in either <> or <> form, based on given - value and precision---trailing zeros and the decimal point are - printed only if necessary; takes a floating-point number - + Prints a signed value in either <> or <> + form, based on the given value and + precision---an exponent less than -4 or + greater than the precision selects the <> + form. Trailing zeros and the decimal point + are printed only if necessary; takes a + <>. + o G - prints the same way as <>, but using <> for the exponent if an - exponent is needed; takes a floating-point number + Like <>, except use <> or <> form. + + o a + Prints a signed value of the form + <<[-]0x1.ffffp[+|-]9>>; takes a <>. + The letters <> are used for digits + beyond <<9>>. The precision determines how + many digits appear after the decimal point. + The exponent contains at least one digit, and + is a decimal value representing the power of + 2; a value of 0 has an exponent of 0. + Non-finite values are printed like <>. + + o A + Like <>, except uses <>, <

>, and + <> instead of lower case. o n - stores (in the same object) a count of the characters written; - takes a pointer to <> + Takes a pointer to <>, and stores a count + of the number of bytes written so far. No + output is created. o p - prints a pointer in an implementation-defined format. - This implementation treats the pointer as an - <> (same as <>). - o- -O- + Takes a pointer to <>, and prints it in + an implementation-defined format. This + implementation is similar to <<%#tx>>), except + that <<0x>> appears even for the NULL pointer. + + o- + O- + <<_printf_r>>, <<_fprintf_r>>, <<_asprintf_r>>, + <<_sprintf_r>>, <<_snprintf_r>>, <<_asnprintf_r>> are simply + reentrant versions of the functions above. RETURNS -<> and <> return the number of bytes in the output string, -save that the concluding <> is not counted. -<> and <> return the number of characters transmitted. -If an error occurs, <> and <> return <> and -<> returns -1. No error returns occur for <>. +On success, <> and <> return the number of bytes in +the output string, except the concluding <> is not counted. +<> returns the number of bytes that would be in the output +string, except the concluding <> is not counted. <> and +<> return the number of characters transmitted. +<> returns the original <[str]> if there was enough room, +otherwise it returns an allocated string. + +If an error occurs, the result of <>, <>, +<>, and <> is a negative value, and the result of +<> is NULL. No error returns occur for <>. For +<> and <>, <> may be set according to +<>. For <> and <>, <> may be set +to ENOMEM if allocation fails, and for <>, <> may be +set to EOVERFLOW if <[size]> or the output length exceeds INT_MAX. PORTABILITY - The ANSI C standard specifies that implementations must - support at least formatted output of up to 509 characters. +ANSI C requires <>, <>, <>, and +<>. <> and <> are newlib extensions. + +The ANSI C standard specifies that implementations must support at +least formatted output of up to 509 characters. This implementation +has no inherent limit. + +Depending on how newlib was configured, not all format specifiers are +supported. Supporting OS subroutines required: <>, <>, <>, <>, <>, <>, <>. -- cgit v1.2.3