1 /* Debugging printf, for debugging the library itself.
3 We don't assume stdio is working.
4 We do assume _write_r is working.
20 static char *parse_number ();
23 static long get_number (char *, long, int);
24 static void print_number (int, int, long);
25 static void write_char (char c
);
26 static void write_string (const char *s
);
28 /* Non-zero for big-endian systems. */
29 static int big_endian_p
;
31 /* For now hardcode 2 (stderr) as the console file descriptor.
32 May wish to let the caller pass in a file descriptor or some such but
33 this is only for debugging purposes anyway. */
36 /* Standalone printf routine.
38 The format string has been enhanced so that multiple values can be dumped
39 without having to have a %-field for each one (say if you want to dump
40 20 words at a certain address). A modifier of `N' says the next argument
41 is a count, and the one after that is a pointer.
43 Example: __dprintf ("%Nx\n", 20, p); /-* print 20 ints at `p' *-/
45 Supported formats are: c d u x s p.
47 All ints are retrieved a byte at a time so alignment issues are not
50 This routine is used in situations where the only debugging capability
51 is console output and was written to aid debugging newlib itself. We don't
52 use printf ourselves as we may be debugging it. We do assume _write_r is
58 __dprintf (const char *fmt
, ...)
60 __dprintf (fmt
, va_alist
)
67 /* Which endian are we? */
70 big_endian_p
= *(char *) &tmp
== 0;
85 if (*fmt
!= '%' || *++fmt
== '%')
93 count
= va_arg (args
, int);
94 p
= va_arg (args
, char *);
103 write_string (unctrl (*p
++));
106 print_number (16, 1, get_number (p
, sizeof (char *), 1));
107 p
+= sizeof (char *);
112 print_number (c
== 'x' ? 16 : 10, c
!= 'd',
113 get_number (p
, sizeof (int), c
!= 'd'));
117 write_string (*(char **) p
);
118 p
+= sizeof (char *);
130 c
= va_arg (args
, int);
131 write_string (unctrl (c
));
134 l
= (_POINTER_INT
) va_arg (args
, char *);
135 print_number (16, 1, l
);
140 l
= va_arg (args
, int);
141 print_number (c
== 'x' ? 16 : 10, c
!= 'd', l
);
144 p
= va_arg (args
, char *);
155 /* Parse a positive decimal integer at S.
156 FIXME: Was used in earlier version, but not currently used.
168 x
= (x
* 10) + (*s
- '0');
177 /* Fetch the number at S of SIZE bytes. */
185 unsigned char *p
= (unsigned char *) s
;
192 x
= (x
^ 0x80) - 0x80;
196 x
= (p
[0] << 8) | p
[1];
198 x
= (p
[1] << 8) | p
[0];
200 x
= (x
^ 0x8000) - 0x8000;
204 x
= ((long)p
[0] << 24) | ((long)p
[1] << 16) | (p
[2] << 8) | p
[3];
206 x
= ((long)p
[3] << 24) | ((long)p
[2] << 16) | (p
[1] << 8) | p
[0];
208 x
= (x
^ 0x80000000L
) - 0x80000000L
;
210 #if 0 /* FIXME: Is there a standard mechanism for knowing if
219 /* Print X in base BASE. */
222 print_number (int base
,
226 static char chars
[16] = "0123456789abcdef";
230 if (!unsigned_p
&& n
< 0)
238 p
= buf
+ sizeof (buf
);
242 *--p
= chars
[x
% base
];
250 /* Write C to the console.
251 We go through the file descriptor directly because we can't assume
257 _write_r (_REENT
, CONSOLE_FD
, &c
, 1);
260 /* Write S to the console.
261 We go through the file descriptor directly because we can't assume
265 write_string (const char *s
)
267 _write_r (_REENT
, CONSOLE_FD
, s
, strlen (s
));