source: trunk/kernel/libk/iprintk.c.bak @ 9

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

First import

File size: 5.4 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 <stdarg.h>
51#include <types.h>
52#include <libk.h>
53
54/* Handling of the printf internals
55 * Addr is either the buffer or the tty addrs
56 * inc is 0 for a tty and 1 for a buffer
57 * Other arguments are self explanatory
58 */
59
60#define SIZE_OF_BUF 20
61
62static char* __attribute__((noinline)) compute_dec64(char **addr,
63                                                     char *buf,
64                                                     int inc,
65                                                     uint64_t val,
66                                                     bool_t isSigned)
67{
68  register int64_t sval;
69  register uint32_t uval;
70  register char *tmp;
71  register uint_t count;
72  register uint_t i;
73
74  if(isSigned == true)
75  {
76    sval = val;
77    if(sval < 0)
78    {
79      sval = -sval;
80      val = sval;
81      **addr = '-';
82      (*addr) += inc;
83    }
84  }
85
86  count = 0;
87  i = 0;
88  tmp = buf + SIZE_OF_BUF;
89  *--tmp = '\0';
90 
91  while(val >= 1000000000UL)
92  {
93    val -= 1000000000UL;
94    count ++;
95  }
96
97  uval = (uint32_t) val;
98
99  do
100  {
101    *--tmp = (uval % 10) + '0';
102    uval /= 10;
103    i++;
104  }while((uval) || (i < 9));
105 
106  uval = count;
107
108  do
109  {
110    *--tmp = (uval % 10) + '0';
111    uval /= 10;
112  }while(uval);
113
114  return tmp;
115}
116
117static char* __attribute__((noinline)) compute_dec(char **addr,
118                                                   char *buf,
119                                                   int inc,
120                                                   uint_t val,
121                                                   bool_t isSigned)
122{
123  register sint_t sval;
124  register char *tmp;
125
126  if(isSigned == true)
127  {
128    sval = val;
129    if(sval < 0)
130    {
131      sval = -sval;
132      val = sval;
133      **addr = '-';
134      (*addr) += inc;
135    }
136  }
137
138  tmp = buf + SIZE_OF_BUF;
139  *--tmp = '\0';
140
141  do
142  {
143    *--tmp = (val % 10) + '0';
144    val /= 10;
145  }while (val);
146
147  return tmp;
148}
149
150static char* __attribute__((noinline)) compute_hex(char **addr,
151                                                   char *buf,
152                                                   uint_t val,
153                                                   bool_t isPointer)
154{
155  register char *tmp;
156  register char *xdigit;
157  register uint_t i;
158
159  i = 0;
160  xdigit = "0123456789abcdef";
161  tmp = buf + SIZE_OF_BUF;
162  *--tmp = '\0';
163
164  do
165  {
166    *--tmp = xdigit[val & 15];
167    val = val >> 4;
168    i++;
169  }while (val);
170
171  if(isPointer)
172  {
173    while (i < 8)
174    {
175      *--tmp = xdigit[0];
176      i++;
177    }
178  }
179
180  return tmp;
181}
182
183int iprintk (char *addr, int inc, const char *fmt, va_list ap)
184{
185   char *tmp;
186   sint_t val;
187   uint_t uval;
188   uint_t count = 0;
189   char buf[SIZE_OF_BUF];
190
191   while (*fmt)
192   {
193      while ((*fmt != '%') && (*fmt))
194      {
195        *addr = *fmt++;
196         addr += inc;
197         count++;
198      }
199      if (*fmt)
200      {
201         fmt++;
202         switch (*fmt)
203         {
204         case '%':
205            *addr = '%';
206            addr += inc;
207            count++;
208            goto next;
209         case 'c':
210            *addr = va_arg (ap, uint_t);
211            addr += inc;
212            count++;
213            goto next;
214         case 'd':
215            count ++;
216            val = va_arg (ap, sint_t);
217            tmp = compute_dec(&addr, &buf[0], inc, val, true);
218            break;
219         case 'u':
220            uval = va_arg (ap, uint_t);
221            tmp = compute_dec(&addr, &buf[0], inc, uval, false);
222            break;
223         case 'D':
224            count ++;
225            val = va_arg (ap, int64_t);
226            tmp = compute_dec64(&addr, &buf[0], inc, val, true);
227            break;
228         case 'U':
229            uval = va_arg (ap, uint64_t);
230            tmp = compute_dec64(&addr, &buf[0], inc, uval, false);
231            break;
232         case 's':
233            tmp = va_arg (ap, char *);
234            if (!tmp)
235               tmp = "empty str";
236            break;
237         case 'p':
238         case 'x':
239           uval = va_arg (ap, uint_t);
240           tmp = compute_hex(&addr, &buf[0], uval, (*fmt == 'p') ? true : false);
241           break;
242         default:
243            *addr = *fmt;
244            count++;
245            goto next;
246         }
247         while (*tmp)
248         {
249            *addr = *tmp++;
250            addr += inc;
251            count++;
252         }
253       next:
254         fmt++;
255      }
256   }
257   va_end (ap);
258   return count;
259}
Note: See TracBrowser for help on using the repository browser.