Updated PCI IDs to latest snapshot.
[tangerine.git] / compiler / arossupport / kprintf.c
blob0ca1879f43c8f3b8a7cd2bce08e1c327d2f8e28a
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>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <aros/system.h>
15 #include <dos/bptr.h>
16 #include <proto/exec.h>
17 #include <proto/arossupport.h>
18 #undef kprintf
19 #undef vkprintf
20 #include <unistd.h>
21 #include <exec/execbase.h>
23 #define AROSBase ((struct AROSBase *)(SysBase->DebugData))
25 /* Can't use ctypt.h *sigh* */
26 #define isdigit(x) ((x) >= '0' && (x) <= '9')
27 #define isprint(x) (((x) >= ' ' && (x) <= 128) || (x) >= 160)
29 /*****************************************************************************
31 NAME */
32 #include <proto/arossupport.h>
34 int kprintf (
36 /* SYNOPSIS */
37 const UBYTE * fmt,
38 ...)
40 /* FUNCTION
41 Formats fmt with the specified arguments like printf() (and *not*
42 like RawDoFmt()) and uses a secure way to deliver the message to
43 the user; ie. the user *will* see this message no matter what.
45 INPUTS
46 fmt - printf()-style format string
48 RESULT
49 The number of characters output.
51 NOTES
52 This function is not part of a library and may thus be called
53 any time.
55 EXAMPLE
57 BUGS
59 SEE ALSO
61 INTERNALS
63 HISTORY
64 24-12-95 digulla created
66 ******************************************************************************/
68 va_list ap;
69 int result;
71 va_start (ap, fmt);
72 result = vkprintf (fmt, ap);
73 va_end (ap);
75 return result;
76 } /* kprintf */
80 int vkprintf (const UBYTE * fmt, va_list args)
82 int ret;
83 static const char uhex[] = "0123456789ABCDEF";
84 static const char lhex[] = "0123456789abcdef";
85 char * fill;
86 ULONG val;
87 LONG lval;
89 if (!fmt)
91 RawPutChars ("(null)", 6);
92 return 6;
95 ret = 0;
97 while (*fmt)
99 if (*fmt == '%')
101 int width = 0;
102 int precision = 0;
104 fmt ++;
106 if (*fmt == '0')
108 fill = "00000000";
109 fmt ++;
111 else
113 fill = " ";
116 if (*fmt == '*')
118 width = va_arg (args, int);
119 fmt++;
121 else
122 if (isdigit (*fmt))
124 width = atoi (fmt);
125 while (isdigit(*fmt)) fmt++;
128 if (*fmt == '.') fmt++;
130 if (*fmt == '*')
132 precision = va_arg (args, int);
133 fmt++;
135 else
136 if (isdigit (*fmt))
137 precision = atoi (fmt);
139 while (isdigit(*fmt) || *fmt=='.' || *fmt=='-' || *fmt=='+')
140 fmt ++;
142 switch (*fmt)
144 case '%':
145 RawPutChar (*fmt);
146 ret ++;
147 break;
149 case 'b':
150 #ifndef AROS_FAST_BPTR
152 char * str = va_arg (args, char *);
153 int len;
155 if (str) {
156 str = (char *)((unsigned long)str << 2);
157 len = *str++;
158 } else {
159 str = "(null)";
160 len = 6;
163 if (precision)
164 len = precision;
166 RawPutChars (str, len);
167 ret += len;
169 break; }
170 #endif
171 case 's':
172 case 'S': {
173 char * str = va_arg (args, char *);
174 int len;
176 if (!str)
177 str = "(null)";
179 if (*fmt == 'S')
181 RawPutChar ('"');
182 ret ++;
185 if (precision)
186 len = precision;
187 else
188 len = strlen (str);
190 RawPutChars (str, len);
191 ret += len;
193 if (*fmt == 'S')
195 RawPutChar ('"');
196 ret ++;
199 break; }
201 case 'p': {
202 int t;
203 char puffer[sizeof (void *)*2];
204 IPTR val;
206 t = sizeof (void *)*2;
207 val = va_arg (args, IPTR);
209 while (t)
211 puffer[--t] = lhex[val & 0x0F];
212 val >>= 4;
215 RawPutChars (puffer, sizeof (void *)*2);
217 break; }
219 case 'c': {
220 UBYTE c;
222 c = va_arg (args, int);
224 if (isprint (c))
225 RawPutChar (c);
226 else
228 RawPutChars ("'\\0x", 4);
229 RawPutChar (lhex[c / 16]);
230 RawPutChar (lhex[c & 15]);
231 RawPutChar ('\'');
234 break; }
236 case 'l': {
237 int t;
238 char puffer[32];
240 if (fmt[1] == 'u' || fmt[1] == 'd' || fmt[1] == 'x' || fmt[1] == 'X')
241 fmt ++;
243 if (*fmt == 'd')
245 lval = va_arg (args, LONG);
247 val = (lval < 0) ? -lval : lval;
249 else
251 val = va_arg (args, ULONG);
254 print_int:
255 if (val==0)
257 if (width == 0)
258 width = 1;
260 if (*fill == ' ')
261 width --;
263 while (width > 0)
265 RawPutChars (fill, (width < 8) ? width : 8);
266 width -= 8;
269 if (*fill == ' ')
270 RawPutChar ('0');
272 ret ++;
273 break;
276 t = 32;
278 if (*fmt == 'd' || *fmt == 'u')
280 if (*fmt == 'd')
282 if (lval < 0)
284 RawPutChar ('-');
285 ret ++;
286 val = -lval;
288 else
289 val = lval;
292 while (val && t)
294 puffer[--t] = lhex[val % 10];
296 val /= 10;
299 else if (*fmt == 'x')
301 while (val && t)
303 puffer[--t] = lhex[val & 0x0F];
305 val >>= 4;
308 else
310 while (val && t)
312 puffer[--t] = uhex[val & 0x0F];
314 val >>= 4;
318 width -= 32-t;
320 while (width > 0)
322 RawPutChars (fill, (width < 8) ? width : 8);
323 width -= 8;
326 RawPutChars (&puffer[t], 32-t);
327 ret += 32-t;
329 break; }
331 default: {
332 if (*fmt == 'd')
334 lval = va_arg (args, int);
336 val = (lval < 0) ? -lval : lval;
338 else
340 val = va_arg (args, unsigned int);
343 goto print_int;
345 break; }
346 } /* switch */
348 else
350 RawPutChar (*fmt);
351 ret ++;
354 fmt ++; /* Next char */
355 } /* while (*fmt); */
357 return ret;
358 } /* vkprintf */