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 */ } |