1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
4 <link rev="made" href="mailto:mark.martinec@ijs.si">
6 snprintf.c - a portable implementation of snprintf
7 (including vsnprintf.c, asnprintf, vasnprintf, asprintf, vasprintf)
9 <meta http-equiv="Content-Language" content="en">
10 <meta name="author" content="Mark Martinec">
11 <meta name="copyright" content="Copyright 2000 Mark Martinec, All Rights Reserved">
12 <meta name="date" content="2000-10-18">
13 <meta name="keywords" lang="en"
14 content="snprintf,portable,vsnprintf,asnprintf,vasnprintf,asprintf,vasprintf
15 ISO/IEC 9899:1999,ISO C99,ISO C9x,POSIX">
16 <style type="text/css">
18 body { background: white; color: black }
24 <br> - a portable implementation of snprintf,
25 <br><font size="+1">including
26 vsnprintf.c, asnprintf, vasnprintf, asprintf, vasprintf</font>
29 <p><b>snprintf</b> is a routine to convert numeric and string arguments
30 to formatted strings. It is similar to sprintf(3) provided in a
31 system's C library, yet it requires an additional argument - the buffer
32 size - and it guarantees never to store anything beyond the given buffer,
33 regardless of the format or arguments to be formatted. Some newer
34 operating systems do provide <b>snprintf</b> in their C library,
35 but many do not or do provide an inadequate (slow or idiosyncratic)
36 version, which calls for a portable implementation of this routine.
40 <p><a href="http://www.ijs.si/people/mark/">Mark Martinec</a>
41 <<a href="mailto:mark.martinec@ijs.si">mark.martinec@ijs.si</a>>,
43 <br>Copyright © 1999, Mark Martinec
45 <h2>Terms and conditions ...</h2>
47 <p>This program is free software; you can redistribute it
48 and/or modify it under the terms of the
49 <i><a href="./LICENSE.txt">Frontier Artistic License</a></i>
50 which comes with this Kit.
55 <li>careful adherence to specs regarding flags, field width and precision;
56 <li>good performance for large string handling (large format, large argument
57 or large paddings). Performance is similar to system's <b>sprintf</b>
58 and in several cases significantly better (make sure you compile with
59 optimizations turned on, tell the compiler the code is strict ANSI
60 if necessary to give it more freedom for optimizations);
61 <li>return value semantics per ISO/IEC 9899:1999 ("ISO C99");
62 <li>written in standard ISO/ANSI C - requires an ANSI C compiler.
65 <h2>Supported conversion specifiers and data types</h2>
67 <p>This <b>snprintf</b> only supports the following conversion specifiers:
68 s, c, d, o, u, x, X, p (and synonyms: i, D, U, O - see below)
69 with flags: '-', '+', ' ', '0' and '#'.
70 An asterisk is supported for field width as well as precision.
72 <p>Length modifiers 'h' (<i>short int</i>), 'l' (<i>long int</i>),
73 and 'll' (<i>long long int</i>) are supported.
77 If macro SNPRINTF_LONGLONG_SUPPORT is not defined (default)
78 the length modifier 'll' is recognized but treated the same as 'l',
79 which may cause argument value truncation!
80 Defining SNPRINTF_LONGLONG_SUPPORT requires that your system's
81 <b>sprintf</b> also handles length modifier 'll'.
82 <i>long long int</i> is a language extension which may not be portable.
85 <p>Conversion of numeric data (conversion specifiers d, o, u, x, X, p)
86 with length modifiers (none or h, l, ll) is left to the system
87 routine <b>sprintf</b>, but all handling of flags, field width and precision
88 as well as c and s conversions is done very carefully by this portable routine.
89 If a string precision (truncation) is specified (e.g. %.8s) it is
90 guaranteed the string beyond the specified precision will not be referenced.
92 <p>Length modifiers h, l and ll are ignored for c and s conversions
93 (data types <i>wint_t</i> and <i>wchar_t</i> are not supported).
95 <p>The following common synonyms for conversion characters are supported:
97 <li>i is a synonym for d
98 <li>D is a synonym for ld, explicit length modifiers are ignored
99 <li>U is a synonym for lu, explicit length modifiers are ignored
100 <li>O is a synonym for lo, explicit length modifiers are ignored
102 The D, O and U conversion characters are nonstandard, they are supported
103 for backward compatibility only, and should not be used for new code.
105 <p>The following is specifically <b>not</b> supported:
107 <li>flag ' (thousands' grouping character) is recognized but ignored
108 <li>numeric conversion specifiers: f, e, E, g, G and synonym F,
109 as well as the new a and A conversion specifiers
110 <li>length modifier 'L' (<i>long double</i>)
111 and 'q' (<i>quad</i> - use 'll' instead)
112 <li>wide character/string conversions: lc, ls, and nonstandard
114 <li>writeback of converted string length: conversion character n
115 <li>the n$ specification for direct reference to n-th argument
119 <p>It is permitted for str_m to be zero, and it is permitted to specify NULL
120 pointer for resulting string argument if str_m is zero (as per ISO C99).
122 <p>The return value is the number of characters which would be generated
123 for the given input, <i>excluding</i> the trailing null. If this value
124 is greater or equal to str_m, not all characters from the result
125 have been stored in str, output bytes beyond the (str_m-1) -th character
126 are discarded. If str_m is greater than zero it is guaranteed
127 the resulting string will be null-terminated.
129 <p>NOTE that this matches the ISO C99, OpenBSD, and GNU C library 2.1,
130 but is different from some older and vendor implementations,
131 and is also different from XPG, XSH5, SUSv2 specifications.
132 For historical discussion on changes in the semantics and standards
133 of snprintf see printf(3) man page in the Linux programmers manual.
135 <p>Routines asprintf and vasprintf return a pointer (in the ptr argument)
136 to a buffer sufficiently large to hold the resulting string. This pointer
137 should be passed to free(3) to release the allocated storage when it is
138 no longer needed. If sufficient space cannot be allocated, these functions
139 will return -1 and set ptr to be a NULL pointer. These two routines are a
140 GNU C library extensions (glibc).
142 <p>Routines asnprintf and vasnprintf are similar to asprintf and vasprintf,
143 yet, like snprintf and vsnprintf counterparts, will write at most str_m-1
144 characters into the allocated output string, the last character in the
145 allocated buffer then gets the terminating null. If the formatted string
146 length (the return value) is greater than or equal to the str_m argument,
147 the resulting string was truncated and some of the formatted characters
148 were discarded. These routines present a handy way to limit the amount
149 of allocated memory to some sane value.
151 <h2>Availability</h2>
153 <p><a href="http://www.ijs.si/software/snprintf/"
154 >http://www.ijs.si/software/snprintf/</a>
158 <a href="./snprintf_1.3.tar.gz">snprintf_1.3.tar.gz</a> (1999-06-30),
159 md5 sum: <a href="./snprintf_1.3.tar.gz.md5">snprintf_1.3.tar.gz.md5</a>
162 <a href="./snprintf_2.1.tar.gz">snprintf_2.1.tar.gz</a> (2000-07-14),
163 md5 sum: <a href="./snprintf_2.1.tar.gz.md5">snprintf_2.1.tar.gz.md5</a>
166 <a href="./snprintf_2.2.tar.gz">snprintf_2.2.tar.gz</a> (2000-10-18),
167 md5 sum: <a href="./snprintf_2.2.tar.gz.md5">snprintf_2.2.tar.gz.md5</a>
171 <h2>Mailing list</h2>
173 <p>There is a very low-traffic mailing list <i>snprintf-announce@ijs.si</i>
174 where announcements about new versions will be posted
175 as well as warnings about threatening bugs if discovered.
176 The posting is restricted to snprintf developer(s).
178 <p>To subscribe to (or unsubscribe from) the mailing list
179 please visit the list server's web page
180 <a href="http://mailman.ijs.si/listinfo/snprintf-announce"
181 >http://mailman.ijs.si/listinfo/snprintf-announce</a>
183 <p>You can also subscribe to the list by mailing
184 the command SUBSCRIBE either in the subject or in the message body
185 to the address <a href="mailto:snprintf-announce-request@ijs.si"
186 >snprintf-announce-request@ijs.si</a> . You will be asked for
187 confirmation before subscription will be effective.
189 <p>The list of members is only accessible to the list administrator,
190 so there is no need for concern about automatic e-mail address gatherers.
192 <p>Questions about the mailing list and concerns for the attention
193 of a person should be sent to <a href="mailto:snprintf-announce-admin@ijs.si"
194 >snprintf-announce-admin@ijs.si</a>
196 <p>There is no <i>general</i> discussion list about portable snprintf
197 at the moment. Please send comments and suggestion to the author.
200 <h2>Revision history</h2>
202 <p><b>Version 1.3 fixes a runaway loop problem from 1.2. Please upgrade.</b>
205 <dt>1999-06-30 V1.3 Mark Martinec <mark.martinec@ijs.si>
207 <li>fixed runaway loop (eventually crashing when str_l wraps
208 beyond 2^31) while copying format string without
209 conversion specifiers to a buffer that is too short
210 (thanks to Edwin Young <edwiny@autonomy.com> for spotting the problem);
211 <li>added macros PORTABLE_SNPRINTF_VERSION_(MAJOR|MINOR) to snprintf.h
214 <dt>2000-02-14 V2.0 (never released) Mark Martinec <mark.martinec@ijs.si>
216 <li>relaxed license terms:
217 <a href="./LICENSE.txt">The Artistic License</a> now applies.
218 You may still apply the GNU GENERAL PUBLIC LICENSE
219 as was distributed with previous versions, if you prefer;
220 <li>changed REVISION HISTORY dates to use
221 <a href="http://www.cl.cam.ac.uk/~mgk25/iso-time.html">ISO 8601
223 <li>added vsnprintf (patch also independently proposed by
224 Caolán McNamara 2000-05-04, and Keith M Willenson 2000-06-01)
227 <dt>2000-06-27 V2.1 Mark Martinec <mark.martinec@ijs.si>
229 <li>removed POSIX check for str_m < 1; value 0 for str_m is
230 allowed by ISO C99 (and GNU C library 2.1) (pointed out
231 on 2000-05-04 by Caolán McNamara, caolan@ csn dot ul dot ie).
232 Besides relaxed license this change in standards adherence
233 is the main reason to bump up the major version number;
234 <li>added nonstandard routines asnprintf, vasnprintf, asprintf,
235 vasprintf that dynamically allocate storage for the
236 resulting string; these routines are not compiled by default,
237 see comments where NEED_V?ASN?PRINTF macros are defined;
238 <li>autoconf contributed by Caolán McNamara
241 <dt>2000-10-06 V2.2 Mark Martinec <mark.martinec@ijs.si>
243 <li><b>BUG FIX</b>: the %c conversion used a temporary variable
244 that was no longer in scope when referenced,
245 possibly causing incorrect resulting character;
246 <li>BUG FIX: make precision and minimal field width unsigned
247 to handle huge values (2^31 <= n < 2^32) correctly;
248 also be more careful in the use of signed/unsigned/size_t
249 internal variables -- probably more careful than many
250 vendor implementations, but there may still be a case
251 where huge values of str_m, precision or minimal field
252 could cause incorrect behaviour;
253 <li>use separate variables for signed/unsigned arguments,
254 and for short/int, long, and long long argument lengths
255 to avoid possible incompatibilities on certain
256 computer architectures. Also use separate variable
257 arg_sign to hold sign of a numeric argument,
258 to make code more transparent;
259 <li>some fiddling with zero padding and "0x" to make it
261 <li>systematically use macros fast_memcpy and fast_memset
262 instead of case-by-case hand optimization; determine some
263 breakeven string lengths for different architectures;
264 <li>terminology change: <i>format</i> -> <i>conversion specifier</i>,
265 <i>C9x</i> -> <i>ISO/IEC 9899:1999 ("ISO C99")</i>,
266 <i>alternative form</i> -> <i>alternate form</i>,
267 <i>data type modifier</i> -> <i>length modifier</i>;
268 <li>several comments rephrased and new ones added;
269 <li>make compiler not complain about 'credits' defined but
274 <h2>Other implementations of snprintf</h2>
276 <p>I am aware of some other (more or less) portable implementations
277 of <b>snprintf</b>. I do not claim they are free software - please refer
278 to their respective copyright and licensing terms.
279 If you know of other versions please let
280 <a href="http://www.ijs.si/people/mark/">me</a> know.
283 <li>a very thorough implementation (src/util_snprintf.c)
284 by the Apache Group distributed with the
285 <a href="http://www.apache.org/">Apache web server
286 - http://www.apache.org/</a> .
287 Does its own floating point conversions using routines
288 ecvt(3), fcvt(3) and gcvt(3) from the standard C library
289 or from the GNU libc.
291 <br>This is from the code:
293 This software [...] was originally based
294 on public domain software written at the
295 <a href="http://www.ncsa.uiuc.edu/ncsa.html">National Center
296 for Supercomputing Applications</a>, University of Illinois,
297 Urbana-Champaign.<br>
298 [...] This code is based on, and used with the permission of,
299 the SIO stdio-replacement strx_* functions by Panos Tsirigotis
300 <<a href="mailto:panos@alumni.cs.colorado.edu">panos@alumni.cs.colorado.edu</a>> for xinetd.
303 <li><a href="http://www.qlue.com/downloads/c_utils_README.html">QCI
304 Utilities</a> use a modified version of snprintf from the Apache group.
306 <li>implementations as distributed with
307 <a href="http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/">OpenBSD</a>,
308 <a href="http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/stdio/">FreeBSD</a>, and
309 <a href="http://cvsweb.netbsd.org/cgi-bin/cvsweb.cgi/basesrc/lib/libc/stdio/">NetBSD</a>
310 are all wrappers to vfprintf.c, which is derived from software
311 contributed to Berkeley by Chris Torek.
313 <li>implementation from Prof. Patrick Powell
314 <<a href="mailto:papowell@sdsu.edu">papowell@sdsu.edu</a>>,
315 Dept. Electrical and Computer Engineering, San Diego State University,
316 San Diego, CA 92182-1309, published in
317 <a href="http://www.geek-girl.com/bugtraq/1995_3/0217.html">Bugtraq
318 archives for 3rd quarter (Jul-Aug) 1995</a>.
319 No floating point conversions.
322 <<a href="mailto:blong@fiction.net">blong@fiction.net</a>>
323 <a href="http://www.fiction.net/~blong/programs/">modified version</a>
324 of Prof. Patrick Powell's snprintf with contributions from others.
325 With minimal floating point support.
327 <li>implementation (src/snprintf.c) as distributed with
328 <a href="http://www.sendmail.org/">sendmail - http://www.sendmail.org/</a>
329 is a cleaned up Prof. Patrick Powell's version
330 to compile properly and to support .precision and %lx.
332 <li>implementation from <a href="http://www.csn.ul.ie/~caolan/"
333 >Caolán McNamara</a> available at
334 <a href="http://www.csn.ul.ie/~caolan/publink/snprintf-1.1.tar.gz"
335 >http://www.csn.ul.ie/~caolan/publink/snprintf-1.1.tar.gz</a>,
336 handles floating point.
338 <li>implementation used by
339 <a href="ftp://ftp.soscorp.com/pub/sos/lib">newlog</a>
340 (a replacement for syslog(3)) made available by
341 the <a href="http://www.soscorp.com">SOS Corporation</a>.
342 Enabling floating point support is a compile-time option.
344 <li>implementation by Michael Richardson
345 <<a href="mailto:mcr@metis.milkyway.com">mcr@metis.milkyway.com</a>>
347 <a href="http://sandelman.ottawa.on.ca/SSW/snp/snp.html"
348 >http://sandelman.ottawa.on.ca/SSW/snp/snp.html</a>.
349 It is based on BSD44-lite's vfprintf() call, modified to function
350 on SunOS. Needs internal routines from the 4.4 strtod (included),
351 requires GCC to compile the long long (aka quad_t) portions.
353 <li>implementation from Tomi Salo
354 <<a href="mailto:ttsalo@ssh.fi">ttsalo@ssh.fi</a>>
356 <a href="http://www.Europe.DataFellows.com/f-secure/ssh/">SSH 2.0
357 Unix Server</a>. Not in public domain.
358 Floating point conversions done by system's sprintf.
360 <li>and for completeness: <a href="http://www.ijs.si/people/mark/">my</a>
361 portable version described in this very document available at
362 <a href="http://www.ijs.si/software/snprintf/"
363 >http://www.ijs.si/software/snprintf/</a> .
366 In retrospect, it appears that a lot of effort was wasted by many
367 people for not being aware of what others are doing. Sigh.
370 <a href="http://www.opengroup.org/platform/resolutions/bwg98-006.html"
371 >The Approved Base Working Group Resolution for XSH5,
372 Ref: bwg98-006, Topic: snprintf</a>.
375 <i><a href="http://www.ijs.si/people/mark/">mm</a></i>
376 <br>Last updated: 2000-10-18
378 <p><a href="http://validator.w3.org/check/referer"
379 ><img src="/images/vh40.gif" alt="Valid HTML 4.0!"
380 border="0" width="88" height="31"></a>