X-Git-Url: http://git.pk910.de/?p=ircu2.10.12-pk.git;a=blobdiff_plain;f=doc%2Fapi%2Fircd_snprintf.txt;fp=doc%2Fapi%2Fircd_snprintf.txt;h=ee9b7f2dad976082191d694c35b4264b509ed206;hp=0000000000000000000000000000000000000000;hb=0400a5a6479398d82526785c18c0df8bc8b92dce;hpb=d17e10da972ce5776c60b4c317267c6abe0e1ead diff --git a/doc/api/ircd_snprintf.txt b/doc/api/ircd_snprintf.txt new file mode 100644 index 0000000..ee9b7f2 --- /dev/null +++ b/doc/api/ircd_snprintf.txt @@ -0,0 +1,268 @@ +These functions are intended to be a complete replacement for sprintf +and sprintf_irc. They are a (nearly) complete reimplementation, and +of course they're snprintf clones, making it more difficult for +accidental buffer overflows to crop up. + +First off, what's missing? These functions support all ANSI C +conversion specifiers and selected ones from ISO 9x, with the +exception of all floating-point conversions. The floating-point +conversions are tricky, and will likely be dependent on the +representation of a floating-point number on a particular +architecture. While that representation is likely to conform to some +standard, it is not currently used in ircu, so seemed like a good +thing to omit, given the difficulty of implementing it. + +There are two more things missing from this implementation that would +be required by ANSI; the first is support for multibyte character +strings, and the second is support for locales, neither of which have +any relevance for ircu, so again omission seemed to be a good policy. +Additionally, %#x always causes '0x' (or '0X') to be printed, even if +the number is zero. + +These functions also have some extensions not seen in a +standards-compliant implementation; technically, the ISO 9x extensions +fall into this category, for instance. The ISO 9x extensions +supported are type extensions--%ju, %tu, and %zu, for instance; %qu +and %hhu are also supported. The extensions added for use in ircu are +%Tu, which takes a time_t, and the new %C conversion, which inserts +either a numeric or a nick, dependent on the parameter. The +GNU %m extension, which inserts the strerror() string corresponding to +the current value of errno, is also supported, as is a special %v +extension, which essentially does a recursive call to ircd_snprintf. + +The following description is descended from the Linux man page for the +printf family of functions. + +The format string is composed of zero or more directives: ordinary +characters (not %), which are copied unchanged to the output stream; +and conversion specifications, each of which results in fetching zero +or more subsequent arguments. Each conversion specification is +introduced by the character %. The arguments must correspond properly +(after type promotion) with the conversion specifier. After the %, +the following appear in sequence: + +* Zero or more of the following flags: + + # specifying that the value should be converted to an "alternate + form." For c, d, i, n, p, s, and u conversions, this option + has no effect. For o conversions, the precision of the number + is increased to force the first character of the output string + to a zero (except if a zero value is printed with an explicit + precision of zero). For x and X conversions, the string '0x' + (or '0X' for X conversions) is prepended to it. For e, E, f, + g, and G conversions, the result will always contain a decimal + point, even if no digits follow it (normally, a decimal point + appears in the results of those conversions only if a digit + follows). For g and G conversions, trailing zeros are not + removed from the result as they would otherwise be. For C + conversions, if the destination is local and the origin is a + user, the nick!user@host form is used. + + 0 specifying zero padding. For all conversions except n, the + converted value is padded on the left with zeros rather than + blanks. If a precision is given with a numeric conversion (d, + i, o, u, i, x, and X), the 0 flag is ignored. + + - (a negative field width flag) indicates the converted value is + to be left adjusted on the field boundary. Except for n + conversions, the converted value is padded on the right with + blanks, rather than on the left with blanks or zeros. A - + overrides a 0 if both are given. + + ' ' (a space) specifying that a blank should be left before a + positive number produced by a signed conversion (d, e, E, f, + g, G, or i). + + + specifying that a sign always be placed before a number + produced by a signed conversion. A + overrides a space if + both are used. + + : specifying that a struct Client name should be preceded by a + ':' character if the destination is a user + +* An optional decimal digit string specifying a minimum field width. + If the converted value has fewer characters than the field width, it + will be padded with spaces on the left (or right, if the + left-adjustment flag has been given) to fill out the field width. + +* An optional precision, in the form of a period (`.') followed by an + optional digit string. If the digit string is omitted, the + precision is taken as zero. This gives the minimum number of digits + to appear for d, i, o, u, x, and X conversions, the number of digits + to appear after the decimal-point for e, E, and f conversions, the + maximum number of significant digits for g and G conversions, or the + maximum number of characters to be printed from a string for s + conversions. + +* The optional character h, specifying that a following d, i, o, u, x, + or X conversion corresponds to a short int or unsigned short int + argument, or that a following n conversion corresponds to a pointer + to a short int argument. If the h character is given again, char is + used instead of short int. + +* The optional character l (ell) specifying that a following d, i, o, + u, x, or X conversion applies to a pointer to a long int or unsigned + long int argument, or that a following n conversion corresponds to a + pointer to a long int argument. + +* The character L specifying that a following e, E, f, g, or G + conversion corresponds to a long double argument, or a following d, + i, o, u, x, or X conversion corresponds to a long long argument. + Note that long long is not specified in ANSI C and therefore not + portable to all architectures. + +* The optional character q. This is equivalent to L. + +* A j character specifying that the following integer (d, i, o, u, x, + or X) conversion corresponds to an intmax_t argument. + +* A t character specifying that the following integer (d, i, o, u, x, + or X) conversion corresponds to a ptrdiff_t argument. + +* A z character specifying that the following integer (d, i, o, u, x, + or X) conversion corresponds to a size_t argument. + +* A T character specifying that the following integer (d, i, o, u, x, + or X) conversion corresponds to a time_t argument. + +* A character that specifies the type of conversion to be applied. + +A field width or precision, or both, may be indicated by an asterisk +`*' instead of a digit string. In this case, an int argument supplies +the field width or precision. A negative field width is treated as a +left adjustment flag followed by a positive field width; a negative +precision is treated as though it were missing. + +The conversion specifiers and their meanings are: + + diouxX The int (or appropriate variant) argument is converted + to signed decimal (d and i), unsigned octal (o), + unsigned decimal (u), or unsigned hexadecimal (x and + X) notation. The letters abcdef are used for x + conversions; the letters ABCDEF are used for X + conversions. The precision, if any, gives the minimum + number of digits that must appear; if the converted + value requires fewer digits, it is padded on the left + with zeros. + + eE [NOT IMPLEMENTED] The double argument is rounded and + converted in the style [-]d.dddedd where there is one + digit before the decimal-point character and the + number of digits after it is equal to the precision; + if the precision is missing, it is taken as 6; if the + precision is zero, no decimal-point character + appears. An E conversion uses the letter E (rather + than e) to introduce the exponent. The exponent + always contains at least two digits; if the value is + zero, the exponent is 00. + + f [NOT IMPLEMENTED] The double argument is rounded and + converted to decimal notation in the style + [-]ddd.ddd, where the number of digits after the + decimal-point character is equal to the precision + specification. If the precision is missing, it is + taken as 6; if the precision is explicitly zero, no + decimal-point character appears. If a decimal point + appears, at least one digit appears before it. + + g [NOT IMPLEMENTED] The double argument is converted in + style f or e (or E for G conversions). The precision + specifies the number of significant digits. If the + precision is missing, 6 digits are given; if the + precision is zero, it is treated as 1. Style e is + used if the exponent from its conversion is less than + -4 or greater than or equal to the precision. + Trailing zeros are removed from the fractional part of + the result; a decimal point appears only if it is + followed by at least one digit. + + c The int argument is converted to an unsigned char, and + the resulting character is written. + + s The "char *" argument is expected to be a pointer to + an array of character type (pointer to a string). + Characters from the array are written up to (but not + including) a terminating NUL character; if a precision + is specified, no more than the number specified are + written. If a precision is given, no null character + need be present; if the precision is not specified, or + is greater than the size of the array, the array must + contain a terminating NUL character. + + p The "void *" pointer argument is printed in + hexadecimal (as if by %#x or %#lx). + + n The number of characters written so far is stored into + the integer indicated by the ``int *'' (or variant) + pointer argument. No argument is converted. + + m The error message associated with the current value of + errno is printed as if by %s. + + C The client argument identifier is printed under the + control of the argument; if is NULL or + is a user, the client's name (nickname or server name) + is printed; otherwise, the client's network numeric is + printed. + + H The channel argument identifier (channel name) is + printed. + + v The argument given must be a pointer to a struct + VarData with vd_format and vd_args must be initialized + appropriately. On return, vd_chars will contain the + number of characters added to the buffer, and + vd_overflow will contain the number of characters that + could not be added due to buffer overflow or due to a + precision. + + % A `%' is written. No argument is converted. The + complete conversion specification is `%%'. + +In no case does a non-existent or small field width cause truncation +of a field; if the result of a conversion is wider than the field +width, the field is expanded to contain the conversion result. + + +struct VarData { + size_t vd_chars; /* number of characters inserted */ + size_t vd_overflow; /* number of characters that couldn't be */ + const char *vd_format; /* format string */ + va_list vd_args; /* arguments for %v */ +}; + +This structure is used by the %v conversion specification. The +_vd_format_ element must contain a format string, and the _vd_args_ +element must be a variable argument list. Upon return from +ircd_snprintf() or ircd_vsnprintf(), the _vd_chars_ element will +contain the number of characters that were able to be inserted, and +the _vd_overflow_ element will contain the number of characters that +could not be inserted. + + + +int ircd_snprintf(struct Client *dest, char *buf, size_t buf_len, + const char *format, ...); + +This formats the argument list, under control of the _format_, into +the buffer specified by _buf_, the size of which is specified by +_buf_len_. The _dest_ parameter is used to determine whether to use a +numeric or a nickname for %C conversions. + + + +int ircd_vsnprintf(struct Client *dest, char *buf, size_t buf_len, + const char *format, va_list args); + +This function is identical to the ircd_snprintf() function except for +the variable argument list given by _args_. + + + +Kev + + + +[2001-6-15 Kev] Initial documentation of the ircd_snprintf family of +functions. +