| Damien Miller | f18462f | 2003-04-01 21:31:56 +1000 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright Patrick Powell 1995 | 
 | 3 |  * This code is based on code written by Patrick Powell (papowell@astart.com) | 
 | 4 |  * It may be used for any purpose as long as this notice remains intact | 
 | 5 |  * on all source code distributions | 
 | 6 |  */ | 
 | 7 |  | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 8 | /************************************************************** | 
 | 9 |  * Original: | 
 | 10 |  * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 | 
 | 11 |  * A bombproof version of doprnt (dopr) included. | 
 | 12 |  * Sigh.  This sort of thing is always nasty do deal with.  Note that | 
 | 13 |  * the version here does not include floating point... | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 14 |  * | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 15 |  * snprintf() is used instead of sprintf() as it does limit checks | 
 | 16 |  * for string length.  This covers a nasty loophole. | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 17 |  * | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 18 |  * The other functions are there to prevent NULL pointers from | 
 | 19 |  * causing nast effects. | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 20 |  * | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 21 |  * More Recently: | 
 | 22 |  *  Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43 | 
 | 23 |  *  This was ugly.  It is still ugly.  I opted out of floating point | 
 | 24 |  *  numbers, but the formatter understands just about everything | 
 | 25 |  *  from the normal C string format, at least as far as I can tell from | 
 | 26 |  *  the Solaris 2.5 printf(3S) man page. | 
 | 27 |  * | 
 | 28 |  *  Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1 | 
 | 29 |  *    Ok, added some minimal floating point support, which means this | 
 | 30 |  *    probably requires libm on most operating systems.  Don't yet | 
 | 31 |  *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint() | 
 | 32 |  *    was pretty badly broken, it just wasn't being exercised in ways | 
 | 33 |  *    which showed it, so that's been fixed.  Also, formated the code | 
 | 34 |  *    to mutt conventions, and removed dead code left over from the | 
 | 35 |  *    original.  Also, there is now a builtin-test, just compile with: | 
 | 36 |  *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm | 
 | 37 |  *    and run snprintf for results. | 
 | 38 |  *  | 
 | 39 |  *  Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i | 
 | 40 |  *    The PGP code was using unsigned hexadecimal formats.  | 
 | 41 |  *    Unfortunately, unsigned formats simply didn't work. | 
 | 42 |  * | 
 | 43 |  *  Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8 | 
 | 44 |  *    The original code assumed that both snprintf() and vsnprintf() were | 
 | 45 |  *    missing.  Some systems only have snprintf() but not vsnprintf(), so | 
 | 46 |  *    the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. | 
 | 47 |  * | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 48 |  *  Andrew Tridgell (tridge@samba.org) Oct 1998 | 
 | 49 |  *    fixed handling of %.0f | 
 | 50 |  *    added test for HAVE_LONG_DOUBLE | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 51 |  * | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 52 |  * tridge@samba.org, idra@samba.org, April 2001 | 
 | 53 |  *    got rid of fcvt code (twas buggy and made testing harder) | 
 | 54 |  *    added C99 semantics | 
 | 55 |  * | 
 | 56 |  * date: 2002/12/19 19:56:31;  author: herb;  state: Exp;  lines: +2 -0 | 
 | 57 |  * actually print args for %g and %e | 
 | 58 |  *  | 
 | 59 |  * date: 2002/06/03 13:37:52;  author: jmcd;  state: Exp;  lines: +8 -0 | 
 | 60 |  * Since includes.h isn't included here, VA_COPY has to be defined here.  I don't | 
 | 61 |  * see any include file that is guaranteed to be here, so I'm defining it | 
 | 62 |  * locally.  Fixes AIX and Solaris builds. | 
 | 63 |  *  | 
 | 64 |  * date: 2002/06/03 03:07:24;  author: tridge;  state: Exp;  lines: +5 -13 | 
 | 65 |  * put the ifdef for HAVE_VA_COPY in one place rather than in lots of | 
 | 66 |  * functions | 
 | 67 |  *  | 
 | 68 |  * date: 2002/05/17 14:51:22;  author: jmcd;  state: Exp;  lines: +21 -4 | 
 | 69 |  * Fix usage of va_list passed as an arg.  Use __va_copy before using it | 
 | 70 |  * when it exists. | 
 | 71 |  *  | 
 | 72 |  * date: 2002/04/16 22:38:04;  author: idra;  state: Exp;  lines: +20 -14 | 
 | 73 |  * Fix incorrect zpadlen handling in fmtfp. | 
 | 74 |  * Thanks to Ollie Oldham <ollie.oldham@metro-optix.com> for spotting it. | 
 | 75 |  * few mods to make it easier to compile the tests. | 
 | 76 |  * addedd the "Ollie" test to the floating point ones. | 
 | 77 |  * | 
 | 78 |  * Martin Pool (mbp@samba.org) April 2003 | 
 | 79 |  *    Remove NO_CONFIG_H so that the test case can be built within a source | 
 | 80 |  *    tree with less trouble. | 
 | 81 |  *    Remove unnecessary SAFE_FREE() definition. | 
 | 82 |  * | 
 | 83 |  * Martin Pool (mbp@samba.org) May 2003 | 
 | 84 |  *    Put in a prototype for dummy_snprintf() to quiet compiler warnings. | 
 | 85 |  * | 
 | 86 |  *    Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even | 
 | 87 |  *    if the C library has some snprintf functions already. | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 88 |  * | 
 | 89 |  * Damien Miller (djm@mindrot.org) Jan 2007 | 
 | 90 |  *    Fix integer overflows in return value. | 
 | 91 |  *    Make formatting quite a bit faster by inlining dopr_outch() | 
 | 92 |  * | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 93 |  **************************************************************/ | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 94 |  | 
