ircu2.10.12 pk910 fork
[ircu2.10.12-pk.git] / doc / api / ircd_snprintf.txt
1 These functions are intended to be a complete replacement for sprintf
2 and sprintf_irc.  They are a (nearly) complete reimplementation, and
3 of course they're snprintf clones, making it more difficult for
4 accidental buffer overflows to crop up.
5
6 First off, what's missing?  These functions support all ANSI C
7 conversion specifiers and selected ones from ISO 9x, with the
8 exception of all floating-point conversions.  The floating-point
9 conversions are tricky, and will likely be dependent on the
10 representation of a floating-point number on a particular
11 architecture.  While that representation is likely to conform to some
12 standard, it is not currently used in ircu, so seemed like a good
13 thing to omit, given the difficulty of implementing it.
14
15 There are two more things missing from this implementation that would
16 be required by ANSI; the first is support for multibyte character
17 strings, and the second is support for locales, neither of which have
18 any relevance for ircu, so again omission seemed to be a good policy.
19 Additionally, %#x always causes '0x' (or '0X') to be printed, even if
20 the number is zero.
21
22 These functions also have some extensions not seen in a
23 standards-compliant implementation; technically, the ISO 9x extensions
24 fall into this category, for instance.  The ISO 9x extensions
25 supported are type extensions--%ju, %tu, and %zu, for instance; %qu
26 and %hhu are also supported.  The extensions added for use in ircu are
27 %Tu, which takes a time_t, and the new %C conversion, which inserts
28 either a numeric or a nick, dependent on the <dest> parameter.  The
29 GNU %m extension, which inserts the strerror() string corresponding to
30 the current value of errno, is also supported, as is a special %v
31 extension, which essentially does a recursive call to ircd_snprintf.
32
33 The following description is descended from the Linux man page for the
34 printf family of functions.
35
36 The format string is composed of zero or more directives: ordinary
37 characters (not %), which are copied unchanged to the output stream;
38 and conversion specifications, each of which results in fetching zero
39 or more subsequent arguments.  Each conversion specification is
40 introduced by the character %.  The arguments must correspond properly
41 (after type promotion) with the conversion specifier.  After the %,
42 the following appear in sequence:
43
44 * Zero or more of the following flags:
45
46   #     specifying that the value should be converted to an "alternate
47         form."  For c, d, i, n, p, s, and u conversions, this option
48         has no effect.  For o conversions, the precision of the number
49         is increased to force the first character of the output string
50         to a zero (except if a zero value is printed with an explicit
51         precision of zero).  For x and X conversions, the string '0x'
52         (or '0X' for X conversions) is prepended to it.  For e, E, f,
53         g, and G conversions, the result will always contain a decimal
54         point, even if no digits follow it (normally, a decimal point
55         appears in the results of those conversions only if a digit
56         follows).  For g and G conversions, trailing zeros are not
57         removed from the result as they would otherwise be.  For C
58         conversions, if the destination is local and the origin is a
59         user, the nick!user@host form is used.
60
61   0     specifying zero padding.  For all conversions except n, the
62         converted value is padded on the left with zeros rather than
63         blanks.  If a precision is given with a numeric conversion (d,
64         i, o, u, i, x, and X), the 0 flag is ignored.
65
66   -     (a negative field width flag) indicates the converted value is
67         to be left adjusted on the field boundary.  Except for n
68         conversions, the converted value is padded on the right with
69         blanks, rather than on the left with blanks or zeros.  A -
70         overrides a 0 if both are given.
71
72  ' '    (a space) specifying that a blank should be left before a
73         positive number produced by a signed conversion (d, e, E, f,
74         g, G, or i).
75
76   +     specifying that a sign always be placed before a number
77         produced by a signed conversion.  A + overrides a space if
78         both are used.
79
80   :     specifying that a struct Client name should be preceded by a
81         ':' character if the destination is a user
82
83 * An optional decimal digit string specifying a minimum field width.
84   If the converted value has fewer characters than the field width, it
85   will be padded with spaces on the left (or right, if the
86   left-adjustment flag has been given) to fill out the field width.
87
88 * An optional precision, in the form of a period (`.') followed by an
89   optional digit string.  If the digit string is omitted, the
90   precision is taken as zero.  This gives the minimum number of digits
91   to appear for d, i, o, u, x, and X conversions, the number of digits
92   to appear after the decimal-point for e, E, and f conversions, the
93   maximum number of significant digits for g and G conversions, or the
94   maximum number of characters to be printed from a string for s
95   conversions.
96
97 * The optional character h, specifying that a following d, i, o, u, x,
98   or X conversion corresponds to a short int or unsigned short int
99   argument, or that a following n conversion corresponds to a pointer
100   to a short int argument.  If the h character is given again, char is
101   used instead of short int.
102
103 * The optional character l (ell) specifying that a following d, i, o,
104   u, x, or X conversion applies to a pointer to a long int or unsigned
105   long int argument, or that a following n conversion corresponds to a
106   pointer to a long int argument.
107
108 * The character L specifying that a following e, E, f, g, or G
109   conversion corresponds to a long double argument, or a following d,
110   i, o, u, x, or X conversion corresponds to a long long argument.
111   Note that long long is not specified in ANSI C and therefore not
112   portable to all architectures.
113
114 * The optional character q.  This is equivalent to L.
115
116 * A j character specifying that the following integer (d, i, o, u, x,
117   or X) conversion corresponds to an intmax_t argument.
118
119 * A t character specifying that the following integer (d, i, o, u, x,
120   or X) conversion corresponds to a ptrdiff_t argument.
121
122 * A z character specifying that the following integer (d, i, o, u, x,
123   or X) conversion corresponds to a size_t argument.
124
125 * A T character specifying that the following integer (d, i, o, u, x,
126   or X) conversion corresponds to a time_t argument.
127
128 * A character that specifies the type of conversion to be applied.
129
130 A field width or precision, or both, may be indicated by an asterisk
131 `*' instead of a digit string.  In this case, an int argument supplies
132 the field width or precision.  A negative field width is treated as a
133 left adjustment flag followed by a positive field width; a negative
134 precision is treated as though it were missing.
135
136 The conversion specifiers and their meanings are:
137
138   diouxX        The int (or appropriate variant) argument is converted
139                 to signed decimal (d and i), unsigned octal (o),
140                 unsigned decimal (u), or unsigned hexadecimal (x and
141                 X) notation.  The letters abcdef are used for x
142                 conversions; the letters ABCDEF are used for X
143                 conversions.  The precision, if any, gives the minimum
144                 number of digits that must appear; if the converted
145                 value requires fewer digits, it is padded on the left
146                 with zeros.
147
148   eE            [NOT IMPLEMENTED] The double argument is rounded and
149                 converted in the style [-]d.dddedd where there is one
150                 digit before the decimal-point character and the
151                 number of digits after it is equal to the precision;
152                 if the precision is missing, it is taken as 6; if the
153                 precision is zero, no decimal-point character
154                 appears.  An E conversion uses the letter E (rather
155                 than e) to introduce the exponent.  The exponent
156                 always contains at least two digits; if the value is
157                 zero, the exponent is 00.
158
159   f             [NOT IMPLEMENTED] The double argument is rounded and
160                 converted to  decimal notation in the style
161                 [-]ddd.ddd, where the number of digits after the
162                 decimal-point character is equal to the precision
163                 specification.  If the precision is missing, it is
164                 taken as 6; if the precision is explicitly zero, no
165                 decimal-point character appears.  If a decimal point
166                 appears, at least one digit appears before it.
167
168   g             [NOT IMPLEMENTED] The double argument is converted in
169                 style f or e (or E for G conversions).  The precision
170                 specifies the number of significant digits.  If the
171                 precision is missing, 6 digits are given; if the
172                 precision is zero, it is treated as 1.  Style e is
173                 used if the exponent from its conversion is less than
174                 -4 or greater than or equal to the precision.
175                 Trailing zeros are removed from the fractional part of
176                 the result; a decimal point appears only if it is
177                 followed by at least one digit.
178
179   c             The int argument is converted to an unsigned char, and
180                 the resulting character is written.
181
182   s             The "char *" argument is expected to be a pointer to
183                 an array of character type (pointer to a string).
184                 Characters from the array are written up to (but not
185                 including) a terminating NUL character; if a precision
186                 is specified, no more than the number specified are
187                 written.  If a precision is given, no null character
188                 need be present; if the precision is not specified, or
189                 is greater than the size of the array, the array must
190                 contain a terminating NUL character.
191
192   p             The "void *" pointer argument is printed in
193                 hexadecimal (as if by %#x or %#lx).
194
195   n             The number of characters written so far is stored into
196                 the integer indicated by the ``int *'' (or variant)
197                 pointer argument.  No argument is converted.
198
199   m             The error message associated with the current value of
200                 errno is printed as if by %s.
201
202   C             The client argument identifier is printed under the
203                 control of the <dest> argument; if <dest> is NULL or
204                 is a user, the client's name (nickname or server name)
205                 is printed; otherwise, the client's network numeric is
206                 printed.
207
208   H             The channel argument identifier (channel name) is
209                 printed.
210
211   v             The argument given must be a pointer to a struct
212                 VarData with vd_format and vd_args must be initialized
213                 appropriately.  On return, vd_chars will contain the
214                 number of characters added to the buffer, and
215                 vd_overflow will contain the number of characters that
216                 could not be added due to buffer overflow or due to a
217                 precision.
218
219   %             A `%' is written.  No argument is converted.  The
220                 complete conversion specification is `%%'.
221
222 In no case does a non-existent or small field width cause truncation
223 of a field; if the result of a conversion is wider than the field
224 width, the field is expanded to contain the conversion result.
225
226 <struct>
227 struct VarData {
228   size_t        vd_chars;       /* number of characters inserted */
229   size_t        vd_overflow;    /* number of characters that couldn't be */
230   const char   *vd_format;      /* format string */
231   va_list       vd_args;        /* arguments for %v */
232 };
233
234 This structure is used by the %v conversion specification.  The
235 _vd_format_ element must contain a format string, and the _vd_args_
236 element must be a variable argument list.  Upon return from
237 ircd_snprintf() or ircd_vsnprintf(), the _vd_chars_ element will
238 contain the number of characters that were able to be inserted, and
239 the _vd_overflow_ element will contain the number of characters that
240 could not be inserted.
241 </struct>
242
243 <function>
244 int ircd_snprintf(struct Client *dest, char *buf, size_t buf_len,
245                   const char *format, ...);
246
247 This formats the argument list, under control of the _format_, into
248 the buffer specified by _buf_, the size of which is specified by
249 _buf_len_.  The _dest_ parameter is used to determine whether to use a
250 numeric or a nickname for %C conversions.
251 </function>
252
253 <function>
254 int ircd_vsnprintf(struct Client *dest, char *buf, size_t buf_len,
255                    const char *format, va_list args);
256
257 This function is identical to the ircd_snprintf() function except for
258 the variable argument list given by _args_.
259 </function>
260
261 <authors>
262 Kev <klmitch@mit.edu>
263 </authors>
264
265 <changelog>
266 [2001-6-15 Kev] Initial documentation of the ircd_snprintf family of
267 functions.
268 </changelog>