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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [rdi-share/] [logging.c] - Blame information for rev 1767

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

Line No. Rev Author Line
1 578 markom
/*
2
 * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3
 *
4
 * This software may be freely used, copied, modified, and distributed
5
 * provided that the above copyright notice is preserved in all copies of the
6
 * software.
7
 */
8
 
9
/* -*-C-*-
10
 *
11
 * $Revision: 1.1.1.1 $
12
 *     $Date: 2002-01-16 10:24:33 $
13
 *
14
 *
15
 * logging.c - methods for logging warnings, errors and trace info
16
 *
17
 */
18
 
19
#include <stdarg.h>     /* ANSI varargs support */
20
 
21
#ifdef TARGET
22
# include "angel.h"
23
# include "devconf.h"
24
#else
25
# include "host.h"
26
#endif
27
 
28
#include "logging.h"    /* Header file for this source code */
29
 
30
#ifndef UNUSED
31
# define UNUSED(x) ((x)=(x))
32
#endif
33
 
34
/*
35
 * __rt_warning
36
 * ------------
37
 * This routine is provided as a standard method of generating
38
 * run-time system warnings. The actual action taken by this code can
39
 * be board or target application specific, e.g. internal logging,
40
 * debug message, etc.
41
 */
42
 
43
#ifdef DEBUG
44
 
45
# ifdef DEBUG_METHOD
46
 
47
#  define  STRINGIFY2(x) #x
48
#  define  STRINGIFY(x)  STRINGIFY2(x)
49
#  define  DEBUG_METHOD_HEADER        STRINGIFY(DEBUG_METHOD##.h)
50
 
51
#  include DEBUG_METHOD_HEADER
52
 
53
#  define  METHOD_EXPAND_2(m, p, c) m##p(c)
54
#  define  METHOD_EXPAND(m, p, c)   METHOD_EXPAND_2(m, p, c)
55
 
56
#  define  CHAROUT(c)    METHOD_EXPAND(DEBUG_METHOD, _PutChar,  (c))
57
#  define  PRE_DEBUG(l)  METHOD_EXPAND(DEBUG_METHOD, _PreWarn,  (l))
58
#  define  POST_DEBUG(n) METHOD_EXPAND(DEBUG_METHOD, _PostWarn, (n))
59
 
60
# else
61
#  error Must define DEBUG_METHOD
62
# endif
63
 
64
#endif /* def DEBUG */
65
 
66
/*
67
 * the guts of __rt_warning
68
 */
69
 
70
#pragma no_check_stack
71
#ifdef DEBUG
72
 
73
static const char hextab[] = "0123456789ABCDEF";
74
 
75
/*
76
 * If debugging, then we break va_warn into sub-functions which
77
 * allow us to get an easy breakpoint on the formatted string
78
 */
79
static int va_warn0(char *format, va_list args)
80
{
81
    int len = 0;
82
 
83
    while ((format != NULL) && (*format != '\0'))
84
    {
85
        if (*format == '%')
86
        {
87
            char fch = *(++format); /* get format character (skipping '%') */
88
            int ival; /* holder for integer arguments */
89
            char *string; /* holder for string arguments */
90
            int width = 0; /* No field width by default */
91
            int padzero = FALSE; /* By default we pad with spaces */
92
 
93
            /*
94
             * Check if the format has a width specified. NOTE: We do
95
             * not use the "isdigit" function here, since it will
96
             * require run-time support. The current ARM Ltd header
97
             * defines "isdigit" as a macro, that uses a fixed
98
             * character description table.
99
             */
100
            if ((fch >= '0') && (fch <= '9'))
101
            {
102
                if (fch == '0')
103
                {
104
                    /* Leading zeroes padding */
105
                    padzero = TRUE;
106
                    fch = *(++format);
107
                }
108
 
109
                while ((fch >= '0') && (fch <= '9'))
110
                {
111
                    width = ((width * 10) + (fch - '0'));
112
                    fch = *(++format);
113
                }
114
            }
115
 
116
            if (fch == 'l')
117
                /* skip 'l' in "%lx", etc. */
118
                fch = *(++format);
119
 
120
            switch (fch)
121
            {
122
              case 'c':
123
                  /* char */
124
                  ival = va_arg(args, int);
125
                  CHAROUT((char)ival);
126
                  len++;
127
                  break;
128
 
129
              case 'x':
130
              case 'X':
131
              {
132
                  /* hexadecimal */
133
                  unsigned int uval = va_arg(args, unsigned int);
134
                  int loop;
135
 
136
                  UNUSED(uval);
137
 
138
                  if ((width == 0) || (width > 8))
139
                      width = 8;
140
 
141
                  for(loop = (width * 4); (loop != 0); loop -= 4)
142
                  {
143
                      CHAROUT(hextab[(uval >> (loop - 4)) & 0xF]);
144
                      len++;
145
                  }
146
              }
147
 
148
              break;
149
 
150
              case 'd':
151
                  /* decimal */
152
                  ival = va_arg(args, int);
153
 
154
                  if (ival < 0)
155
                  {
156
                      ival = -ival;
157
                      CHAROUT('-');
158
                      len++;
159
                  }
160
 
161
                  if (ival == 0)
162
                  {
163
                      CHAROUT('0');
164
                      len++;
165
                  }
166
                  else
167
                  {
168
                      /*
169
                       * The simplest method of displaying numbers is
170
                       * to provide a small recursive routine, that
171
                       * nests until the most-significant digit is
172
                       * reached, and then falls back out displaying
173
                       * individual digits. However, we want to avoid
174
                       * using recursive code within the lo-level
175
                       * parts of Angel (to minimise the stack
176
                       * usage). The following number conversion is a
177
                       * non-recursive solution.
178
                       */
179
                      char buffer[16]; /* stack space used to hold number */
180
                      int count = 0; /* pointer into buffer */
181
 
182
                      /*
183
                       * Place the conversion into the buffer in
184
                       * reverse order:
185
                       */
186
                      while (ival != 0)
187
                      {
188
                          buffer[count++] = ('0' + ((unsigned int)ival % 10));
189
                          ival = ((unsigned int)ival / 10);
190
                      }
191
 
192
                      /*
193
                       * Check if we are placing the data in a
194
                       * fixed width field:
195
                       */
196
                      if (width != 0)
197
                      {
198
                          width -= count;
199
 
200
                          for (; (width != 0); width--)
201
                          {
202
                              CHAROUT(padzero ? '0': ' ');
203
                              len++;
204
                          }
205
                      }
206
 
207
                      /* then display the buffer in reverse order */
208
                      for (; (count != 0); count--)
209
                      {
210
                          CHAROUT(buffer[count - 1]);
211
                          len++;
212
                      }
213
                  }
214
 
215
                  break;
216
 
217
              case 's':
218
                  /* string */
219
                  string = va_arg(args, char *);
220
 
221
                  /* we only need this test once */
222
                  if (string != NULL)
223
                      /* whilst we check this for every character */
224
                      while (*string)
225
                      {
226
                          CHAROUT(*string);
227
                          len++;
228
                          string++;
229
 
230
                          /*
231
                           * NOTE: We do not use "*string++" as the macro
232
                           * parameter, since we do not know how many times
233
                           *the parameter may be expanded within the macro.
234
                           */
235
                      }
236
 
237
                  break;
238
 
239
              case '\0':
240
                  /*
241
                   * string terminated by '%' character, bodge things
242
                   * to prepare for default "format++" below
243
                   */
244
                  format--;
245
 
246
                  break;
247
 
248
              default:
249
                  /* just display the character */
250
                  CHAROUT(*format);
251
                  len++;
252
 
253
                  break;
254
            }
255
 
256
            format++; /* step over format character */
257
        }
258
        else
259
        {
260
            CHAROUT(*format);
261
            len++;
262
            format++;
263
        }
264
    }
265
    return len;
266
}
267
 
