gem5  v21.0.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
cprintf.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002-2006 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 
29 #include "base/cprintf.hh"
30 
31 #include <iomanip>
32 #include <iostream>
33 #include <sstream>
34 
35 #include "base/compiler.hh"
36 
37 namespace cp
38 {
39 
40 Print::Print(std::ostream &stream, const std::string &format)
41  : stream(stream), format(format.c_str()), ptr(format.c_str()), cont(false)
42 {
43  savedFlags = stream.flags();
44  savedFill = stream.fill();
45  savedPrecision = stream.precision();
46  savedWidth = stream.width();
47 }
48 
49 Print::Print(std::ostream &stream, const char *format)
50  : stream(stream), format(format), ptr(format), cont(false)
51 {
52  savedFlags = stream.flags();
53  savedFill = stream.fill();
54  savedPrecision = stream.precision();
55  savedWidth = stream.width();
56 }
57 
59 {
60 }
61 
62 void
64 {
65  fmt.clear();
66 
67  size_t len;
68 
69  while (*ptr) {
70  switch (*ptr) {
71  case '%':
72  if (ptr[1] != '%') {
73  processFlag();
74  return;
75  }
76  stream.put('%');
77  ptr += 2;
78  break;
79 
80  case '\n':
81  stream << std::endl;
82  ++ptr;
83  break;
84  case '\r':
85  ++ptr;
86  if (*ptr != '\n')
87  stream << std::endl;
88  break;
89 
90  default:
91  len = strcspn(ptr, "%\n\r\0");
92  stream.write(ptr, len);
93  ptr += len;
94  break;
95  }
96  }
97 }
98 
99 void
101 {
102  bool done = false;
103  bool end_number = false;
104  bool have_precision = false;
105  int number = 0;
106 
107  stream.fill(' ');
108  stream.flags((std::ios::fmtflags)0);
109 
110  while (!done) {
111  ++ptr;
112  if (*ptr >= '0' && *ptr <= '9') {
113  if (end_number)
114  continue;
115  } else if (number > 0) {
116  end_number = true;
117  }
118 
119  switch (*ptr) {
120  case 's':
122  done = true;
123  break;
124 
125  case 'c':
127  done = true;
128  break;
129 
130  case 'l':
131  continue;
132 
133  case 'p':
135  fmt.base = Format::Hex;
136  fmt.alternateForm = true;
137  done = true;
138  break;
139 
140  case 'X':
141  fmt.uppercase = true;
143  case 'x':
144  fmt.base = Format::Hex;
146  done = true;
147  break;
148 
149  case 'o':
150  fmt.base = Format::Oct;
152  done = true;
153  break;
154 
155  case 'd':
156  case 'i':
157  case 'u':
159  done = true;
160  break;
161 
162  case 'G':
163  fmt.uppercase = true;
165  case 'g':
168  done = true;
169  break;
170 
171  case 'E':
172  fmt.uppercase = true;
174  case 'e':
177  done = true;
178  break;
179 
180  case 'f':
183  done = true;
184  break;
185 
186  case 'n':
187  stream << "we don't do %n!!!\n";
188  done = true;
189  break;
190 
191  case '#':
192  fmt.alternateForm = true;
193  break;
194 
195  case '-':
196  fmt.flushLeft = true;
197  break;
198 
199  case '+':
200  fmt.printSign = true;
201  break;
202 
203  case ' ':
204  fmt.blankSpace = true;
205  break;
206 
207  case '.':
208  fmt.width = number;
209  fmt.precision = 0;
210  have_precision = true;
211  number = 0;
212  end_number = false;
213  break;
214 
215  case '0':
216  if (number == 0) {
217  fmt.fillZero = true;
218  break;
219  }
221  case '1':
222  case '2':
223  case '3':
224  case '4':
225  case '5':
226  case '6':
227  case '7':
228  case '8':
229  case '9':
230  number = number * 10 + (*ptr - '0');
231  break;
232 
233  case '*':
234  if (have_precision)
235  fmt.getPrecision = true;
236  else
237  fmt.getWidth = true;
238  break;
239 
240  case '%':
241  M5_UNREACHABLE;
242  break;
243 
244  default:
245  done = true;
246  break;
247  }
248 
249  if (end_number) {
250  if (have_precision)
251  fmt.precision = number;
252  else
253  fmt.width = number;
254 
255  end_number = false;
256  number = 0;
257  }
258 
259  if (done) {
260  if ((fmt.format == Format::Integer) && have_precision) {
261  // specified a . but not a float, set width
263  // precision requries digits for width, must fill with 0
264  fmt.fillZero = true;
265  } else if ((fmt.format == Format::Floating) && !have_precision &&
266  fmt.fillZero) {
267  // ambiguous case, matching printf
269  }
270  }
271  } // end while
272 
273  ++ptr;
274 }
275 
276 void
278 {
279  size_t len;
280 
281  while (*ptr) {
282  switch (*ptr) {
283  case '%':
284  if (ptr[1] != '%')
285  stream << "<extra arg>";
286 
287  stream.put('%');
288  ptr += 2;
289  break;
290 
291  case '\n':
292  stream << std::endl;
293  ++ptr;
294  break;
295  case '\r':
296  ++ptr;
297  if (*ptr != '\n')
298  stream << std::endl;
299  break;
300 
301  default:
302  len = strcspn(ptr, "%\n\r\0");
303  stream.write(ptr, len);
304  ptr += len;
305  break;
306  }
307  }
308 
309  stream.flags(savedFlags);
310  stream.fill(savedFill);
311  stream.precision(savedPrecision);
312  stream.width(savedWidth);
313 }
314 
315 } // namespace cp
cp::Format::Best
@ Best
Definition: cprintf_formats.hh:63
cp::Print::ptr
const char * ptr
Definition: cprintf.hh:47
cp::Format::Hex
@ Hex
Definition: cprintf_formats.hh:50
cp::Print::savedPrecision
int savedPrecision
Definition: cprintf.hh:52
cp::Format::Fixed
@ Fixed
Definition: cprintf_formats.hh:64
cp::Print::stream
std::ostream & stream
Definition: cprintf.hh:45
cp::Format::Integer
@ Integer
Definition: cprintf_formats.hh:57
cp::Print::process
void process()
Definition: cprintf.cc:63
cp::Format::getPrecision
bool getPrecision
Definition: cprintf_formats.hh:69
cp::Print::~Print
~Print()
Definition: cprintf.cc:58
cp::Format::base
enum cp::Format::@21 base
cp::Print::savedFill
char savedFill
Definition: cprintf.hh:51
cp::Print::savedFlags
std::ios::fmtflags savedFlags
Definition: cprintf.hh:50
cp::Format::precision
int precision
Definition: cprintf_formats.hh:67
cp::Format::Character
@ Character
Definition: cprintf_formats.hh:58
cp
Definition: cprintf.cc:37
cp::Print::endArgs
void endArgs()
Definition: cprintf.cc:277
cp::Format::Scientific
@ Scientific
Definition: cprintf_formats.hh:65
cp::Format::alternateForm
bool alternateForm
Definition: cprintf_formats.hh:41
M5_FALLTHROUGH
#define M5_FALLTHROUGH
Definition: compiler.hh:59
cprintf.hh
compiler.hh
cp::Format::floatFormat
enum cp::Format::@23 floatFormat
cp::Format::flushLeft
bool flushLeft
Definition: cprintf_formats.hh:42
cp::Format::width
int width
Definition: cprintf_formats.hh:68
cp::Format::getWidth
bool getWidth
Definition: cprintf_formats.hh:70
cp::Format::clear
void clear()
Definition: cprintf_formats.hh:75
ArmISA::len
Bitfield< 18, 16 > len
Definition: miscregs_types.hh:439
cp::Print::Print
Print(std::ostream &stream, const std::string &format)
Definition: cprintf.cc:40
cp::Format::Floating
@ Floating
Definition: cprintf_formats.hh:59
cp::Format::format
enum cp::Format::@22 format
ArmISA::format
Bitfield< 31, 29 > format
Definition: miscregs_types.hh:640
cp::Print::processFlag
void processFlag()
Definition: cprintf.cc:100
cp::Print::savedWidth
int savedWidth
Definition: cprintf.hh:53
cp::Format::blankSpace
bool blankSpace
Definition: cprintf_formats.hh:44
cp::Format::fillZero
bool fillZero
Definition: cprintf_formats.hh:45
cp::Format::String
@ String
Definition: cprintf_formats.hh:56
cp::Format::Oct
@ Oct
Definition: cprintf_formats.hh:51
cp::Print::fmt
Format fmt
Definition: cprintf.hh:55
cp::Format::printSign
bool printSign
Definition: cprintf_formats.hh:43
cp::Format::uppercase
bool uppercase
Definition: cprintf_formats.hh:46

Generated on Tue Jun 22 2021 15:28:25 for gem5 by doxygen 1.8.17