11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright Patrick Powell 1995 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This code is based on code written by Patrick Powell (papowell@astart.com) 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * It may be used for any purpose as long as this notice remains intact 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * on all source code distributions 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/************************************************************** 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Original: 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * A bombproof version of doprnt (dopr) included. 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Sigh. This sort of thing is always nasty do deal with. Note that 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the version here does not include floating point... 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * snprintf() is used instead of sprintf() as it does limit checks 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * for string length. This covers a nasty loophole. 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The other functions are there to prevent NULL pointers from 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * causing nast effects. 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * More Recently: 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This was ugly. It is still ugly. I opted out of floating point 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * numbers, but the formatter understands just about everything 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * from the normal C string format, at least as far as I can tell from 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the Solaris 2.5 printf(3S) man page. 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Ok, added some minimal floating point support, which means this 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * probably requires libm on most operating systems. Don't yet 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * support the exponent (e,E) and sigfig (g,G). Also, fmtint() 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * was pretty badly broken, it just wasn't being exercised in ways 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * which showed it, so that's been fixed. Also, formated the code 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * to mutt conventions, and removed dead code left over from the 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * original. Also, there is now a builtin-test, just compile with: 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * and run snprintf for results. 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The PGP code was using unsigned hexadecimal formats. 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Unfortunately, unsigned formats simply didn't work. 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The original code assumed that both snprintf() and vsnprintf() were 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * missing. Some systems only have snprintf() but not vsnprintf(), so 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Andrew Tridgell (tridge@samba.org) Oct 1998 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * fixed handling of %.0f 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * added test for HAVE_LONG_DOUBLE 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * tridge@samba.org, idra@samba.org, April 2001 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * got rid of fcvt code (twas buggy and made testing harder) 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * added C99 semantics 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * date: 2002/12/19 19:56:31; author: herb; state: Exp; lines: +2 -0 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * actually print args for %g and %e 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * date: 2002/06/03 13:37:52; author: jmcd; state: Exp; lines: +8 -0 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Since includes.h isn't included here, VA_COPY has to be defined here. I don't 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * see any include file that is guaranteed to be here, so I'm defining it 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * locally. Fixes AIX and Solaris builds. 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * date: 2002/06/03 03:07:24; author: tridge; state: Exp; lines: +5 -13 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * put the ifdef for HAVE_VA_COPY in one place rather than in lots of 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * functions 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * date: 2002/05/17 14:51:22; author: jmcd; state: Exp; lines: +21 -4 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Fix usage of va_list passed as an arg. Use __va_copy before using it 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * when it exists. 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * date: 2002/04/16 22:38:04; author: idra; state: Exp; lines: +20 -14 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Fix incorrect zpadlen handling in fmtfp. 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Thanks to Ollie Oldham <ollie.oldham@metro-optix.com> for spotting it. 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * few mods to make it easier to compile the tests. 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * addedd the "Ollie" test to the floating point ones. 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Martin Pool (mbp@samba.org) April 2003 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Remove NO_CONFIG_H so that the test case can be built within a source 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * tree with less trouble. 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Remove unnecessary SAFE_FREE() definition. 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Martin Pool (mbp@samba.org) May 2003 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Put in a prototype for dummy_snprintf() to quiet compiler warnings. 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * if the C library has some snprintf functions already. 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Damien Miller (djm@mindrot.org) Jan 2007 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Fix integer overflows in return value. 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Make formatting quite a bit faster by inlining dopr_outch() 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood **************************************************************/ 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# undef HAVE_SNPRINTF 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# undef HAVE_VSNPRINTF 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef VA_COPY 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# ifdef HAVE_VA_COPY 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# define VA_COPY(dest, src) va_copy(dest, src) 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# else 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# ifdef HAVE___VA_COPY 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# define VA_COPY(dest, src) __va_copy(dest, src) 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# else 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# define VA_COPY(dest, src) (dest) = (src) 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# endif 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# endif 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <ctype.h> 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h> 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdlib.h> 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <limits.h> 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h> 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_LONG_DOUBLE 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# define LDOUBLE long double 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# define LDOUBLE double 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_LONG_LONG 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# define LLONG long long 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# define LLONG long 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * dopr(): poor man's version of doprintf 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* format read states */ 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_S_DEFAULT 0 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_S_FLAGS 1 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_S_MIN 2 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_S_DOT 3 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_S_MAX 4 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_S_MOD 5 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_S_CONV 6 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_S_DONE 7 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* format flags - Bits */ 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_F_MINUS (1 << 0) 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_F_PLUS (1 << 1) 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_F_SPACE (1 << 2) 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_F_NUM (1 << 3) 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_F_ZERO (1 << 4) 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_F_UP (1 << 5) 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_F_UNSIGNED (1 << 6) 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Conversion Flags */ 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_C_SHORT 1 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_C_LONG 2 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_C_LDOUBLE 3 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DP_C_LLONG 4 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define char_to_int(p) ((p)- '0') 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef MAX 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# define MAX(p,q) (((p) >= (q)) ? (p) : (q)) 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DOPR_OUTCH(buf, pos, buflen, thechar) \ 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do { \ 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pos + 1 >= INT_MAX) { \ 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood errno = ERANGE; \ 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; \ 1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } \ 1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pos < buflen) \ 1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buf[pos] = thechar; \ 1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (pos)++; \ 1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } while (0) 1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int dopr(char *buffer, size_t maxlen, const char *format, 1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_list args_in); 1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int fmtstr(char *buffer, size_t *currlen, size_t maxlen, 1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *value, int flags, int min, int max); 1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int fmtint(char *buffer, size_t *currlen, size_t maxlen, 1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood LLONG value, int base, int min, int max, int flags); 1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int fmtfp(char *buffer, size_t *currlen, size_t maxlen, 1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood LDOUBLE fvalue, int min, int max, int flags); 1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddopr(char *buffer, size_t maxlen, const char *format, va_list args_in) 1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char ch; 1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood LLONG value; 1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood LDOUBLE fvalue; 1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *strvalue; 1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int min; 1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int max; 1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int state; 1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int flags; 2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int cflags; 2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood size_t currlen; 2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_list args; 2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood VA_COPY(args, args_in); 2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = DP_S_DEFAULT; 2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood currlen = flags = cflags = min = 0; 2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max = -1; 2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (state != DP_S_DONE) { 2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ch == '\0') 2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = DP_S_DONE; 2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch(state) { 2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case DP_S_DEFAULT: 2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ch == '%') 2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = DP_S_FLAGS; 2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, currlen, maxlen, ch); 2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case DP_S_FLAGS: 2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (ch) { 2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case '-': 2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flags |= DP_F_MINUS; 2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case '+': 2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flags |= DP_F_PLUS; 2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case ' ': 2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flags |= DP_F_SPACE; 2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case '#': 2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flags |= DP_F_NUM; 2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case '0': 2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flags |= DP_F_ZERO; 2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = DP_S_MIN; 2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case DP_S_MIN: 2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (isdigit((unsigned char)ch)) { 2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood min = 10*min + char_to_int (ch); 2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (ch == '*') { 2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood min = va_arg (args, int); 2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = DP_S_DOT; 2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = DP_S_DOT; 2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case DP_S_DOT: 2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ch == '.') { 2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = DP_S_MAX; 2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = DP_S_MOD; 2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case DP_S_MAX: 2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (isdigit((unsigned char)ch)) { 2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (max < 0) 2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max = 0; 2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max = 10*max + char_to_int (ch); 2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (ch == '*') { 2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max = va_arg (args, int); 2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = DP_S_MOD; 2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = DP_S_MOD; 2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case DP_S_MOD: 2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (ch) { 2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'h': 2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cflags = DP_C_SHORT; 2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'l': 2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cflags = DP_C_LONG; 2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ch == 'l') { /* It's a long long */ 2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cflags = DP_C_LLONG; 2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'L': 2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cflags = DP_C_LDOUBLE; 3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = DP_S_CONV; 3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case DP_S_CONV: 3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (ch) { 3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'd': 3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'i': 3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cflags == DP_C_SHORT) 3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = va_arg (args, int); 3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (cflags == DP_C_LONG) 3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = va_arg (args, long int); 3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (cflags == DP_C_LLONG) 3161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = va_arg (args, LLONG); 3171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 3181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = va_arg (args, int); 3191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fmtint(buffer, &currlen, maxlen, 3201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value, 10, min, max, flags) == -1) 3211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 3221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'o': 3241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flags |= DP_F_UNSIGNED; 3251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cflags == DP_C_SHORT) 3261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = va_arg (args, unsigned int); 3271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (cflags == DP_C_LONG) 3281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = (long)va_arg (args, unsigned long int); 3291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (cflags == DP_C_LLONG) 3301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = (long)va_arg (args, unsigned LLONG); 3311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 3321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = (long)va_arg (args, unsigned int); 3331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fmtint(buffer, &currlen, maxlen, value, 3341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8, min, max, flags) == -1) 3351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 3361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'u': 3381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flags |= DP_F_UNSIGNED; 3391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cflags == DP_C_SHORT) 3401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = va_arg (args, unsigned int); 3411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (cflags == DP_C_LONG) 3421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = (long)va_arg (args, unsigned long int); 3431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (cflags == DP_C_LLONG) 3441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = (LLONG)va_arg (args, unsigned LLONG); 3451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 3461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = (long)va_arg (args, unsigned int); 3471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fmtint(buffer, &currlen, maxlen, value, 3481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10, min, max, flags) == -1) 3491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 3501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'X': 3521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flags |= DP_F_UP; 3531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'x': 3541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flags |= DP_F_UNSIGNED; 3551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cflags == DP_C_SHORT) 3561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = va_arg (args, unsigned int); 3571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (cflags == DP_C_LONG) 3581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = (long)va_arg (args, unsigned long int); 3591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (cflags == DP_C_LLONG) 3601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = (LLONG)va_arg (args, unsigned LLONG); 3611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 3621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = (long)va_arg (args, unsigned int); 3631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fmtint(buffer, &currlen, maxlen, value, 3641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16, min, max, flags) == -1) 3651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 3661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'f': 3681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cflags == DP_C_LDOUBLE) 3691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fvalue = va_arg (args, LDOUBLE); 3701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 3711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fvalue = va_arg (args, double); 3721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fmtfp(buffer, &currlen, maxlen, fvalue, 3731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood min, max, flags) == -1) 3741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 3751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'E': 3771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flags |= DP_F_UP; 3781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'e': 3791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cflags == DP_C_LDOUBLE) 3801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fvalue = va_arg (args, LDOUBLE); 3811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 3821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fvalue = va_arg (args, double); 3831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fmtfp(buffer, &currlen, maxlen, fvalue, 3841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood min, max, flags) == -1) 3851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 3861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'G': 3881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flags |= DP_F_UP; 3891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'g': 3901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cflags == DP_C_LDOUBLE) 3911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fvalue = va_arg (args, LDOUBLE); 3921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 3931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fvalue = va_arg (args, double); 3941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fmtfp(buffer, &currlen, maxlen, fvalue, 3951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood min, max, flags) == -1) 3961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 3971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'c': 3991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, currlen, maxlen, 4001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_arg (args, int)); 4011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 's': 4031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strvalue = va_arg (args, char *); 4041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!strvalue) strvalue = "(NULL)"; 4051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (max == -1) { 4061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max = strlen(strvalue); 4071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (min > 0 && max >= 0 && min > max) max = min; 4091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fmtstr(buffer, &currlen, maxlen, 4101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strvalue, flags, min, max) == -1) 4111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 4121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'p': 4141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strvalue = va_arg (args, void *); 4151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fmtint(buffer, &currlen, maxlen, 4161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (long) strvalue, 16, min, max, flags) == -1) 4171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 4181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'n': 4201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cflags == DP_C_SHORT) { 4211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood short int *num; 4221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood num = va_arg (args, short int *); 4231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *num = currlen; 4241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (cflags == DP_C_LONG) { 4251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood long int *num; 4261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood num = va_arg (args, long int *); 4271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *num = (long int)currlen; 4281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (cflags == DP_C_LLONG) { 4291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood LLONG *num; 4301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood num = va_arg (args, LLONG *); 4311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *num = (LLONG)currlen; 4321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 4331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int *num; 4341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood num = va_arg (args, int *); 4351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *num = currlen; 4361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case '%': 4391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, currlen, maxlen, ch); 4401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'w': 4421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* not supported yet, treat as next char */ 4431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 4441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 4461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Unknown, skip */ 4471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *format++; 4501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = DP_S_DEFAULT; 4511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flags = cflags = min = 0; 4521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max = -1; 4531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case DP_S_DONE: 4551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 4571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* hmm? */ 4581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; /* some picky compilers need this */ 4591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (maxlen != 0) { 4621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (currlen < maxlen - 1) 4631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer[currlen] = '\0'; 4641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (maxlen > 0) 4651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer[maxlen - 1] = '\0'; 4661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return currlen < INT_MAX ? (int)currlen : -1; 4691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 4721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodfmtstr(char *buffer, size_t *currlen, size_t maxlen, 4731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *value, int flags, int min, int max) 4741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int padlen, strln; /* amount to pad */ 4761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int cnt = 0; 4771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_SNPRINTF 4791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); 4801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 4811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (value == 0) { 4821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = "<NULL>"; 4831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */ 4861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood padlen = min - strln; 4871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (padlen < 0) 4881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood padlen = 0; 4891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (flags & DP_F_MINUS) 4901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood padlen = -padlen; /* Left Justify */ 4911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while ((padlen > 0) && (cnt < max)) { 4931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, ' '); 4941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood --padlen; 4951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ++cnt; 4961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (*value && (cnt < max)) { 4981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, *value); 4991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *value++; 5001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ++cnt; 5011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while ((padlen < 0) && (cnt < max)) { 5031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, ' '); 5041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ++padlen; 5051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ++cnt; 5061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 5081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 5091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ 5111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 5131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodfmtint(char *buffer, size_t *currlen, size_t maxlen, 5141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood LLONG value, int base, int min, int max, int flags) 5151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 5161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int signvalue = 0; 5171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unsigned LLONG uvalue; 5181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char convert[20]; 5191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int place = 0; 5201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int spadlen = 0; /* amount to space pad */ 5211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int zpadlen = 0; /* amount to zero pad */ 5221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int caps = 0; 5231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (max < 0) 5251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max = 0; 5261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood uvalue = value; 5281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if(!(flags & DP_F_UNSIGNED)) { 5301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if( value < 0 ) { 5311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signvalue = '-'; 5321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood uvalue = -value; 5331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 5341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (flags & DP_F_PLUS) /* Do a sign (+/i) */ 5351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signvalue = '+'; 5361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (flags & DP_F_SPACE) 5371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signvalue = ' '; 5381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ 5421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do { 5441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood convert[place++] = 5451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (caps? "0123456789ABCDEF":"0123456789abcdef") 5461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood [uvalue % (unsigned)base ]; 5471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood uvalue = (uvalue / (unsigned)base ); 5481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } while(uvalue && (place < 20)); 5491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (place == 20) place--; 5501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood convert[place] = 0; 5511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood zpadlen = max - place; 5531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); 5541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (zpadlen < 0) zpadlen = 0; 5551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (spadlen < 0) spadlen = 0; 5561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (flags & DP_F_ZERO) { 5571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood zpadlen = MAX(zpadlen, spadlen); 5581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood spadlen = 0; 5591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (flags & DP_F_MINUS) 5611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood spadlen = -spadlen; /* Left Justifty */ 5621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_SNPRINTF 5641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", 5651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood zpadlen, spadlen, min, max, place); 5661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 5671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Spaces */ 5691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (spadlen > 0) { 5701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, ' '); 5711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood --spadlen; 5721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Sign */ 5751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (signvalue) 5761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); 5771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Zeros */ 5791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (zpadlen > 0) { 5801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (zpadlen > 0) { 5811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, '0'); 5821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood --zpadlen; 5831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Digits */ 5871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (place > 0) { 5881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood --place; 5891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, convert[place]); 5901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Left Justified spaces */ 5931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (spadlen < 0) { 5941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, ' '); 5951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ++spadlen; 5961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 5981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 5991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic LDOUBLE abs_val(LDOUBLE value) 6011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood LDOUBLE result = value; 6031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (value < 0) 6051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood result = -value; 6061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return result; 6081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic LDOUBLE POW10(int val) 6111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood LDOUBLE result = 1; 6131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (val) { 6151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood result *= 10; 6161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood val--; 6171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return result; 6201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic LLONG ROUND(LDOUBLE value) 6231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood LLONG intpart; 6251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood intpart = (LLONG)value; 6271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = value - intpart; 6281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (value >= 0.5) intpart++; 6291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return intpart; 6311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* a replacement for modf that doesn't need the math library. Should 6341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood be portable, but slow */ 6351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic double my_modf(double x0, double *iptr) 6361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 6381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood long l; 6391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood double x = x0; 6401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood double f = 1.0; 6411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i=0;i<100;i++) { 6431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood l = (long)x; 6441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (l <= (x+1) && l >= (x-1)) break; 6451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x *= 0.1; 6461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood f *= 10.0; 6471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i == 100) { 6501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 6511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * yikes! the number is beyond what we can handle. 6521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * What do we do? 6531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 6541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (*iptr) = 0; 6551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 6561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i != 0) { 6591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood double i2; 6601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood double ret; 6611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = my_modf(x0-l*f, &i2); 6631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (*iptr) = l*f + i2; 6641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ret; 6651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (*iptr) = l; 6681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return x - (*iptr); 6691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 6731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodfmtfp (char *buffer, size_t *currlen, size_t maxlen, 6741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood LDOUBLE fvalue, int min, int max, int flags) 6751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int signvalue = 0; 6771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood double ufvalue; 6781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char iconvert[311]; 6791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char fconvert[311]; 6801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int iplace = 0; 6811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int fplace = 0; 6821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int padlen = 0; /* amount to pad */ 6831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int zpadlen = 0; 6841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int caps = 0; 6851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int idx; 6861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood double intpart; 6871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood double fracpart; 6881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood double temp; 6891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 6911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * AIX manpage says the default is 0, but Solaris says the default 6921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * is 6, and sprintf on AIX defaults to 6 6931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 6941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (max < 0) 6951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max = 6; 6961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ufvalue = abs_val (fvalue); 6981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fvalue < 0) { 7001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signvalue = '-'; 7011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 7021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ 7031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signvalue = '+'; 7041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 7051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (flags & DP_F_SPACE) 7061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signvalue = ' '; 7071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if 0 7111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ 7121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 7131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if 0 7151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ 7161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 7171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 7191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Sorry, we only support 16 digits past the decimal because of our 7201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * conversion method 7211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 7221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (max > 16) 7231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max = 16; 7241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* We "cheat" by converting the fractional part to integer by 7261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * multiplying by a factor of 10 7271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 7281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood temp = ufvalue; 7301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood my_modf(temp, &intpart); 7311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); 7331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fracpart >= POW10(max)) { 7351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood intpart++; 7361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fracpart -= POW10(max); 7371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Convert integer part */ 7401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do { 7411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood temp = intpart*0.1; 7421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood my_modf(temp, &intpart); 7431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood idx = (int) ((temp -intpart +0.05)* 10.0); 7441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ 7451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* printf ("%llf, %f, %x\n", temp, intpart, idx); */ 7461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood iconvert[iplace++] = 7471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; 7481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } while (intpart && (iplace < 311)); 7491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (iplace == 311) iplace--; 7501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood iconvert[iplace] = 0; 7511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Convert fractional part */ 7531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fracpart) 7541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { 7551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do { 7561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood temp = fracpart*0.1; 7571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood my_modf(temp, &fracpart); 7581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood idx = (int) ((temp -fracpart +0.05)* 10.0); 7591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */ 7601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */ 7611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fconvert[fplace++] = 7621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; 7631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } while(fracpart && (fplace < 311)); 7641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fplace == 311) fplace--; 7651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fconvert[fplace] = 0; 7671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* -1 for decimal point, another -1 if we are printing a sign */ 7691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 7701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood zpadlen = max - fplace; 7711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (zpadlen < 0) zpadlen = 0; 7721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (padlen < 0) 7731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood padlen = 0; 7741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (flags & DP_F_MINUS) 7751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood padlen = -padlen; /* Left Justifty */ 7761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((flags & DP_F_ZERO) && (padlen > 0)) { 7781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (signvalue) { 7791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); 7801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood --padlen; 7811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signvalue = 0; 7821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (padlen > 0) { 7841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, '0'); 7851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood --padlen; 7861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (padlen > 0) { 7891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, ' '); 7901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood --padlen; 7911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (signvalue) 7931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); 7941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (iplace > 0) { 7961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood --iplace; 7971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, iconvert[iplace]); 7981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_SNPRINTF 8011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); 8021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 8031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 8051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Decimal point. This should probably use locale to find the correct 8061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * char to print out. 8071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 8081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (max > 0) { 8091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, '.'); 8101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (zpadlen > 0) { 8121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, '0'); 8131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood --zpadlen; 8141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (fplace > 0) { 8171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood --fplace; 8181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, fconvert[fplace]); 8191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (padlen < 0) { 8231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DOPR_OUTCH(buffer, *currlen, maxlen, ' '); 8241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ++padlen; 8251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 8271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ 8291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if !defined(HAVE_VSNPRINTF) 8311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 8321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvsnprintf (char *str, size_t count, const char *fmt, va_list args) 8331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return dopr(str, count, fmt, args); 8351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 8371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if !defined(HAVE_SNPRINTF) 8391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 8401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsnprintf(char *str, size_t count, SNPRINTF_CONST char *fmt, ...) 8411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood size_t ret; 8431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_list ap; 8441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_start(ap, fmt); 8461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = vsnprintf(str, count, fmt, ap); 8471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_end(ap); 8481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ret; 8491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 851