268
/*
269
 * this routine is simply here as a good breakpoint for dumping msg -
270
 * can be used by DEBUG_METHOD macros or functions, if required.
271
 */
272
# ifdef DEBUG_NEED_VA_WARN1
273
static void va_warn1(int len, char *msg)
274
{
275
    UNUSED(len); UNUSED(msg);
276
}
277
# endif
278
 
279
void va_warn(WarnLevel level, char *format, va_list args)
280
{
281
    int len;
282
 
283
    if ( PRE_DEBUG( level ) )
284
    {
285
        len = va_warn0(format, args);
286
        POST_DEBUG( len );
287
    }
288
}
289
 
290
#else /* ndef DEBUG */
291
 
292
void va_warn(WarnLevel level, char *format, va_list args)
293
{
294
    UNUSED(level); UNUSED(format); UNUSED(args);
295
}
296
 
297
#endif /* ... else ndef(DEBUG) ... */
298
#pragma check_stack
299
 
300
#pragma no_check_stack
301
void __rt_warning(char *format, ...)
302
{
303
    va_list args;
304
 
305
    /*
306
     * For a multi-threaded system we should provide a lock at this point
307
     * to ensure that the warning messages are sequenced properly.
308
     */
309
 
310
    va_start(args, format);
311
    va_warn(WL_WARN, format, args);
312
    va_end(args);
313
 
314
    return;
315
}
316
#pragma check_stack
317
 
318
#ifdef TARGET
319
 
320
#pragma no_check_stack
321
void __rt_uninterruptable_loop( void ); /* in suppasm.s */
322
 
323
void __rt_error(char *format, ...)
324
{
325
    va_list args;
326
 
327
    va_start(args, format);
328
 
329
    /* Display warning message */
330
    va_warn(WL_ERROR, format, args);
331
 
332
    __rt_uninterruptable_loop();
333
 
334
    va_end(args);
335
    return;
336
}
337
#pragma check_stack
338
 
339
#endif /* def TARGET */
340
 
341
#ifdef DO_TRACE
342
 
343
static bool trace_on = FALSE; /* must be set true in debugger if req'd */
344
 
345
#pragma no_check_stack
346
void __rt_trace(char *format, ...)
347
{
348
    va_list args;
349
 
350
    /*
351
     * For a multi-threaded system we should provide a lock at this point
352
     * to ensure that the warning messages are sequenced properly.
353
     */
354
 
355
    if (trace_on)
356
    {
357
        va_start(args, format);
358
        va_warn(WL_TRACE, format, args);
359
        va_end(args);
360
    }
361
 
362
    return;
363
}
364
#pragma check_stack
365
 
366
#endif /* def DO_TRACE */
367
 
368
 
369
/* EOF logging.c */

powered by: WebSVN 2.1.0

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