| Damien Miller | e9cf357 | 2001-02-09 12:55:35 +1100 | [diff] [blame] | 95 | #include "includes.h" | 
 | 96 |  | 
| Ben Lindstrom | 63941f9 | 2001-02-25 23:20:40 +0000 | [diff] [blame] | 97 | #if defined(BROKEN_SNPRINTF)		/* For those with broken snprintf() */ | 
 | 98 | # undef HAVE_SNPRINTF | 
 | 99 | # undef HAVE_VSNPRINTF | 
 | 100 | #endif | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 101 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 102 | #ifndef VA_COPY | 
 | 103 | # ifdef HAVE_VA_COPY | 
 | 104 | #  define VA_COPY(dest, src) va_copy(dest, src) | 
 | 105 | # else | 
 | 106 | #  ifdef HAVE___VA_COPY | 
 | 107 | #   define VA_COPY(dest, src) __va_copy(dest, src) | 
 | 108 | #  else | 
 | 109 | #   define VA_COPY(dest, src) (dest) = (src) | 
 | 110 | #  endif | 
 | 111 | # endif | 
 | 112 | #endif | 
 | 113 |  | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 114 | #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 115 |  | 
| Darren Tucker | f78fb54 | 2006-08-06 21:25:24 +1000 | [diff] [blame] | 116 | #include <ctype.h> | 
| Darren Tucker | 08432d5 | 2006-09-09 15:59:43 +1000 | [diff] [blame] | 117 | #include <stdarg.h> | 
| Darren Tucker | f78fb54 | 2006-08-06 21:25:24 +1000 | [diff] [blame] | 118 | #include <stdlib.h> | 
| Damien Miller | 62da44f | 2006-07-24 15:08:35 +1000 | [diff] [blame] | 119 | #include <string.h> | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 120 | #include <limits.h> | 
 | 121 | #include <errno.h> | 
| Damien Miller | 62da44f | 2006-07-24 15:08:35 +1000 | [diff] [blame] | 122 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 123 | #ifdef HAVE_LONG_DOUBLE | 
 | 124 | # define LDOUBLE long double | 
 | 125 | #else | 
 | 126 | # define LDOUBLE double | 
 | 127 | #endif | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 128 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 129 | #ifdef HAVE_LONG_LONG | 
 | 130 | # define LLONG long long | 
 | 131 | #else | 
 | 132 | # define LLONG long | 
 | 133 | #endif | 
| Ben Lindstrom | 116b6bd | 2001-02-13 14:05:59 +0000 | [diff] [blame] | 134 |  | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 135 | /* | 
 | 136 |  * dopr(): poor man's version of doprintf | 
 | 137 |  */ | 
 | 138 |  | 
 | 139 | /* format read states */ | 
 | 140 | #define DP_S_DEFAULT 0 | 
 | 141 | #define DP_S_FLAGS   1 | 
 | 142 | #define DP_S_MIN     2 | 
 | 143 | #define DP_S_DOT     3 | 
 | 144 | #define DP_S_MAX     4 | 
 | 145 | #define DP_S_MOD     5 | 
 | 146 | #define DP_S_CONV    6 | 
 | 147 | #define DP_S_DONE    7 | 
 | 148 |  | 
 | 149 | /* format flags - Bits */ | 
 | 150 | #define DP_F_MINUS 	(1 << 0) | 
 | 151 | #define DP_F_PLUS  	(1 << 1) | 
 | 152 | #define DP_F_SPACE 	(1 << 2) | 
 | 153 | #define DP_F_NUM   	(1 << 3) | 
 | 154 | #define DP_F_ZERO  	(1 << 4) | 
 | 155 | #define DP_F_UP    	(1 << 5) | 
 | 156 | #define DP_F_UNSIGNED 	(1 << 6) | 
 | 157 |  | 
 | 158 | /* Conversion Flags */ | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 159 | #define DP_C_SHORT   1 | 
 | 160 | #define DP_C_LONG    2 | 
 | 161 | #define DP_C_LDOUBLE 3 | 
 | 162 | #define DP_C_LLONG   4 | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 163 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 164 | #define char_to_int(p) ((p)- '0') | 
 | 165 | #ifndef MAX | 
 | 166 | # define MAX(p,q) (((p) >= (q)) ? (p) : (q)) | 
 | 167 | #endif | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 168 |  | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 169 | #define DOPR_OUTCH(buf, pos, buflen, thechar) \ | 
 | 170 | 	do { \ | 
| Darren Tucker | 07877ca | 2007-01-24 00:07:29 +1100 | [diff] [blame^] | 171 | 		if (pos + 1 >= INT_MAX) { \ | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 172 | 			errno = ERANGE; \ | 
 | 173 | 			return -1; \ | 
| Darren Tucker | 07877ca | 2007-01-24 00:07:29 +1100 | [diff] [blame^] | 174 | 		} \ | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 175 | 		if (pos < buflen) \ | 
 | 176 | 			buf[pos] = thechar; \ | 
| Darren Tucker | 07877ca | 2007-01-24 00:07:29 +1100 | [diff] [blame^] | 177 | 		(pos)++; \ | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 178 | 	} while (0) | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 179 |  | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 180 | static int dopr(char *buffer, size_t maxlen, const char *format,  | 
 | 181 |     va_list args_in); | 
 | 182 | static int fmtstr(char *buffer, size_t *currlen, size_t maxlen, | 
 | 183 |     char *value, int flags, int min, int max); | 
 | 184 | static int fmtint(char *buffer, size_t *currlen, size_t maxlen, | 
 | 185 |     LLONG value, int base, int min, int max, int flags); | 
 | 186 | static int fmtfp(char *buffer, size_t *currlen, size_t maxlen, | 
 | 187 |     LDOUBLE fvalue, int min, int max, int flags); | 
 | 188 |  | 
 | 189 | static int | 
 | 190 | dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) | 
