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