Deleted Added
sdiff udiff text old ( 2665:a124942bacb8 ) new ( 4039:b910b61a52b9 )
full compact
1/*
2 * Copyright (c) 2002-2005 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
42ArgList::~ArgList()
43{
44 while (!objects.empty()) {
45 delete objects.front();
46 objects.pop_front();
47 }
48}
49
50void
51ArgList::dump(const string &format)
52{
53 list_t::iterator iter = objects.begin();
54 list_t::iterator end = objects.end();
55
56 const char *p = format.c_str();
57
58 stream->fill(' ');
59 stream->flags((ios::fmtflags)0);
60
61 while (*p) {
62 switch (*p) {
63 case '%': {
64 if (p[1] == '%') {
65 *stream << '%';
66 p += 2;
67 continue;
68 }
69
70 Format fmt;
71 bool done = false;
72 bool end_number = false;
73 bool have_precision = false;
74 int number = 0;
75
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;
83
84 switch (*p) {
85 case 's':
86 fmt.format = Format::string;
87 done = true;
88 break;
89
90 case 'c':
91 fmt.format = Format::character;
92 done = true;
93 break;
94
95 case 'l':
96 continue;
97
98 case 'p':
99 fmt.format = Format::integer;
100 fmt.base = Format::hex;
101 fmt.alternate_form = true;
102 done = true;
103 break;
104
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;
112
113 case 'o':
114 fmt.base = Format::oct;
115 fmt.format = Format::integer;
116 done = true;
117 break;
118
119 case 'd':
120 case 'i':
121 case 'u':
122 fmt.format = Format::integer;
123 done = true;
124 break;
125
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;
133
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;
141
142 case 'f':
143 fmt.format = Format::floating;
144 fmt.float_format = Format::fixed;
145 done = true;
146 break;
147
148 case 'n':
149 *stream << "we don't do %n!!!\n";
150 done = true;
151 break;
152
153 case '#':
154 fmt.alternate_form = true;
155 break;
156
157 case '-':
158 fmt.flush_left = true;
159 break;
160
161 case '+':
162 fmt.print_sign = true;
163 break;
164
165 case ' ':
166 fmt.blank_space = true;
167 break;
168
169 case '.':
170 fmt.width = number;
171 fmt.precision = 0;
172 have_precision = true;
173 number = 0;
174 end_number = false;
175 break;
176
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;
193
194 case '%':
195 assert("we shouldn't get here");
196 break;
197
198 default:
199 done = true;
200 break;
201 }
202
203 if (end_number) {
204 if (have_precision)
205 fmt.precision = number;
206 else
207 fmt.width = number;
208
209 end_number = false;
210 number = 0;
211 }
212 }
213
214 if (iter != end)
215 {
216 ios::fmtflags saved_flags = stream->flags();
217 char old_fill = stream->fill();
218 int old_precision = stream->precision();
219
220 (*iter)->process(*stream, fmt);
221
222 stream->flags(saved_flags);
223 stream->fill(old_fill);
224 stream->precision(old_precision);
225
226 ++iter;
227 } else {
228 *stream << "<missing arg for format>";
229 }
230
231 ++p;
232 }
233 break;
234
235 case '\n':
236 *stream << endl;
237 ++p;
238 break;
239 case '\r':
240 ++p;
241 if (*p != '\n')
242 *stream << endl;
243 break;
244
245 default: {
246 size_t len = strcspn(p, "%\n\r\0");
247 stream->write(p, len);
248 p += len;
249 }
250 break;
251 }
252 }
253
254 while (iter != end) {
255 *stream << "<extra arg>";
256 ++iter;
257 }
258}
259
260string
261ArgList::dumpToString(const string &format)
262{
263 stringstream ss;
264
265 dump(ss, format);
266
267 return ss.str();
268}
269
270}