]> jfr.im git - irc/quakenet/snircd.git/blame - include/ircd_snprintf.h
seems snircd also needs gline_resend updated - it was using ircu .12 gline format...
[irc/quakenet/snircd.git] / include / ircd_snprintf.h
CommitLineData
189935b1 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,v 1.8 2004/10/05 04:21:37 entrope Exp $
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
34struct Client;
35
36/** structure passed as argument for %v conversion */
37struct 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
53extern int ircd_snprintf(struct Client *dest, char *buf, size_t buf_len,
54 const char *format, ...);
55extern 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 */