cprintf.hh revision 10292:933dfb9d8279
110037SARM gem5 Developers/*
210037SARM gem5 Developers * Copyright (c) 2014 ARM Limited
310037SARM gem5 Developers * Copyright (c) 2002-2006 The Regents of The University of Michigan
410037SARM gem5 Developers * All rights reserved.
510037SARM gem5 Developers *
610037SARM gem5 Developers * Redistribution and use in source and binary forms, with or without
710037SARM gem5 Developers * modification, are permitted provided that the following conditions are
810037SARM gem5 Developers * met: redistributions of source code must retain the above copyright
910037SARM gem5 Developers * notice, this list of conditions and the following disclaimer;
1010037SARM gem5 Developers * redistributions in binary form must reproduce the above copyright
1110037SARM gem5 Developers * notice, this list of conditions and the following disclaimer in the
1210037SARM gem5 Developers * documentation and/or other materials provided with the distribution;
1310037SARM gem5 Developers * neither the name of the copyright holders nor the names of its
1410037SARM gem5 Developers * contributors may be used to endorse or promote products derived from
1510037SARM gem5 Developers * this software without specific prior written permission.
1610037SARM gem5 Developers *
1710037SARM gem5 Developers * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1810037SARM gem5 Developers * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1910037SARM gem5 Developers * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2010037SARM gem5 Developers * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2110037SARM gem5 Developers * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2210037SARM gem5 Developers * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2310037SARM gem5 Developers * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2410037SARM gem5 Developers * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2510037SARM gem5 Developers * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2610037SARM gem5 Developers * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2710037SARM gem5 Developers * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2810037SARM gem5 Developers *
2910037SARM gem5 Developers * Authors: Nathan Binkert
3010037SARM gem5 Developers *          Steve Reinhardt
3110037SARM gem5 Developers *          Andreas Sandberg
3210037SARM gem5 Developers */
3310037SARM gem5 Developers
3410037SARM gem5 Developers#ifndef __BASE_CPRINTF_HH__
3510037SARM gem5 Developers#define __BASE_CPRINTF_HH__
3610037SARM gem5 Developers
3710037SARM gem5 Developers#include <ios>
3810037SARM gem5 Developers#include <iostream>
3910037SARM gem5 Developers#include <list>
4010037SARM gem5 Developers#include <string>
4110037SARM gem5 Developers
4210037SARM gem5 Developers#include "base/cprintf_formats.hh"
4310037SARM gem5 Developers
4410037SARM gem5 Developersnamespace cp {
4510037SARM gem5 Developers
4610037SARM gem5 Developersstruct Print
4710037SARM gem5 Developers{
4810037SARM gem5 Developers  protected:
4910037SARM gem5 Developers    std::ostream &stream;
5010037SARM gem5 Developers    const char *format;
5110037SARM gem5 Developers    const char *ptr;
5210037SARM gem5 Developers    bool cont;
5310037SARM gem5 Developers
5410037SARM gem5 Developers    std::ios::fmtflags saved_flags;
5510037SARM gem5 Developers    char saved_fill;
5610037SARM gem5 Developers    int saved_precision;
5710037SARM gem5 Developers
5810037SARM gem5 Developers    Format fmt;
5910037SARM gem5 Developers    void process();
6010037SARM gem5 Developers    void process_flag();
6110037SARM gem5 Developers
6210037SARM gem5 Developers  public:
6310037SARM gem5 Developers    Print(std::ostream &stream, const std::string &format);
6410037SARM gem5 Developers    Print(std::ostream &stream, const char *format);
6510037SARM gem5 Developers    ~Print();
6610037SARM gem5 Developers
6710037SARM gem5 Developers    int
6810037SARM gem5 Developers    get_number(int data)
6910037SARM gem5 Developers    {
7010037SARM gem5 Developers        return data;
7110037SARM gem5 Developers    }
7210037SARM gem5 Developers
7310037SARM gem5 Developers    template <typename T>
7410037SARM gem5 Developers    int
7510037SARM gem5 Developers    get_number(const T& data)
7610037SARM gem5 Developers    {
7710037SARM gem5 Developers        return 0;
7810037SARM gem5 Developers    }
7910037SARM gem5 Developers
8010037SARM gem5 Developers    template <typename T>
8110037SARM gem5 Developers    void
8210037SARM gem5 Developers    add_arg(const T &data)
8310037SARM gem5 Developers    {
8410037SARM gem5 Developers        if (!cont)
8510037SARM gem5 Developers            process();
8610037SARM gem5 Developers
8710037SARM gem5 Developers        if (fmt.get_width) {
8810037SARM gem5 Developers            fmt.get_width = false;
8910037SARM gem5 Developers            cont = true;
9010037SARM gem5 Developers            fmt.width = get_number(data);
9110037SARM gem5 Developers            return;
9210037SARM gem5 Developers        }
9310037SARM gem5 Developers
9410037SARM gem5 Developers        if (fmt.get_precision) {
9510037SARM gem5 Developers            fmt.get_precision = false;
9610037SARM gem5 Developers            cont = true;
9710037SARM gem5 Developers            fmt.precision = get_number(data);
9810037SARM gem5 Developers            return;
9910037SARM gem5 Developers        }
10010037SARM gem5 Developers
10110037SARM gem5 Developers        switch (fmt.format) {
10210037SARM gem5 Developers          case Format::character:
10310037SARM gem5 Developers            format_char(stream, data, fmt);
10410037SARM gem5 Developers            break;
10510037SARM gem5 Developers
10610037SARM gem5 Developers          case Format::integer:
10710037SARM gem5 Developers            format_integer(stream, data, fmt);
10810037SARM gem5 Developers            break;
10910037SARM gem5 Developers
11010037SARM gem5 Developers          case Format::floating:
11110037SARM gem5 Developers            format_float(stream, data, fmt);
11210037SARM gem5 Developers            break;
11310037SARM gem5 Developers
11410037SARM gem5 Developers          case Format::string:
11510037SARM gem5 Developers            format_string(stream, data, fmt);
11610037SARM gem5 Developers            break;
11710037SARM gem5 Developers
11810037SARM gem5 Developers          default:
11910037SARM gem5 Developers            stream << "<bad format>";
12010037SARM gem5 Developers            break;
12110037SARM gem5 Developers        }
12210037SARM gem5 Developers    }
12310037SARM gem5 Developers
12410037SARM gem5 Developers    void end_args();
12510037SARM gem5 Developers};
12610037SARM gem5 Developers
12710037SARM gem5 Developers} // namespace cp
12810037SARM gem5 Developers
12910037SARM gem5 Developersinline void
13010037SARM gem5 Developersccprintf(cp::Print &print)
13110037SARM gem5 Developers{
13210037SARM gem5 Developers    print.end_args();
13310037SARM gem5 Developers}
13410037SARM gem5 Developers
13510037SARM gem5 Developers
13610037SARM gem5 Developerstemplate<typename T, typename ...Args> void
13710037SARM gem5 Developersccprintf(cp::Print &print, const T &value, const Args &...args)
13810037SARM gem5 Developers{
13910037SARM gem5 Developers    print.add_arg(value);
14010037SARM gem5 Developers
14110037SARM gem5 Developers    ccprintf(print, args...);
14210037SARM gem5 Developers}
14310037SARM gem5 Developers
14410037SARM gem5 Developers
14510037SARM gem5 Developerstemplate<typename ...Args> void
14610037SARM gem5 Developersccprintf(std::ostream &stream, const char *format, const Args &...args)
14710037SARM gem5 Developers{
14810037SARM gem5 Developers    cp::Print print(stream, format);
14910037SARM gem5 Developers
15010037SARM gem5 Developers    ccprintf(print, args...);
15110037SARM gem5 Developers}
15210037SARM gem5 Developers
15310037SARM gem5 Developers
15410037SARM gem5 Developerstemplate<typename ...Args> void
15510037SARM gem5 Developerscprintf(const char *format, const Args &...args)
15610037SARM gem5 Developers{
15710037SARM gem5 Developers    ccprintf(std::cout, format, args...);
15810037SARM gem5 Developers}
15910037SARM gem5 Developers
16010037SARM gem5 Developerstemplate<typename ...Args> std::string
16110037SARM gem5 Developerscsprintf(const char *format, const Args &...args)
16210037SARM gem5 Developers{
16310037SARM gem5 Developers    std::stringstream stream;
16410037SARM gem5 Developers    ccprintf(stream, format, args...);
16510037SARM gem5 Developers    return stream.str();
16610037SARM gem5 Developers}
16710037SARM gem5 Developers
16810037SARM gem5 Developers/*
16910037SARM gem5 Developers * functions again with std::string.  We have both so we don't waste
17010037SARM gem5 Developers * time converting const char * to std::string since we don't take
17110037SARM gem5 Developers * advantage of it.
17210037SARM gem5 Developers */
17310037SARM gem5 Developerstemplate<typename ...Args> void
17410037SARM gem5 Developersccprintf(std::ostream &stream, const std::string &format, const Args &...args)
17510037SARM gem5 Developers{
17610037SARM gem5 Developers    ccprintf(stream, format.c_str(), args...);
17710037SARM gem5 Developers}
17810037SARM gem5 Developers
17910037SARM gem5 Developerstemplate<typename ...Args> void
18010037SARM gem5 Developerscprintf(const std::string &format, const Args &...args)
18110037SARM gem5 Developers{
18210037SARM gem5 Developers    ccprintf(std::cout, format.c_str(), args...);
18310037SARM gem5 Developers}
18410037SARM gem5 Developers
18510037SARM gem5 Developerstemplate<typename ...Args> std::string
18610037SARM gem5 Developerscsprintf(const std::string &format, const Args &...args)
18710037SARM gem5 Developers{
18810037SARM gem5 Developers    return csprintf(format.c_str(), args...);
18910037SARM gem5 Developers}
19010037SARM gem5 Developers
19110037SARM gem5 Developers#endif // __CPRINTF_HH__
19210037SARM gem5 Developers