root/user/printf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. putc
  2. printint
  3. printptr
  4. vprintf
  5. fprintf
  6. printf

   1 #include "kernel/types.h"
   2 #include "kernel/stat.h"
   3 #include "user/user.h"
   4 
   5 #include <stdarg.h>
   6 
   7 static char digits[] = "0123456789ABCDEF";
   8 
   9 static void
  10 putc(int fd, char c)
  11 {
  12   write(fd, &c, 1);
  13 }
  14 
  15 static void
  16 printint(int fd, long long xx, int base, int sgn)
  17 {
  18   char buf[20];
  19   int i, neg;
  20   unsigned long long x;
  21 
  22   neg = 0;
  23   if (sgn && xx < 0) {
  24     neg = 1;
  25     x = -xx;
  26   } else {
  27     x = xx;
  28   }
  29 
  30   i = 0;
  31   do {
  32     buf[i++] = digits[x % base];
  33   } while ((x /= base) != 0);
  34   if (neg)
  35     buf[i++] = '-';
  36 
  37   while (--i >= 0)
  38     putc(fd, buf[i]);
  39 }
  40 
  41 static void
  42 printptr(int fd, uint64 x)
  43 {
  44   int i;
  45   putc(fd, '0');
  46   putc(fd, 'x');
  47   for (i = 0; i < (sizeof(uint64) * 2); i++, x <<= 4)
  48     putc(fd, digits[x >> (sizeof(uint64) * 8 - 4)]);
  49 }
  50 
  51 // Print to the given fd. Only understands %d, %x, %p, %c, %s.
  52 void
  53 vprintf(int fd, const char *fmt, va_list ap)
  54 {
  55   char *s;
  56   int c0, c1, c2, i, state;
  57 
  58   state = 0;
  59   for (i = 0; fmt[i]; i++) {
  60     c0 = fmt[i] & 0xff;
  61     if (state == 0) {
  62       if (c0 == '%') {
  63         state = '%';
  64       } else {
  65         putc(fd, c0);
  66       }
  67     } else if (state == '%') {
  68       c1 = c2 = 0;
  69       if (c0)
  70         c1 = fmt[i + 1] & 0xff;
  71       if (c1)
  72         c2 = fmt[i + 2] & 0xff;
  73       if (c0 == 'd') {
  74         printint(fd, va_arg(ap, int), 10, 1);
  75       } else if (c0 == 'l' && c1 == 'd') {
  76         printint(fd, va_arg(ap, uint64), 10, 1);
  77         i += 1;
  78       } else if (c0 == 'l' && c1 == 'l' && c2 == 'd') {
  79         printint(fd, va_arg(ap, uint64), 10, 1);
  80         i += 2;
  81       } else if (c0 == 'u') {
  82         printint(fd, va_arg(ap, uint32), 10, 0);
  83       } else if (c0 == 'l' && c1 == 'u') {
  84         printint(fd, va_arg(ap, uint64), 10, 0);
  85         i += 1;
  86       } else if (c0 == 'l' && c1 == 'l' && c2 == 'u') {
  87         printint(fd, va_arg(ap, uint64), 10, 0);
  88         i += 2;
  89       } else if (c0 == 'x') {
  90         printint(fd, va_arg(ap, uint32), 16, 0);
  91       } else if (c0 == 'l' && c1 == 'x') {
  92         printint(fd, va_arg(ap, uint64), 16, 0);
  93         i += 1;
  94       } else if (c0 == 'l' && c1 == 'l' && c2 == 'x') {
  95         printint(fd, va_arg(ap, uint64), 16, 0);
  96         i += 2;
  97       } else if (c0 == 'p') {
  98         printptr(fd, va_arg(ap, uint64));
  99       } else if (c0 == 'c') {
 100         putc(fd, va_arg(ap, uint32));
 101       } else if (c0 == 's') {
 102         if ((s = va_arg(ap, char *)) == 0)
 103           s = "(null)";
 104         for (; *s; s++)
 105           putc(fd, *s);
 106       } else if (c0 == '%') {
 107         putc(fd, '%');
 108       } else {
 109         // Unknown % sequence.  Print it to draw attention.
 110         putc(fd, '%');
 111         putc(fd, c0);
 112       }
 113 
 114       state = 0;
 115     }
 116   }
 117 }
 118 
 119 void
 120 fprintf(int fd, const char *fmt, ...)
 121 {
 122   va_list ap;
 123 
 124   va_start(ap, fmt);
 125   vprintf(fd, fmt, ap);
 126 }
 127 
 128 void
 129 printf(const char *fmt, ...)
 130 {
 131   va_list ap;
 132 
 133   va_start(ap, fmt);
 134   vprintf(1, fmt, ap);
 135 }

/* [<][>][^][v][top][bottom][index][help] */