cprintf.cc revision 5756
12SN/A/* 24039Sbinkertn@umich.edu * Copyright (c) 2002-2006 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 292SN/A */ 302SN/A 312SN/A#include <cassert> 322SN/A#include <iomanip> 332SN/A#include <iostream> 342SN/A#include <sstream> 352SN/A 3656SN/A#include "base/cprintf.hh" 372SN/A 382SN/Ausing namespace std; 392SN/A 402SN/Anamespace cp { 412SN/A 424039Sbinkertn@umich.eduPrint::Print(std::ostream &stream, const std::string &format) 435756Snate@binkert.org : stream(stream), format(format.c_str()), ptr(format.c_str()), cont(false) 44492SN/A{ 454039Sbinkertn@umich.edu saved_flags = stream.flags(); 464039Sbinkertn@umich.edu saved_fill = stream.fill(); 474039Sbinkertn@umich.edu saved_precision = stream.precision(); 484039Sbinkertn@umich.edu} 494039Sbinkertn@umich.edu 504039Sbinkertn@umich.eduPrint::Print(std::ostream &stream, const char *format) 515756Snate@binkert.org : stream(stream), format(format), ptr(format), cont(false) 524039Sbinkertn@umich.edu{ 534039Sbinkertn@umich.edu saved_flags = stream.flags(); 544039Sbinkertn@umich.edu saved_fill = stream.fill(); 554039Sbinkertn@umich.edu saved_precision = stream.precision(); 564039Sbinkertn@umich.edu} 574039Sbinkertn@umich.edu 584039Sbinkertn@umich.eduPrint::~Print() 594039Sbinkertn@umich.edu{ 60492SN/A} 61492SN/A 622SN/Avoid 635756Snate@binkert.orgPrint::process() 642SN/A{ 655756Snate@binkert.org fmt.clear(); 665756Snate@binkert.org 674039Sbinkertn@umich.edu size_t len; 68492SN/A 694039Sbinkertn@umich.edu while (*ptr) { 704039Sbinkertn@umich.edu switch (*ptr) { 714039Sbinkertn@umich.edu case '%': 724039Sbinkertn@umich.edu if (ptr[1] != '%') 734039Sbinkertn@umich.edu goto processing; 742SN/A 754039Sbinkertn@umich.edu stream.put('%'); 764039Sbinkertn@umich.edu ptr += 2; 772SN/A break; 782SN/A 792SN/A case '\n': 804039Sbinkertn@umich.edu stream << endl; 814039Sbinkertn@umich.edu ++ptr; 822SN/A break; 832SN/A case '\r': 844039Sbinkertn@umich.edu ++ptr; 854039Sbinkertn@umich.edu if (*ptr != '\n') 864039Sbinkertn@umich.edu stream << endl; 872SN/A break; 882SN/A 894039Sbinkertn@umich.edu default: 904039Sbinkertn@umich.edu len = strcspn(ptr, "%\n\r\0"); 914039Sbinkertn@umich.edu stream.write(ptr, len); 924039Sbinkertn@umich.edu ptr += len; 932SN/A break; 942SN/A } 952SN/A } 962SN/A 974039Sbinkertn@umich.edu return; 984039Sbinkertn@umich.edu 994039Sbinkertn@umich.edu processing: 1004039Sbinkertn@umich.edu bool done = false; 1014039Sbinkertn@umich.edu bool end_number = false; 1024039Sbinkertn@umich.edu bool have_precision = false; 1034039Sbinkertn@umich.edu int number = 0; 1044039Sbinkertn@umich.edu 1054039Sbinkertn@umich.edu stream.fill(' '); 1064039Sbinkertn@umich.edu stream.flags((ios::fmtflags)0); 1074039Sbinkertn@umich.edu 1084039Sbinkertn@umich.edu while (!done) { 1094039Sbinkertn@umich.edu ++ptr; 1104039Sbinkertn@umich.edu if (*ptr >= '0' && *ptr <= '9') { 1114039Sbinkertn@umich.edu if (end_number) 1124039Sbinkertn@umich.edu continue; 1134039Sbinkertn@umich.edu } else if (number > 0) 1144039Sbinkertn@umich.edu end_number = true; 1154039Sbinkertn@umich.edu 1164039Sbinkertn@umich.edu switch (*ptr) { 1174039Sbinkertn@umich.edu case 's': 1184039Sbinkertn@umich.edu fmt.format = Format::string; 1194039Sbinkertn@umich.edu done = true; 1204039Sbinkertn@umich.edu break; 1214039Sbinkertn@umich.edu 1224039Sbinkertn@umich.edu case 'c': 1234039Sbinkertn@umich.edu fmt.format = Format::character; 1244039Sbinkertn@umich.edu done = true; 1254039Sbinkertn@umich.edu break; 1264039Sbinkertn@umich.edu 1274039Sbinkertn@umich.edu case 'l': 1284039Sbinkertn@umich.edu continue; 1294039Sbinkertn@umich.edu 1304039Sbinkertn@umich.edu case 'p': 1314039Sbinkertn@umich.edu fmt.format = Format::integer; 1324039Sbinkertn@umich.edu fmt.base = Format::hex; 1334039Sbinkertn@umich.edu fmt.alternate_form = true; 1344039Sbinkertn@umich.edu done = true; 1354039Sbinkertn@umich.edu break; 1364039Sbinkertn@umich.edu 1374039Sbinkertn@umich.edu case 'X': 1384039Sbinkertn@umich.edu fmt.uppercase = true; 1394039Sbinkertn@umich.edu case 'x': 1404039Sbinkertn@umich.edu fmt.base = Format::hex; 1414039Sbinkertn@umich.edu fmt.format = Format::integer; 1424039Sbinkertn@umich.edu done = true; 1434039Sbinkertn@umich.edu break; 1444039Sbinkertn@umich.edu 1454039Sbinkertn@umich.edu case 'o': 1464039Sbinkertn@umich.edu fmt.base = Format::oct; 1474039Sbinkertn@umich.edu fmt.format = Format::integer; 1484039Sbinkertn@umich.edu done = true; 1494039Sbinkertn@umich.edu break; 1504039Sbinkertn@umich.edu 1514039Sbinkertn@umich.edu case 'd': 1524039Sbinkertn@umich.edu case 'i': 1534039Sbinkertn@umich.edu case 'u': 1544039Sbinkertn@umich.edu fmt.format = Format::integer; 1554039Sbinkertn@umich.edu done = true; 1564039Sbinkertn@umich.edu break; 1574039Sbinkertn@umich.edu 1584039Sbinkertn@umich.edu case 'G': 1594039Sbinkertn@umich.edu fmt.uppercase = true; 1604039Sbinkertn@umich.edu case 'g': 1614039Sbinkertn@umich.edu fmt.format = Format::floating; 1624039Sbinkertn@umich.edu fmt.float_format = Format::best; 1634039Sbinkertn@umich.edu done = true; 1644039Sbinkertn@umich.edu break; 1654039Sbinkertn@umich.edu 1664039Sbinkertn@umich.edu case 'E': 1674039Sbinkertn@umich.edu fmt.uppercase = true; 1684039Sbinkertn@umich.edu case 'e': 1694039Sbinkertn@umich.edu fmt.format = Format::floating; 1704039Sbinkertn@umich.edu fmt.float_format = Format::scientific; 1714039Sbinkertn@umich.edu done = true; 1724039Sbinkertn@umich.edu break; 1734039Sbinkertn@umich.edu 1744039Sbinkertn@umich.edu case 'f': 1754039Sbinkertn@umich.edu fmt.format = Format::floating; 1764039Sbinkertn@umich.edu fmt.float_format = Format::fixed; 1774039Sbinkertn@umich.edu done = true; 1784039Sbinkertn@umich.edu break; 1794039Sbinkertn@umich.edu 1804039Sbinkertn@umich.edu case 'n': 1814039Sbinkertn@umich.edu stream << "we don't do %n!!!\n"; 1824039Sbinkertn@umich.edu done = true; 1834039Sbinkertn@umich.edu break; 1844039Sbinkertn@umich.edu 1854039Sbinkertn@umich.edu case '#': 1864039Sbinkertn@umich.edu fmt.alternate_form = true; 1874039Sbinkertn@umich.edu break; 1884039Sbinkertn@umich.edu 1894039Sbinkertn@umich.edu case '-': 1904039Sbinkertn@umich.edu fmt.flush_left = true; 1914039Sbinkertn@umich.edu break; 1924039Sbinkertn@umich.edu 1934039Sbinkertn@umich.edu case '+': 1944039Sbinkertn@umich.edu fmt.print_sign = true; 1954039Sbinkertn@umich.edu break; 1964039Sbinkertn@umich.edu 1974039Sbinkertn@umich.edu case ' ': 1984039Sbinkertn@umich.edu fmt.blank_space = true; 1994039Sbinkertn@umich.edu break; 2004039Sbinkertn@umich.edu 2014039Sbinkertn@umich.edu case '.': 2024039Sbinkertn@umich.edu fmt.width = number; 2034039Sbinkertn@umich.edu fmt.precision = 0; 2044039Sbinkertn@umich.edu have_precision = true; 2054039Sbinkertn@umich.edu number = 0; 2064039Sbinkertn@umich.edu end_number = false; 2074039Sbinkertn@umich.edu break; 2084039Sbinkertn@umich.edu 2094039Sbinkertn@umich.edu case '0': 2104039Sbinkertn@umich.edu if (number == 0) { 2114039Sbinkertn@umich.edu fmt.fill_zero = true; 2124039Sbinkertn@umich.edu break; 2134039Sbinkertn@umich.edu } 2144039Sbinkertn@umich.edu case '1': 2154039Sbinkertn@umich.edu case '2': 2164039Sbinkertn@umich.edu case '3': 2174039Sbinkertn@umich.edu case '4': 2184039Sbinkertn@umich.edu case '5': 2194039Sbinkertn@umich.edu case '6': 2204039Sbinkertn@umich.edu case '7': 2214039Sbinkertn@umich.edu case '8': 2224039Sbinkertn@umich.edu case '9': 2234039Sbinkertn@umich.edu number = number * 10 + (*ptr - '0'); 2244039Sbinkertn@umich.edu break; 2254039Sbinkertn@umich.edu 2265756Snate@binkert.org case '*': 2275756Snate@binkert.org if (have_precision) 2285756Snate@binkert.org fmt.get_precision = true; 2295756Snate@binkert.org else 2305756Snate@binkert.org fmt.get_width = true; 2315756Snate@binkert.org break; 2325756Snate@binkert.org 2334039Sbinkertn@umich.edu case '%': 2345756Snate@binkert.org assert(false && "we shouldn't get here"); 2354039Sbinkertn@umich.edu break; 2364039Sbinkertn@umich.edu 2374039Sbinkertn@umich.edu default: 2384039Sbinkertn@umich.edu done = true; 2394039Sbinkertn@umich.edu break; 2404039Sbinkertn@umich.edu } 2414039Sbinkertn@umich.edu 2424039Sbinkertn@umich.edu if (end_number) { 2434039Sbinkertn@umich.edu if (have_precision) 2444039Sbinkertn@umich.edu fmt.precision = number; 2454039Sbinkertn@umich.edu else 2464039Sbinkertn@umich.edu fmt.width = number; 2474039Sbinkertn@umich.edu 2484039Sbinkertn@umich.edu end_number = false; 2494039Sbinkertn@umich.edu number = 0; 2504039Sbinkertn@umich.edu } 2512SN/A } 2524039Sbinkertn@umich.edu 2534039Sbinkertn@umich.edu ++ptr; 2542SN/A} 2552SN/A 2564039Sbinkertn@umich.eduvoid 2574039Sbinkertn@umich.eduPrint::end_args() 2582SN/A{ 2594039Sbinkertn@umich.edu size_t len; 2602SN/A 2614039Sbinkertn@umich.edu while (*ptr) { 2624039Sbinkertn@umich.edu switch (*ptr) { 2634039Sbinkertn@umich.edu case '%': 2644039Sbinkertn@umich.edu if (ptr[1] != '%') 2654039Sbinkertn@umich.edu stream << "<extra arg>"; 2662SN/A 2674039Sbinkertn@umich.edu stream.put('%'); 2684039Sbinkertn@umich.edu ptr += 2; 2694039Sbinkertn@umich.edu break; 2704039Sbinkertn@umich.edu 2714039Sbinkertn@umich.edu case '\n': 2724039Sbinkertn@umich.edu stream << endl; 2734039Sbinkertn@umich.edu ++ptr; 2744039Sbinkertn@umich.edu break; 2754039Sbinkertn@umich.edu case '\r': 2764039Sbinkertn@umich.edu ++ptr; 2774039Sbinkertn@umich.edu if (*ptr != '\n') 2784039Sbinkertn@umich.edu stream << endl; 2794039Sbinkertn@umich.edu break; 2804039Sbinkertn@umich.edu 2814039Sbinkertn@umich.edu default: 2824039Sbinkertn@umich.edu len = strcspn(ptr, "%\n\r\0"); 2834039Sbinkertn@umich.edu stream.write(ptr, len); 2844039Sbinkertn@umich.edu ptr += len; 2854039Sbinkertn@umich.edu break; 2864039Sbinkertn@umich.edu } 2874039Sbinkertn@umich.edu } 2884039Sbinkertn@umich.edu 2894039Sbinkertn@umich.edu stream.flags(saved_flags); 2904039Sbinkertn@umich.edu stream.fill(saved_fill); 2914039Sbinkertn@umich.edu stream.precision(saved_precision); 2922SN/A} 2932SN/A 2944039Sbinkertn@umich.edu/* end namespace cp */ } 295