printk.cc revision 2665:a124942bacb8
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Ali Saidi
29 */
30
31#include <sys/types.h>
32#include <algorithm>
33
34#include "base/trace.hh"
35#include "arch/arguments.hh"
36
37using namespace std;
38
39
40void
41Printk(AlphaISA::AlphaArguments args)
42{
43    char *p = (char *)args++;
44
45    ios::fmtflags saved_flags = DebugOut().flags();
46    char old_fill = DebugOut().fill();
47    int old_precision = DebugOut().precision();
48
49    while (*p) {
50        switch (*p) {
51          case '%': {
52              bool more = true;
53              bool islong = false;
54              bool leftjustify = false;
55              bool format = false;
56              bool zero = false;
57              int width = 0;
58              while (more && *++p) {
59                  switch (*p) {
60                    case 'l':
61                    case 'L':
62                      islong = true;
63                      break;
64                    case '-':
65                      leftjustify = true;
66                      break;
67                    case '#':
68                      format = true;
69                      break;
70                    case '0':
71                      if (width)
72                          width *= 10;
73                      else
74                          zero = true;
75                      break;
76                    default:
77                      if (*p >= '1' && *p <= '9')
78                          width = 10 * width + *p - '0';
79                      else
80                          more = false;
81                      break;
82                  }
83              }
84
85              bool hexnum = false;
86              bool octal = false;
87              bool sign = false;
88              switch (*p) {
89                case 'X':
90                case 'x':
91                  hexnum = true;
92                  break;
93                case 'O':
94                case 'o':
95                  octal = true;
96                  break;
97                case 'D':
98                case 'd':
99                  sign = true;
100                  break;
101                case 'P':
102                  format = true;
103                case 'p':
104                  hexnum = true;
105                  break;
106              }
107
108              switch (*p) {
109                case 'D':
110                case 'd':
111                case 'U':
112                case 'u':
113                case 'X':
114                case 'x':
115                case 'O':
116                case 'o':
117                case 'P':
118                case 'p': {
119                  if (hexnum)
120                      DebugOut() << hex;
121
122                  if (octal)
123                      DebugOut() << oct;
124
125                  if (format) {
126                      if (!zero)
127                          DebugOut().setf(ios::showbase);
128                      else {
129                          if (hexnum) {
130                              DebugOut() << "0x";
131                              width -= 2;
132                          } else if (octal) {
133                              DebugOut() << "0";
134                              width -= 1;
135                          }
136                      }
137                  }
138
139                  if (zero)
140                      DebugOut().fill('0');
141
142                  if (width > 0)
143                      DebugOut().width(width);
144
145                  if (leftjustify && !zero)
146                      DebugOut().setf(ios::left);
147
148                  if (sign) {
149                      if (islong)
150                          DebugOut() << (int64_t)args;
151                      else
152                          DebugOut() << (int32_t)args;
153                  } else {
154                      if (islong)
155                          DebugOut() << (uint64_t)args;
156                      else
157                          DebugOut() << (uint32_t)args;
158                  }
159
160                  if (zero)
161                      DebugOut().fill(' ');
162
163                  if (width > 0)
164                      DebugOut().width(0);
165
166                  DebugOut() << dec;
167
168                  ++args;
169                }
170                  break;
171
172                case 's': {
173                    char *s = (char *)args;
174                    if (!s)
175                        s = "<NULL>";
176
177                    if (width > 0)
178                        DebugOut().width(width);
179                    if (leftjustify)
180                        DebugOut().setf(ios::left);
181
182                    DebugOut() << s;
183                    ++args;
184                }
185                  break;
186                case 'C':
187                case 'c': {
188                    uint64_t mask = (*p == 'C') ? 0xffL : 0x7fL;
189                    uint64_t num;
190                    int width;
191
192                    if (islong) {
193                        num = (uint64_t)args;
194                        width = sizeof(uint64_t);
195                    } else {
196                        num = (uint32_t)args;
197                        width = sizeof(uint32_t);
198                    }
199
200                    while (width-- > 0) {
201                        char c = (char)(num & mask);
202                        if (c)
203                            DebugOut() << c;
204                        num >>= 8;
205                    }
206
207                    ++args;
208                }
209                  break;
210                case 'b': {
211                  uint64_t n = (uint64_t)args++;
212                  char *s = (char *)args++;
213                  DebugOut() << s << ": " << n;
214                }
215                  break;
216                case 'n':
217                case 'N': {
218                    args += 2;
219#if 0
220                    uint64_t n = (uint64_t)args++;
221                    struct reg_values *rv = (struct reg_values *)args++;
222#endif
223                }
224                  break;
225                case 'r':
226                case 'R': {
227                    args += 2;
228#if 0
229                    uint64_t n = (uint64_t)args++;
230                    struct reg_desc *rd = (struct reg_desc *)args++;
231#endif
232                }
233                  break;
234                case '%':
235                  DebugOut() << '%';
236                  break;
237              }
238              ++p;
239          }
240            break;
241          case '\n':
242            DebugOut() << endl;
243            ++p;
244            break;
245          case '\r':
246            ++p;
247            if (*p != '\n')
248                DebugOut() << endl;
249            break;
250
251          default: {
252              size_t len = strcspn(p, "%\n\r\0");
253              DebugOut().write(p, len);
254              p += len;
255          }
256        }
257    }
258
259    DebugOut().flags(saved_flags);
260    DebugOut().fill(old_fill);
261    DebugOut().precision(old_precision);
262}
263
264