00001
00039 #include "mprintf.h"
00040 #define edigito(c) ((c)>='0' && (c)<='9')
00041
00042
00043 int u2str(char *buf, unsigned int num, int base)
00044 {
00045 int nd=0, c;
00046 do {
00047 c = (num % base) + '0';
00048 if(c > '9') c+=7;
00049 buf[nd++] = c;
00050 num /= base;
00051 } while(num);
00052 return nd;
00053 }
00054
00055
00056
00057
00058
00059
00060
00061
00062 int atoi(char *str)
00063 {
00064 int x, d, s;
00065 x=s=0;
00066 while(!edigito(*str)) s |= (*str++ == '-');
00067 do {
00068 d = *str++;
00069 if(!edigito(d)) break;
00070 x = x*10 + d - '0';
00071 } while(1);
00072 return s? -x: x;
00073 }
00074
00075
00076 double atod(char *str)
00077 {
00078 double x, p;
00079 int d, s;
00080 p=1.0;
00081 x=0.0; s=0;
00082 while(*str == ' ') str++;
00083 if(*str == '-') { s=1; str++; }
00084 do {
00085 d = *str++;
00086 if(d=='.') { d = *str++; s |= 2; }
00087 if(d < '0' || d > '9') break;
00088 x = x*10 + d - '0';
00089 if(s & 2) p *=10.;
00090 } while(1);
00091 if(d=='e' || d=='E'){
00092 if(*str == '-') { str++; s |= 4; }
00093 if(*str == '+') str++;
00094 d=0;
00095 while(edigito(*str)) d = 10*d + (*str++) - '0';
00096 if(s & 4) while(d--) p *= 10.0;
00097 else while(d--) x *= 10.0;
00098 }
00099 if(s & 1) x = -x;
00100 return x/p;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109 int dprint(double x, int campo, int frac, void (*putc)(int))
00110 {
00111 int dig, k, sinal=0, npr=1;
00112 double ar;
00113 if(x < 0) { sinal=1; x=-x; campo--; }
00114 for(ar=0.5, k=0; k<frac; k++) ar/=10.0;
00115 x += ar;
00116 k=0;
00117 campo -= (frac+1);
00118 while(x >= 1.0) { x/=10.0; k++; campo--; }
00119 if(!k) { k=1; campo--; x/=10.0; }
00120 frac += k;
00121 while(campo-- > 0) { putc(' '); npr++; }
00122 if(sinal) { putc('-'); npr++; }
00123 npr += frac;
00124 while(frac--) {
00125 x *= 10;
00126 dig = x;
00127 x -= dig;
00128 putc(dig+'0');
00129 if(!(--k)) { putc('.'); k=800; }
00130 }
00131 return npr;
00132 }
00133
00134 int va_printf(void (*putc)(int), const char *formato, va_list va)
00135 {
00136 char buf[16];
00137 char *s, *ps;
00138 int c, frac, n, sinal, base, nprinted;
00139 int campo,padchar;
00140 double x, y;
00141 s=(char *)formato;
00142 nprinted=campo=0;
00143 while((c=*s++)) {
00144 if(c != '%') { putc(c); nprinted++; continue;}
00145 c=*s++;
00146 sinal=frac=campo=0;
00147 padchar = ((c=='0')? '0' + 0x100:' ' + 0x100);
00148 if(c=='-') { padchar =' '; c=*s++; }
00149 while(edigito(c)) { campo=10*campo+c-'0'; c=*s++; }
00150 if(c=='.') {
00151 c=*s++;
00152 while(edigito(c)) { frac=10*frac+c-'0'; c=*s++; }
00153 }
00154 while(c=='l' || c=='L' || c=='h') c=*s++;
00155 base=10;
00156 if(c >= 'A' && c <= 'Z') c ^= 0x20;
00157 switch(c){
00158 case 'o': case 'q': base=8; goto lbl_u;
00159 case 'x': base=16;
00160 case 'u':
00161 lbl_u:
00162 n = u2str(buf, va_arg(va, unsigned int), base);
00163 lbl_escrevei:
00164 nprinted += n;
00165 campo -= (n+sinal);
00166 if(campo < 0) campo=0;
00167 nprinted +=campo;
00168 if(padchar & 0x100) while(campo--) putc(padchar);
00169 if(sinal) putc('-');
00170 while(n--) putc(buf[n]);
00171 break;
00172 case 'd': case 'i':
00173 base=va_arg(va, int);
00174 if(base < 0) { sinal=1; base=-base; }
00175 n = u2str(buf, base, 10);
00176 goto lbl_escrevei;
00177 case 'c':
00178 if(campo < 0) campo=0;
00179 nprinted +=campo;
00180 if(padchar & 0x100) while(campo--) putc(padchar);
00181 putc(va_arg(va, int)); nprinted++; break;
00182 case 's':
00183 ps = va_arg(va, char *);
00184 for(n=0; ps[n]; n++);
00185 nprinted += n;
00186 campo -= n;
00187 if(campo < 0) campo=0;
00188 nprinted +=campo;
00189 if(padchar & 0x100) while(campo--) putc(padchar);
00190 while(*ps) { putc(*ps); ps++; }
00191 break;
00192 case 'e': case 'f': case 'g':
00193 n=0;
00194 x=y=va_arg(va, double);
00195 if(x<0) { x=-x; sinal=1; }
00196 while((x > 1.0)) { x /= 10.0; n++; }
00197 if(x) while((x < 1.0)) { x *= 10.0; n--; }
00198 if(c=='e' || ((c=='g') &&
00199 ((n > 9) || ((-n >= frac)&& frac)))){
00200 y = (sinal ? -x: x);
00201 sinal = 2;
00202 campo -=4;
00203 if(frac<2) frac=2;
00204 }
00205 c = dprint(y, (padchar & 0x100)?campo:0, frac, putc);
00206 campo -=c;
00207 nprinted +=c;
00208 if(sinal & 2){
00209 putc('E');
00210 if(n < 0) { putc('-'); n=-n; }
00211 else putc('+');
00212 if(n>99) { putc((n/100) + '0'); n %= 100; }
00213 putc((n / 10) + '0');
00214 putc((n % 10) + '0');
00215 }
00216 break;
00217 case '%': putc(c); nprinted++; break;
00218 }
00219 if(campo < 0) campo=0;
00220 nprinted +=campo;
00221 if(!(padchar & 0x100)) while(campo--) putc(padchar);
00222 }
00223 return nprinted;
00224 }
00225
00226 int mprintf(void (*putc)(int), const char *formato, ... )
00227 {
00228 va_list va;
00229 va_start(va,formato);
00230 return va_printf(putc, formato, va);
00231 }
00232
00233 char *gp_buf;
00234 void sputchar(int c) { *gp_buf++=c; }
00235
00236
00237 int sprintf(char *buf, const char *formato, ... )
00238 {
00239 va_list va;
00240 int n;
00241 va_start(va,formato);
00242 gp_buf=buf;
00243 n=va_printf(sputchar, formato, va);
00244 *gp_buf='\0';
00245 return n;
00246 }