cprintf.hh revision 4039:b910b61a52b9
1/*
2 * Copyright (c) 2002-2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
29 *          Steve Reinhardt
30 */
31
32#ifndef __BASE_CPRINTF_HH__
33#define __BASE_CPRINTF_HH__
34
35#include <ios>
36#include <iostream>
37#include <list>
38#include <string>
39
40#include "base/varargs.hh"
41#include "base/cprintf_formats.hh"
42
43namespace cp {
44
45#define CPRINTF_DECLARATION VARARGS_DECLARATION(cp::Print)
46#define CPRINTF_DEFINITION VARARGS_DEFINITION(cp::Print)
47
48struct Print
49{
50  protected:
51    std::ostream &stream;
52    const char *format;
53    const char *ptr;
54
55    std::ios::fmtflags saved_flags;
56    char saved_fill;
57    int saved_precision;
58
59    void process(Format &fmt);
60
61  public:
62    Print(std::ostream &stream, const std::string &format);
63    Print(std::ostream &stream, const char *format);
64    ~Print();
65
66    template <typename T>
67    void
68    add_arg(const T &data)
69    {
70        Format fmt;
71        process(fmt);
72
73        switch (fmt.format) {
74          case Format::character:
75            format_char(stream, data, fmt);
76            break;
77
78          case Format::integer:
79            format_integer(stream, data, fmt);
80            break;
81
82          case Format::floating:
83            format_float(stream, data, fmt);
84            break;
85
86          case Format::string:
87            format_string(stream, data, fmt);
88            break;
89
90          default:
91            stream << "<bad format>";
92            break;
93        }
94    }
95
96    void end_args();
97};
98
99/* end namespace cp */ }
100
101typedef VarArgs::List<cp::Print> CPrintfArgsList;
102
103inline void
104ccprintf(std::ostream &stream, const char *format, const CPrintfArgsList &args)
105{
106    cp::Print print(stream, format);
107    args.add_args(print);
108}
109
110inline void
111ccprintf(std::ostream &stream, const char *format, CPRINTF_DECLARATION)
112{
113    cp::Print print(stream, format);
114    VARARGS_ADDARGS(print);
115}
116
117inline void
118cprintf(const char *format, CPRINTF_DECLARATION)
119{
120    ccprintf(std::cout, format, VARARGS_ALLARGS);
121}
122
123inline std::string
124csprintf(const char *format, CPRINTF_DECLARATION)
125{
126    std::stringstream stream;
127    ccprintf(stream, format, VARARGS_ALLARGS);
128    return stream.str();
129}
130
131/*
132 * functions again with std::string.  We have both so we don't waste
133 * time converting const char * to std::string since we don't take
134 * advantage of it.
135 */
136inline void
137ccprintf(std::ostream &stream, const std::string &format,
138         const CPrintfArgsList &args)
139{
140    ccprintf(stream, format.c_str(), args);
141}
142
143inline void
144ccprintf(std::ostream &stream, const std::string &format, CPRINTF_DECLARATION)
145{
146    ccprintf(stream, format, VARARGS_ALLARGS);
147}
148
149inline void
150cprintf(const std::string &format, CPRINTF_DECLARATION)
151{
152    ccprintf(std::cout, format, VARARGS_ALLARGS);
153}
154
155inline std::string
156csprintf(const std::string &format, CPRINTF_DECLARATION)
157{
158    std::stringstream stream;
159    ccprintf(stream, format, VARARGS_ALLARGS);
160    return stream.str();
161}
162
163#endif // __CPRINTF_HH__
164