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