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   uint 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   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 }
  49 
  50 // Print to the given fd. Only understands %d, %x, %p, %c, %s.
  51 void
  52 vprintf(int fd, const char *fmt, va_list ap)
  53 {
  54   char *s;
  55   int c0, c1, c2, i, state;
  56 
  57   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       }
 110 
 111       state = 0;
 112     }
 113   }
 114 }
 115 
 116 void
 117 fprintf(int fd, const char *fmt, ...)
 118 {
 119   va_list ap;
 120 
 121   va_start(ap, fmt);
 122   vprintf(fd, fmt, ap);
 123 }
 124 
 125 void
 126 printf(const char *fmt, ...)
 127 {
 128   va_list ap;
 129 
 130   va_start(ap, fmt);
 131   vprintf(1, fmt, ap);
 132 }

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