This is vprintf.c in view mode; [Download] [Up]
#include <stdio.h> #ifdef NEED_VPRINTF /* Portable vsprintf by Robert A. Larson <blarson@skat.usc.edu> */ /* Portable vfprintf by Robert A. Larson <blarson@skat.usc.edu> */ /* Copyright 1989 Robert A. Larson. * Distribution in any form is allowed as long as the author * retains credit, changes are noted by their author and the * copyright message remains intact. This program comes as-is * with no warentee of fitness for any purpouse. * * Thanks to Doug Gwen, Chris Torek, and others who helped clarify * the ansi printf specs. * * Please send any bug fixes and improvments to blarson@skat.usc.edu . * The use of goto is NOT a bug. */ /* Feb 7, 1989 blarson First usenet release */ /* This code implements the vsprintf function, without relying on * the existance of _doprint or other system specific code. * * Define NOVOID if void * is not a supported type. * * Two compile options are available for efficency: * INTSPRINTF should be defined if sprintf is int and returns * the number of chacters formated. * LONGINT should be defined if sizeof(long) == sizeof(int) * * They only make the code smaller and faster, they need not be * defined. * * UNSIGNEDSPECIAL should be defined if unsigned is treated differently * than int in argument passing. If this is definded, and LONGINT is not, * the compiler must support the type unsingned long. * * Most quirks and bugs of the available sprintf fuction are duplicated, * however * in the width and precision fields will work correctly * even if sprintf does not support this, as will the n format. * * Bad format strings, or those with very long width and precision * fields (including expanded * fields) will cause undesired results. */ #ifdef OSK /* os9/68k can take advantage of both */ #define LONGINT #define INTSPRINTF #endif /* This must be a typedef not a #define! */ #ifdef NOVOID typedef char *pointer; #else typedef void *pointer; #endif #ifdef INTSPRINTF #define Sprintf(string,format,arg) (sprintf((string),(format),(arg))) #else #define Sprintf(string,format,arg) (\ sprintf((string),(format),(arg)),\ strlen(string)\ ) #endif #if defined(__STDC__) && !defined(NOSTDHDRS) #include <stdarg.h> #else #include <varargs.h> #endif typedef int *intp; int vsprintf(dest, format, args) char *dest; register char *format; va_list args; { register char *dp = dest; register char c; register char *tp; char tempfmt[64]; #ifndef LONGINT int longflag; #endif tempfmt[0] = '%'; while( (c = *format++) != 0) { if(c=='%') { tp = &tempfmt[1]; #ifndef LONGINT longflag = 0; #endif continue_format: switch(c = *format++) { case 's': *tp++ = c; *tp = '\0'; dp += Sprintf(dp, tempfmt, va_arg(args, char *)); break; case 'u': case 'x': case 'o': case 'X': #ifdef UNSIGNEDSPECIAL *tp++ = c; *tp = '\0'; #ifndef LONGINT if(longflag) dp += Sprintf(dp, tempfmt, va_arg(args, unsigned long)); else #endif dp += Sprintf(dp, tempfmt, va_arg(args, unsigned)); break; #endif case 'd': case 'c': case 'i': *tp++ = c; *tp = '\0'; #ifndef LONGINT if(longflag) dp += Sprintf(dp, tempfmt, va_arg(args, long)); else #endif dp += Sprintf(dp, tempfmt, va_arg(args, int)); break; case 'f': case 'e': case 'E': case 'g': case 'G': *tp++ = c; *tp = '\0'; dp += Sprintf(dp, tempfmt, va_arg(args, double)); break; case 'p': *tp++ = c; *tp = '\0'; dp += Sprintf(dp, tempfmt, va_arg(args, pointer)); break; case '-': case '+': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': case ' ': case '#': case 'h': *tp++ = c; goto continue_format; case 'l': #ifndef LONGINT longflag = 1; *tp++ = c; #endif goto continue_format; case '*': tp += Sprintf(tp, "%d", va_arg(args, int)); goto continue_format; case 'n': *va_arg(args, intp) = dp - dest; break; case '%': default: *dp++ = c; break; } } else *dp++ = c; } *dp = '\0'; return dp - dest; } int vfprintf(dest, format, args) FILE *dest; register char *format; va_list args; { register char c; register char *tp; register int count = 0; char tempfmt[64]; #ifndef LONGINT int longflag; #endif tempfmt[0] = '%'; while(c = *format++) { if(c=='%') { tp = &tempfmt[1]; #ifndef LONGINT longflag = 0; #endif continue_format: switch(c = *format++) { case 's': *tp++ = c; *tp = '\0'; count += fprintf(dest, tempfmt, va_arg(args, char *)); break; case 'u': case 'x': case 'o': case 'X': #ifdef UNSIGNEDSPECIAL *tp++ = c; *tp = '\0'; #ifndef LONGINT if(longflag) count += fprintf(dest, tempfmt, va_arg(args, unsigned long)); else #endif count += fprintf(dest, tempfmt, va_arg(args, unsigned)); break; #endif case 'd': case 'c': case 'i': *tp++ = c; *tp = '\0'; #ifndef LONGINT if(longflag) count += fprintf(dest, tempfmt, va_arg(args, long)); else #endif count += fprintf(dest, tempfmt, va_arg(args, int)); break; case 'f': case 'e': case 'E': case 'g': case 'G': *tp++ = c; *tp = '\0'; count += fprintf(dest, tempfmt, va_arg(args, double)); break; case 'p': *tp++ = c; *tp = '\0'; count += fprintf(dest, tempfmt, va_arg(args, pointer)); break; case '-': case '+': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': case ' ': case '#': case 'h': *tp++ = c; goto continue_format; case 'l': #ifndef LONGINT longflag = 1; *tp++ = c; #endif goto continue_format; case '*': tp += Sprintf(tp, "%d", va_arg(args, int)); goto continue_format; case 'n': *va_arg(args, intp) = count; break; case '%': default: putc(c, dest); count++; break; } } else { putc(c, dest); count++; } } return count; } vprintf(format, args) char *format; va_list args; { return vfprintf(stdout, format, args); } #endif #ifdef NEED_MEMROUTINES #include <sys/types.h> char *strchr(s1,c) char *s1; int c; { char *p; p=s1; while(*p) if(*(p++) == c) return p-1; return NULL; } void *memset(s,c,n) char *s; int c; size_t n; { char *p; for (p=s; n--;) *(p++) = c; return; } #endif /* NEED_MEMROUTINES */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.