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