efi_loader: Fix some entry/exit points
[platform/kernel/u-boot.git] / lib / tiny-printf.c
1 /*
2  * Tiny printf version for SPL
3  *
4  * Copied from:
5  * http://www.sparetimelabs.com/printfrevisited/printfrevisited.php
6  *
7  * Copyright (C) 2004,2008  Kustaa Nyholm
8  *
9  * SPDX-License-Identifier:     LGPL-2.1+
10  */
11
12 #include <common.h>
13 #include <stdarg.h>
14 #include <serial.h>
15
16 static char *bf;
17 static char zs;
18
19 static void out(char c)
20 {
21         *bf++ = c;
22 }
23
24 static void out_dgt(char dgt)
25 {
26         out(dgt + (dgt < 10 ? '0' : 'a' - 10));
27         zs = 1;
28 }
29
30 static void div_out(unsigned int *num, unsigned int div)
31 {
32         unsigned char dgt = 0;
33
34         while (*num >= div) {
35                 *num -= div;
36                 dgt++;
37         }
38
39         if (zs || dgt > 0)
40                 out_dgt(dgt);
41 }
42
43 int vprintf(const char *fmt, va_list va)
44 {
45         char ch;
46         char *p;
47         unsigned int num;
48         char buf[12];
49         unsigned int div;
50
51         while ((ch = *(fmt++))) {
52                 if (ch != '%') {
53                         putc(ch);
54                 } else {
55                         char lz = 0;
56                         char w = 0;
57
58                         ch = *(fmt++);
59                         if (ch == '0') {
60                                 ch = *(fmt++);
61                                 lz = 1;
62                         }
63
64                         if (ch >= '0' && ch <= '9') {
65                                 w = 0;
66                                 while (ch >= '0' && ch <= '9') {
67                                         w = (w * 10) + ch - '0';
68                                         ch = *fmt++;
69                                 }
70                         }
71                         bf = buf;
72                         p = bf;
73                         zs = 0;
74
75                         switch (ch) {
76                         case 0:
77                                 goto abort;
78                         case 'u':
79                         case 'd':
80                                 num = va_arg(va, unsigned int);
81                                 if (ch == 'd' && (int)num < 0) {
82                                         num = -(int)num;
83                                         out('-');
84                                 }
85                                 if (!num) {
86                                         out_dgt(0);
87                                 } else {
88                                         for (div = 1000000000; div; div /= 10)
89                                                 div_out(&num, div);
90                                 }
91                                 break;
92                         case 'x':
93                                 num = va_arg(va, unsigned int);
94                                 if (!num) {
95                                         out_dgt(0);
96                                 } else {
97                                         for (div = 0x10000000; div; div /= 0x10)
98                                                 div_out(&num, div);
99                                 }
100                                 break;
101                         case 'c':
102                                 out((char)(va_arg(va, int)));
103                                 break;
104                         case 's':
105                                 p = va_arg(va, char*);
106                                 break;
107                         case '%':
108                                 out('%');
109                         default:
110                                 break;
111                         }
112
113                         *bf = 0;
114                         bf = p;
115                         while (*bf++ && w > 0)
116                                 w--;
117                         while (w-- > 0)
118                                 putc(lz ? '0' : ' ');
119                         if (p) {
120                                 while ((ch = *p++))
121                                         putc(ch);
122                         }
123                 }
124         }
125
126 abort:
127         return 0;
128 }
129
130 int printf(const char *fmt, ...)
131 {
132         va_list va;
133         int ret;
134
135         va_start(va, fmt);
136         ret = vprintf(fmt, va);
137         va_end(va);
138
139         return ret;
140 }