| Damien Miller | 13bc0be | 1999-12-28 10:19:16 +1100 | [diff] [blame] | 191 | { | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 192 | 	char ch; | 
 | 193 | 	LLONG value; | 
 | 194 | 	LDOUBLE fvalue; | 
 | 195 | 	char *strvalue; | 
 | 196 | 	int min; | 
 | 197 | 	int max; | 
 | 198 | 	int state; | 
 | 199 | 	int flags; | 
 | 200 | 	int cflags; | 
 | 201 | 	size_t currlen; | 
 | 202 | 	va_list args; | 
| Damien Miller | 13bc0be | 1999-12-28 10:19:16 +1100 | [diff] [blame] | 203 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 204 | 	VA_COPY(args, args_in); | 
 | 205 | 	 | 
 | 206 | 	state = DP_S_DEFAULT; | 
 | 207 | 	currlen = flags = cflags = min = 0; | 
 | 208 | 	max = -1; | 
 | 209 | 	ch = *format++; | 
 | 210 | 	 | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 211 | 	while (state != DP_S_DONE) { | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 212 | 		if (ch == '\0')  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 213 | 			state = DP_S_DONE; | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 214 |  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 215 | 		switch(state) { | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 216 | 		case DP_S_DEFAULT: | 
 | 217 | 			if (ch == '%')  | 
 | 218 | 				state = DP_S_FLAGS; | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 219 | 			else | 
 | 220 | 				DOPR_OUTCH(buffer, currlen, maxlen, ch); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 221 | 			ch = *format++; | 
 | 222 | 			break; | 
 | 223 | 		case DP_S_FLAGS: | 
 | 224 | 			switch (ch) { | 
 | 225 | 			case '-': | 
 | 226 | 				flags |= DP_F_MINUS; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 227 | 				ch = *format++; | 
 | 228 | 				break; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 229 | 			case '+': | 
 | 230 | 				flags |= DP_F_PLUS; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 231 | 				ch = *format++; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 232 | 				break; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 233 | 			case ' ': | 
 | 234 | 				flags |= DP_F_SPACE; | 
 | 235 | 				ch = *format++; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 236 | 				break; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 237 | 			case '#': | 
 | 238 | 				flags |= DP_F_NUM; | 
 | 239 | 				ch = *format++; | 
 | 240 | 				break; | 
 | 241 | 			case '0': | 
 | 242 | 				flags |= DP_F_ZERO; | 
 | 243 | 				ch = *format++; | 
 | 244 | 				break; | 
 | 245 | 			default: | 
 | 246 | 				state = DP_S_MIN; | 
 | 247 | 				break; | 
 | 248 | 			} | 
 | 249 | 			break; | 
 | 250 | 		case DP_S_MIN: | 
 | 251 | 			if (isdigit((unsigned char)ch)) { | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 252 | 				min = 10*min + char_to_int (ch); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 253 | 				ch = *format++; | 
 | 254 | 			} else if (ch == '*') { | 
 | 255 | 				min = va_arg (args, int); | 
 | 256 | 				ch = *format++; | 
 | 257 | 				state = DP_S_DOT; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 258 | 			} else { | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 259 | 				state = DP_S_DOT; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 260 | 			} | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 261 | 			break; | 
 | 262 | 		case DP_S_DOT: | 
 | 263 | 			if (ch == '.') { | 
 | 264 | 				state = DP_S_MAX; | 
 | 265 | 				ch = *format++; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 266 | 			} else {  | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 267 | 				state = DP_S_MOD; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 268 | 			} | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 269 | 			break; | 
 | 270 | 		case DP_S_MAX: | 
 | 271 | 			if (isdigit((unsigned char)ch)) { | 
 | 272 | 				if (max < 0) | 
 | 273 | 					max = 0; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 274 | 				max = 10*max + char_to_int (ch); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 275 | 				ch = *format++; | 
 | 276 | 			} else if (ch == '*') { | 
 | 277 | 				max = va_arg (args, int); | 
 | 278 | 				ch = *format++; | 
 | 279 | 				state = DP_S_MOD; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 280 | 			} else { | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 281 | 				state = DP_S_MOD; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 282 | 			} | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 283 | 			break; | 
 | 284 | 		case DP_S_MOD: | 
 | 285 | 			switch (ch) { | 
 | 286 | 			case 'h': | 
 | 287 | 				cflags = DP_C_SHORT; | 
 | 288 | 				ch = *format++; | 
 | 289 | 				break; | 
 | 290 | 			case 'l': | 
 | 291 | 				cflags = DP_C_LONG; | 
 | 292 | 				ch = *format++; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 293 | 				if (ch == 'l') {	/* It's a long long */ | 
 | 294 | 					cflags = DP_C_LLONG; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 295 | 					ch = *format++; | 
 | 296 | 				} | 
 | 297 | 				break; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 298 | 			case 'L': | 
 | 299 | 				cflags = DP_C_LDOUBLE; | 
 | 300 | 				ch = *format++; | 
 | 301 | 				break; | 
 | 302 | 			default: | 
 | 303 | 				break; | 
 | 304 | 			} | 
 | 305 | 			state = DP_S_CONV; | 
 | 306 | 			break; | 
 | 307 | 		case DP_S_CONV: | 
 | 308 | 			switch (ch) { | 
 | 309 | 			case 'd': | 
 | 310 | 			case 'i': | 
 | 311 | 				if (cflags == DP_C_SHORT)  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 312 | 					value = va_arg (args, int); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 313 | 				else if (cflags == DP_C_LONG) | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 314 | 					value = va_arg (args, long int); | 
 | 315 | 				else if (cflags == DP_C_LLONG) | 
 | 316 | 					value = va_arg (args, LLONG); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 317 | 				else | 
 | 318 | 					value = va_arg (args, int); | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 319 | 				if (fmtint(buffer, &currlen, maxlen, | 
 | 320 | 				    value, 10, min, max, flags) == -1) | 
 | 321 | 					return -1; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 322 | 				break; | 
 | 323 | 			case 'o': | 
 | 324 | 				flags |= DP_F_UNSIGNED; | 
 | 325 | 				if (cflags == DP_C_SHORT) | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 326 | 					value = va_arg (args, unsigned int); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 327 | 				else if (cflags == DP_C_LONG) | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 328 | 					value = (long)va_arg (args, unsigned long int); | 
 | 329 | 				else if (cflags == DP_C_LLONG) | 
 | 330 | 					value = (long)va_arg (args, unsigned LLONG); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 331 | 				else | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 332 | 					value = (long)va_arg (args, unsigned int); | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 333 | 				if (fmtint(buffer, &currlen, maxlen, value, | 
 | 334 | 				    8, min, max, flags) == -1) | 
 | 335 | 					return -1; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 336 | 				break; | 
 | 337 | 			case 'u': | 
 | 338 | 				flags |= DP_F_UNSIGNED; | 
 | 339 | 				if (cflags == DP_C_SHORT) | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 340 | 					value = va_arg (args, unsigned int); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 341 | 				else if (cflags == DP_C_LONG) | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 342 | 					value = (long)va_arg (args, unsigned long int); | 
 | 343 | 				else if (cflags == DP_C_LLONG) | 
 | 344 | 					value = (LLONG)va_arg (args, unsigned LLONG); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 345 | 				else | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 346 | 					value = (long)va_arg (args, unsigned int); | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 347 | 				if (fmtint(buffer, &currlen, maxlen, value, | 
 | 348 | 				    10, min, max, flags) == -1) | 
 | 349 | 					return -1; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 350 | 				break; | 
 | 351 | 			case 'X': | 
 | 352 | 				flags |= DP_F_UP; | 
 | 353 | 			case 'x': | 
 | 354 | 				flags |= DP_F_UNSIGNED; | 
 | 355 | 				if (cflags == DP_C_SHORT) | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 356 | 					value = va_arg (args, unsigned int); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 357 | 				else if (cflags == DP_C_LONG) | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 358 | 					value = (long)va_arg (args, unsigned long int); | 
 | 359 | 				else if (cflags == DP_C_LLONG) | 
 | 360 | 					value = (LLONG)va_arg (args, unsigned LLONG); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 361 | 				else | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 362 | 					value = (long)va_arg (args, unsigned int); | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 363 | 				if (fmtint(buffer, &currlen, maxlen, value, | 
 | 364 | 				    16, min, max, flags) == -1) | 
 | 365 | 					return -1; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 366 | 				break; | 
 | 367 | 			case 'f': | 
 | 368 | 				if (cflags == DP_C_LDOUBLE) | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 369 | 					fvalue = va_arg (args, LDOUBLE); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 370 | 				else | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 371 | 					fvalue = va_arg (args, double); | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 372 | 				if (fmtfp(buffer, &currlen, maxlen, fvalue, | 
 | 373 | 				    min, max, flags) == -1) | 
 | 374 | 					return -1; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 375 | 				break; | 
 | 376 | 			case 'E': | 
 | 377 | 				flags |= DP_F_UP; | 
 | 378 | 			case 'e': | 
 | 379 | 				if (cflags == DP_C_LDOUBLE) | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 380 | 					fvalue = va_arg (args, LDOUBLE); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 381 | 				else | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 382 | 					fvalue = va_arg (args, double); | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 383 | 				if (fmtfp(buffer, &currlen, maxlen, fvalue, | 
 | 384 | 				    min, max, flags) == -1) | 
 | 385 | 					return -1; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 386 | 				break; | 
 | 387 | 			case 'G': | 
 | 388 | 				flags |= DP_F_UP; | 
 | 389 | 			case 'g': | 
 | 390 | 				if (cflags == DP_C_LDOUBLE) | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 391 | 					fvalue = va_arg (args, LDOUBLE); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 392 | 				else | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 393 | 					fvalue = va_arg (args, double); | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 394 | 				if (fmtfp(buffer, &currlen, maxlen, fvalue, | 
 | 395 | 				    min, max, flags) == -1) | 
 | 396 | 					return -1; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 397 | 				break; | 
 | 398 | 			case 'c': | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 399 | 				DOPR_OUTCH(buffer, currlen, maxlen, | 
 | 400 | 				    va_arg (args, int)); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 401 | 				break; | 
 | 402 | 			case 's': | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 403 | 				strvalue = va_arg (args, char *); | 
 | 404 | 				if (!strvalue) strvalue = "(NULL)"; | 
 | 405 | 				if (max == -1) { | 
 | 406 | 					max = strlen(strvalue); | 
 | 407 | 				} | 
 | 408 | 				if (min > 0 && max >= 0 && min > max) max = min; | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 409 | 				if (fmtstr(buffer, &currlen, maxlen, | 
 | 410 | 				    strvalue, flags, min, max) == -1) | 
 | 411 | 					return -1; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 412 | 				break; | 
 | 413 | 			case 'p': | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 414 | 				strvalue = va_arg (args, void *); | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 415 | 				if (fmtint(buffer, &currlen, maxlen, | 
 | 416 | 				    (long) strvalue, 16, min, max, flags) == -1) | 
 | 417 | 					return -1; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 418 | 				break; | 
 | 419 | 			case 'n': | 
 | 420 | 				if (cflags == DP_C_SHORT) { | 
 | 421 | 					short int *num; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 422 | 					num = va_arg (args, short int *); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 423 | 					*num = currlen; | 
 | 424 | 				} else if (cflags == DP_C_LONG) { | 
 | 425 | 					long int *num; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 426 | 					num = va_arg (args, long int *); | 
 | 427 | 					*num = (long int)currlen; | 
 | 428 | 				} else if (cflags == DP_C_LLONG) { | 
 | 429 | 					LLONG *num; | 
 | 430 | 					num = va_arg (args, LLONG *); | 
 | 431 | 					*num = (LLONG)currlen; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 432 | 				} else { | 
 | 433 | 					int *num; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 434 | 					num = va_arg (args, int *); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 435 | 					*num = currlen; | 
 | 436 | 				} | 
 | 437 | 				break; | 
 | 438 | 			case '%': | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 439 | 				DOPR_OUTCH(buffer, currlen, maxlen, ch); | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 440 | 				break; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 441 | 			case 'w': | 
 | 442 | 				/* not supported yet, treat as next char */ | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 443 | 				ch = *format++; | 
 | 444 | 				break; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 445 | 			default: | 
 | 446 | 				/* Unknown, skip */ | 
 | 447 | 				break; | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 448 | 			} | 
 | 449 | 			ch = *format++; | 
 | 450 | 			state = DP_S_DEFAULT; | 
 | 451 | 			flags = cflags = min = 0; | 
 | 452 | 			max = -1; | 
 | 453 | 			break; | 
 | 454 | 		case DP_S_DONE: | 
 | 455 | 			break; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 456 | 		default: | 
 | 457 | 			/* hmm? */ | 
| Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 458 | 			break; /* some picky compilers need this */ | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 459 | 		} | 
 | 460 | 	} | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 461 | 	if (maxlen != 0) { | 
 | 462 | 		if (currlen < maxlen - 1)  | 
 | 463 | 			buffer[currlen] = '\0'; | 
 | 464 | 		else if (maxlen > 0)  | 
 | 465 | 			buffer[maxlen - 1] = '\0'; | 
 | 466 | 	} | 
 | 467 | 	 | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 468 | 	return currlen < INT_MAX ? (int)currlen : -1; | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 469 | } | 
 | 470 |  | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 471 | static int | 
 | 472 | fmtstr(char *buffer, size_t *currlen, size_t maxlen, | 
 | 473 |     char *value, int flags, int min, int max) | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 474 | { | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 475 | 	int padlen, strln;     /* amount to pad */ | 
 | 476 | 	int cnt = 0; | 
 | 477 |  | 
 | 478 | #ifdef DEBUG_SNPRINTF | 
 | 479 | 	printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); | 
 | 480 | #endif | 
 | 481 | 	if (value == 0) { | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 482 | 		value = "<NULL>"; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 483 | 	} | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 484 |  | 
