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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib-1.10.0/] [newlib/] [libc/] [misc/] [dprintf.c] - Blame information for rev 1773

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

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

powered by: WebSVN 2.1.0

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