source: trunk/kernel/libk/iprintk.c @ 286

Last change on this file since 286 was 1, checked in by alain, 8 years ago

First import

File size: 5.2 KB
Line 
1/*
2   This file is part of MutekP.
3
4   MutekP is free software; you can redistribute it and/or modify it
5   under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2 of the License, or
7   (at your option) any later version.
8
9   MutekP is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with MutekP; if not, write to the Free Software Foundation,
16   Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18   UPMC / LIP6 / SOC (c) 2007
19   */
20
21/*
22   revision 1.2.2 2011/07/12 11:08:34 Ghassan
23   - Split main loop into 3 noinline functions: compute_dec32, compute_dec64, compute_hex
24   - Use bigger buffer size
25   - Reuse buffer treatment
26   - Add 64 bits support
27   - Add char count;
28
29   revision 1.2.1 2007/11/11 18:54:23 Ghassan
30   rename iprintf to __iprintk, it's a copy of iprintf called on system level.
31
32   stdio of the ghost of libc
33   Developped by Denis Hommais and Frédéric Pétrot
34   $Log: iprintf.c,v $
35   Revision 1.2  2003/07/01 13:40:46  fred
36   Supports the %u and doesnt core anymore on an unrecognized char
37   following a %
38
39   Revision 1.1.1.1  2002/02/28 12:58:56  disydent
40   Creation of Disydent CVS Tree
41
42   Revision 1.1  2001/11/22 15:07:36  fred
43   Adding the iprintf function that does the formatting, and removes all
44   the old stuff hanging around.
45
46   $Id: iprintf.c,v 1.2 2003/07/01 13:40:46 fred Exp $
47   Made up this file to centralize the printf behavior
48   */
49
50#include <remote_access.h>
51#include <stdarg.h>
52#include <types.h>
53#include <libk.h>
54
55/* Handling of the printf internals
56 * Addr is either the buffer or the tty addrs
57 * inc is 0 for a tty and 1 for a buffer
58 * Other arguments are self explanatory
59 */
60
61#define SIZE_OF_BUF 20
62
63char* __attribute__((noinline)) compute_dec64(char **addr,
64                uint_t cid,
65                char *buf,
66                uint_t *len,
67                int inc, 
68                uint64_t val, 
69                bool_t isSigned)
70{
71        register int64_t sval;
72        register uint32_t uval;
73        register char *tmp;
74        register uint_t count;
75        register uint_t i;
76
77        if(isSigned == true)
78        {
79                sval = val;
80                if(sval < 0)
81                {
82                        sval = -sval;
83                        val = sval;
84                        remote_sb((void*)*addr, cid, '-');
85                        *len = *len + 1;
86                        (*addr) += inc;
87                }
88        }
89
90        count = 0;
91        i = 0;
92        tmp = buf + SIZE_OF_BUF;
93        *--tmp = '\0';
94
95        while(val >= 1000000000UL)
96        {
97                val -= 1000000000UL;
98                count ++;
99        }
100
101        uval = (uint32_t) val;
102
103        do
104        {
105                *--tmp = (uval % 10) + '0';
106                uval /= 10;
107                i++;
108        }while((uval) || (i < 9));
109
110        uval = count;
111
112        do
113        {
114                *--tmp = (uval % 10) + '0';
115                uval /= 10;
116        }while(uval);
117
118        return tmp;
119}
120
121static char* __attribute__((noinline)) compute_dec(char **addr,
122                uint_t cid,
123                char *buf,
124                uint_t *len,
125                int inc, 
126                uint_t val, 
127                bool_t isSigned)
128{
129        register sint_t sval;
130        register char *tmp;
131
132        if(isSigned == true)
133        {
134                sval = val;
135                if(sval < 0)
136                {
137                        sval = -sval;
138                        val = sval;
139                        remote_sb(*addr, cid, '-');
140                        *len = *len + 1;
141                        (*addr) += inc;
142                }
143        }
144
145        tmp = buf + SIZE_OF_BUF;
146        *--tmp = '\0';
147
148        do
149        {
150                *--tmp = (val % 10) + '0';
151                val /= 10;
152        }while (val);
153
154        return tmp;
155}
156
157static char* __attribute__((noinline)) compute_hex(char **addr, 
158                uint_t cid,
159                char *buf, 
160                uint_t val, 
161                bool_t isPointer)
162{
163        register char *tmp;
164        register char *xdigit;
165        register uint_t i;
166
167        i = 0;
168        xdigit = "0123456789abcdef";
169        tmp = buf + SIZE_OF_BUF;
170        *--tmp = '\0';
171
172        do
173        {
174                *--tmp = xdigit[val & 15];
175                val = val >> 4;
176                i++;
177        }while (val);
178
179        if(isPointer)
180        {
181                while (i < 8)
182                {
183                        *--tmp = xdigit[0];
184                        i++;
185                }
186        }
187
188        return tmp;
189}
190
191int iprintk (char *addr, uint_t cid, int inc, const char *fmt, va_list ap)
192{
193        char *tmp;
194        sint_t val;
195        uint_t uval;
196        uint64_t val64;
197        uint_t count = 0;
198        char buf[SIZE_OF_BUF];
199
200        while (*fmt)
201        {
202                while ((*fmt != '%') && (*fmt))
203                {
204                        remote_sb(addr, cid, *fmt++);
205                        addr += inc;
206                        count++;
207                }
208                if (*fmt)
209                {
210                        fmt++;
211                        switch (*fmt)
212                        {
213                                case '%':
214                                        remote_sb(addr, cid, '%');
215                                        addr += inc;
216                                        count++;
217                                        goto next;
218                                case 'c':
219                                        remote_sb(addr, cid, va_arg (ap, uint_t));
220                                        addr += inc;
221                                        count++;
222                                        goto next;
223                                case 'd':
224                                        val = va_arg (ap, sint_t);
225                                        tmp = compute_dec(&addr, cid, &buf[0], &count, inc, val, true); 
226                                        break;
227                                case 'u':
228                                        uval = va_arg (ap, uint_t);
229                                        tmp = compute_dec(&addr, cid, &buf[0], &count, inc, uval, false); 
230                                        break;
231                                case 'D':
232                                        val64 = va_arg (ap, int64_t);
233                                        tmp = compute_dec64(&addr, cid, &buf[0], &count, inc, val64, true); 
234                                        break;
235                                case 'U':
236                                        val64 = va_arg (ap, uint64_t);
237                                        tmp = compute_dec64(&addr, cid, &buf[0], &count, inc, val64, false); 
238                                        break;
239                                case 's':
240                                        tmp = va_arg (ap, char *);
241                                        if (!tmp)
242                                                tmp = "empty str";
243                                        break;
244                                case 'p':
245                                case 'x':
246                                        uval = va_arg (ap, uint_t);
247                                        tmp = compute_hex(&addr, cid, &buf[0], uval, (*fmt == 'p') ? true : false);
248                                        break;
249                                default:
250                                        remote_sb(addr, cid, *fmt);
251                                        count++;
252                                        goto next;
253                        }
254                        while (*tmp)
255                        {
256                                remote_sb(addr, cid, *tmp++);
257                                addr += inc;
258                                count++;
259                        }
260next:
261                        fmt++;
262                }
263        }
264        va_end (ap);
265        return count;
266}
Note: See TracBrowser for help on using the repository browser.