gem5  v20.1.0.0
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 <cassert>
32 #include <iomanip>
33 #include <iostream>
34 #include <sstream>
35 
36 #include "base/compiler.hh"
37 
38 using namespace std;
39 
40 namespace cp {
41 
42 Print::Print(std::ostream &stream, const std::string &format)
43  : stream(stream), format(format.c_str()), ptr(format.c_str()), cont(false)
44 {
45  saved_flags = stream.flags();
46  saved_fill = stream.fill();
47  saved_precision = stream.precision();
48  saved_width = stream.width();
49 }
50 
51 Print::Print(std::ostream &stream, const char *format)
52  : stream(stream), format(format), ptr(format), cont(false)
53 {
54  saved_flags = stream.flags();
55  saved_fill = stream.fill();
56  saved_precision = stream.precision();
57  saved_width = stream.width();
58 }
59 
61 {
62 }
63 
64 void
66 {
67  fmt.clear();
68 
69  size_t len;
70 
71  while (*ptr) {
72  switch (*ptr) {
73  case '%':
74  if (ptr[1] != '%') {
75  process_flag();
76  return;
77  }
78  stream.put('%');
79  ptr += 2;
80  break;
81 
82  case '\n':
83  stream << endl;
84  ++ptr;
85  break;
86  case '\r':
87  ++ptr;
88  if (*ptr != '\n')
89  stream << endl;
90  break;
91 
92  default:
93  len = strcspn(ptr, "%\n\r\0");
94  stream.write(ptr, len);
95  ptr += len;
96  break;
97  }
98  }
99 }
100 
101 void
103 {
104  bool done = false;
105  bool end_number = false;
106  bool have_precision = false;
107  int number = 0;
108 
109  stream.fill(' ');
110  stream.flags((ios::fmtflags)0);
111 
112  while (!done) {
113  ++ptr;
114  if (*ptr >= '0' && *ptr <= '9') {
115  if (end_number)
116  continue;
117  } else if (number > 0)
118  end_number = true;
119 
120  switch (*ptr) {
121  case 's':
123  done = true;
124  break;
125 
126  case 'c':
128  done = true;
129  break;
130 
131  case 'l':
132  continue;
133 
134  case 'p':
136  fmt.base = Format::hex;
137  fmt.alternate_form = true;
138  done = true;
139  break;
140 
141  case 'X':
142  fmt.uppercase = true;
144  case 'x':
145  fmt.base = Format::hex;
147  done = true;
148  break;
149 
150  case 'o':
151  fmt.base = Format::oct;
153  done = true;
154  break;
155 
156  case 'd':
157  case 'i':
158  case 'u':
160  done = true;
161  break;
162 
163  case 'G':
164  fmt.uppercase = true;
166  case 'g':
169  done = true;
170  break;
171 
172  case 'E':
173  fmt.uppercase = true;
175  case 'e':
178  done = true;
179  break;
180 
181  case 'f':
184  done = true;
185  break;
186 
187  case 'n':
188  stream << "we don't do %n!!!\n";
189  done = true;
190  break;
191 
192  case '#':
193  fmt.alternate_form = true;
194  break;
195 
196  case '-':
197  fmt.flush_left = true;
198  break;
199 
200  case '+':
201  fmt.print_sign = true;
202  break;
203 
204  case ' ':
205  fmt.blank_space = true;
206  break;
207 
208  case '.':
209  fmt.width = number;
210  fmt.precision = 0;
211  have_precision = true;
212  number = 0;
213  end_number = false;
214  break;
215 
216  case '0':
217  if (number == 0) {
218  fmt.fill_zero = true;
219  break;
220  }
222  case '1':
223  case '2':
224  case '3':
225  case '4':
226  case '5':
227  case '6':
228  case '7':
229  case '8':
230  case '9':
231  number = number * 10 + (*ptr - '0');
232  break;
233 
234  case '*':
235  if (have_precision)
236  fmt.get_precision = true;
237  else
238  fmt.get_width = true;
239  break;
240 
241  case '%':
242  assert(false && "we shouldn't get here");
243  break;
244 
245  default:
246  done = true;
247  break;
248  }
249 
250  if (end_number) {
251  if (have_precision)
252  fmt.precision = number;
253  else
254  fmt.width = number;
255 
256  end_number = false;
257  number = 0;
258  }
259 
260  if (done) {
261  if ((fmt.format == Format::integer) && have_precision) {
262  // specified a . but not a float, set width
264  // precision requries digits for width, must fill with 0
265  fmt.fill_zero = true;
266  } else if ((fmt.format == Format::floating) && !have_precision &&
267  fmt.fill_zero) {
268  // ambiguous case, matching printf
270  }
271  }
272  } // end while
273 
274  ++ptr;
275 }
276 
277 void
279 {
280  size_t len;
281 
282  while (*ptr) {
283  switch (*ptr) {
284  case '%':
285  if (ptr[1] != '%')
286  stream << "<extra arg>";
287 
288  stream.put('%');
289  ptr += 2;
290  break;
291 
292  case '\n':
293  stream << endl;
294  ++ptr;
295  break;
296  case '\r':
297  ++ptr;
298  if (*ptr != '\n')
299  stream << endl;
300  break;
301 
302  default:
303  len = strcspn(ptr, "%\n\r\0");
304  stream.write(ptr, len);
305  ptr += len;
306  break;
307  }
308  }
309 
310  stream.flags(saved_flags);
311  stream.fill(saved_fill);
312  stream.precision(saved_precision);
313  stream.width(saved_width);
314 }
315 
316 } // namespace cp
cp::Format::string
@ string
Definition: cprintf_formats.hh:47
cp::Print::ptr
const char * ptr
Definition: cprintf.hh:47
cp::Format::character
@ character
Definition: cprintf_formats.hh:47
cp::Format::format
enum cp::Format::@24 format
cp::Format::floating
@ floating
Definition: cprintf_formats.hh:47
cp::Format::print_sign
bool print_sign
Definition: cprintf_formats.hh:42
cp::Print::stream
std::ostream & stream
Definition: cprintf.hh:45
cp::Print::process
void process()
Definition: cprintf.cc:65
cp::Format::get_width
bool get_width
Definition: cprintf_formats.hh:52
cp::Print::~Print
~Print()
Definition: cprintf.cc:60
cp::Print::end_args
void end_args()
Definition: cprintf.cc:278
cp::Format::fixed
@ fixed
Definition: cprintf_formats.hh:48
cp::Format::get_precision
bool get_precision
Definition: cprintf_formats.hh:51
cp::Format::scientific
@ scientific
Definition: cprintf_formats.hh:48
cp::Format::oct
@ oct
Definition: cprintf_formats.hh:46
cp::Format::precision
int precision
Definition: cprintf_formats.hh:49
cp::Format::best
@ best
Definition: cprintf_formats.hh:48
cp::Format::integer
@ integer
Definition: cprintf_formats.hh:47
cp
Definition: cprintf.cc:40
cp::Format::alternate_form
bool alternate_form
Definition: cprintf_formats.hh:40
cp::Print::saved_fill
char saved_fill
Definition: cprintf.hh:51
cp::Format::base
enum cp::Format::@23 base
M5_FALLTHROUGH
#define M5_FALLTHROUGH
Definition: compiler.hh:84
cprintf.hh
compiler.hh
cp::Format::hex
@ hex
Definition: cprintf_formats.hh:46
cp::Print::saved_flags
std::ios::fmtflags saved_flags
Definition: cprintf.hh:50
cp::Format::width
int width
Definition: cprintf_formats.hh:50
cp::Print::saved_precision
int saved_precision
Definition: cprintf.hh:52
std
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
cp::Print::process_flag
void process_flag()
Definition: cprintf.cc:102
cp::Print::saved_width
int saved_width
Definition: cprintf.hh:53
cp::Format::clear
void clear()
Definition: cprintf_formats.hh:56
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:42
cp::Format::blank_space
bool blank_space
Definition: cprintf_formats.hh:43
cp::Format::float_format
enum cp::Format::@25 float_format
ArmISA::format
Bitfield< 31, 29 > format
Definition: miscregs_types.hh:640
cp::Format::flush_left
bool flush_left
Definition: cprintf_formats.hh:41
cp::Print::fmt
Format fmt
Definition: cprintf.hh:55
cp::Format::fill_zero
bool fill_zero
Definition: cprintf_formats.hh:44
cp::Format::uppercase
bool uppercase
Definition: cprintf_formats.hh:45

Generated on Wed Sep 30 2020 14:02:07 for gem5 by doxygen 1.8.17