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 --- 23 unchanged lines hidden (view full) --- 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()) |
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) 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(Format &fmt) |
64{ |
65 size_t len; |
66 |
67 while (*ptr) { 68 switch (*ptr) { 69 case '%': 70 if (ptr[1] != '%') 71 goto processing; |
72 |
73 stream.put('%'); 74 ptr += 2; 75 break; |
76 |
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 |
87 default: 88 len = strcspn(ptr, "%\n\r\0"); 89 stream.write(ptr, len); 90 ptr += len; 91 break; 92 } 93 } |
94 |
95 return; |
96 |
97 processing: 98 bool done = false; 99 bool end_number = false; 100 bool have_precision = false; 101 int number = 0; |
102 |
103 stream.fill(' '); 104 stream.flags((ios::fmtflags)0); |
105 |
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 |
114 switch (*ptr) { 115 case 's': 116 fmt.format = Format::string; 117 done = true; 118 break; |
119 |
120 case 'c': 121 fmt.format = Format::character; 122 done = true; 123 break; |
124 |
125 case 'l': 126 continue; |
127 |
128 case 'p': 129 fmt.format = Format::integer; 130 fmt.base = Format::hex; 131 fmt.alternate_form = true; 132 done = true; 133 break; |
134 |
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 |
143 case 'o': 144 fmt.base = Format::oct; 145 fmt.format = Format::integer; 146 done = true; 147 break; |
148 |
149 case 'd': 150 case 'i': 151 case 'u': 152 fmt.format = Format::integer; 153 done = true; 154 break; |
155 |
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 |
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 |
172 case 'f': 173 fmt.format = Format::floating; 174 fmt.float_format = Format::fixed; 175 done = true; 176 break; |
177 |
178 case 'n': 179 stream << "we don't do %n!!!\n"; 180 done = true; 181 break; |
182 |
183 case '#': 184 fmt.alternate_form = true; 185 break; |
186 |
187 case '-': 188 fmt.flush_left = true; 189 break; |
190 |
191 case '+': 192 fmt.print_sign = true; 193 break; |
194 |
195 case ' ': 196 fmt.blank_space = true; 197 break; |
198 |
199 case '.': 200 fmt.width = number; 201 fmt.precision = 0; 202 have_precision = true; 203 number = 0; 204 end_number = false; 205 break; |
206 |
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 |
224 case '%': 225 assert("we shouldn't get here"); 226 break; |
227 |
228 default: 229 done = true; 230 break; 231 } |
232 |
233 if (end_number) { 234 if (have_precision) 235 fmt.precision = number; 236 else 237 fmt.width = number; |
238 |
239 end_number = false; 240 number = 0; 241 } 242 } |
243 |
244 ++ptr; 245} |
246 |
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': |
263 stream << endl; 264 ++ptr; |
265 break; 266 case '\r': |
267 ++ptr; 268 if (*ptr != '\n') 269 stream << endl; |
270 break; 271 |
272 default: 273 len = strcspn(ptr, "%\n\r\0"); 274 stream.write(ptr, len); 275 ptr += len; |
276 break; 277 } 278 } 279 |
280 stream.flags(saved_flags); 281 stream.fill(saved_fill); 282 stream.precision(saved_precision); |
283} 284 |
285/* end namespace cp */ } |