/************************************************************* * File: lib/vsprintf.c * Purpose: Part of C runtime library * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970304 Start of revision history */ #include #include #include #include #define strNcpy(x,y,z) strncpy(x,y,z),(x)[z]=0 #ifdef PMCC #include #else #define vsprintf xvsprintf #endif #ifdef TEST main(argc,argv) int argc; char *argv[]; { printf("Hello world\n"); printf("%%c, %c%c%c\n",'A','B','C'); printf("%%d, 2356=%d\n",2356); printf("%%x, 235c=%x\n",0x235C); printf("%%X, 235C=%X\n",0x235C); printf("%%08X, 235C=%08X\n",0x235C); printf("%%b, 11001=%b\n",25); printf("%%s, Hello=[%s]\n","Hello"); printf("%%10s, Hello=[%10s]\n","Hello"); printf("%%-10s, Hello=[%-10s]\n","Hello"); printf("%%~10s, Hello=[%~10s]\n","Hello"); printf("%%~10s, Hello=[%~10s] World=[%s]\n","Hello","World"); printf("%%~10s, Hello=[%~10s] World=[%-10.5s]\n","Hello","World War"); printf("%%~*s, Hello=[%~*s] World=[%-*.*s]\n",10,"Hello",10,5,"World War"); } printf(fmt,va_alist) char *fmt; va_dcl { va_list ap; va_start(ap); vfprintf(1,fmt,ap); va_end(ap); } vfprintf(fd,fmt,ap) int fd; char *fmt; va_list ap; { char buf[MAXLN+1]; vsprintf(buf,fmt,ap); write(fd,buf,strlen(buf)); } #endif /************************************************************* * int vsprintf(d,s,ap) */ int vsprintf(char *d,const char *s,va_list ap) { char *p,*dst,tmp[40]; const char *t; unsigned int n; int fmt,trunc,haddot,width,base; #ifdef FLOATINGPT double dbl; #endif dst = d; for (;*s;) { if (*s == '%') { s++; fmt = FMT_RJUST; width = trunc = haddot = 0; for (;*s;s++) { if (strchr("dobxXuscefg%",*s)) break; else if (*s == '-') fmt = FMT_LJUST; else if (*s == '0') fmt = FMT_RJUST0; else if (*s == '~') fmt = FMT_CENTER; else if (*s == '*') { if (haddot) trunc = va_arg(ap,int); else width = va_arg(ap,int); } else if (*s >= '1' && *s <= '9') { for (t=s;isdigit(*s);s++) ; strNcpy(tmp,t,s-t); atob(&n,tmp,10); if (haddot) trunc = n; else width = n; s--; } else if (*s == '.') haddot = 1; } if (*s == '%') { *d++ = '%'; *d = 0; } else if (*s == 's') { p = va_arg(ap,char *); if (p) strcpy(d,p); else strcpy(d,"(null)"); } else if (*s == 'c') { n = va_arg(ap,int); *d = n; d[1] = 0; } else { if (strchr("dobxXu",*s)) { if (*s == 'd' || *s == 'u') base = 10; else if (*s == 'x' || *s == 'X') base = 16; else if (*s == 'o') base = 8; else if (*s == 'b') base = 2; btoa(d,va_arg(ap,int),base); if (*s == 'X') strtoupper(d); } #ifdef FLOATINGPT else if (strchr("efg",*s)) { dbl = va_arg(ap,double); dbl_to_ascii(&dbl,tmp); if (trunc) trunc_fp(*s,tmp,trunc); else trunc_fp(*s,tmp,6); strcpy(d,tmp); trunc = 0; } #endif } if (trunc) d[trunc] = 0; if (width) str_fmt(d,width,fmt); for (;*d;d++) ; s++; } else *d++ = *s++; } *d = 0; return(d-dst); }