| Darren Tucker | 4127f55 | 2004-09-23 21:35:09 +1000 | [diff] [blame] | 485 | 	for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */ | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 486 | 	padlen = min - strln; | 
 | 487 | 	if (padlen < 0)  | 
 | 488 | 		padlen = 0; | 
 | 489 | 	if (flags & DP_F_MINUS)  | 
 | 490 | 		padlen = -padlen; /* Left Justify */ | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 491 | 	 | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 492 | 	while ((padlen > 0) && (cnt < max)) { | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 493 | 		DOPR_OUTCH(buffer, *currlen, maxlen, ' '); | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 494 | 		--padlen; | 
 | 495 | 		++cnt; | 
 | 496 | 	} | 
 | 497 | 	while (*value && (cnt < max)) { | 
| Darren Tucker | 07877ca | 2007-01-24 00:07:29 +1100 | [diff] [blame^] | 498 | 		DOPR_OUTCH(buffer, *currlen, maxlen, *value); | 
 | 499 | 		*value++; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 500 | 		++cnt; | 
 | 501 | 	} | 
 | 502 | 	while ((padlen < 0) && (cnt < max)) { | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 503 | 		DOPR_OUTCH(buffer, *currlen, maxlen, ' '); | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 504 | 		++padlen; | 
 | 505 | 		++cnt; | 
 | 506 | 	} | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 507 | 	return 0; | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 508 | } | 
 | 509 |  | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 510 | /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ | 
 | 511 |  | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 512 | static int | 
 | 513 | fmtint(char *buffer, size_t *currlen, size_t maxlen, | 
| Darren Tucker | 9834cab | 2006-03-19 00:07:07 +1100 | [diff] [blame] | 514 | 		    LLONG value, int base, int min, int max, int flags) | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 515 | { | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 516 | 	int signvalue = 0; | 
| Darren Tucker | 9834cab | 2006-03-19 00:07:07 +1100 | [diff] [blame] | 517 | 	unsigned LLONG uvalue; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 518 | 	char convert[20]; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 519 | 	int place = 0; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 520 | 	int spadlen = 0; /* amount to space pad */ | 
 | 521 | 	int zpadlen = 0; /* amount to zero pad */ | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 522 | 	int caps = 0; | 
 | 523 | 	 | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 524 | 	if (max < 0) | 
 | 525 | 		max = 0; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 526 | 	 | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 527 | 	uvalue = value; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 528 | 	 | 
 | 529 | 	if(!(flags & DP_F_UNSIGNED)) { | 
 | 530 | 		if( value < 0 ) { | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 531 | 			signvalue = '-'; | 
 | 532 | 			uvalue = -value; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 533 | 		} else { | 
 | 534 | 			if (flags & DP_F_PLUS)  /* Do a sign (+/i) */ | 
 | 535 | 				signvalue = '+'; | 
 | 536 | 			else if (flags & DP_F_SPACE) | 
 | 537 | 				signvalue = ' '; | 
 | 538 | 		} | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 539 | 	} | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 540 |    | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 541 | 	if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ | 
 | 542 |  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 543 | 	do { | 
 | 544 | 		convert[place++] = | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 545 | 			(caps? "0123456789ABCDEF":"0123456789abcdef") | 
 | 546 | 			[uvalue % (unsigned)base  ]; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 547 | 		uvalue = (uvalue / (unsigned)base ); | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 548 | 	} while(uvalue && (place < 20)); | 
 | 549 | 	if (place == 20) place--; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 550 | 	convert[place] = 0; | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 551 |  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 552 | 	zpadlen = max - place; | 
 | 553 | 	spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 554 | 	if (zpadlen < 0) zpadlen = 0; | 
 | 555 | 	if (spadlen < 0) spadlen = 0; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 556 | 	if (flags & DP_F_ZERO) { | 
 | 557 | 		zpadlen = MAX(zpadlen, spadlen); | 
 | 558 | 		spadlen = 0; | 
 | 559 | 	} | 
 | 560 | 	if (flags & DP_F_MINUS)  | 
 | 561 | 		spadlen = -spadlen; /* Left Justifty */ | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 562 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 563 | #ifdef DEBUG_SNPRINTF | 
 | 564 | 	printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", | 
 | 565 | 	       zpadlen, spadlen, min, max, place); | 
 | 566 | #endif | 
 | 567 |  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 568 | 	/* Spaces */ | 
 | 569 | 	while (spadlen > 0) { | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 570 | 		DOPR_OUTCH(buffer, *currlen, maxlen, ' '); | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 571 | 		--spadlen; | 
 | 572 | 	} | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 573 |  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 574 | 	/* Sign */ | 
 | 575 | 	if (signvalue)  | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 576 | 		DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 577 |  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 578 | 	/* Zeros */ | 
 | 579 | 	if (zpadlen > 0) { | 
 | 580 | 		while (zpadlen > 0) { | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 581 | 			DOPR_OUTCH(buffer, *currlen, maxlen, '0'); | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 582 | 			--zpadlen; | 
 | 583 | 		} | 
 | 584 | 	} | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 585 |  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 586 | 	/* Digits */ | 
