gem5
v20.1.0.0
base
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
60
Print::~Print
()
61
{
62
}
63
64
void
65
Print::process
()
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
102
Print::process_flag
()
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'
:
122
fmt
.
format
=
Format::string
;
123
done =
true
;
124
break
;
125
126
case
'c'
:
127
fmt
.
format
=
Format::character
;
128
done =
true
;
129
break
;
130
131
case
'l'
:
132
continue
;
133
134
case
'p'
:
135
fmt
.
format
=
Format::integer
;
136
fmt
.
base
=
Format::hex
;
137
fmt
.
alternate_form
=
true
;
138
done =
true
;
139
break
;
140
141
case
'X'
:
142
fmt
.
uppercase
=
true
;
143
M5_FALLTHROUGH
;
144
case
'x'
:
145
fmt
.
base
=
Format::hex
;
146
fmt
.
format
=
Format::integer
;
147
done =
true
;
148
break
;
149
150
case
'o'
:
151
fmt
.
base
=
Format::oct
;
152
fmt
.
format
=
Format::integer
;
153
done =
true
;
154
break
;
155
156
case
'd'
:
157
case
'i'
:
158
case
'u'
:
159
fmt
.
format
=
Format::integer
;
160
done =
true
;
161
break
;
162
163
case
'G'
:
164
fmt
.
uppercase
=
true
;
165
M5_FALLTHROUGH
;
166
case
'g'
:
167
fmt
.
format
=
Format::floating
;
168
fmt
.
float_format
=
Format::best
;
169
done =
true
;
170
break
;
171
172
case
'E'
:
173
fmt
.
uppercase
=
true
;
174
M5_FALLTHROUGH
;
175
case
'e'
:
176
fmt
.
format
=
Format::floating
;
177
fmt
.
float_format
=
Format::scientific
;
178
done =
true
;
179
break
;
180
181
case
'f'
:
182
fmt
.
format
=
Format::floating
;
183
fmt
.
float_format
=
Format::fixed
;
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
}
221
M5_FALLTHROUGH
;
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
263
fmt
.
width
=
fmt
.
precision
;
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
269
fmt
.
precision
=
fmt
.
width
;
270
}
271
}
272
}
// end while
273
274
++
ptr
;
275
}
276
277
void
278
Print::end_args
()
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