1 | #include "types.h" |
2 | #include "stat.h" |
3 | #include "user.h" |
4 | |
5 | static void |
6 | putc(int fd, char c) |
7 | { |
8 | write(fd, &c, 1); |
9 | } |
10 | |
11 | static void |
12 | printint(int fd, int xx, int base, int sgn) |
13 | { |
14 | static char digits[] = "0123456789ABCDEF" ; |
15 | char buf[16]; |
16 | int i, neg; |
17 | uint x; |
18 | |
19 | neg = 0; |
20 | if(sgn && xx < 0){ |
21 | neg = 1; |
22 | x = -xx; |
23 | } else { |
24 | x = xx; |
25 | } |
26 | |
27 | i = 0; |
28 | do{ |
29 | buf[i++] = digits[x % base]; |
30 | }while((x /= base) != 0); |
31 | if(neg) |
32 | buf[i++] = '-'; |
33 | |
34 | while(--i >= 0) |
35 | putc(fd, buf[i]); |
36 | } |
37 | |
38 | // Print to the given fd. Only understands %d, %x, %p, %s. |
39 | void |
40 | printf(int fd, const char *fmt, ...) |
41 | { |
42 | char *s; |
43 | int c, i, state; |
44 | uint *ap; |
45 | |
46 | state = 0; |
47 | ap = (uint*)(void*)&fmt + 1; |
48 | for(i = 0; fmt[i]; i++){ |
49 | c = fmt[i] & 0xff; |
50 | if(state == 0){ |
51 | if(c == '%'){ |
52 | state = '%'; |
53 | } else { |
54 | putc(fd, c); |
55 | } |
56 | } else if(state == '%'){ |
57 | if(c == 'd'){ |
58 | printint(fd, *ap, 10, 1); |
59 | ap++; |
60 | } else if(c == 'x' || c == 'p'){ |
61 | printint(fd, *ap, 16, 0); |
62 | ap++; |
63 | } else if(c == 's'){ |
64 | s = (char*)*ap; |
65 | ap++; |
66 | if(s == 0) |
67 | s = "(null)" ; |
68 | while(*s != 0){ |
69 | putc(fd, *s); |
70 | s++; |
71 | } |
72 | } else if(c == 'c'){ |
73 | putc(fd, *ap); |
74 | ap++; |
75 | } else if(c == '%'){ |
76 | putc(fd, c); |
77 | } else { |
78 | // Unknown % sequence. Print it to draw attention. |
79 | putc(fd, '%'); |
80 | putc(fd, c); |
81 | } |
82 | state = 0; |
83 | } |
84 | } |
85 | } |
86 | |