[alt.sources] where does vsprintf

jik@athena.mit.edu (Jonathan I. Kamens) (12/20/90)

Submitted-by: jik@MIT.Edu
Archive-name: vprintf/part01

In article <8477@uwm.edu>, datta@vacs.uwp.wisc.edu (David Datta) writes:
|> Having just gotten a new version of ftpd.c, which came with a new version
|> of syslog.c that calls a routine vsprintf() that didn't come with...
|> 
|> Where is the function defined? I haven't been able to locate it anywhere
|> in any of the sources we have for BSD 4.3. 

  The standard BSD 4.3 C libraries don't have it.  Newer libraries (including,
I believe, 4.3-tahoe and 4.3-reno, as well as many other vendors' libraries)
do.

  Below is a shar archive of a portable implementation of it that came with
the source code to xrn (I didn't write it; see the files in the archive for
proper credit to the author.).  It may or may not have been posted to
alt.sources before, although I can't find it in the comp.sources.unix archives.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

------------------------------------------------------------------

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  vprintf.doc vprintf.c
# Wrapped by jik@pit-manager on Thu Dec 20 09:31:27 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'vprintf.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'vprintf.doc'\"
else
echo shar: Extracting \"'vprintf.doc'\" \(1707 characters\)
sed "s/^X//" >'vprintf.doc' <<'END_OF_FILE'
XPortable vsprintf, vfprintf, and vprintf  by Robert A. Larson
X	<blarson@skat.usc.edu>
X
XCopyright 1989 Robert A. Larson.
XDistribution in any form is allowed as long as the author
Xretains credit, changes are noted by their author and the
Xcopyright message remains intact.  This program comes as-is
Xwith no warentee of fitness for any purpouse.
X
XThanks to Doug Gwen, Chris Torek, and others who helped clarify
Xthe ansi printf specs.
X
XPlease send any bug fixes and improvments to blarson@skat.usc.edu .
XThe use of goto is NOT a bug.
X
X
XFeb  9, 1989		blarson		First usenet release
X
XThis code implements the vsprintf function, without relying on
Xthe existance of _doprint or other system specific code.
X
XDefine NOVOID if void * is not a supported type.
X
XTwo compile options are available for efficency:
X	INTSPRINTF	should be defined if sprintf is int and returns
X			the number of chacters formated.
X	LONGINT		should be defined if sizeof(long) == sizeof(int)
X
X	They only make the code smaller and faster, they need not be 
X	defined.
X
XUNSIGNEDSPECIAL should be defined if unsigned is treated differently
Xthan int in argument passing.  If this is definded, and LONGINT is not,
Xthe compiler must support the type unsigned long.
X
XMost quirks and bugs of the available sprintf and fprintf fuction are
Xduplicated, however * in the width and precision fields will work
Xcorrectly even if sprintf does not support this, and the %n format
Xwill always work in vsprintf.  %n and return count will work properly
Xin vfprintf and vprintf only if fprintf returns the number of
Xcharacters formatted.
X
XBad format strings, or those with very long width and precision
Xfields (including expanded * fields) will cause undesired results.
END_OF_FILE
if test 1707 -ne `wc -c <'vprintf.doc'`; then
    echo shar: \"'vprintf.doc'\" unpacked with wrong size!
