123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- #include "types.h"
- #include "stat.h"
- #include "user.h"
- static void
- putc(int fd, char c)
- {
- write(fd, &c, 1);
- }
- u32 div(u32 n, u32 d) // long division
- {
- u32 q=0, r=0;
- int i;
- for(i=31;i>=0;i--){
- r = r << 1;
- r = r | ((n >> i) & 1);
- if(r >= d) {
- r = r - d;
- q = q | (1 << i);
- }
- }
- return q;
- }
- static void
- printint(int fd, int xx, int base, int sgn)
- {
- static char digits[] = "0123456789ABCDEF";
- char buf[16];
- int i, neg;
- uint x, y, b;
- neg = 0;
- if(sgn && xx < 0){
- neg = 1;
- x = -xx;
- } else {
- x = xx;
- }
- b = base;
- i = 0;
- do{
- y = div(x, b);
- buf[i++] = digits[x - y * b];
- }while((x = y) != 0);
- if(neg)
- buf[i++] = '-';
- while(--i >= 0)
- putc(fd, buf[i]);
- }
- // Print to the given fd. Only understands %d, %x, %p, %s.
- void
- printf(int fd, char *fmt, ...)
- {
- char *s;
- int c, i, state;
- uint *ap;
- state = 0;
- ap = (uint*)(void*)&fmt + 1;
- for(i = 0; fmt[i]; i++){
- c = fmt[i] & 0xff;
- if(state == 0){
- if(c == '%'){
- state = '%';
- } else {
- putc(fd, c);
- }
- } else if(state == '%'){
- if(c == 'd'){
- printint(fd, *ap, 10, 1);
- ap++;
- } else if(c == 'x' || c == 'p'){
- printint(fd, *ap, 16, 0);
- ap++;
- } else if(c == 's'){
- s = (char*)*ap;
- ap++;
- if(s == 0)
- s = "(null)";
- while(*s != 0){
- putc(fd, *s);
- s++;
- }
- } else if(c == 'c'){
- putc(fd, *ap);
- ap++;
- } else if(c == '%'){
- putc(fd, c);
- } else {
- // Unknown % sequence. Print it to draw attention.
- putc(fd, '%');
- putc(fd, c);
- }
- state = 0;
- }
- }
- }
|