diff options
author | Timothy Pearson <[email protected]> | 2012-01-22 01:02:36 -0600 |
---|---|---|
committer | Timothy Pearson <[email protected]> | 2012-01-22 01:02:36 -0600 |
commit | b81e43465b14836b17e4fe2dea91c78a2bdd29b3 (patch) | |
tree | 7815d61ce59a6ccb6e655ed44f5fea786f520985 /kdm/backend/printf.c | |
parent | 7021f40c13f949b7cb5ded32d0241d648a43bf6c (diff) | |
download | tdebase-b81e43465b14836b17e4fe2dea91c78a2bdd29b3.tar.gz tdebase-b81e43465b14836b17e4fe2dea91c78a2bdd29b3.zip |
Part 2 of prior commit
Diffstat (limited to 'kdm/backend/printf.c')
-rw-r--r-- | kdm/backend/printf.c | 872 |
1 files changed, 0 insertions, 872 deletions
diff --git a/kdm/backend/printf.c b/kdm/backend/printf.c deleted file mode 100644 index d7220642b..000000000 --- a/kdm/backend/printf.c +++ /dev/null @@ -1,872 +0,0 @@ -/* - -Copyright 2001,2002,2004 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * printf.c - working horse of error.c - */ - -/* - * NOTE: this file is meant to be included, not linked, - * so it can be used in the helper programs without much voodoo. - */ - -/* ########## printf core implementation with some extensions ########## */ -/* - * How to use the extensions: - * - put ' or " in the flags field to quote a string with this char and - * escape special characters (only available, if PRINT_QUOTES is defined) - * - put \\ in the flags field to quote special characters and leading and - * trailing spaces (only available, if PRINT_QUOTES is defined) - * - arrays (only available, if PRINT_ARRAYS is defined) - * - the array modifier [ comes after the maximal field width specifier - * - the array length can be specified literally, with the '*' modifier - * (in which case an argument is expected) or will be automatically - * determined (stop values are -1 for ints and 0 for strings) - * - these modifiers expect their argument to be an in-line string quoted - * with an arbitrary character: - * - (, ) -> array pre-/suf-fix; default "" - * - <, > -> element pre-/suf-fix; default "" - * - | -> element separator; default " " - * - these modifiers expect no argument: - * - : -> print '<number of elements>: ' before an array - * - , -> short for |',' - * - { -> short for ('{')' }'<' '|'' - * - the pointer to the array is the last argument to the format - * - the %m conversion from syslog() is supported - */ - -/************************************************************** - * Partially stolen from OpenSSH's OpenBSD compat directory. - * (C) Patrick Powell, Brandon Long, Thomas Roessler, - * Michael Elkins, Ben Lindstrom - **************************************************************/ - -#include <ctype.h> -#include <string.h> -#include <stdarg.h> - -/* format flags - Bits */ -#define DP_F_MINUS (1 << 0) -#define DP_F_PLUS (1 << 1) -#define DP_F_SPACE (1 << 2) -#define DP_F_NUM (1 << 3) -#define DP_F_ZERO (1 << 4) -#define DP_F_UPCASE (1 << 5) -#define DP_F_UNSIGNED (1 << 6) -#define DP_F_SQUOTE (1 << 7) -#define DP_F_DQUOTE (1 << 8) -#define DP_F_BACKSL (1 << 9) -#define DP_F_ARRAY (1 << 10) -#define DP_F_COLON (1 << 11) - -/* Conversion Flags */ -#define DP_C_INT 0 -#define DP_C_BYTE 1 -#define DP_C_SHORT 2 -#define DP_C_LONG 3 -#define DP_C_STR 10 - -typedef void (*OutCh)( void *bp, char c ); - - -static void -fmtint( OutCh dopr_outch, void *bp, - long value, int base, int min, int max, int flags ) -{ - const char *ctab; - unsigned long uvalue; - int signvalue = 0; - int place = 0; - int spadlen = 0; /* amount to space pad */ - int zpadlen = 0; /* amount to zero pad */ - char convert[20]; - - if (max < 0) - max = 0; - - uvalue = value; - - if (!(flags & DP_F_UNSIGNED)) { - if (value < 0) { - signvalue = '-'; - uvalue = -value; - } else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else if (flags & DP_F_SPACE) - signvalue = ' '; - } - - ctab = (flags & DP_F_UPCASE) ? "0123456789ABCDEF" : "0123456789abcdef"; - do { - convert[place++] = ctab[uvalue % (unsigned)base]; - uvalue = uvalue / (unsigned)base; - } while (uvalue); - - zpadlen = max - place; - spadlen = min - (max > place ? max : place) - - (signvalue ? 1 : 0) - ((flags & DP_F_NUM) ? 2 : 0); - if (zpadlen < 0) - zpadlen = 0; - if (spadlen < 0) - spadlen = 0; - if (flags & DP_F_ZERO) { - zpadlen = zpadlen > spadlen ? zpadlen : spadlen; - spadlen = 0; - } - if (flags & DP_F_MINUS) - spadlen = -spadlen; /* Left Justifty */ - - - /* Spaces */ - while (spadlen > 0) { - dopr_outch( bp, ' ' ); - --spadlen; - } - - /* Sign */ - if (signvalue) - dopr_outch( bp, signvalue ); - - /* Prefix */ - if (flags & DP_F_NUM) { - dopr_outch( bp, '0' ); - dopr_outch( bp, 'x' ); - } - - /* Zeros */ - if (zpadlen > 0) - while (zpadlen > 0) { - dopr_outch( bp, '0' ); - --zpadlen; - } - - /* Digits */ - while (place > 0) - dopr_outch( bp, convert[--place] ); - - /* Left Justified spaces */ - while (spadlen < 0) { - dopr_outch( bp, ' ' ); - ++spadlen; - } -} - -typedef struct { - const char *str; - size_t len; -} str_t; - -static void -putstr( OutCh dopr_outch, void *bp, str_t *st ) -{ - size_t pt; - - for (pt = 0; pt < st->len; pt++) - dopr_outch( bp, st->str[pt] ); -} - -static str_t _null_parents = { "(null)", 6 }; -#ifdef PRINT_ARRAYS -static str_t _null_dparents = { "((null))", 8 }; -#endif -#if defined(PRINT_QUOTES) || defined(PRINT_ARRAYS) -static str_t _null_caps = { "NULL", 4 }; -#endif - -static void -fmtstr( OutCh dopr_outch, void *bp, - const char *value, int flags, int min, int max ) -{ - int padlen, strln, curcol; -#ifdef PRINT_QUOTES - int lastcol; -#endif - char ch; - - if (!value) { -#ifdef PRINT_QUOTES - if (flags & (DP_F_SQUOTE | DP_F_DQUOTE)) - putstr( dopr_outch, bp, &_null_caps ); - else -#endif - putstr( dopr_outch, bp, &_null_parents ); - return; - } - - for (strln = 0; (unsigned)strln < (unsigned)max && value[strln]; strln++); - padlen = min - strln; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justify */ - - for (; padlen > 0; padlen--) - dopr_outch( bp, ' ' ); -#ifdef PRINT_QUOTES -# if 0 /* gcc's flow analyzer is not the smartest ... */ - lastcol = 0; -# endif - if (flags & DP_F_SQUOTE) - dopr_outch( bp, '\'' ); - else if (flags & DP_F_DQUOTE) - dopr_outch( bp, '"'); - else if (flags & DP_F_BACKSL) - for (lastcol = strln; lastcol && value[lastcol - 1] == ' '; lastcol--); -#endif - for (curcol = 0; curcol < strln; curcol++) { - ch = value[curcol]; -#ifdef PRINT_QUOTES - if (flags & (DP_F_SQUOTE | DP_F_DQUOTE | DP_F_BACKSL)) { - switch (ch) { - case '\r': ch = 'r'; break; - case '\n': ch = 'n'; break; - case '\t': ch = 't'; break; - case '\a': ch = 'a'; break; - case '\b': ch = 'b'; break; - case '\v': ch = 'v'; break; - case '\f': ch = 'f'; break; - default: - if (ch < 32 || - ((unsigned char)ch >= 0x7f && (unsigned char)ch < 0xa0)) - { - dopr_outch( bp, '\\' ); - fmtint( dopr_outch, bp, (unsigned char)ch, 8, 3, 3, DP_F_ZERO ); - continue; - } else { - if ((ch == '\'' && (flags & DP_F_SQUOTE)) || - (ch == '"' && (flags & DP_F_DQUOTE) ) || - (ch == ' ' && (flags & DP_F_BACKSL) && - (!curcol || curcol >= lastcol)) || - ch == '\\') - dopr_outch( bp, '\\' ); - dopr_outch( bp, ch ); - continue; - } - } - dopr_outch( bp, '\\' ); - } -#endif - dopr_outch( bp, ch ); - } -#ifdef PRINT_QUOTES - if (flags & DP_F_SQUOTE) - dopr_outch( bp, '\'' ); - else if (flags & DP_F_DQUOTE) - dopr_outch( bp, '"' ); -#endif - for (; padlen < 0; padlen++) - dopr_outch( bp, ' ' ); -} - -static void -DoPr( OutCh dopr_outch, void *bp, const char *format, va_list args ) -{ - const char *strvalue; -#ifdef PRINT_ARRAYS - str_t arpr, arsf, arepr, aresf, aresp, *arp; - void *arptr; -#endif - unsigned long value; - int radix, min, max, flags, cflags, errn; -#ifdef PRINT_ARRAYS - int arlen; - unsigned aridx; - char sch; -#endif - char ch; -#define NCHR if (!(ch = *format++)) return - -#if 0 /* gcc's flow analyzer is not the smartest ... */ -# ifdef PRINT_ARRAYS - arlen = 0; -# endif - radix = 0; -#endif - errn = errno; - for (;;) { - for (;;) { - NCHR; - if (ch == '%') - break; - dopr_outch (bp, ch); - } - flags = cflags = min = 0; - max = -1; - for (;;) { - NCHR; - switch (ch) { - case '#': flags |= DP_F_NUM; continue; - case '-': flags |= DP_F_MINUS; continue; - case '+': flags |= DP_F_PLUS; continue; - case ' ': flags |= DP_F_SPACE; continue; - case '0': flags |= DP_F_ZERO; continue; -#ifdef PRINT_QUOTES - case '"': flags |= DP_F_DQUOTE; continue; - case '\'': flags |= DP_F_SQUOTE; continue; - case '\\': flags |= DP_F_BACKSL; continue; -#endif - } - break; - } - for (;;) { - if (isdigit( (unsigned char)ch )) { - min = 10 * min + (ch - '0'); - NCHR; - continue; - } else if (ch == '*') { - min = va_arg( args, int ); - NCHR; - } - break; - } - if (ch == '.') { - max = 0; - for (;;) { - NCHR; - if (isdigit( (unsigned char)ch )) { - max = 10 * max + (ch - '0'); - continue; - } else if (ch == '*') { - max = va_arg( args, int ); - NCHR; - } - break; - } - } -#ifdef PRINT_ARRAYS - if (ch == '[') { - flags |= DP_F_ARRAY; - arlen = -1; - arpr.len = arsf.len = arepr.len = aresf.len = 0; - aresp.len = 1, aresp.str = " "; - for (;;) { - NCHR; - if (isdigit( (unsigned char)ch )) { - arlen = 0; - for (;;) { - arlen += (ch - '0'); - NCHR; - if (!isdigit( (unsigned char)ch )) - break; - arlen *= 10; - } - } - switch (ch) { - case ':': flags |= DP_F_COLON; continue; - case '*': arlen = va_arg( args, int ); continue; - case '(': arp = &arpr; goto rar; - case ')': arp = &arsf; goto rar; - case '<': arp = &arepr; goto rar; - case '>': arp = &aresf; goto rar; - case '|': arp = &aresp; - rar: - NCHR; - sch = ch; - arp->str = format; - do { - NCHR; - } while (ch != sch); - arp->len = format - arp->str - 1; - continue; - case ',': - aresp.len = 1, aresp.str = ","; - continue; - case '{': - aresp.len = 0, arpr.len = arepr.len = 1, arsf.len = 2; - arpr.str = "{", arepr.str = " ", arsf.str = " }"; - continue; - } - break; - } - } -#endif - for (;;) { - switch (ch) { - case 'h': - cflags = DP_C_SHORT; - NCHR; - if (ch == 'h') { - cflags = DP_C_BYTE; - NCHR; - } - continue; - case 'l': - cflags = DP_C_LONG; - NCHR; - continue; - } - break; - } - switch (ch) { - case '%': - dopr_outch( bp, ch ); - break; - case 'm': - fmtstr( dopr_outch, bp, strerror( errn ), flags, min, max ); - break; - case 'c': - dopr_outch( bp, va_arg( args, int ) ); - break; - case 's': -#ifdef PRINT_ARRAYS - cflags = DP_C_STR; - goto printit; -#else - strvalue = va_arg( args, char * ); - fmtstr( dopr_outch, bp, strvalue, flags, min, max ); - break; -#endif - case 'u': - flags |= DP_F_UNSIGNED; - case 'd': - case 'i': - radix = 10; - goto printit; - case 'X': - flags |= DP_F_UPCASE; - case 'x': - flags |= DP_F_UNSIGNED; - radix = 16; - printit: -#ifdef PRINT_ARRAYS - if (flags & DP_F_ARRAY) { - if (!(arptr = va_arg( args, void * ))) - putstr( dopr_outch, bp, - arpr.len ? &_null_caps : &_null_dparents ); - else { - if (arlen == -1) { - arlen = 0; - switch (cflags) { - case DP_C_STR: while (((char **)arptr)[arlen]) arlen++; break; - case DP_C_BYTE: while (((unsigned char *)arptr)[arlen] != (unsigned char)-1) arlen++; break; - case DP_C_SHORT: while (((unsigned short int *)arptr)[arlen] != (unsigned short int)-1) arlen++; break; - case DP_C_LONG: while (((unsigned long int *)arptr)[arlen] != (unsigned long int)-1) arlen++; break; - default: while (((unsigned int *)arptr)[arlen] != (unsigned int)-1) arlen++; break; - } - } - if (flags & DP_F_COLON) { - fmtint( dopr_outch, bp, (long)arlen, 10, 0, -1, DP_F_UNSIGNED ); - dopr_outch( bp, ':' ); - dopr_outch( bp, ' ' ); - } - putstr( dopr_outch, bp, &arpr ); - for (aridx = 0; aridx < (unsigned)arlen; aridx++) { - if (aridx) - putstr( dopr_outch, bp, &aresp ); - putstr( dopr_outch, bp, &arepr ); - if (cflags == DP_C_STR) { - strvalue = ((char **)arptr)[aridx]; - fmtstr( dopr_outch, bp, strvalue, flags, min, max ); - } else { - if (flags & DP_F_UNSIGNED) { - switch (cflags) { - case DP_C_BYTE: value = ((unsigned char *)arptr)[aridx]; break; - case DP_C_SHORT: value = ((unsigned short int *)arptr)[aridx]; break; - case DP_C_LONG: value = ((unsigned long int *)arptr)[aridx]; break; - default: value = ((unsigned int *)arptr)[aridx]; break; - } - } else { - switch (cflags) { - case DP_C_BYTE: value = ((signed char *)arptr)[aridx]; break; - case DP_C_SHORT: value = ((short int *)arptr)[aridx]; break; - case DP_C_LONG: value = ((long int *)arptr)[aridx]; break; - default: value = ((int *)arptr)[aridx]; break; - } - } - fmtint( dopr_outch, bp, value, radix, min, max, flags ); - } - putstr( dopr_outch, bp, &aresf ); - } - putstr( dopr_outch, bp, &arsf ); - } - } else { - if (cflags == DP_C_STR) { - strvalue = va_arg( args, char * ); - fmtstr( dopr_outch, bp, strvalue, flags, min, max ); - } else { -#endif - if (flags & DP_F_UNSIGNED) { - switch (cflags) { - case DP_C_LONG: value = va_arg( args, unsigned long int ); break; - default: value = va_arg( args, unsigned int ); break; - } - } else { - switch (cflags) { - case DP_C_LONG: value = va_arg( args, long int ); break; - default: value = va_arg( args, int ); break; - } - } - fmtint( dopr_outch, bp, value, radix, min, max, flags ); -#ifdef PRINT_ARRAYS - } - } -#endif - break; - case 'p': - value = (long)va_arg( args, void * ); - fmtint( dopr_outch, bp, value, 16, sizeof(long) * 2 + 2, - max, flags | DP_F_UNSIGNED | DP_F_ZERO | DP_F_NUM ); - break; - } - } -} - -/* ########## end of printf core implementation ########## */ - - -/* - * Logging function for xdm and helper programs. - */ -#ifndef NO_LOGGER - -#include <stdio.h> -#include <time.h> - -#ifdef USE_SYSLOG -# include <syslog.h> -# ifdef LOG_NAME -# define InitLog() openlog(LOG_NAME, LOG_PID, LOG_DAEMON) -# else -# define InitLog() openlog(prog, LOG_PID, LOG_DAEMON) -# endif -static int lognums[] = { LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_CRIT }; -#else -# define InitLog() while(0) -#endif - -static const char *lognams[] = { "debug", "info", "warning", "error", "panic" }; - -static void -logTime( char *dbuf ) -{ - time_t tim; - (void)time( &tim ); - strftime( dbuf, 20, "%b %e %H:%M:%S", localtime( &tim ) ); -} - -#if defined(LOG_DEBUG_MASK) || defined(USE_SYSLOG) -STATIC int debugLevel; -#endif - -#define OOMSTR "Out of memory. Expect problems.\n" - -STATIC void -LogOutOfMem( void ) -{ - static time_t last; - time_t tnow; - - time( &tnow ); - if (last + 100 > tnow) { /* don't log bursts */ - last = tnow; - return; - } - last = tnow; -#ifdef USE_SYSLOG - if (!(debugLevel & DEBUG_NOSYSLOG)) - syslog( LOG_CRIT, OOMSTR ); - else -#endif - { - int el; - char dbuf[24], sbuf[128]; - logTime( dbuf ); - el = sprintf( sbuf, "%s " -#ifdef LOG_NAME - LOG_NAME "[%ld]: " OOMSTR, dbuf, -#else - "%s[%ld]: " OOMSTR, dbuf, prog, -#endif - (long)getpid() ); - write( 2, sbuf, el ); - } -} - -typedef struct { - char *buf; - int clen, blen, type; - char lmbuf[128]; -} OCLBuf; - -static void -OutChLFlush( OCLBuf *oclbp ) -{ - if (oclbp->clen) { -#ifdef USE_SYSLOG - if (!(debugLevel & DEBUG_NOSYSLOG)) - syslog( lognums[oclbp->type], "%.*s", oclbp->clen, oclbp->buf ); - else -#endif - { - oclbp->buf[oclbp->clen] = '\n'; - write( 2, oclbp->buf, oclbp->clen + 1 ); - } - oclbp->clen = 0; - } -} - -static void -OutChL( void *bp, char c ) -{ - OCLBuf *oclbp = (OCLBuf *)bp; - char *nbuf; - int nlen; - - if (c == '\n') - OutChLFlush( oclbp ); - else { - if (oclbp->clen >= oclbp->blen - 1) { - if (oclbp->buf == oclbp->lmbuf) { - OutChLFlush( oclbp ); - oclbp->buf = 0; - oclbp->blen = 0; - } - nlen = oclbp->blen * 3 / 2 + 128; - nbuf = Realloc( oclbp->buf, nlen ); - if (nbuf) { - oclbp->buf = nbuf; - oclbp->blen = nlen; - } else { - OutChLFlush( oclbp ); - oclbp->buf = oclbp->lmbuf; - oclbp->blen = sizeof(oclbp->lmbuf); - } - } -#ifdef USE_SYSLOG - if (!oclbp->clen && (debugLevel & DEBUG_NOSYSLOG)) { -#else - if (!oclbp->clen) { -#endif - char dbuf[24]; - logTime( dbuf ); - oclbp->clen = sprintf( oclbp->buf, "%s " -#ifdef LOG_NAME - LOG_NAME "[%ld] %s: ", dbuf, -#else - "%s[%ld] %s: ", dbuf, prog, -#endif - (long)getpid(), lognams[oclbp->type] ); - } - oclbp->buf[oclbp->clen++] = c; - } -} - -static void -Logger( int type, const char *fmt, va_list args ) -{ - OCLBuf oclb; - - oclb.buf = 0; - oclb.blen = oclb.clen = 0; - oclb.type = type; - DoPr( OutChL, &oclb, fmt, args ); - /* no flush, every message is supposed to be \n-terminated */ - if (oclb.buf && oclb.buf != oclb.lmbuf) - free( oclb.buf ); -} - -#ifdef LOG_DEBUG_MASK -STATIC void -Debug( const char *fmt, ... ) -{ - if (debugLevel & LOG_DEBUG_MASK) { - va_list args; - int olderrno = errno; - va_start( args, fmt ); - Logger( DM_DEBUG, fmt, args ); - va_end( args ); - errno = olderrno; - } -} -#endif - -#ifndef LOG_NO_INFO -STATIC void -LogInfo( const char *fmt, ... ) -{ - va_list args; - - va_start( args, fmt ); - Logger( DM_INFO, fmt, args ); - va_end( args ); -} -#endif - -#ifndef LOG_NO_WARN -STATIC void -LogWarn( const char *fmt, ... ) -{ - va_list args; - - va_start( args, fmt ); - Logger( DM_WARN, fmt, args ); - va_end( args ); -} -#endif - -#ifndef LOG_NO_ERROR -STATIC void -LogError( const char *fmt, ... ) -{ - va_list args; - - va_start( args, fmt ); - Logger( DM_ERR, fmt, args ); - va_end( args ); -} -#endif - -#ifdef LOG_PANIC_EXIT -STATIC void -LogPanic( const char *fmt, ... ) -{ - va_list args; - - va_start( args, fmt ); - Logger( DM_PANIC, fmt, args ); - va_end( args ); - exit( LOG_PANIC_EXIT ); -} -#endif - -#endif /* NO_LOGGER */ - -#ifdef NEED_FDPRINTF - -typedef struct { - char *buf; - int clen, blen, tlen; -} OCFBuf; - -static void -OutCh_OCF( void *bp, char c ) -{ - OCFBuf *ocfbp = (OCFBuf *)bp; - char *nbuf; - int nlen; - - ocfbp->tlen++; - if (ocfbp->clen >= ocfbp->blen) { - if (ocfbp->blen < 0) - return; - nlen = ocfbp->blen * 3 / 2 + 100; - nbuf = Realloc( ocfbp->buf, nlen ); - if (!nbuf) { - free( ocfbp->buf ); - ocfbp->blen = -1; - ocfbp->buf = 0; - ocfbp->clen = 0; - return; - } - ocfbp->blen = nlen; - ocfbp->buf = nbuf; - } - ocfbp->buf[ocfbp->clen++] = c; -} - -STATIC int -FdPrintf( int fd, const char *fmt, ... ) -{ - va_list args; - OCFBuf ocfb = { 0, 0, 0, -1 }; - - va_start( args, fmt ); - DoPr( OutCh_OCF, &ocfb, fmt, args ); - va_end( args ); - if (ocfb.buf) { - Debug( "FdPrintf %\".*s to %d\n", ocfb.clen, ocfb.buf, fd ); - (void)write( fd, ocfb.buf, ocfb.clen ); - free( ocfb.buf ); - } - return ocfb.tlen; -} - -#endif /* NEED_FDPRINTF */ - -#ifdef NEED_ASPRINTF - -typedef struct { - char *buf; - int clen, blen, tlen; -} OCABuf; - -static void -OutCh_OCA( void *bp, char c ) -{ - OCABuf *ocabp = (OCABuf *)bp; - char *nbuf; - int nlen; - - ocabp->tlen++; - if (ocabp->clen >= ocabp->blen) { - if (ocabp->blen < 0) - return; - nlen = ocabp->blen * 3 / 2 + 100; - nbuf = Realloc( ocabp->buf, nlen ); - if (!nbuf) { - free( ocabp->buf ); - ocabp->blen = -1; - ocabp->buf = 0; - ocabp->clen = 0; - return; - } - ocabp->blen = nlen; - ocabp->buf = nbuf; - } - ocabp->buf[ocabp->clen++] = c; -} - -STATIC int -VASPrintf( char **strp, const char *fmt, va_list args ) -{ - OCABuf ocab = { 0, 0, 0, -1 }; - - DoPr( OutCh_OCA, &ocab, fmt, args ); - OutCh_OCA( &ocab, 0 ); - *strp = Realloc( ocab.buf, ocab.clen ); - if (!*strp) - *strp = ocab.buf; - return ocab.tlen; -} - -STATIC int -ASPrintf( char **strp, const char *fmt, ... ) -{ - va_list args; - int len; - - va_start( args, fmt ); - len = VASPrintf( strp, fmt, args ); - va_end( args ); - return len; -} - -#endif /* NEED_ASPRINTF */ |