]> jfr.im git - irc/quakenet/snircd.git/blame - doc/api/ircd_snprintf.txt
sync undernet upstream ircu changes.
[irc/quakenet/snircd.git] / doc / api / ircd_snprintf.txt
CommitLineData
189935b1 1These functions are intended to be a complete replacement for sprintf
2and sprintf_irc. They are a (nearly) complete reimplementation, and
3of course they're snprintf clones, making it more difficult for
4accidental buffer overflows to crop up.
5
6First off, what's missing? These functions support all ANSI C
7conversion specifiers and selected ones from ISO 9x, with the
8exception of all floating-point conversions. The floating-point
9conversions are tricky, and will likely be dependent on the
10representation of a floating-point number on a particular
11architecture. While that representation is likely to conform to some
12standard, it is not currently used in ircu, so seemed like a good
13thing to omit, given the difficulty of implementing it.
14
15There are two more things missing from this implementation that would
16be required by ANSI; the first is support for multibyte character
17strings, and the second is support for locales, neither of which have
18any relevance for ircu, so again omission seemed to be a good policy.
19Additionally, %#x always causes '0x' (or '0X') to be printed, even if
20the number is zero.
21
22These functions also have some extensions not seen in a
23standards-compliant implementation; technically, the ISO 9x extensions
24fall into this category, for instance. The ISO 9x extensions
25supported are type extensions--%ju, %tu, and %zu, for instance; %qu
26and %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
28either a numeric or a nick, dependent on the <dest> parameter. The
29GNU %m extension, which inserts the strerror() string corresponding to
30the current value of errno, is also supported, as is a special %v
31extension, which essentially does a recursive call to ircd_snprintf.
32
33The following description is descended from the Linux man page for the
34printf family of functions.
35
36The format string is composed of zero or more directives: ordinary
37characters (not %), which are copied unchanged to the output stream;
38and conversion specifications, each of which results in fetching zero
39or more subsequent arguments. Each conversion specification is
40introduced by the character %. The arguments must correspond properly
41(after type promotion) with the conversion specifier. After the %,
42the 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
130A 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
132the field width or precision. A negative field width is treated as a
133left adjustment flag followed by a positive field width; a negative
134precision is treated as though it were missing.
135
136The 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
222In no case does a non-existent or small field width cause truncation
223of a field; if the result of a conversion is wider than the field
224width, the field is expanded to contain the conversion result.
225
226<struct>
227struct 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
234This structure is used by the %v conversion specification. The
235_vd_format_ element must contain a format string, and the _vd_args_
236element must be a variable argument list. Upon return from
237ircd_snprintf() or ircd_vsnprintf(), the _vd_chars_ element will
238contain the number of characters that were able to be inserted, and
239the _vd_overflow_ element will contain the number of characters that
240could not be inserted.
241</struct>
242
243<function>
244int ircd_snprintf(struct Client *dest, char *buf, size_t buf_len,
245 const char *format, ...);
246
247This formats the argument list, under control of the _format_, into
248the 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
250numeric or a nickname for %C conversions.
251</function>
252
253<function>
254int ircd_vsnprintf(struct Client *dest, char *buf, size_t buf_len,
255 const char *format, va_list args);
256
257This function is identical to the ircd_snprintf() function except for
258the variable argument list given by _args_.
259</function>
260
261<authors>
262Kev <klmitch@mit.edu>
263</authors>
264
265<changelog>
266[2001-6-15 Kev] Initial documentation of the ircd_snprintf family of
267functions.
268</changelog>