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

Generated on Wed Dec 21 2022 10:22:28 for gem5 by doxygen 1.9.1