Indentation fix, cleanup.
[AROS.git] / compiler / arossupport / kprintf.c
blob84cf2c7a0fcaabe5cb3c4ccda6312a7761e6e03a
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Formats a message and makes sure the user will see it.
6 Lang: english
7 */
9 #include <aros/config.h>
10 #include <aros/arossupportbase.h>
11 #include <stdarg.h>
13 #include <aros/system.h>
14 #include <dos/bptr.h>
15 #include <proto/exec.h>
16 #include <proto/arossupport.h>
17 #undef kprintf
18 #undef vkprintf
19 #include <exec/execbase.h>
21 /* Can't use ctype.h *sigh* */
22 #define isdigit(x) ((x) >= '0' && (x) <= '9')
23 #define isprint(x) (((x) >= ' ' && (x) <= 128) || (x) >= 160)
25 /* Nor string.h */
26 static inline int my_strlen(const char *c)
28 int i = 0;
29 while (*(c++)) i++;
30 return i;
33 /* Nor atoi */
34 static inline int atoi(const char *c)
36 int i;
37 int isneg = 0;
39 if (*c == '+')
40 c++;
42 if (*c == '-') {
43 isneg = 1;
44 c++;
47 for (i = 0; *c && isdigit(*c); c++) {
48 i *= 10;
49 i += *c - '0';
52 return (isneg) ? -i : i;
55 /*****************************************************************************
57 NAME */
58 #include <proto/arossupport.h>
60 int kprintf (
62 /* SYNOPSIS */
63 const char * fmt,
64 ...)
66 /* FUNCTION
67 Formats fmt with the specified arguments like printf() (and *not*
68 like RawDoFmt()) and uses a secure way to deliver the message to
69 the user; ie. the user *will* see this message no matter what.
71 INPUTS
72 fmt - printf()-style format string
74 RESULT
75 The number of characters output.
77 NOTES
78 This function is not part of a library and may thus be called
79 any time.
81 EXAMPLE
83 BUGS
85 SEE ALSO
87 INTERNALS
89 HISTORY
90 24-12-95 digulla created
92 ******************************************************************************/
94 va_list ap;
95 int result;
97 va_start (ap, fmt);
98 result = vkprintf (fmt, ap);
99 va_end (ap);
101 return result;
102 } /* kprintf */
106 int vkprintf (const char * fmt, va_list args)
108 int ret;
109 static const char uhex[] = "0123456789ABCDEF";
110 static const char lhex[] = "0123456789abcdef";
111 char * fill;
112 unsigned long val;
113 long lval = 0;
115 if (!fmt)
117 RawPutChars ("(null)", 6);
118 return 6;
121 ret = 0;
123 while (*fmt)
125 if (*fmt == '%')
127 int width = 0;
128 int precision = 0;
130 fmt ++;
132 if (*fmt == '0')
134 fill = "00000000";
135 fmt ++;
137 else
139 fill = " ";
142 if (*fmt == '*')
144 width = va_arg (args, int);
145 fmt++;
147 else
148 if (isdigit (*fmt))
150 width = atoi (fmt);
151 while (isdigit(*fmt)) fmt++;
154 if (*fmt == '.') fmt++;
156 if (*fmt == '*')
158 precision = va_arg (args, int);
159 fmt++;
161 else
162 if (isdigit (*fmt))
163 precision = atoi (fmt);
165 while (isdigit(*fmt) || *fmt=='.' || *fmt=='-' || *fmt=='+')
166 fmt ++;
168 switch (*fmt)
170 case '%':
171 RawPutChar (*fmt);
172 ret ++;
173 break;
175 case 'b':
176 #ifndef AROS_FAST_BPTR
178 char * str = va_arg (args, char *);
179 int len;
181 if (str) {
182 str = (char *)((unsigned long)str << 2);
183 len = *str++;
184 } else {
185 str = "(null)";
186 len = 6;
189 if (precision)
190 len = precision;
192 RawPutChars (str, len);
193 ret += len;
195 break; }
196 #endif
197 case 's':
198 case 'S': {
199 char * str = va_arg (args, char *);
200 int len;
202 if (!str)
203 str = "(null)";
205 if (*fmt == 'S')
207 RawPutChar ('"');
208 ret ++;
211 if (precision)
212 len = precision;
213 else
214 len = my_strlen (str);
216 RawPutChars (str, len);
217 ret += len;
219 if (*fmt == 'S')
221 RawPutChar ('"');
222 ret ++;
225 break; }
227 case 'p': {
228 int t;
229 char puffer[sizeof (void *)*2];
231 t = sizeof (void *)*2;
232 val = va_arg (args, IPTR);
234 while (t)
236 puffer[--t] = lhex[val & 0x0F];
237 val >>= 4;
240 RawPutChars (puffer, sizeof (void *)*2);
242 break; }
244 case 'c': {
245 UBYTE c;
247 c = va_arg (args, int);
249 if (isprint (c))
250 RawPutChar (c);
251 else
253 RawPutChars ("'\\0x", 4);
254 RawPutChar (lhex[c / 16]);
255 RawPutChar (lhex[c & 15]);
256 RawPutChar ('\'');
259 break; }
261 case 'l': {
262 int t;
263 char puffer[32];
265 if (fmt[1] == 'u' || fmt[1] == 'd' || fmt[1] == 'x' || fmt[1] == 'X')
266 fmt ++;
268 if (*fmt == 'd')
270 lval = va_arg (args, long);
272 val = (lval < 0) ? -lval : lval;
274 else
276 val = va_arg (args, unsigned long);
279 print_int:
280 if (val==0)
282 if (width == 0)
283 width = 1;
285 if (*fill == ' ')
286 width --;
288 while (width > 0)
290 RawPutChars (fill, (width < 8) ? width : 8);
291 width -= 8;
294 if (*fill == ' ')
295 RawPutChar ('0');
297 ret ++;
298 break;
301 t = 32;
303 if (*fmt == 'd' || *fmt == 'u')
305 if (*fmt == 'd')
307 if (lval < 0)
309 RawPutChar ('-');
310 ret ++;
311 val = -lval;
313 else
314 val = lval;
317 while (val && t)
319 puffer[--t] = lhex[val % 10];
321 val /= 10;
324 else if (*fmt == 'x')
326 while (val && t)
328 puffer[--t] = lhex[val & 0x0F];
330 val >>= 4;
333 else
335 while (val && t)
337 puffer[--t] = uhex[val & 0x0F];
339 val >>= 4;
343 width -= 32-t;
345 while (width > 0)
347 RawPutChars (fill, (width < 8) ? width : 8);
348 width -= 8;
351 RawPutChars (&puffer[t], 32-t);
352 ret += 32-t;
354 break; }
356 default: {
357 if (*fmt == 'd')
359 lval = va_arg (args, int);
361 val = (lval < 0) ? -lval : lval;
363 else
365 val = va_arg (args, unsigned int);
368 goto print_int;
370 break; }
371 } /* switch */
373 else
375 RawPutChar (*fmt);
376 ret ++;
379 fmt ++; /* Next char */
380 } /* while (*fmt); */
382 return ret;
383 } /* vkprintf */