|
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
|
2 <html> |
|
3 <head> |
|
4 <link rev="made" href="mailto:mark.martinec@ijs.si"> |
|
5 <title> |
|
6 snprintf.c - a portable implementation of snprintf |
|
7 (including vsnprintf.c, asnprintf, vasnprintf, asprintf, vasprintf) |
|
8 </title> |
|
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"> |
|
17 <!-- |
|
18 body { background: white; color: black } |
|
19 --> |
|
20 </style> |
|
21 </head> |
|
22 <body> |
|
23 <h1><b>snprintf.c</b> |
|
24 <br> - a portable implementation of snprintf, |
|
25 <br><font size="+1">including |
|
26 vsnprintf.c, asnprintf, vasnprintf, asprintf, vasprintf</font> |
|
27 </h1> |
|
28 |
|
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. |
|
37 |
|
38 <h2>Author</h2> |
|
39 |
|
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>>, |
|
42 April 1999, June 2000 |
|
43 <br>Copyright © 1999, Mark Martinec |
|
44 |
|
45 <h2>Terms and conditions ...</h2> |
|
46 |
|
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. |
|
51 |
|
52 <h2>Features</h2> |
|
53 |
|
54 <ul> |
|
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. |
|
63 </ul> |
|
64 |
|
65 <h2>Supported conversion specifiers and data types</h2> |
|
66 |
|
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. |
|
71 |
|
72 <p>Length modifiers 'h' (<i>short int</i>), 'l' (<i>long int</i>), |
|
73 and 'll' (<i>long long int</i>) are supported. |
|
74 |
|
75 <p>NOTE: |
|
76 <blockquote> |
|
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. |
|
83 </blockquote> |
|
84 |
|
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. |
|
91 |
|
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). |
|
94 |
|
95 <p>The following common synonyms for conversion characters are supported: |
|
96 <ul> |
|
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 |
|
101 </ul> |
|
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. |
|
104 |
|
105 <p>The following is specifically <b>not</b> supported: |
|
106 <ul> |
|
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 |
|
113 synonyms C and S |
|
114 <li>writeback of converted string length: conversion character n |
|
115 <li>the n$ specification for direct reference to n-th argument |
|
116 <li>locales |
|
117 </ul> |
|
118 |
|
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). |
|
121 |
|
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. |
|
128 |
|
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. |
|
134 |
|
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). |
|
141 |
|
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. |
|
150 |
|
151 <h2>Availability</h2> |
|
152 |
|
153 <p><a href="http://www.ijs.si/software/snprintf/" |
|
154 >http://www.ijs.si/software/snprintf/</a> |
|
155 |
|
156 <ul> |
|
157 <li> |
|
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> |
|
160 |
|
161 <li> |
|
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> |
|
164 |
|
165 <li> |
|
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> |
|
168 </ul> |
|
169 |
|
170 |
|
171 <h2>Mailing list</h2> |
|
172 |
|
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). |
|
177 |
|
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> |
|
182 |
|
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. |
|
188 |
|
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. |
|
191 |
|
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> |
|
195 |
|
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. |
|
198 |
|
199 |
|
200 <h2>Revision history</h2> |
|
201 |
|
202 <p><b>Version 1.3 fixes a runaway loop problem from 1.2. Please upgrade.</b> |
|
203 |
|
204 <dl> |
|
205 <dt>1999-06-30 V1.3 Mark Martinec <mark.martinec@ijs.si> |
|
206 <dd><ul> |
|
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 |
|
212 </ul> |
|
213 |
|
214 <dt>2000-02-14 V2.0 (never released) Mark Martinec <mark.martinec@ijs.si> |
|
215 <dd><ul> |
|
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 |
|
222 date format</a>; |
|
223 <li>added vsnprintf (patch also independently proposed by |
|
224 Caolán McNamara 2000-05-04, and Keith M Willenson 2000-06-01) |
|
225 </ul> |
|
226 |
|
227 <dt>2000-06-27 V2.1 Mark Martinec <mark.martinec@ijs.si> |
|
228 <dd><ul> |
|
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 |
|
239 </ul> |
|
240 |
|
241 <dt>2000-10-06 V2.2 Mark Martinec <mark.martinec@ijs.si> |
|
242 <dd><ul> |
|
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 |
|
260 Linux compatible; |
|
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 |
|
270 not used; |
|
271 </ul> |
|
272 </dl> |
|
273 |
|
274 <h2>Other implementations of snprintf</h2> |
|
275 |
|
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. |
|
281 |
|
282 <ul> |
|
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. |
|
290 |
|
291 <br>This is from the code: |
|
292 <blockquote> |
|
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. |
|
301 </blockquote> |
|
302 |
|
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. |
|
305 |
|
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. |
|
312 |
|
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. |
|
320 |
|
321 <li>Brandon Long's |
|
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. |
|
326 |
|
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. |
|
331 |
|
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. |
|
337 |
|
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. |
|
343 |
|
344 <li>implementation by Michael Richardson |
|
345 <<a href="mailto:mcr@metis.milkyway.com">mcr@metis.milkyway.com</a>> |
|
346 is available at |
|
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. |
|
352 |
|
353 <li>implementation from Tomi Salo |
|
354 <<a href="mailto:ttsalo@ssh.fi">ttsalo@ssh.fi</a>> |
|
355 distributed with |
|
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. |
|
359 |
|
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> . |
|
364 </ul> |
|
365 |
|
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. |
|
368 |
|
369 <p>Also of interest: |
|
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>. |
|
373 |
|
374 <p><hr> |
|
375 <i><a href="http://www.ijs.si/people/mark/">mm</a></i> |
|
376 <br>Last updated: 2000-10-18 |
|
377 |
|
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> |
|
381 </body> |
|
382 </html> |