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