user/printf.c

132 lines
1#include "kernel/types.h"2#include "kernel/stat.h"3#include "user/user.h"45#include <stdarg.h>67static char digits[] = "0123456789ABCDEF";89static void10putc(int fd, char c)11{12  write(fd, &c, 1);13}1415static void16printint(int fd, long long xx, int base, int sgn)17{18  char buf[20];19  int i, neg;20  unsigned long long x;2122  neg = 0;23  if(sgn && xx < 0){24    neg = 1;25    x = -xx;26  } else {27    x = xx;28  }2930  i = 0;31  do{32    buf[i++] = digits[x % base];33  }while((x /= base) != 0);34  if(neg)35    buf[i++] = '-';3637  while(--i >= 0)38    putc(fd, buf[i]);39}4041static void42printptr(int fd, uint64 x) {43  int i;44  putc(fd, '0');45  putc(fd, 'x');46  for (i = 0; i < (sizeof(uint64) * 2); i++, x <<= 4)47    putc(fd, digits[x >> (sizeof(uint64) * 8 - 4)]);48}4950// Print to the given fd. Only understands %d, %x, %p, %c, %s.51void52vprintf(int fd, const char *fmt, va_list ap)53{54  char *s;55  int c0, c1, c2, i, state;5657  state = 0;58  for(i = 0; fmt[i]; i++){59    c0 = fmt[i] & 0xff;60    if(state == 0){61      if(c0 == '%'){62        state = '%';63      } else {64        putc(fd, c0);65      }66    } else if(state == '%'){67      c1 = c2 = 0;68      if(c0) c1 = fmt[i+1] & 0xff;69      if(c1) c2 = fmt[i+2] & 0xff;70      if(c0 == 'd'){71        printint(fd, va_arg(ap, int), 10, 1);72      } else if(c0 == 'l' && c1 == 'd'){73        printint(fd, va_arg(ap, uint64), 10, 1);74        i += 1;75      } else if(c0 == 'l' && c1 == 'l' && c2 == 'd'){76        printint(fd, va_arg(ap, uint64), 10, 1);77        i += 2;78      } else if(c0 == 'u'){79        printint(fd, va_arg(ap, uint32), 10, 0);80      } else if(c0 == 'l' && c1 == 'u'){81        printint(fd, va_arg(ap, uint64), 10, 0);82        i += 1;83      } else if(c0 == 'l' && c1 == 'l' && c2 == 'u'){84        printint(fd, va_arg(ap, uint64), 10, 0);85        i += 2;86      } else if(c0 == 'x'){87        printint(fd, va_arg(ap, uint32), 16, 0);88      } else if(c0 == 'l' && c1 == 'x'){89        printint(fd, va_arg(ap, uint64), 16, 0);90        i += 1;91      } else if(c0 == 'l' && c1 == 'l' && c2 == 'x'){92        printint(fd, va_arg(ap, uint64), 16, 0);93        i += 2;94      } else if(c0 == 'p'){95        printptr(fd, va_arg(ap, uint64));96      } else if(c0 == 'c'){97        putc(fd, va_arg(ap, uint32));98      } else if(c0 == 's'){99        if((s = va_arg(ap, char*)) == 0)100          s = "(null)";101        for(; *s; s++)102          putc(fd, *s);103      } else if(c0 == '%'){104        putc(fd, '%');105      } else {106        // Unknown % sequence.  Print it to draw attention.107        putc(fd, '%');108        putc(fd, c0);109      }110111      state = 0;112    }113  }114}115116void117fprintf(int fd, const char *fmt, ...)118{119  va_list ap;120121  va_start(ap, fmt);122  vprintf(fd, fmt, ap);123}124125void126printf(const char *fmt, ...)127{128  va_list ap;129130  va_start(ap, fmt);131  vprintf(1, fmt, ap);132}133