fi
# end of 'vprintf.doc'
fi
if test -f 'vprintf.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'vprintf.c'\"
else
echo shar: Extracting \"'vprintf.c'\" \(6216 characters\)
sed "s/^X//" >'vprintf.c' <<'END_OF_FILE'
X#include <stdio.h>
X
X/* Portable vfprintf  by Robert A. Larson <blarson@skat.usc.edu> */
X
X/* Copyright 1989 Robert A. Larson.
X * Distribution in any form is allowed as long as the author
X * retains credit, changes are noted by their author and the
X * copyright message remains intact.  This program comes as-is
X * with no warentee of fitness for any purpouse.
X *
X * Thanks to Doug Gwen, Chris Torek, and others who helped clarify
X * the ansi printf specs.
X *
X * Please send any bug fixes and improvments to blarson@skat.usc.edu .
X * The use of goto is NOT a bug.
X */
X
X/* Feb	7, 1989		blarson		First usenet release */
X
X/* This code implements the vsprintf function, without relying on
X * the existance of _doprint or other system specific code.
X *
X * Define NOVOID if void * is not a supported type.
X *
X * Two compile options are available for efficency:
X *	INTSPRINTF	should be defined if sprintf is int and returns
X *			the number of chacters formated.
X *	LONGINT		should be defined if sizeof(long) == sizeof(int)
X *
X *	They only make the code smaller and faster, they need not be
X *	defined.
X *
X * UNSIGNEDSPECIAL should be defined if unsigned is treated differently
X * than int in argument passing.  If this is definded, and LONGINT is not,
X * the compiler must support the type unsingned long.
X *
X * Most quirks and bugs of the available sprintf fuction are duplicated,
X * however * in the width and precision fields will work correctly
X * even if sprintf does not support this, as will the n format.
X *
X * Bad format strings, or those with very long width and precision
X * fields (including expanded * fields) will cause undesired results.
X */
X
X#ifdef OSK		/* os9/68k can take advantage of both */
X#define LONGINT
X#define INTSPRINTF
X#endif
X
X/* This must be a typedef not a #define! */
X#ifdef NOVOID
Xtypedef char *pointer;
X#else
Xtypedef void *pointer;
X#endif
X
X#ifdef	INTSPRINTF
X#define Sprintf(string,format,arg)	(sprintf((string),(format),(arg)))
X#else
X#define Sprintf(string,format,arg)	(\
X	sprintf((string),(format),(arg)),\
X	strlen(string)\
X)
X#endif
X
X#if defined(__STDC__) && !defined(NOSTDHDRS)
X#include <stdarg.h>
X#else
X#include <varargs.h>
X#endif
X
Xtypedef int *intp;
X
Xint vsprintf(dest, format, args)
Xchar *dest;
Xregister char *format;
Xva_list args;
X{
X    register char *dp = dest;
X    register char c;
X    register char *tp;
X    char tempfmt[64];
X#ifndef LONGINT
X    int longflag;
X#endif
X
X    tempfmt[0] = '%';
X    while(c = *format++) {
X	if(c=='%') {
X	    tp = &tempfmt[1];
X#ifndef LONGINT
X	    longflag = 0;
X#endif
Xcontinue_format:
X	    switch(c = *format++) {
X		case 's':
X		    *tp++ = c;
X		    *tp = '\0';
X		    dp += Sprintf(dp, tempfmt, va_arg(args, char *));
X		    break;
X		case 'u':
X		case 'x':
X		case 'o':
X		case 'X':
X#ifdef UNSIGNEDSPECIAL
X		    *tp++ = c;
X		    *tp = '\0';
X#ifndef LONGINT
X		    if(longflag)
X			dp += Sprintf(dp, tempfmt, va_arg(args, unsigned long));
X		    else
X#endif
X			dp += Sprintf(dp, tempfmt, va_arg(args, unsigned));
X		    break;
X#endif
X		case 'd':
X		case 'c':
X		case 'i':
X		    *tp++ = c;
X		    *tp = '\0';
X#ifndef LONGINT
X		    if(longflag)
X			dp += Sprintf(dp, tempfmt, va_arg(args, long));
X		    else
X#endif
X			dp += Sprintf(dp, tempfmt, va_arg(args, int));
X		    break;
X		case 'f':
X		case 'e':
X		case 'E':
X		case 'g':
X		case 'G':
X		    *tp++ = c;
X		    *tp = '\0';
X		    dp += Sprintf(dp, tempfmt, va_arg(args, double));
X		    break;
X		case 'p':
X		    *tp++ = c;
X		    *tp = '\0';
X		    dp += Sprintf(dp, tempfmt, va_arg(args, pointer));
X		    break;
X		case '-':
X		case '+':
X		case '0':
X		case '1':
X		case '2':
X		case '3':
X		case '4':
X		case '5':
X		case '6':
X		case '7':
X		case '8':
X		case '9':
X		case '.':
X		case ' ':
X		case '#':
X		case 'h':
X		    *tp++ = c;
X		    goto continue_format;
X		case 'l':
X#ifndef LONGINT
X		    longflag = 1;
X		    *tp++ = c;
X#endif
X		    goto continue_format;
X		case '*':
X		    tp += Sprintf(tp, "%d", va_arg(args, int));
X		    goto continue_format;
X		case 'n':
X		    *va_arg(args, intp) = dp - dest;
X		    break;
X		case '%':
X		default:
X		    *dp++ = c;
X		    break;
X	    }
X	} else *dp++ = c;
X    }
X    *dp = '\0';
X    return dp - dest;
X}
X
X
Xint vfprintf(dest, format, args)
XFILE *dest;
Xregister char *format;
Xva_list args;
X{
X    register char c;
X    register char *tp;
X    register int count = 0;
X    char tempfmt[64];
X#ifndef LONGINT
X    int longflag;
X#endif
X
X    tempfmt[0] = '%';
X    while(c = *format++) {
X	if(c=='%') {
X	    tp = &tempfmt[1];
X#ifndef LONGINT
X	    longflag = 0;
X#endif
Xcontinue_format:
X	    switch(c = *format++) {
X		case 's':
X		    *tp++ = c;
X		    *tp = '\0';
X		    count += fprintf(dest, tempfmt, va_arg(args, char *));
X		    break;
X		case 'u':
X		case 'x':
X		case 'o':
X		case 'X':
X#ifdef UNSIGNEDSPECIAL
X		    *tp++ = c;
X		    *tp = '\0';
X#ifndef LONGINT
X		    if(longflag)
X			count += fprintf(dest, tempfmt, va_arg(args, unsigned long));
X		    else
X#endif
X			count += fprintf(dest, tempfmt, va_arg(args, unsigned));
X		    break;
X#endif
X		case 'd':
X		case 'c':
X		case 'i':
X		    *tp++ = c;
X		    *tp = '\0';
X#ifndef LONGINT
X		    if(longflag)
X			count += fprintf(dest, tempfmt, va_arg(args, long));
X		    else
X#endif
X			count += fprintf(dest, tempfmt, va_arg(args, int));
X		    break;
X		case 'f':
X		case 'e':
X		case 'E':
X		case 'g':
X		case 'G':
X		    *tp++ = c;
X		    *tp = '\0';
X		    count += fprintf(dest, tempfmt, va_arg(args, double));
X		    break;
X		case 'p':
X		    *tp++ = c;
X		    *tp = '\0';
X		    count += fprintf(dest, tempfmt, va_arg(args, pointer));
X		    break;
X		case '-':
X		case '+':
X		case '0':
X		case '1':
X		case '2':
X		case '3':
X		case '4':
X		case '5':
X		case '6':
X		case '7':
X		case '8':
X		case '9':
X		case '.':
X		case ' ':
X		case '#':
X		case 'h':
X		    *tp++ = c;
X		    goto continue_format;
X		case 'l':
X#ifndef LONGINT
X		    longflag = 1;
X		    *tp++ = c;
X#endif
X		    goto continue_format;
X		case '*':
X		    tp += Sprintf(tp, "%d", va_arg(args, int));
X		    goto continue_format;
X		case 'n':
X		    *va_arg(args, intp) = count;
X		    break;
X		case '%':
X		default:
X		    putc(c, dest);
X		    count++;
X		    break;
X	    }
X	} else {
X	    putc(c, dest);
X	    count++;
X	}
X    }
X    return count;
X}
X
Xvprintf(format, args)
Xchar *format;
Xva_list args;
X{
X    return vfprintf(stdout, format, args);
X}
END_OF_FILE
if test 6216 -ne `wc -c <'vprintf.c'`; then
    echo shar: \"'vprintf.c'\" unpacked with wrong size!
fi
# end of 'vprintf.c'
fi
echo shar: End of shell archive.
exit 0