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