snprintf_2.2/README

changeset 35
5a71d53d0228
equal deleted inserted replaced
34:828f3afd5c76 35:5a71d53d0228
1
2 snprintf.c
3 - a portable implementation of snprintf,
4 including vsnprintf.c, asnprintf, vasnprintf, asprintf, vasprintf
5
6 snprintf is a routine to convert numeric and string arguments to
7 formatted strings. It is similar to sprintf(3) provided in a system's
8 C library, yet it requires an additional argument - the buffer size -
9 and it guarantees never to store anything beyond the given buffer,
10 regardless of the format or arguments to be formatted. Some newer
11 operating systems do provide snprintf in their C library, but many do
12 not or do provide an inadequate (slow or idiosyncratic) version, which
13 calls for a portable implementation of this routine.
14
15 Author
16
17 Mark Martinec <mark.martinec@ijs.si>, April 1999, June 2000
18 Copyright © 1999, Mark Martinec
19
20 Terms and conditions ...
21
22 This program is free software; you can redistribute it and/or modify
23 it under the terms of the Frontier Artistic License which comes with
24 this Kit.
25
26 Features
27
28 * careful adherence to specs regarding flags, field width and
29 precision;
30 * good performance for large string handling (large format, large
31 argument or large paddings). Performance is similar to system's
32 sprintf and in several cases significantly better (make sure you
33 compile with optimizations turned on, tell the compiler the code
34 is strict ANSI if necessary to give it more freedom for
35 optimizations);
36 * return value semantics per ISO/IEC 9899:1999 ("ISO C99");
37 * written in standard ISO/ANSI C - requires an ANSI C compiler.
38
39 Supported conversion specifiers and data types
40
41 This snprintf only supports the following conversion specifiers: s, c,
42 d, o, u, x, X, p (and synonyms: i, D, U, O - see below) with flags:
43 '-', '+', ' ', '0' and '#'. An asterisk is supported for field width
44 as well as precision.
45
46 Length modifiers 'h' (short int), 'l' (long int), and 'll' (long long
47 int) are supported.
48
49 NOTE:
50
51 If macro SNPRINTF_LONGLONG_SUPPORT is not defined (default) the
52 length modifier 'll' is recognized but treated the same as 'l',
53 which may cause argument value truncation! Defining
54 SNPRINTF_LONGLONG_SUPPORT requires that your system's sprintf also
55 handles length modifier 'll'. long long int is a language extension
56 which may not be portable.
57
58 Conversion of numeric data (conversion specifiers d, o, u, x, X, p)
59 with length modifiers (none or h, l, ll) is left to the system routine
60 sprintf, but all handling of flags, field width and precision as well
61 as c and s conversions is done very carefully by this portable
62 routine. If a string precision (truncation) is specified (e.g. %.8s)
63 it is guaranteed the string beyond the specified precision will not be
64 referenced.
65
66 Length modifiers h, l and ll are ignored for c and s conversions (data
67 types wint_t and wchar_t are not supported).
68
69 The following common synonyms for conversion characters are supported:
70 * i is a synonym for d
71 * D is a synonym for ld, explicit length modifiers are ignored
72 * U is a synonym for lu, explicit length modifiers are ignored
73 * O is a synonym for lo, explicit length modifiers are ignored
74
75 The D, O and U conversion characters are nonstandard, they are
76 supported for backward compatibility only, and should not be used for
77 new code.
78
79 The following is specifically not supported:
80 * flag ' (thousands' grouping character) is recognized but ignored
81 * numeric conversion specifiers: f, e, E, g, G and synonym F, as
82 well as the new a and A conversion specifiers
83 * length modifier 'L' (long double) and 'q' (quad - use 'll'
84 instead)
85 * wide character/string conversions: lc, ls, and nonstandard
86 synonyms C and S
87 * writeback of converted string length: conversion character n
88 * the n$ specification for direct reference to n-th argument
89 * locales
90
91 It is permitted for str_m to be zero, and it is permitted to specify
92 NULL pointer for resulting string argument if str_m is zero (as per
93 ISO C99).
94
95 The return value is the number of characters which would be generated
96 for the given input, excluding the trailing null. If this value is
97 greater or equal to str_m, not all characters from the result have
98 been stored in str, output bytes beyond the (str_m-1) -th character
99 are discarded. If str_m is greater than zero it is guaranteed the
100 resulting string will be null-terminated.
101
102 NOTE that this matches the ISO C99, OpenBSD, and GNU C library 2.1,
103 but is different from some older and vendor implementations, and is
104 also different from XPG, XSH5, SUSv2 specifications. For historical
105 discussion on changes in the semantics and standards of snprintf see
106 printf(3) man page in the Linux programmers manual.
107
108 Routines asprintf and vasprintf return a pointer (in the ptr argument)
109 to a buffer sufficiently large to hold the resulting string. This
110 pointer should be passed to free(3) to release the allocated storage
111 when it is no longer needed. If sufficient space cannot be allocated,
112 these functions will return -1 and set ptr to be a NULL pointer. These
113 two routines are a GNU C library extensions (glibc).
114
115 Routines asnprintf and vasnprintf are similar to asprintf and
116 vasprintf, yet, like snprintf and vsnprintf counterparts, will write
117 at most str_m-1 characters into the allocated output string, the last
118 character in the allocated buffer then gets the terminating null. If
119 the formatted string length (the return value) is greater than or
120 equal to the str_m argument, the resulting string was truncated and
121 some of the formatted characters were discarded. These routines
122 present a handy way to limit the amount of allocated memory to some
123 sane value.
124
125 Availability
126
127 http://www.ijs.si/software/snprintf/
128 * snprintf_1.3.tar.gz (1999-06-30), md5 sum: snprintf_1.3.tar.gz.md5
129 * snprintf_2.1.tar.gz (2000-07-14), md5 sum: snprintf_2.1.tar.gz.md5
130 * snprintf_2.2.tar.gz (2000-10-18), md5 sum: snprintf_2.2.tar.gz.md5
131
132 Mailing list
133
134 There is a very low-traffic mailing list snprintf-announce@ijs.si
135 where announcements about new versions will be posted as well as
136 warnings about threatening bugs if discovered. The posting is
137 restricted to snprintf developer(s).
138
139 To subscribe to (or unsubscribe from) the mailing list please visit
140 the list server's web page
141 http://mailman.ijs.si/listinfo/snprintf-announce
142
143 You can also subscribe to the list by mailing the command SUBSCRIBE
144 either in the subject or in the message body to the address
145 snprintf-announce-request@ijs.si . You will be asked for confirmation
146 before subscription will be effective.
147
148 The list of members is only accessible to the list administrator, so
149 there is no need for concern about automatic e-mail address gatherers.
150
151 Questions about the mailing list and concerns for the attention of a
152 person should be sent to snprintf-announce-admin@ijs.si
153
154 There is no general discussion list about portable snprintf at the
155 moment. Please send comments and suggestion to the author.
156
157 Revision history
158
159 Version 1.3 fixes a runaway loop problem from 1.2. Please upgrade.
160
161 1999-06-30 V1.3 Mark Martinec <mark.martinec@ijs.si>
162
163 + fixed runaway loop (eventually crashing when str_l wraps
164 beyond 2^31) while copying format string without conversion
165 specifiers to a buffer that is too short (thanks to Edwin
166 Young <edwiny@autonomy.com> for spotting the problem);
167 + added macros PORTABLE_SNPRINTF_VERSION_(MAJOR|MINOR) to
168 snprintf.h
169
170 2000-02-14 V2.0 (never released) Mark Martinec <mark.martinec@ijs.si>
171
172 + relaxed license terms: The Artistic License now applies. You
173 may still apply the GNU GENERAL PUBLIC LICENSE as was
174 distributed with previous versions, if you prefer;
175 + changed REVISION HISTORY dates to use ISO 8601 date format;
176 + added vsnprintf (patch also independently proposed by Caolán
177 McNamara 2000-05-04, and Keith M Willenson 2000-06-01)
178
179 2000-06-27 V2.1 Mark Martinec <mark.martinec@ijs.si>
180
181 + removed POSIX check for str_m < 1; value 0 for str_m is
182 allowed by ISO C99 (and GNU C library 2.1) (pointed out on
183 2000-05-04 by Caolán McNamara, caolan@ csn dot ul dot ie).
184 Besides relaxed license this change in standards adherence is
185 the main reason to bump up the major version number;
186 + added nonstandard routines asnprintf, vasnprintf, asprintf,
187 vasprintf that dynamically allocate storage for the resulting
188 string; these routines are not compiled by default, see
189 comments where NEED_V?ASN?PRINTF macros are defined;
190 + autoconf contributed by Caolán McNamara
191
192 2000-10-06 V2.2 Mark Martinec <mark.martinec@ijs.si>
193
194 + BUG FIX: the %c conversion used a temporary variable that was
195 no longer in scope when referenced, possibly causing
196 incorrect resulting character;
197 + BUG FIX: make precision and minimal field width unsigned to
198 handle huge values (2^31 <= n < 2^32) correctly; also be more
199 careful in the use of signed/unsigned/size_t internal
200 variables -- probably more careful than many vendor
201 implementations, but there may still be a case where huge
202 values of str_m, precision or minimal field could cause
203 incorrect behaviour;
204 + use separate variables for signed/unsigned arguments, and for
205 short/int, long, and long long argument lengths to avoid
206 possible incompatibilities on certain computer architectures.
207 Also use separate variable arg_sign to hold sign of a numeric
208 argument, to make code more transparent;
209 + some fiddling with zero padding and "0x" to make it Linux
210 compatible;
211 + systematically use macros fast_memcpy and fast_memset instead
212 of case-by-case hand optimization; determine some breakeven
213 string lengths for different architectures;
214 + terminology change: format -> conversion specifier, C9x ->
215 ISO/IEC 9899:1999 ("ISO C99"), alternative form -> alternate
216 form, data type modifier -> length modifier;
217 + several comments rephrased and new ones added;
218 + make compiler not complain about 'credits' defined but not
219 used;
220
221 Other implementations of snprintf
222
223 I am aware of some other (more or less) portable implementations of
224 snprintf. I do not claim they are free software - please refer to
225 their respective copyright and licensing terms. If you know of other
226 versions please let me know.
227 * a very thorough implementation (src/util_snprintf.c) by the Apache
228 Group distributed with the Apache web server -
229 http://www.apache.org/ . Does its own floating point conversions
230 using routines ecvt(3), fcvt(3) and gcvt(3) from the standard C
231 library or from the GNU libc.
232 This is from the code:
233
234 This software [...] was originally based on public domain software
235 written at the National Center for Supercomputing Applications,
236 University of Illinois, Urbana-Champaign.
237 [...] This code is based on, and used with the permission of, the
238 SIO stdio-replacement strx_* functions by Panos Tsirigotis
239 <panos@alumni.cs.colorado.edu> for xinetd.
240 * QCI Utilities use a modified version of snprintf from the Apache
241 group.
242 * implementations as distributed with OpenBSD, FreeBSD, and NetBSD
243 are all wrappers to vfprintf.c, which is derived from software
244 contributed to Berkeley by Chris Torek.
245 * implementation from Prof. Patrick Powell <papowell@sdsu.edu>,
246 Dept. Electrical and Computer Engineering, San Diego State
247 University, San Diego, CA 92182-1309, published in Bugtraq
248 archives for 3rd quarter (Jul-Aug) 1995. No floating point
249 conversions.
250 * Brandon Long's <blong@fiction.net> modified version of Prof.
251 Patrick Powell's snprintf with contributions from others. With
252 minimal floating point support.
253 * implementation (src/snprintf.c) as distributed with sendmail -
254 http://www.sendmail.org/ is a cleaned up Prof. Patrick Powell's
255 version to compile properly and to support .precision and %lx.
256 * implementation from Caolán McNamara available at
257 http://www.csn.ul.ie/~caolan/publink/snprintf-1.1.tar.gz, handles
258 floating point.
259 * implementation used by newlog (a replacement for syslog(3)) made
260 available by the SOS Corporation. Enabling floating point support
261 is a compile-time option.
262 * implementation by Michael Richardson <mcr@metis.milkyway.com> is
263 available at http://sandelman.ottawa.on.ca/SSW/snp/snp.html. It is
264 based on BSD44-lite's vfprintf() call, modified to function on
265 SunOS. Needs internal routines from the 4.4 strtod (included),
266 requires GCC to compile the long long (aka quad_t) portions.
267 * implementation from Tomi Salo <ttsalo@ssh.fi> distributed with SSH
268 2.0 Unix Server. Not in public domain. Floating point conversions
269 done by system's sprintf.
270 * and for completeness: my portable version described in this very
271 document available at http://www.ijs.si/software/snprintf/ .
272
273 In retrospect, it appears that a lot of effort was wasted by many
274 people for not being aware of what others are doing. Sigh.
275
276 Also of interest: The Approved Base Working Group Resolution for XSH5,
277 Ref: bwg98-006, Topic: snprintf.
278 _________________________________________________________________
279
280 mm
281 Last updated: 2000-10-18
282
283 Valid HTML 4.0!

mercurial