| Darren Tucker | 07877ca | 2007-01-24 00:07:29 +1100 | [diff] [blame^] | 587 | 	while (place > 0) { | 
 | 588 | 		--place; | 
 | 589 | 		DOPR_OUTCH(buffer, *currlen, maxlen, convert[place]); | 
 | 590 | 	} | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 591 |    | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 592 | 	/* Left Justified spaces */ | 
 | 593 | 	while (spadlen < 0) { | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 594 | 		DOPR_OUTCH(buffer, *currlen, maxlen, ' '); | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 595 | 		++spadlen; | 
 | 596 | 	} | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 597 | 	return 0; | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 598 | } | 
 | 599 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 600 | static LDOUBLE abs_val(LDOUBLE value) | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 601 | { | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 602 | 	LDOUBLE result = value; | 
| Damien Miller | 42b81ff | 1999-11-26 12:21:24 +1100 | [diff] [blame] | 603 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 604 | 	if (value < 0) | 
 | 605 | 		result = -value; | 
 | 606 | 	 | 
 | 607 | 	return result; | 
 | 608 | } | 
 | 609 |  | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 610 | static LDOUBLE POW10(int val) | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 611 | { | 
 | 612 | 	LDOUBLE result = 1; | 
 | 613 | 	 | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 614 | 	while (val) { | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 615 | 		result *= 10; | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 616 | 		val--; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 617 | 	} | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 618 |    | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 619 | 	return result; | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 620 | } | 
 | 621 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 622 | static LLONG ROUND(LDOUBLE value) | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 623 | { | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 624 | 	LLONG intpart; | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 625 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 626 | 	intpart = (LLONG)value; | 
 | 627 | 	value = value - intpart; | 
 | 628 | 	if (value >= 0.5) intpart++; | 
 | 629 | 	 | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 630 | 	return intpart; | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 631 | } | 
 | 632 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 633 | /* a replacement for modf that doesn't need the math library. Should | 
 | 634 |    be portable, but slow */ | 
 | 635 | static double my_modf(double x0, double *iptr) | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 636 | { | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 637 | 	int i; | 
 | 638 | 	long l; | 
 | 639 | 	double x = x0; | 
 | 640 | 	double f = 1.0; | 
 | 641 |  | 
 | 642 | 	for (i=0;i<100;i++) { | 
 | 643 | 		l = (long)x; | 
 | 644 | 		if (l <= (x+1) && l >= (x-1)) break; | 
 | 645 | 		x *= 0.1; | 
 | 646 | 		f *= 10.0; | 
 | 647 | 	} | 
 | 648 |  | 
 | 649 | 	if (i == 100) { | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 650 | 		/* | 
 | 651 | 		 * yikes! the number is beyond what we can handle. | 
 | 652 | 		 * What do we do? | 
 | 653 | 		 */ | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 654 | 		(*iptr) = 0; | 
 | 655 | 		return 0; | 
 | 656 | 	} | 
 | 657 |  | 
 | 658 | 	if (i != 0) { | 
 | 659 | 		double i2; | 
 | 660 | 		double ret; | 
 | 661 |  | 
 | 662 | 		ret = my_modf(x0-l*f, &i2); | 
 | 663 | 		(*iptr) = l*f + i2; | 
 | 664 | 		return ret; | 
 | 665 | 	}  | 
 | 666 |  | 
 | 667 | 	(*iptr) = l; | 
 | 668 | 	return x - (*iptr); | 
 | 669 | } | 
 | 670 |  | 
 | 671 |  | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 672 | static int | 
 | 673 | fmtfp (char *buffer, size_t *currlen, size_t maxlen, | 
 | 674 |     LDOUBLE fvalue, int min, int max, int flags) | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 675 | { | 
 | 676 | 	int signvalue = 0; | 
 | 677 | 	double ufvalue; | 
 | 678 | 	char iconvert[311]; | 
 | 679 | 	char fconvert[311]; | 
 | 680 | 	int iplace = 0; | 
 | 681 | 	int fplace = 0; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 682 | 	int padlen = 0; /* amount to pad */ | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 683 | 	int zpadlen = 0;  | 
 | 684 | 	int caps = 0; | 
 | 685 | 	int idx; | 
 | 686 | 	double intpart; | 
 | 687 | 	double fracpart; | 
 | 688 | 	double temp; | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 689 |    | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 690 | 	/*  | 
 | 691 | 	 * AIX manpage says the default is 0, but Solaris says the default | 
 | 692 | 	 * is 6, and sprintf on AIX defaults to 6 | 
 | 693 | 	 */ | 
 | 694 | 	if (max < 0) | 
 | 695 | 		max = 6; | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 696 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 697 | 	ufvalue = abs_val (fvalue); | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 698 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 699 | 	if (fvalue < 0) { | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 700 | 		signvalue = '-'; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 701 | 	} else { | 
 | 702 | 		if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ | 
 | 703 | 			signvalue = '+'; | 
 | 704 | 		} else { | 
 | 705 | 			if (flags & DP_F_SPACE) | 
 | 706 | 				signvalue = ' '; | 
 | 707 | 		} | 
 | 708 | 	} | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 709 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 710 | #if 0 | 
 | 711 | 	if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ | 
 | 712 | #endif | 
 | 713 |  | 
 | 714 | #if 0 | 
 | 715 | 	 if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ | 
 | 716 | #endif | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 717 |  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 718 | 	/*  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 719 | 	 * Sorry, we only support 16 digits past the decimal because of our  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 720 | 	 * conversion method | 
 | 721 | 	 */ | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 722 | 	if (max > 16) | 
 | 723 | 		max = 16; | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 724 |  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 725 | 	/* We "cheat" by converting the fractional part to integer by | 
 | 726 | 	 * multiplying by a factor of 10 | 
 | 727 | 	 */ | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 728 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 729 | 	temp = ufvalue; | 
 | 730 | 	my_modf(temp, &intpart); | 
 | 731 |  | 
 | 732 | 	fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); | 
 | 733 | 	 | 
 | 734 | 	if (fracpart >= POW10(max)) { | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 735 | 		intpart++; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 736 | 		fracpart -= POW10(max); | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 737 | 	} | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 738 |  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 739 | 	/* Convert integer part */ | 
 | 740 | 	do { | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 741 | 		temp = intpart*0.1; | 
 | 742 | 		my_modf(temp, &intpart); | 
 | 743 | 		idx = (int) ((temp -intpart +0.05)* 10.0); | 
 | 744 | 		/* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ | 
 | 745 | 		/* printf ("%llf, %f, %x\n", temp, intpart, idx); */ | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 746 | 		iconvert[iplace++] = | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 747 | 			(caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; | 
 | 748 | 	} while (intpart && (iplace < 311)); | 
 | 749 | 	if (iplace == 311) iplace--; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 750 | 	iconvert[iplace] = 0; | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 751 |  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 752 | 	/* Convert fractional part */ | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 753 | 	if (fracpart) | 
 | 754 | 	{ | 
 | 755 | 		do { | 
 | 756 | 			temp = fracpart*0.1; | 
 | 757 | 			my_modf(temp, &fracpart); | 
 | 758 | 			idx = (int) ((temp -fracpart +0.05)* 10.0); | 
 | 759 | 			/* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */ | 
 | 760 | 			/* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */ | 
 | 761 | 			fconvert[fplace++] = | 
 | 762 | 			(caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; | 
 | 763 | 		} while(fracpart && (fplace < 311)); | 
 | 764 | 		if (fplace == 311) fplace--; | 
 | 765 | 	} | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 766 | 	fconvert[fplace] = 0; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 767 |    | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 768 | 	/* -1 for decimal point, another -1 if we are printing a sign */ | 
 | 769 | 	padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);  | 
 | 770 | 	zpadlen = max - fplace; | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 771 | 	if (zpadlen < 0) zpadlen = 0; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 772 | 	if (padlen < 0)  | 
 | 773 | 		padlen = 0; | 
 | 774 | 	if (flags & DP_F_MINUS)  | 
 | 775 | 		padlen = -padlen; /* Left Justifty */ | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 776 | 	 | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 777 | 	if ((flags & DP_F_ZERO) && (padlen > 0)) { | 
 | 778 | 		if (signvalue) { | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 779 | 			DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 780 | 			--padlen; | 
 | 781 | 			signvalue = 0; | 
 | 782 | 		} | 
 | 783 | 		while (padlen > 0) { | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 784 | 			DOPR_OUTCH(buffer, *currlen, maxlen, '0'); | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 785 | 			--padlen; | 
 | 786 | 		} | 
 | 787 | 	} | 
 | 788 | 	while (padlen > 0) { | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 789 | 		DOPR_OUTCH(buffer, *currlen, maxlen, ' '); | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 790 | 		--padlen; | 
 | 791 | 	} | 
 | 792 | 	if (signvalue)  | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 793 | 		DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 794 | 	 | 
| Darren Tucker | 07877ca | 2007-01-24 00:07:29 +1100 | [diff] [blame^] | 795 | 	while (iplace > 0) { | 
 | 796 | 		--iplace; | 
 | 797 | 		DOPR_OUTCH(buffer, *currlen, maxlen, iconvert[iplace]); | 
 | 798 | 	} | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 799 |  | 
 | 800 | #ifdef DEBUG_SNPRINTF | 
 | 801 | 	printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); | 
 | 802 | #endif | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 803 |  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 804 | 	/* | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 805 | 	 * Decimal point.  This should probably use locale to find the correct | 
 | 806 | 	 * char to print out. | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 807 | 	 */ | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 808 | 	if (max > 0) { | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 809 | 		DOPR_OUTCH(buffer, *currlen, maxlen, '.'); | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 810 | 		 | 
 | 811 | 		while (zpadlen > 0) { | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 812 | 			DOPR_OUTCH(buffer, *currlen, maxlen, '0'); | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 813 | 			--zpadlen; | 
 | 814 | 		} | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 815 |  | 
| Darren Tucker | 07877ca | 2007-01-24 00:07:29 +1100 | [diff] [blame^] | 816 | 		while (fplace > 0) { | 
 | 817 | 			--fplace; | 
 | 818 | 			DOPR_OUTCH(buffer, *currlen, maxlen, fconvert[fplace]); | 
 | 819 | 		} | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 820 | 	} | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 821 |  | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 822 | 	while (padlen < 0) { | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 823 | 		DOPR_OUTCH(buffer, *currlen, maxlen, ' '); | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 824 | 		++padlen; | 
 | 825 | 	} | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 826 | 	return 0; | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 827 | } | 
 | 828 | #endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ | 
 | 829 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 830 | #if !defined(HAVE_VSNPRINTF) | 
