cprintf.cc revision 7811:a8fc35183c10
19665Sandreas.hansson@arm.com/* 29665Sandreas.hansson@arm.com * Copyright (c) 2002-2006 The Regents of The University of Michigan 39665Sandreas.hansson@arm.com * All rights reserved. 49665Sandreas.hansson@arm.com * 59665Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 69665Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 79665Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 89665Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 99665Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 109665Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 119665Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 129665Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 135353Svilas.sridharan@gmail.com * contributors may be used to endorse or promote products derived from 143395Shsul@eecs.umich.edu * this software without specific prior written permission. 153395Shsul@eecs.umich.edu * 163395Shsul@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173395Shsul@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183395Shsul@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193395Shsul@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203395Shsul@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213395Shsul@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223395Shsul@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233395Shsul@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243395Shsul@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253395Shsul@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263395Shsul@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273395Shsul@eecs.umich.edu * 283395Shsul@eecs.umich.edu * Authors: Nathan Binkert 293395Shsul@eecs.umich.edu */ 303395Shsul@eecs.umich.edu 313395Shsul@eecs.umich.edu#include <cassert> 323395Shsul@eecs.umich.edu#include <iomanip> 333395Shsul@eecs.umich.edu#include <iostream> 343395Shsul@eecs.umich.edu#include <sstream> 353395Shsul@eecs.umich.edu 363395Shsul@eecs.umich.edu#include "base/cprintf.hh" 373395Shsul@eecs.umich.edu 383395Shsul@eecs.umich.eduusing namespace std; 393395Shsul@eecs.umich.edu 403395Shsul@eecs.umich.edunamespace cp { 418920Snilay@cs.wisc.edu 428920Snilay@cs.wisc.eduPrint::Print(std::ostream &stream, const std::string &format) 438920Snilay@cs.wisc.edu : stream(stream), format(format.c_str()), ptr(format.c_str()), cont(false) 448920Snilay@cs.wisc.edu{ 457025SBrad.Beckmann@amd.com saved_flags = stream.flags(); 469520SAndreas.Sandberg@ARM.com saved_fill = stream.fill(); 479665Sandreas.hansson@arm.com saved_precision = stream.precision(); 489520SAndreas.Sandberg@ARM.com} 499520SAndreas.Sandberg@ARM.com 509520SAndreas.Sandberg@ARM.comPrint::Print(std::ostream &stream, const char *format) 519520SAndreas.Sandberg@ARM.com : stream(stream), format(format), ptr(format), cont(false) 529520SAndreas.Sandberg@ARM.com{ 539665Sandreas.hansson@arm.com saved_flags = stream.flags(); 549665Sandreas.hansson@arm.com saved_fill = stream.fill(); 559665Sandreas.hansson@arm.com saved_precision = stream.precision(); 569665Sandreas.hansson@arm.com} 578920Snilay@cs.wisc.edu 588920Snilay@cs.wisc.eduPrint::~Print() 599520SAndreas.Sandberg@ARM.com{ 609520SAndreas.Sandberg@ARM.com} 619520SAndreas.Sandberg@ARM.com 628920Snilay@cs.wisc.eduvoid 639520SAndreas.Sandberg@ARM.comPrint::process() 648920Snilay@cs.wisc.edu{ 658920Snilay@cs.wisc.edu fmt.clear(); 668920Snilay@cs.wisc.edu 679827Sakash.bagdia@arm.com size_t len; 689827Sakash.bagdia@arm.com 699827Sakash.bagdia@arm.com while (*ptr) { 709827Sakash.bagdia@arm.com switch (*ptr) { 719790Sakash.bagdia@arm.com case '%': 729790Sakash.bagdia@arm.com if (ptr[1] != '%') 739790Sakash.bagdia@arm.com goto processing; 749790Sakash.bagdia@arm.com 759789Sakash.bagdia@arm.com stream.put('%'); 769789Sakash.bagdia@arm.com ptr += 2; 779789Sakash.bagdia@arm.com break; 789800Snilay@cs.wisc.edu 799800Snilay@cs.wisc.edu case '\n': 809800Snilay@cs.wisc.edu stream << endl; 819800Snilay@cs.wisc.edu ++ptr; 829800Snilay@cs.wisc.edu break; 839800Snilay@cs.wisc.edu case '\r': 849800Snilay@cs.wisc.edu ++ptr; 859800Snilay@cs.wisc.edu if (*ptr != '\n') 869800Snilay@cs.wisc.edu stream << endl; 879800Snilay@cs.wisc.edu break; 889800Snilay@cs.wisc.edu 899800Snilay@cs.wisc.edu default: 909800Snilay@cs.wisc.edu len = strcspn(ptr, "%\n\r\0"); 919836Sandreas.hansson@arm.com stream.write(ptr, len); 929836Sandreas.hansson@arm.com ptr += len; 939800Snilay@cs.wisc.edu break; 949800Snilay@cs.wisc.edu } 959800Snilay@cs.wisc.edu } 969800Snilay@cs.wisc.edu 979800Snilay@cs.wisc.edu return; 989800Snilay@cs.wisc.edu 999800Snilay@cs.wisc.edu processing: 1009800Snilay@cs.wisc.edu bool done = false; 1018920Snilay@cs.wisc.edu bool end_number = false; 1028920Snilay@cs.wisc.edu bool have_precision = false; 1038920Snilay@cs.wisc.edu int number = 0; 1048920Snilay@cs.wisc.edu 1058920Snilay@cs.wisc.edu stream.fill(' '); 1068920Snilay@cs.wisc.edu stream.flags((ios::fmtflags)0); 1078920Snilay@cs.wisc.edu 1088920Snilay@cs.wisc.edu while (!done) { 1098920Snilay@cs.wisc.edu ++ptr; 1108920Snilay@cs.wisc.edu if (*ptr >= '0' && *ptr <= '9') { 1118920Snilay@cs.wisc.edu if (end_number) 1128920Snilay@cs.wisc.edu continue; 1139800Snilay@cs.wisc.edu } else if (number > 0) 1149800Snilay@cs.wisc.edu end_number = true; 1158920Snilay@cs.wisc.edu 1163395Shsul@eecs.umich.edu switch (*ptr) { 1178920Snilay@cs.wisc.edu case 's': 1189909Snilay@cs.wisc.edu fmt.format = Format::string; 1199816Sjthestness@gmail.com done = true; 1209816Sjthestness@gmail.com break; 1219816Sjthestness@gmail.com 1229816Sjthestness@gmail.com case 'c': 1239816Sjthestness@gmail.com fmt.format = Format::character; 1249816Sjthestness@gmail.com done = true; 1259816Sjthestness@gmail.com break; 1269816Sjthestness@gmail.com 1279816Sjthestness@gmail.com case 'l': 1288920Snilay@cs.wisc.edu continue; 1298920Snilay@cs.wisc.edu 1308920Snilay@cs.wisc.edu case 'p': 1318920Snilay@cs.wisc.edu fmt.format = Format::integer; 1328920Snilay@cs.wisc.edu fmt.base = Format::hex; 1338920Snilay@cs.wisc.edu fmt.alternate_form = true; 1348920Snilay@cs.wisc.edu done = true; 1358920Snilay@cs.wisc.edu break; 1368920Snilay@cs.wisc.edu 1378920Snilay@cs.wisc.edu case 'X': 1388920Snilay@cs.wisc.edu fmt.uppercase = true; 1398920Snilay@cs.wisc.edu case 'x': 1408920Snilay@cs.wisc.edu fmt.base = Format::hex; 1418920Snilay@cs.wisc.edu fmt.format = Format::integer; 1426776SBrad.Beckmann@amd.com done = true; 1439800Snilay@cs.wisc.edu break; 1449800Snilay@cs.wisc.edu 1459800Snilay@cs.wisc.edu case 'o': 1469800Snilay@cs.wisc.edu fmt.base = Format::oct; 1479800Snilay@cs.wisc.edu fmt.format = Format::integer; 1489800Snilay@cs.wisc.edu done = true; 1498920Snilay@cs.wisc.edu break; 1508920Snilay@cs.wisc.edu 1518920Snilay@cs.wisc.edu case 'd': 1528920Snilay@cs.wisc.edu case 'i': 1539357Sandreas.hansson@arm.com case 'u': 1548920Snilay@cs.wisc.edu fmt.format = Format::integer; 1558920Snilay@cs.wisc.edu done = true; 1568920Snilay@cs.wisc.edu break; 1578920Snilay@cs.wisc.edu 1588920Snilay@cs.wisc.edu case 'G': 1598920Snilay@cs.wisc.edu fmt.uppercase = true; 1608920Snilay@cs.wisc.edu case 'g': 1618920Snilay@cs.wisc.edu fmt.format = Format::floating; 1628920Snilay@cs.wisc.edu fmt.float_format = Format::best; 1638920Snilay@cs.wisc.edu done = true; 1648920Snilay@cs.wisc.edu break; 1658920Snilay@cs.wisc.edu 1668920Snilay@cs.wisc.edu case 'E': 1678920Snilay@cs.wisc.edu fmt.uppercase = true; 1688920Snilay@cs.wisc.edu case 'e': 1699736Sandreas@sandberg.pp.se fmt.format = Format::floating; 1708920Snilay@cs.wisc.edu fmt.float_format = Format::scientific; 1713395Shsul@eecs.umich.edu done = true; 1725361Srstrong@cs.ucsd.edu break; 1738920Snilay@cs.wisc.edu 1748920Snilay@cs.wisc.edu case 'f': 1758920Snilay@cs.wisc.edu fmt.format = Format::floating; 1769151Satgutier@umich.edu fmt.float_format = Format::fixed; 1779151Satgutier@umich.edu done = true; 1789151Satgutier@umich.edu break; 1799151Satgutier@umich.edu 1809151Satgutier@umich.edu case 'n': 1819151Satgutier@umich.edu stream << "we don't do %n!!!\n"; 1829562Ssaidi@eecs.umich.edu done = true; 1838920Snilay@cs.wisc.edu break; 1848920Snilay@cs.wisc.edu 1858920Snilay@cs.wisc.edu case '#': 1868920Snilay@cs.wisc.edu fmt.alternate_form = true; 1878920Snilay@cs.wisc.edu break; 1888920Snilay@cs.wisc.edu 1898920Snilay@cs.wisc.edu case '-': 1908920Snilay@cs.wisc.edu fmt.flush_left = true; 1918920Snilay@cs.wisc.edu break; 1928920Snilay@cs.wisc.edu 1938920Snilay@cs.wisc.edu case '+': 1948920Snilay@cs.wisc.edu fmt.print_sign = true; 1958920Snilay@cs.wisc.edu break; 1968920Snilay@cs.wisc.edu 1978920Snilay@cs.wisc.edu case ' ': 1988920Snilay@cs.wisc.edu fmt.blank_space = true; 1998920Snilay@cs.wisc.edu break; 2008920Snilay@cs.wisc.edu 2018920Snilay@cs.wisc.edu case '.': 2028920Snilay@cs.wisc.edu fmt.width = number; 2038920Snilay@cs.wisc.edu fmt.precision = 0; 2048920Snilay@cs.wisc.edu have_precision = true; 2058920Snilay@cs.wisc.edu number = 0; 2068920Snilay@cs.wisc.edu end_number = false; 2078920Snilay@cs.wisc.edu break; 2088920Snilay@cs.wisc.edu 2098920Snilay@cs.wisc.edu case '0': 2108920Snilay@cs.wisc.edu if (number == 0) { 2118920Snilay@cs.wisc.edu fmt.fill_zero = true; 2128920Snilay@cs.wisc.edu break; 2138920Snilay@cs.wisc.edu } 2148920Snilay@cs.wisc.edu case '1': 2158920Snilay@cs.wisc.edu case '2': 2168920Snilay@cs.wisc.edu case '3': 2178920Snilay@cs.wisc.edu case '4': 2188920Snilay@cs.wisc.edu case '5': 2198920Snilay@cs.wisc.edu case '6': 2208920Snilay@cs.wisc.edu case '7': 2218920Snilay@cs.wisc.edu case '8': 2228920Snilay@cs.wisc.edu case '9': 2238920Snilay@cs.wisc.edu number = number * 10 + (*ptr - '0'); 2248920Snilay@cs.wisc.edu break; 2258920Snilay@cs.wisc.edu 2268920Snilay@cs.wisc.edu case '*': 2278920Snilay@cs.wisc.edu if (have_precision) 2288920Snilay@cs.wisc.edu fmt.get_precision = true; 2298920Snilay@cs.wisc.edu else 2308920Snilay@cs.wisc.edu fmt.get_width = true; 2318920Snilay@cs.wisc.edu break; 2329539Satgutier@umich.edu 2339539Satgutier@umich.edu case '%': 2349539Satgutier@umich.edu assert(false && "we shouldn't get here"); 2359935Sdam.sunwoo@arm.com break; 2369935Sdam.sunwoo@arm.com 2379935Sdam.sunwoo@arm.com default: 2389935Sdam.sunwoo@arm.com done = true; 2398920Snilay@cs.wisc.edu break; 2408920Snilay@cs.wisc.edu } 2418920Snilay@cs.wisc.edu 2428920Snilay@cs.wisc.edu if (end_number) { 2438920Snilay@cs.wisc.edu if (have_precision) 2448920Snilay@cs.wisc.edu fmt.precision = number; 2458920Snilay@cs.wisc.edu else 2468920Snilay@cs.wisc.edu fmt.width = number; 2478920Snilay@cs.wisc.edu 2488920Snilay@cs.wisc.edu end_number = false; 2498920Snilay@cs.wisc.edu number = 0; 2508920Snilay@cs.wisc.edu } 2518956Sjayneel@cs.wisc.edu } 2528956Sjayneel@cs.wisc.edu 2538956Sjayneel@cs.wisc.edu ++ptr; 2548956Sjayneel@cs.wisc.edu} 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 294} // namespace cp 295