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