home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <limits.h>
- #include <stdarg.h>
-
- int _printf(void *,int (),const char *,va_list);
- int _sputc(int,char *);
- int _printul(void *out,int putfunc(),unsigned long val,int min,int max,int flags,int base);
- int _printsl(void *out,int putfunc(),long val,int min,int max,int flags);
-
- int _printf(void *out,int putfunc(),const char *fmt,va_list vl)
- /* die eigentliche printf-Routine; out ist ein Zeiger auf entweder ein */
- /* FILE oder einen String und putfunc() ein Zeiger auf eine Funktion, */
- /* die ein Zeichen ausgibt */
- {
- int k,n=0;
- while(k=*fmt){
- if(k=='%'){
- int min=0,max=INT_MAX,flags=0,i;
- char *str;long l;unsigned long ul;int base=0;
- k=*++fmt;
- if(k=='-'){flags|=1;k=*++fmt;}
- while(k>='0'&&k<='9'){
- min=min*10+k-'0';
- k=*++fmt;
- }
- if(k=='.'){
- k=*++fmt;max=0;
- while(k>='0'&&k<='9'){
- max=max*10+k-'0';
- k=*++fmt;
- }
- }
- if(k=='h'){flags|=2;k=*++fmt;}
- if(k=='l'){flags|=4;k=*++fmt;}
- fmt++;
- switch(k){
- default:
- case '%':
- putfunc(k,out);n++;break;
- case 'c':
- if(min>1&&!(flags&1)) for(i=0;i<min-1;i++) putfunc(' ',out);
- putfunc(va_arg(vl,int),out);
- if(min>1&&(flags&1)) for(i=0;i<min-1;i++) putfunc(' ',out);
- if(min>1) n+=min; else n+=1;
- break;
- case 's':
- str=va_arg(vl,char *);
- ul=strlen(str);
- if(ul>=max){
- for(i=0;i<max;i++) putfunc(*str++,out);
- n+=max;
- break;
- }
- if(ul<min&&!(flags&1)) for(i=0;i<min-ul;i++) putfunc(' ',out);
- while(*str) putfunc(*str++,out);
- if(ul<min&&(flags&1)) for(i=0;i<min-ul;i++) putfunc(' ',out);
- if(min>ul) n+=min; else n+=ul;
- break;
- case 'p':
- case 'x':
- case 'X':
- if(!base) base=16;
- case 'o':
- if(!base) base=8;
- case 'u':
- if(!base) base=10;
- if(flags&2) ul=va_arg(vl,unsigned short);
- else{
- if(flags&4) ul=va_arg(vl,unsigned long);
- else ul=va_arg(vl,unsigned int);
- }
- n+=_printul(out,putfunc,ul,min,max,flags,base);
- break;
- case 'i':
- case 'd':
- if(flags&2) l=va_arg(vl,short);
- else{
- if(flags&4) l=va_arg(vl,long);
- else l=va_arg(vl,int);
- }
- n+=_printsl(out,putfunc,l,min,max,flags);
- break;
-
- }
- }else{
- putfunc(k,out);
- n++;fmt++;
- }
- }
- return(n);
- }
- int _printul(void *out,int putfunc(),unsigned long val,int min,int max,int flags,int base)
- {
- static char dig[]="0123456789abcdef";
- char buf[20],*p=buf; /* lang hoffentlich immer */
- int n,i;
- if(!val){*p++='0';
- }else{
- while(val){
- *p++=dig[val%base];
- val/=base;
- }
- }
- n=p-buf;
- if(n>=max){
- for(i=0;i<max;i++) putfunc(*--p,out);
- return(max);
- }else{
- if(min>n&&!(flags&1)) for(i=0;i<min-n;i++) putfunc(' ',out);
- for(i=0;i<n;i++) putfunc(*--p,out);
- if(min>n&&(flags&1)) for(i=0;i<min-n;i++) putfunc(' ',out);
- if(n>min) return(n); else return(min);
- }
- }
- int _printsl(void *out,int putfunc(),long val,int min,int max,int flags)
- {
- char buf[20],*p=buf; /* lang hoffentlich immer */
- int n,i;unsigned long uval;
- if(val>=0){ uval=val;i=0;
- }else{
- uval=0;i=1;
- while(val<-LONG_MAX){
- uval+=LONG_MAX;
- val+=LONG_MAX;
- }
- uval+=(-val);
- }
- if(!uval){*p++='0';
- }else{
- while(uval){
- *p++=uval%10+'0';
- uval/=10;
- }
- if(i) *p++='-';
- }
- n=p-buf;
- if(n>=max){
- for(i=0;i<max;i++) putfunc(*--p,out);
- return(max);
- }else{
- if(min>n&&!(flags&1)) for(i=0;i<min-n;i++) putfunc(' ',out);
- for(i=0;i<n;i++) putfunc(*--p,out);
- if(min>n&&(flags&1)) for(i=0;i<min-n;i++) putfunc(' ',out);
- if(n>min) return(n); else return(min);
- }
- }
-