OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.17.0/] [newlib/] [libc/] [misc/] [__dprintf.c] - Blame information for rev 455

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
/* Debugging printf, for debugging the library itself.
2
 
3
   We don't assume stdio is working.
4
   We do assume _write_r is working.
5
*/
6
 
7
#include <_ansi.h>
8
#include "ctype.h"
9
#include "reent.h"
10
#include "string.h"
11
#include "unctrl.h"
12
 
13
#ifdef __STDC__
14
#include "stdarg.h"
15
#else
16
#include "varargs.h"
17
#endif
18
 
19
#if 0
20
static char *parse_number ();
21
#endif
22
 
23
static long _EXFUN(get_number, (char *, long, int));
24
static void _EXFUN(print_number, (int, int, long));
25
static void _EXFUN(write_char, (char c));
26
static void _EXFUN(write_string, (_CONST char *s));
27
 
28
/* Non-zero for big-endian systems.  */
29
static int big_endian_p;
30
 
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.  */
34
#define CONSOLE_FD 2
35
 
36
/* Standalone printf routine.
37
 
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.
42
 
43
   Example: __dprintf ("%Nx\n", 20, p); /-* print 20 ints at `p' *-/
44
 
45
   Supported formats are: c d u x s p.
46
 
47
   All ints are retrieved a byte at a time so alignment issues are not
48
   a problem.
49
 
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
53
   working.
54
*/
55
 
56
void
57
#ifdef __STDC__
58
__dprintf (const char *fmt, ...)
59
#else
60
__dprintf (fmt, va_alist)
61
     char *fmt;
62
     va_dcl
63
#endif
64
{
65
  va_list args;
66
 
67
  /* Which endian are we?  */
68
  {
69
    short tmp = 1;
70
    big_endian_p = *(char *) &tmp == 0;
71
  }
72
 
73
#ifdef __STDC__
74
  va_start (args, fmt);
75
#else
76
  va_start (args);
77
#endif
78
 
79
  while (*fmt)
80
    {
81
      char c, *p;
82
      int count;
83
      long l;
84
 
85
      if (*fmt != '%' || *++fmt == '%')
86
        {
87
          write_char (*fmt++);
88
          continue;
89
        }
90
 
91
      if (*fmt == 'N')
92
        {
93
          count = va_arg (args, int);
94
          p = va_arg (args, char *);
95
          ++fmt;
96
          c = *fmt++;
97
 
98
          while (--count >= 0)
99
            {
100
              switch (c)
101
                {
102
                case 'c' :
103
                  write_string (unctrl (*p++));
104
                  break;
105
                case 'p' :
106
                  print_number (16, 1, get_number (p, sizeof (char *), 1));
107
                  p += sizeof (char *);
108
                  break;
109
                case 'd' :
110
                case 'u' :
111
                case 'x' :
112
                  print_number (c == 'x' ? 16 : 10, c != 'd',
113
                                get_number (p, sizeof (int), c != 'd'));
114
                  p += sizeof (int);
115
                  break;
116
                case 's' :
117
                  write_string (*(char **) p);
118
                  p += sizeof (char *);
119
                  break;
120
                }
121
              if (count > 0)
122
                write_char (' ');
123
            }
124
        }
125
      else
126
        {
127
          switch (c = *fmt++)
128
            {
129
            case 'c' :
130
              c = va_arg (args, int);
131
              write_string (unctrl (c));
132
              break;
133
            case 'p' :
134
              l = (_POINTER_INT) va_arg (args, char *);
135
              print_number (16, 1, l);
136
              break;
137
            case 'd' :
138
            case 'u' :
139
            case 'x' :
140
              l = va_arg (args, int);
141
              print_number (c == 'x' ? 16 : 10, c != 'd', l);
142
              break;
143
            case 's' :
144
              p = va_arg (args, char *);
145
              write_string (p);
146
              break;
147
            }
148
        }
149
    }
150
 
151
  va_end (args);
152
}
153
 
154
#if 0
155
/* Parse a positive decimal integer at S.
156
   FIXME: Was used in earlier version, but not currently used.
157
   Keep for now.  */
158
 
159
static char *
160
parse_number (s, p)
161
     char *s;
162
     long *p;
163
{
164
  long x = 0;
165
 
166
  while (isdigit (*s))
167
    {
168
      x = (x * 10) + (*s - '0');
169
      ++s;
170
    }
171
 
172
  *p = x;
173
  return s;
174
}
175
#endif
176
 
177
/* Fetch the number at S of SIZE bytes.  */
178
 
179
static long
180
_DEFUN(get_number, (s, size, unsigned_p),
181
     char *s _AND
182
     long size _AND
183
     int unsigned_p)
184
{
185
  long x;
186
  unsigned char *p = (unsigned char *) s;
187
 
188
  switch (size)
189
    {
190
    case 1 :
191
      x = *p;
192
      if (!unsigned_p)
193
        x = (x ^ 0x80) - 0x80;
194
      return x;
195
    case 2 :
196
      if (big_endian_p)
197
        x = (p[0] << 8) | p[1];
198
      else
199
        x = (p[1] << 8) | p[0];
200
      if (!unsigned_p)
201
        x = (x ^ 0x8000) - 0x8000;
202
      return x;
203
    case 4 :
204
      if (big_endian_p)
205
        x = ((long)p[0] << 24) | ((long)p[1] << 16) | (p[2] << 8) | p[3];
206
      else
207
        x = ((long)p[3] << 24) | ((long)p[2] << 16) | (p[1] << 8) | p[0];
208
      if (!unsigned_p)
209
        x = (x ^ 0x80000000L) - 0x80000000L;
210
      return x;
211
#if 0 /* FIXME: Is there a standard mechanism for knowing if
212
         long longs exist?  */
213
    case 8 :
214
#endif
215
    default :
216
      return 0;
217
  }
218
}
219
 
220
/* Print X in base BASE.  */
221
 
222
static void
223
_DEFUN(print_number, (base, unsigned_p, n),
224
     int base _AND
225
     int unsigned_p _AND
226
     long n)
227
{
228
  static char chars[16] = "0123456789abcdef";
229
  char *p, buf[32];
230
  unsigned long x;
231
 
232
  if (!unsigned_p && n < 0)
233
    {
234
      write_char ('-');
235
      x = -n;
236
    }
237
  else
238
    x = n;
239
 
240
  p = buf + sizeof (buf);
241
  *--p = '\0';
242
  do
243
    {
244
      *--p = chars[x % base];
245
      x /= base;
246
    }
247
  while (x != 0);
248
 
249
  write_string (p);
250
}
251
 
252
/* Write C to the console.
253
   We go through the file descriptor directly because we can't assume
254
   stdio is working.  */
255
 
256
static void
257
_DEFUN(write_char, (c),
258
     char c)
259
{
260
  _write_r (_REENT, CONSOLE_FD, &c, 1);
261
}
262
 
263
/* Write S to the console.
264
   We go through the file descriptor directly because we can't assume
265
   stdio is working.  */
266
 
267
static void
268
_DEFUN(write_string, (s),
269
     _CONST char *s)
270
{
271
  _write_r (_REENT, CONSOLE_FD, s, strlen (s));
272
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.