| Darren Tucker | 07877ca | 2007-01-24 00:07:29 +1100 | [diff] [blame^] | 831 | int | 
| Damien Miller | 742cc1c | 2007-01-14 21:20:30 +1100 | [diff] [blame] | 832 | vsnprintf (char *str, size_t count, const char *fmt, va_list args) | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 833 | { | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 834 | 	return dopr(str, count, fmt, args); | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 835 | } | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 836 | #endif | 
| Damien Miller | 168e6ac | 2000-07-11 12:23:01 +1000 | [diff] [blame] | 837 |  | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 838 | #if !defined(HAVE_SNPRINTF) | 
| Darren Tucker | 07877ca | 2007-01-24 00:07:29 +1100 | [diff] [blame^] | 839 | int | 
 | 840 | snprintf(char *str, size_t count, SNPRINTF_CONST char *fmt, ...) | 
| Damien Miller | c6b3bbe | 1999-12-13 08:27:33 +1100 | [diff] [blame] | 841 | { | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 842 | 	size_t ret; | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 843 | 	va_list ap; | 
 | 844 |  | 
 | 845 | 	va_start(ap, fmt); | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 846 | 	ret = vsnprintf(str, count, fmt, ap); | 
| Ben Lindstrom | 6c92dab | 2001-02-13 02:18:50 +0000 | [diff] [blame] | 847 | 	va_end(ap); | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 848 | 	return ret; | 
| Damien Miller | c6b3bbe | 1999-12-13 08:27:33 +1100 | [diff] [blame] | 849 | } | 
| Damien Miller | 57f3915 | 2005-11-24 19:58:19 +1100 | [diff] [blame] | 850 | #endif |