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 3111793Sbrandon.potter@amd.com#include "base/cprintf.hh" 3211793Sbrandon.potter@amd.com 332SN/A#include <cassert> 342SN/A#include <iomanip> 352SN/A#include <iostream> 362SN/A#include <sstream> 372SN/A 3812392Sjason@lowepower.com#include "base/compiler.hh" 3912392Sjason@lowepower.com 402SN/Ausing namespace std; 412SN/A 422SN/Anamespace cp { 432SN/A 444039Sbinkertn@umich.eduPrint::Print(std::ostream &stream, const std::string &format) 455756Snate@binkert.org : stream(stream), format(format.c_str()), ptr(format.c_str()), cont(false) 46492SN/A{ 474039Sbinkertn@umich.edu saved_flags = stream.flags(); 484039Sbinkertn@umich.edu saved_fill = stream.fill(); 494039Sbinkertn@umich.edu saved_precision = stream.precision(); 5012979Sgabeblack@google.com saved_width = stream.width(); 514039Sbinkertn@umich.edu} 524039Sbinkertn@umich.edu 534039Sbinkertn@umich.eduPrint::Print(std::ostream &stream, const char *format) 545756Snate@binkert.org : stream(stream), format(format), ptr(format), cont(false) 554039Sbinkertn@umich.edu{ 564039Sbinkertn@umich.edu saved_flags = stream.flags(); 574039Sbinkertn@umich.edu saved_fill = stream.fill(); 584039Sbinkertn@umich.edu saved_precision = stream.precision(); 5912979Sgabeblack@google.com saved_width = stream.width(); 604039Sbinkertn@umich.edu} 614039Sbinkertn@umich.edu 624039Sbinkertn@umich.eduPrint::~Print() 634039Sbinkertn@umich.edu{ 64492SN/A} 65492SN/A 662SN/Avoid 675756Snate@binkert.orgPrint::process() 682SN/A{ 695756Snate@binkert.org fmt.clear(); 705756Snate@binkert.org 714039Sbinkertn@umich.edu size_t len; 72492SN/A 734039Sbinkertn@umich.edu while (*ptr) { 744039Sbinkertn@umich.edu switch (*ptr) { 754039Sbinkertn@umich.edu case '%': 769331Schander.sudanthi@arm.com if (ptr[1] != '%') { 779331Schander.sudanthi@arm.com process_flag(); 789331Schander.sudanthi@arm.com return; 799331Schander.sudanthi@arm.com } 804039Sbinkertn@umich.edu stream.put('%'); 814039Sbinkertn@umich.edu ptr += 2; 822SN/A break; 832SN/A 842SN/A case '\n': 854039Sbinkertn@umich.edu stream << endl; 864039Sbinkertn@umich.edu ++ptr; 872SN/A break; 882SN/A case '\r': 894039Sbinkertn@umich.edu ++ptr; 904039Sbinkertn@umich.edu if (*ptr != '\n') 914039Sbinkertn@umich.edu stream << endl; 922SN/A break; 932SN/A 944039Sbinkertn@umich.edu default: 954039Sbinkertn@umich.edu len = strcspn(ptr, "%\n\r\0"); 964039Sbinkertn@umich.edu stream.write(ptr, len); 974039Sbinkertn@umich.edu ptr += len; 982SN/A break; 992SN/A } 1002SN/A } 1019331Schander.sudanthi@arm.com} 1022SN/A 1039331Schander.sudanthi@arm.comvoid 1049331Schander.sudanthi@arm.comPrint::process_flag() 1059331Schander.sudanthi@arm.com{ 1064039Sbinkertn@umich.edu bool done = false; 1074039Sbinkertn@umich.edu bool end_number = false; 1084039Sbinkertn@umich.edu bool have_precision = false; 1094039Sbinkertn@umich.edu int number = 0; 1104039Sbinkertn@umich.edu 1114039Sbinkertn@umich.edu stream.fill(' '); 1124039Sbinkertn@umich.edu stream.flags((ios::fmtflags)0); 1134039Sbinkertn@umich.edu 1144039Sbinkertn@umich.edu while (!done) { 1154039Sbinkertn@umich.edu ++ptr; 1164039Sbinkertn@umich.edu if (*ptr >= '0' && *ptr <= '9') { 1174039Sbinkertn@umich.edu if (end_number) 1184039Sbinkertn@umich.edu continue; 1194039Sbinkertn@umich.edu } else if (number > 0) 1204039Sbinkertn@umich.edu end_number = true; 1214039Sbinkertn@umich.edu 1224039Sbinkertn@umich.edu switch (*ptr) { 1234039Sbinkertn@umich.edu case 's': 1244039Sbinkertn@umich.edu fmt.format = Format::string; 1254039Sbinkertn@umich.edu done = true; 1264039Sbinkertn@umich.edu break; 1274039Sbinkertn@umich.edu 1284039Sbinkertn@umich.edu case 'c': 1294039Sbinkertn@umich.edu fmt.format = Format::character; 1304039Sbinkertn@umich.edu done = true; 1314039Sbinkertn@umich.edu break; 1324039Sbinkertn@umich.edu 1334039Sbinkertn@umich.edu case 'l': 1344039Sbinkertn@umich.edu continue; 1354039Sbinkertn@umich.edu 1364039Sbinkertn@umich.edu case 'p': 1374039Sbinkertn@umich.edu fmt.format = Format::integer; 1384039Sbinkertn@umich.edu fmt.base = Format::hex; 1394039Sbinkertn@umich.edu fmt.alternate_form = true; 1404039Sbinkertn@umich.edu done = true; 1414039Sbinkertn@umich.edu break; 1424039Sbinkertn@umich.edu 1434039Sbinkertn@umich.edu case 'X': 1444039Sbinkertn@umich.edu fmt.uppercase = true; 14512392Sjason@lowepower.com M5_FALLTHROUGH; 1464039Sbinkertn@umich.edu case 'x': 1474039Sbinkertn@umich.edu fmt.base = Format::hex; 1484039Sbinkertn@umich.edu fmt.format = Format::integer; 1494039Sbinkertn@umich.edu done = true; 1504039Sbinkertn@umich.edu break; 1514039Sbinkertn@umich.edu 1524039Sbinkertn@umich.edu case 'o': 1534039Sbinkertn@umich.edu fmt.base = Format::oct; 1544039Sbinkertn@umich.edu fmt.format = Format::integer; 1554039Sbinkertn@umich.edu done = true; 1564039Sbinkertn@umich.edu break; 1574039Sbinkertn@umich.edu 1584039Sbinkertn@umich.edu case 'd': 1594039Sbinkertn@umich.edu case 'i': 1604039Sbinkertn@umich.edu case 'u': 1614039Sbinkertn@umich.edu fmt.format = Format::integer; 1624039Sbinkertn@umich.edu done = true; 1634039Sbinkertn@umich.edu break; 1644039Sbinkertn@umich.edu 1654039Sbinkertn@umich.edu case 'G': 1664039Sbinkertn@umich.edu fmt.uppercase = true; 16712392Sjason@lowepower.com M5_FALLTHROUGH; 1684039Sbinkertn@umich.edu case 'g': 1694039Sbinkertn@umich.edu fmt.format = Format::floating; 1704039Sbinkertn@umich.edu fmt.float_format = Format::best; 1714039Sbinkertn@umich.edu done = true; 1724039Sbinkertn@umich.edu break; 1734039Sbinkertn@umich.edu 1744039Sbinkertn@umich.edu case 'E': 1754039Sbinkertn@umich.edu fmt.uppercase = true; 17612392Sjason@lowepower.com M5_FALLTHROUGH; 1774039Sbinkertn@umich.edu case 'e': 1784039Sbinkertn@umich.edu fmt.format = Format::floating; 1794039Sbinkertn@umich.edu fmt.float_format = Format::scientific; 1804039Sbinkertn@umich.edu done = true; 1814039Sbinkertn@umich.edu break; 1824039Sbinkertn@umich.edu 1834039Sbinkertn@umich.edu case 'f': 1844039Sbinkertn@umich.edu fmt.format = Format::floating; 1854039Sbinkertn@umich.edu fmt.float_format = Format::fixed; 1864039Sbinkertn@umich.edu done = true; 1874039Sbinkertn@umich.edu break; 1884039Sbinkertn@umich.edu 1894039Sbinkertn@umich.edu case 'n': 1904039Sbinkertn@umich.edu stream << "we don't do %n!!!\n"; 1914039Sbinkertn@umich.edu done = true; 1924039Sbinkertn@umich.edu break; 1934039Sbinkertn@umich.edu 1944039Sbinkertn@umich.edu case '#': 1954039Sbinkertn@umich.edu fmt.alternate_form = true; 1964039Sbinkertn@umich.edu break; 1974039Sbinkertn@umich.edu 1984039Sbinkertn@umich.edu case '-': 1994039Sbinkertn@umich.edu fmt.flush_left = true; 2004039Sbinkertn@umich.edu break; 2014039Sbinkertn@umich.edu 2024039Sbinkertn@umich.edu case '+': 2034039Sbinkertn@umich.edu fmt.print_sign = true; 2044039Sbinkertn@umich.edu break; 2054039Sbinkertn@umich.edu 2064039Sbinkertn@umich.edu case ' ': 2074039Sbinkertn@umich.edu fmt.blank_space = true; 2084039Sbinkertn@umich.edu break; 2094039Sbinkertn@umich.edu 2104039Sbinkertn@umich.edu case '.': 2114039Sbinkertn@umich.edu fmt.width = number; 2124039Sbinkertn@umich.edu fmt.precision = 0; 2134039Sbinkertn@umich.edu have_precision = true; 2144039Sbinkertn@umich.edu number = 0; 2154039Sbinkertn@umich.edu end_number = false; 2164039Sbinkertn@umich.edu break; 2174039Sbinkertn@umich.edu 2184039Sbinkertn@umich.edu case '0': 2194039Sbinkertn@umich.edu if (number == 0) { 2204039Sbinkertn@umich.edu fmt.fill_zero = true; 2214039Sbinkertn@umich.edu break; 2224039Sbinkertn@umich.edu } 22312392Sjason@lowepower.com M5_FALLTHROUGH; 2244039Sbinkertn@umich.edu case '1': 2254039Sbinkertn@umich.edu case '2': 2264039Sbinkertn@umich.edu case '3': 2274039Sbinkertn@umich.edu case '4': 2284039Sbinkertn@umich.edu case '5': 2294039Sbinkertn@umich.edu case '6': 2304039Sbinkertn@umich.edu case '7': 2314039Sbinkertn@umich.edu case '8': 2324039Sbinkertn@umich.edu case '9': 2334039Sbinkertn@umich.edu number = number * 10 + (*ptr - '0'); 2344039Sbinkertn@umich.edu break; 2354039Sbinkertn@umich.edu 2365756Snate@binkert.org case '*': 2375756Snate@binkert.org if (have_precision) 2385756Snate@binkert.org fmt.get_precision = true; 2395756Snate@binkert.org else 2405756Snate@binkert.org fmt.get_width = true; 2415756Snate@binkert.org break; 2425756Snate@binkert.org 2434039Sbinkertn@umich.edu case '%': 2445756Snate@binkert.org assert(false && "we shouldn't get here"); 2454039Sbinkertn@umich.edu break; 2464039Sbinkertn@umich.edu 2474039Sbinkertn@umich.edu default: 2484039Sbinkertn@umich.edu done = true; 2494039Sbinkertn@umich.edu break; 2504039Sbinkertn@umich.edu } 2514039Sbinkertn@umich.edu 2524039Sbinkertn@umich.edu if (end_number) { 2534039Sbinkertn@umich.edu if (have_precision) 2544039Sbinkertn@umich.edu fmt.precision = number; 2554039Sbinkertn@umich.edu else 2564039Sbinkertn@umich.edu fmt.width = number; 2574039Sbinkertn@umich.edu 2584039Sbinkertn@umich.edu end_number = false; 2594039Sbinkertn@umich.edu number = 0; 2604039Sbinkertn@umich.edu } 2619331Schander.sudanthi@arm.com 2629331Schander.sudanthi@arm.com if (done) { 2639331Schander.sudanthi@arm.com if ((fmt.format == Format::integer) && have_precision) { 2649331Schander.sudanthi@arm.com // specified a . but not a float, set width 2659331Schander.sudanthi@arm.com fmt.width = fmt.precision; 2669331Schander.sudanthi@arm.com // precision requries digits for width, must fill with 0 2679331Schander.sudanthi@arm.com fmt.fill_zero = true; 2689331Schander.sudanthi@arm.com } else if ((fmt.format == Format::floating) && !have_precision && 2699331Schander.sudanthi@arm.com fmt.fill_zero) { 2709331Schander.sudanthi@arm.com // ambiguous case, matching printf 2719331Schander.sudanthi@arm.com fmt.precision = fmt.width; 2729331Schander.sudanthi@arm.com } 2739331Schander.sudanthi@arm.com } 2749331Schander.sudanthi@arm.com } // end while 2754039Sbinkertn@umich.edu 2764039Sbinkertn@umich.edu ++ptr; 2772SN/A} 2782SN/A 2794039Sbinkertn@umich.eduvoid 2804039Sbinkertn@umich.eduPrint::end_args() 2812SN/A{ 2824039Sbinkertn@umich.edu size_t len; 2832SN/A 2844039Sbinkertn@umich.edu while (*ptr) { 2854039Sbinkertn@umich.edu switch (*ptr) { 2864039Sbinkertn@umich.edu case '%': 2874039Sbinkertn@umich.edu if (ptr[1] != '%') 2884039Sbinkertn@umich.edu stream << "<extra arg>"; 2892SN/A 2904039Sbinkertn@umich.edu stream.put('%'); 2914039Sbinkertn@umich.edu ptr += 2; 2924039Sbinkertn@umich.edu break; 2934039Sbinkertn@umich.edu 2944039Sbinkertn@umich.edu case '\n': 2954039Sbinkertn@umich.edu stream << endl; 2964039Sbinkertn@umich.edu ++ptr; 2974039Sbinkertn@umich.edu break; 2984039Sbinkertn@umich.edu case '\r': 2994039Sbinkertn@umich.edu ++ptr; 3004039Sbinkertn@umich.edu if (*ptr != '\n') 3014039Sbinkertn@umich.edu stream << endl; 3024039Sbinkertn@umich.edu break; 3034039Sbinkertn@umich.edu 3044039Sbinkertn@umich.edu default: 3054039Sbinkertn@umich.edu len = strcspn(ptr, "%\n\r\0"); 3064039Sbinkertn@umich.edu stream.write(ptr, len); 3074039Sbinkertn@umich.edu ptr += len; 3084039Sbinkertn@umich.edu break; 3094039Sbinkertn@umich.edu } 3104039Sbinkertn@umich.edu } 3114039Sbinkertn@umich.edu 3124039Sbinkertn@umich.edu stream.flags(saved_flags); 3134039Sbinkertn@umich.edu stream.fill(saved_fill); 3144039Sbinkertn@umich.edu stream.precision(saved_precision); 31512979Sgabeblack@google.com stream.width(saved_width); 3162SN/A} 3172SN/A 3187811Ssteve.reinhardt@amd.com} // namespace cp 319