ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/include/ircd_snprintf.h
Revision: 1085
Committed: Sat Mar 13 23:50:45 2010 UTC (14 years ago) by michael
Content type: text/x-chdr
File size: 13756 byte(s)
Log Message:
- Add Kev's snprintf

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 *
4 * Copyright (C) 2000 Kevin L. Mitchell <klmitch@mit.edu>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 */
21
22 /*! \file ircd_snprintf.h
23 * \brief IRC-specific printf() clone implementation.
24 * \version $Id: ircd_snprintf.h 1011 2009-09-18 10:14:09Z michael $
25 */
26
27 #ifndef INCLUDED_ircd_snprintf_h
28 #define INCLUDED_ircd_snprintf_h
29
30 #ifndef INCLUDED_sys_types_h
31 #include <sys/types.h>
32 #define INCLUDED_sys_types_h
33 #endif
34 #ifndef INCLUDED_stdarg_h
35 #include <stdarg.h>
36 #define INCLUDED_stdarg_h
37 #endif
38
39
40 /** structure passed as argument for %v conversion */
41 struct VarData {
42 size_t vd_chars; /**< number of characters inserted */
43 size_t vd_overflow; /**< number of characters that couldn't be */
44 const char *vd_format; /**< format string */
45 va_list vd_args; /**< arguments for %v */
46 };
47
48 extern int ircd_snprintf(void *, char *, size_t, const char *, ...);
49 extern int ircd_vsnprintf(void *, char *, size_t, const char *, va_list);
50
51 /** @fn int ircd_snprintf(struct Client *dest, char *buf, size_t
52 buf_len, const char *format, ...)
53 **
54 ** These functions are intended to be a complete replacement for
55 ** sprintf and sprintf_irc. They are a (nearly) complete
56 ** reimplementation, and of course they're snprintf clones, making it
57 ** more difficult for accidental buffer overflows to crop up.
58 **
59 ** First off, what's missing? These functions support all ANSI C
60 ** conversion specifiers and selected ones from ISO 9x, with the
61 ** exception of all floating-point conversions. The floating-point
62 ** conversions are tricky, and will likely be dependent on the
63 ** representation of a floating-point number on a particular
64 ** architecture. While that representation is likely to conform to
65 ** some standard, it is not currently used in ircu, so seemed like a
66 ** good thing to omit, given the difficulty of implementing it.
67 **
68 ** There are two more things missing from this implementation that
69 ** would be required by ANSI; the first is support for multibyte
70 ** character strings, and the second is support for locales, neither
71 ** of which have any relevance for ircu, so again omission seemed to
72 ** be a good policy. Additionally, %#x always causes '0x' (or '0X')
73 ** to be printed, even if the number is zero.
74 **
75 ** These functions also have some extensions not seen in a
76 ** standards-compliant implementation; technically, the ISO 9x
77 ** extensions fall into this category, for instance. The ISO 9x
78 ** extensions supported are type extensions--%ju, %tu, and %zu, for
79 ** instance; %qu and %hhu are also supported. The extensions added
80 ** for use in ircu are %Tu, which takes a time_t, and the new %C
81 ** conversion, which inserts either a numeric or a nick, dependant on
82 ** the &lt;dest> parameter. The GNU %m extension, which inserts the
83 ** strerror() string corresponding to the current value of errno, is
84 ** also supported, as is a special %v extension, which essentially
85 ** does a recursive call to ircd_snprintf.
86 **
87 ** The following description is descended from the Linux manpage for
88 ** the printf family of functions.
89 **
90 ** The format string is composed of zero or more directives:
91 ** ordinary characters (not %), which are copied unchanged to the
92 ** output stream; and conversion specifications, each of which results
93 ** in fetching zero or more subsequent arguments. Each conversion
94 ** specification is introduced by the character %. The arguments must
95 ** correspond properly (after type promotion) with the conversion
96 ** specifier. After the %, the following appear in sequence:
97 **
98 ** <ul><li>Zero or more of the following flags:<dl>
99 **
100 ** <dt>#</dt>
101 ** <dd>specifying that the value should be converted to an
102 ** "alternate form." For c, d, i, n, p, s, and u conversions,
103 ** this option has no effect. For o conversions, the precision
104 ** of the number is increased to force the first character of the
105 ** output string to a zero (except if a zero value is printed
106 ** with an explicit precision of zero). For x and X conversions,
107 ** the string '0x' (or '0X' for X conversions) is prepended to
108 ** it. For e, E, f, g, and G conversions, the result will always
109 ** contain a decimal point, even if no digits follow it
110 ** (normally, a decimal point appears in the results of those
111 ** conversions only if a digit follows). For g and G
112 ** conversions, trailing zeros are not removed from the result as
113 ** they would otherwise be. For C conversions, if the
114 ** destination is local and the origin is a user, the
115 ** nick!user\@host form is used.</dd>
116 **
117 ** <dt>0</dt>
118 ** <dd> specifying zero padding. For all conversions except n, the
119 ** converted value is padded on the left with zeros rather than
120 ** blanks. If a precision is given with a numeric conversion (d,
121 ** i, o, u, i, x, and X), the 0 flag is ignored.</dd>
122 **
123 ** <dt>-</dt>
124 ** <dd>(a negative field width flag) indicates the converted value is
125 ** to be left adjusted on the field boundary. Except for n
126 ** conversions, the converted value is padded on the right with
127 ** blanks, rather than on the left with blanks or zeros. A -
128 ** overrides a 0 if both are given.</dd>
129 **
130 ** <dt>' ' (a space)</dt>
131 ** <dd>specifying that a blank should be left before a
132 ** positive number produced by a signed conversion (d, e, E, f,
133 ** g, G, or i).</dd>
134 **
135 ** <dt>+</dt>
136 ** <dd>specifying that a sign always be placed before a number
137 ** produced by a signed conversion. A + overrides a space if
138 ** both are used.</dd>
139 **
140 ** <dt>:</dt>
141 ** <dd>specifying that a struct Client name should be preceded by a
142 ** ':' character if the destination is a user.</dd>
143 ** </dl></li>
144 **
145 ** <li>An optional decimal digit string specifying a minimum field
146 ** width. If the converted value has fewer characters than the
147 ** field width, it will be padded with spaces on the left (or right,
148 ** if the left-adjustment flag has been given) to fill out the field
149 ** width.</li>
150 **
151 ** <li>An optional precision, in the form of a period (`.') followed by
152 ** an optional digit string. If the digit string is omitted, the
153 ** precision is taken as zero. This gives the minimum number of
154 ** digits to appear for d, i, o, u, x, and X conversions, the number
155 ** of digits to appear after the decimal-point for e, E, and f
156 ** conversions, the maximum number of significant digits for g and G
157 ** conversions, or the maximum number of characters to be printed
158 ** from a string for s conversions.</li>
159 **
160 ** <li>The optional character h, specifying that a following d, i, o, u,
161 ** x, or X conversion corresponds to a short int or unsigned short
162 ** int argument, or that a following n conversion corresponds to a
163 ** pointer to a short int argument. If the h character is given
164 ** again, char is used instead of short int.</li>
165 **
166 ** <li>The optional character l (ell) specifying that a following d, i,
167 ** o, u, x, or X conversion applies to a pointer to a long int or
168 ** unsigned long int argument, or that a following n conversion
169 ** corresponds to a pointer to a long int argument.</li>
170 **
171 ** <li>The character L specifying that a following e, E, f, g, or G
172 ** conversion corresponds to a long double argument, or a following
173 ** d, i, o, u, x, or X conversion corresponds to a long long
174 ** argument. Note that long long is not specified in ANSI C and
175 ** therefore not portable to all architectures.</li>
176 **
177 ** <li>The optional character q. This is equivalent to L.</li>
178 **
179 ** <li>A j character specifying that the following integer (d, i, o, u,
180 ** x, or X) conversion corresponds to an intmax_t argument.</li>
181 **
182 ** <li>A t character specifying that the following integer (d, i, o, u,
183 ** x, or X) conversion corresponds to a ptrdiff_t argument.</li>
184 **
185 ** <li>A z character specifying that the following integer (d, i, o, u,
186 ** x, or X) conversion corresponds to a size_t argument.</li>
187 **
188 ** <li>A T character specifying that the following integer (d, i, o, u,
189 ** x, or X) conversion corresponds to a time_t argument.</li>
190 **
191 ** <li>A character that specifies the type of conversion to be applied.</li>
192 ** </ul>
193 **
194 ** A field width or precision, or both, may be indicated by an
195 ** asterisk `*' instead of a digit string. In this case, an int
196 ** argument supplies the field width or precision. A negative field
197 ** width is treated as a left adjustment flag followed by a positive
198 ** field width; a negative precision is treated as though it were
199 ** missing.
200 **
201 ** The conversion specifiers and their meanings are:
202 **
203 ** <dl>
204 ** <dt>diouxX</dt>
205 ** <dd>The int (or appropriate variant) argument is converted
206 ** to signed decimal (d and i), unsigned octal (o),
207 ** unsigned decimal (u), or unsigned hexadecimal (x and
208 ** X) notation. The letters abcdef are used for x
209 ** conversions; the letters ABCDEF are used for X
210 ** conversions. The precision, if any, gives the minimum
211 ** number of digits that must appear; if the converted
212 ** value requires fewer digits, it is padded on the left
213 ** with zeros.</dd>
214 **
215 ** <dt>eE [NOT IMPLEMENTED]</dt>
216 ** <dd>The double argument is rounded and
217 ** converted in the style [-]d.dddedd where there is one
218 ** digit before the decimal-point character and the
219 ** number of digits after it is equal to the precision;
220 ** if the precision is missing, it is taken as 6; if the
221 ** precision is zero, no decimal-point character appears.
222 ** An E conversion uses the letter E (rather than e) to
223 ** introduce the exponent. The exponent always contains
224 ** at least two digits; if the value is zero, the
225 ** exponent is 00.</dd>
226 **
227 ** <dt>f [NOT IMPLEMENTED]</dt>
228 ** <dd>The double argument is rounded and
229 ** converted to decimal notation in the style
230 ** [-]ddd.ddd, where the number of digits after the
231 ** decimal-point character is equal to the precision
232 ** specification. If the precision is missing, it is
233 ** taken as 6; if the precision is explicitly zero, no
234 ** decimal-point character appears. If a decimal point
235 ** appears, at least one digit appears before it.</dd>
236 **
237 ** <dt>g [NOT IMPLEMENTED]</dt>
238 ** <dd>The double argument is converted in
239 ** style f or e (or E for G conversions). The precision
240 ** specifies the number of significant digits. If the
241 ** precision is missing, 6 digits are given; if the
242 ** precision is zero, it is treated as 1. Style e is
243 ** used if the exponent from its conversion is less than
244 ** -4 or greater than or equal to the precision.
245 ** Trailing zeros are removed from the fractional part of
246 ** the result; a decimal point appears only if it is
247 ** followed by at least one digit.</dd>
248 **
249 ** <dt>c</dt>
250 ** <dd>The int argument is converted to an unsigned char, and
251 ** the resulting character is written.</dd>
252 **
253 ** <dt>s</dt>
254 ** <dd>The "char *" argument is expected to be a pointer to
255 ** an array of character type (pointer to a string).
256 ** Characters from the array are written up to (but not
257 ** including) a terminating NUL character; if a precision
258 ** is specified, no more than the number specified are
259 ** written. If a precision is given, no null character
260 ** need be present; if the precision is not specified, or
261 ** is greater than the size of the array, the array must
262 ** contain a terminating NUL character.</dd>
263 **
264 ** <dt>p</dt>
265 ** <dd>The "void *" pointer argument is printed in
266 ** hexadecimal (as if by %#x or %#lx).</dd>
267 **
268 ** <dt>n</dt>
269 ** <dd>The number of characters written so far is stored into
270 ** the integer indicated by the ``int *'' (or variant)
271 ** pointer argument. No argument is converted.</dd>
272 **
273 ** <dt>m</dt>
274 ** <dd>The error message associated with the current value of
275 ** errno is printed as if by %s.</dd>
276 **
277 ** <dt>C</dt>
278 ** <dd>The client argument identifier is printed under the
279 ** control of the &lt;dest> argument; if &lt;dest> is NULL or
280 ** is a user, the client's name (nickname or server name)
281 ** is printed; otherwise, the client's network numeric is
282 ** printed.</dd>
283 **
284 ** <dt>H</dt>
285 ** <dd>The channel argument identifier (channel name) is
286 ** printed.</dd>
287 **
288 ** <dt>v</dt>
289 ** <dd>The argument given must be a pointer to a struct
290 ** VarData with vd_format and vd_args must be initialized
291 ** appropriately. On return, vd_chars will contain the
292 ** number of characters added to the buffer, and
293 ** vd_overflow will contain the number of characters that
294 ** could not be added due to buffer overflow or due to a
295 ** precision.</dd>
296 **
297 ** <dt>%<dt>
298 ** <dd>A `%' is written. No argument is converted. The
299 ** complete conversion specification is `%%'.</dd>
300 ** </dl>
301 **
302 ** In no case does a non-existent or small field width cause
303 ** truncation of a field; if the result of a conversion is wider than
304 ** the field width, the field is expanded to contain the conversion
305 ** result.
306 **
307 ** @param[in] dest Client receiving of message.
308 ** @param[out] buf Output buffer for formatted message.
309 ** @param[in] buf_len Number of bytes that can be written to \a buf.
310 ** @param[in] format Format string for message.
311 ** @return Number of bytes that would be written to \a buf without truncation.
312 */
313
314 #endif

Properties

Name Value
svn_keywords Id Revision