carl9170: Update based on commit 467556acea56f361a21b2a3761ca056b9da2d237 dated Nov...
[linux-libre-firmware.git] / carl9170fw / carlfw / src / printf.c
1 /*
2  * Copyright (C) 2004,2008  Kustaa Nyholm
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * with this program; If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include "carl9170.h"
19 #include "printf.h"
20
21 #ifdef CONFIG_CARL9170FW_PRINTF
22 static char *bf;
23 static char buf[12];
24 static unsigned int num;
25 static char uc;
26 static char zs;
27
28 static void out(const char c)
29 {
30         *bf++ = c;
31 }
32
33 static void outDgt(const char dgt)
34 {
35         out(dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10));
36         zs = 1;
37 }
38
39 static void divOut(const unsigned int d)
40 {
41         unsigned char dgt = 0;
42
43         while (num >= d) {
44                 num -= d;
45                 dgt++;
46         }
47
48         if (zs || dgt > 0)
49                 outDgt(dgt);
50 }
51
52 void tfp_printf(const char *fmt, ...)
53 {
54         va_list va;
55         char *p;
56         unsigned int i;
57         char ch;
58
59         va_start(va, fmt);
60
61         while ((ch = *(fmt++))) {
62                 if (ch != '%') {
63                         putcharacter(ch);
64                 } else {
65                         char lz = 0;
66                         char w = 0;
67                         ch = *(fmt++);
68
69                         if (ch == '0') {
70                                 ch = *(fmt++);
71                                 lz = 1;
72                         }
73
74                         if (ch >= '0' && ch <= '9') {
75                                 w = 0;
76                                 while (ch >= '0' && ch <= '9') {
77                                         w = (((w << 2) + w) << 1) + ch - '0';
78                                         ch = *fmt++;
79                                         }
80                         }
81
82                         bf = buf;
83                         p = bf;
84                         zs = 0;
85
86                         switch (ch) {
87                         case 0:
88                                 goto abort;
89
90                         case 'u':
91                         case 'd':
92                                 num = va_arg(va, unsigned int);
93                                 if (ch == 'd' && (int) num < 0) {
94                                         num = -(int)num;
95                                         out('-');
96                                 }
97
98                                 for (i = 100000000; i != 1; i /= 10)
99                                         divOut(i);
100
101                                 outDgt(num);
102                                 break;
103
104                         case 'p':
105                         case 'x':
106                         case 'X':
107                                 uc = ch == 'X';
108                                 num = va_arg(va, unsigned int);
109                                 for (i = 0x10000000; i != 0x1; i >>= 4)
110                                         divOut(i);
111
112                                 outDgt(num);
113                                 break;
114
115                         case 'c':
116                                 out((char)(va_arg(va, int)));
117                                 break;
118
119                         case 's':
120                                 p = va_arg(va, char*);
121                                 break;
122                         case '%':
123                                 out('%');
124                                 break;
125
126                         default:
127                                 break;
128                                 }
129
130                         *bf = 0;
131                         bf = p;
132                         while (*bf++ && w > 0)
133                                 w--;
134
135                         while (w-- > 0)
136                                 putcharacter(lz ? '0' : ' ');
137
138                         while ((ch = *p++))
139                                 putcharacter(ch);
140                 }
141         }
142
143 abort:
144         putcharacter('\0');
145         va_end(va);
146 }
147
148 #else
149
150 void min_printf(const char *fmt, ...)
151 {
152         char ch;
153
154         do {
155                 ch = *(fmt++);
156                 putcharacter(ch);
157         } while (ch);
158 }
159
160 #endif /* CONFIG_CARL9170FW_PRINTF */