Deleted Added
sdiff udiff text old ( 7811:a8fc35183c10 ) new ( 9331:6630b3ffe7c0 )
full compact
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 * Authors: Nathan Binkert
29 */
30
31#include <cassert>
32#include <iomanip>
33#include <iostream>
34#include <sstream>
35
36#include "base/cprintf.hh"
37
38using namespace std;
39
40namespace cp {
41
42Print::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}
49
50Print::Print(std::ostream &stream, const char *format)
51 : stream(stream), format(format), ptr(format), cont(false)
52{
53 saved_flags = stream.flags();
54 saved_fill = stream.fill();
55 saved_precision = stream.precision();
56}
57
58Print::~Print()
59{
60}
61
62void
63Print::process()
64{
65 fmt.clear();
66
67 size_t len;
68
69 while (*ptr) {
70 switch (*ptr) {
71 case '%':
72 if (ptr[1] != '%')
73 goto processing;
74
75 stream.put('%');
76 ptr += 2;
77 break;
78
79 case '\n':
80 stream << endl;
81 ++ptr;
82 break;
83 case '\r':
84 ++ptr;
85 if (*ptr != '\n')
86 stream << endl;
87 break;
88
89 default:
90 len = strcspn(ptr, "%\n\r\0");
91 stream.write(ptr, len);
92 ptr += len;
93 break;
94 }
95 }
96
97 return;
98
99 processing:
100 bool done = false;
101 bool end_number = false;
102 bool have_precision = false;
103 int number = 0;
104
105 stream.fill(' ');
106 stream.flags((ios::fmtflags)0);
107
108 while (!done) {
109 ++ptr;
110 if (*ptr >= '0' && *ptr <= '9') {
111 if (end_number)
112 continue;
113 } else if (number > 0)
114 end_number = true;
115
116 switch (*ptr) {
117 case 's':
118 fmt.format = Format::string;
119 done = true;
120 break;
121
122 case 'c':
123 fmt.format = Format::character;
124 done = true;
125 break;
126
127 case 'l':
128 continue;
129
130 case 'p':
131 fmt.format = Format::integer;
132 fmt.base = Format::hex;
133 fmt.alternate_form = true;
134 done = true;
135 break;
136
137 case 'X':
138 fmt.uppercase = true;
139 case 'x':
140 fmt.base = Format::hex;
141 fmt.format = Format::integer;
142 done = true;
143 break;
144
145 case 'o':
146 fmt.base = Format::oct;
147 fmt.format = Format::integer;
148 done = true;
149 break;
150
151 case 'd':
152 case 'i':
153 case 'u':
154 fmt.format = Format::integer;
155 done = true;
156 break;
157
158 case 'G':
159 fmt.uppercase = true;
160 case 'g':
161 fmt.format = Format::floating;
162 fmt.float_format = Format::best;
163 done = true;
164 break;
165
166 case 'E':
167 fmt.uppercase = true;
168 case 'e':
169 fmt.format = Format::floating;
170 fmt.float_format = Format::scientific;
171 done = true;
172 break;
173
174 case 'f':
175 fmt.format = Format::floating;
176 fmt.float_format = Format::fixed;
177 done = true;
178 break;
179
180 case 'n':
181 stream << "we don't do %n!!!\n";
182 done = true;
183 break;
184
185 case '#':
186 fmt.alternate_form = true;
187 break;
188
189 case '-':
190 fmt.flush_left = true;
191 break;
192
193 case '+':
194 fmt.print_sign = true;
195 break;
196
197 case ' ':
198 fmt.blank_space = true;
199 break;
200
201 case '.':
202 fmt.width = number;
203 fmt.precision = 0;
204 have_precision = true;
205 number = 0;
206 end_number = false;
207 break;
208
209 case '0':
210 if (number == 0) {
211 fmt.fill_zero = true;
212 break;
213 }
214 case '1':
215 case '2':
216 case '3':
217 case '4':
218 case '5':
219 case '6':
220 case '7':
221 case '8':
222 case '9':
223 number = number * 10 + (*ptr - '0');
224 break;
225
226 case '*':
227 if (have_precision)
228 fmt.get_precision = true;
229 else
230 fmt.get_width = true;
231 break;
232
233 case '%':
234 assert(false && "we shouldn't get here");
235 break;
236
237 default:
238 done = true;
239 break;
240 }
241
242 if (end_number) {
243 if (have_precision)
244 fmt.precision = number;
245 else
246 fmt.width = number;
247
248 end_number = false;
249 number = 0;
250 }
251 }
252
253 ++ptr;
254}
255
256void
257Print::end_args()
258{
259 size_t len;
260
261 while (*ptr) {
262 switch (*ptr) {
263 case '%':
264 if (ptr[1] != '%')
265 stream << "<extra arg>";
266
267 stream.put('%');
268 ptr += 2;
269 break;
270
271 case '\n':
272 stream << endl;
273 ++ptr;
274 break;
275 case '\r':
276 ++ptr;
277 if (*ptr != '\n')
278 stream << endl;
279 break;
280
281 default:
282 len = strcspn(ptr, "%\n\r\0");
283 stream.write(ptr, len);
284 ptr += len;
285 break;
286 }
287 }
288
289 stream.flags(saved_flags);
290 stream.fill(saved_fill);
291 stream.precision(saved_precision);
292}
293
294} // namespace cp