cprintf.cc (2665:a124942bacb8) cprintf.cc (4039:b910b61a52b9)
1/*
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

--- 23 unchanged lines hidden (view full) ---

34#include <sstream>
35
36#include "base/cprintf.hh"
37
38using namespace std;
39
40namespace cp {
41
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

--- 23 unchanged lines hidden (view full) ---

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())
43{
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
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
50void
62void
51ArgList::dump(const string &format)
63Print::process(Format &fmt)
52{
64{
53 list_t::iterator iter = objects.begin();
54 list_t::iterator end = objects.end();
65 size_t len;
55
66
56 const char *p = format.c_str();
67 while (*ptr) {
68 switch (*ptr) {
69 case '%':
70 if (ptr[1] != '%')
71 goto processing;
57
72
58 stream->fill(' ');
59 stream->flags((ios::fmtflags)0);
73 stream.put('%');
74 ptr += 2;
75 break;
60
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;
69
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 }
75
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;
83
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;
89
102
90 case 'c':
91 fmt.format = Format::character;
92 done = true;
93 break;
103 stream.fill(' ');
104 stream.flags((ios::fmtflags)0);
94
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;
97
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;
104
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;
112
124
113 case 'o':
114 fmt.base = Format::oct;
115 fmt.format = Format::integer;
116 done = true;
117 break;
125 case 'l':
126 continue;
118
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;
125
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;
133
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;
141
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;
147
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;
152
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;
156
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;
160
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;
164
182
165 case ' ':
166 fmt.blank_space = true;
167 break;
183 case '#':
184 fmt.alternate_form = true;
185 break;
168
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;
176
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;
193
194
194 case '%':
195 assert("we shouldn't get here");
196 break;
195 case ' ':
196 fmt.blank_space = true;
197 break;
197
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;
202
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;
208
223
209 end_number = false;
210 number = 0;
211 }
212 }
224 case '%':
225 assert("we shouldn't get here");
226 break;
213
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 }
219
232
220 (*iter)->process(*stream, fmt);
233 if (end_number) {
234 if (have_precision)
235 fmt.precision = number;
236 else
237 fmt.width = number;
221
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 }
225
243
226 ++iter;
227 } else {
228 *stream << "<missing arg for format>";
229 }
244 ++ptr;
245}
230
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;
233 break;
234
235 case '\n':
260 break;
261
262 case '\n':
236 *stream << endl;
237 ++p;
263 stream << endl;
264 ++ptr;
238 break;
239 case '\r':
265 break;
266 case '\r':
240 ++p;
241 if (*p != '\n')
242 *stream << endl;
267 ++ptr;
268 if (*ptr != '\n')
269 stream << endl;
243 break;
244
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;
250 break;
251 }
252 }
253
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);
258}
259
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 */ }