cprintf_formats.hh revision 10360:919c02740209
12SN/A/*
21762SN/A * Copyright (c) 2003-2005 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.
272665SN/A *
282665SN/A * Authors: Nathan Binkert
292665SN/A */
302665SN/A
312665SN/A#ifndef __BASE_CPRINTF_FORMATS_HH__
322SN/A#define __BASE_CPRINTF_FORMATS_HH__
332SN/A
341722SN/A#include <cstring>
355480Snate@binkert.org#include <ostream>
362SN/A#include <sstream>
372SN/A
38146SN/Anamespace cp {
392SN/A
402SN/Astruct Format
412158SN/A{
42146SN/A    bool alternate_form;
431805SN/A    bool flush_left;
44146SN/A    bool print_sign;
451717SN/A    bool blank_space;
462680SN/A    bool fill_zero;
478232Snate@binkert.org    bool uppercase;
485480Snate@binkert.org    enum { dec, hex, oct } base;
498741Sgblack@eecs.umich.edu    enum { none, string, integer, character, floating } format;
508741Sgblack@eecs.umich.edu    enum { best, fixed, scientific } float_format;
518741Sgblack@eecs.umich.edu    int precision;
522521SN/A    int width;
5356SN/A    bool get_precision;
545478SN/A    bool get_width;
553348SN/A
563348SN/A    Format() { clear(); }
572521SN/A
585480Snate@binkert.org    void clear()
591805SN/A    {
602SN/A        alternate_form = false;
612SN/A        flush_left = false;
622107SN/A        print_sign = false;
632SN/A        blank_space = false;
645480Snate@binkert.org        fill_zero = false;
659808Sstever@gmail.com        uppercase = false;
669808Sstever@gmail.com        base = dec;
678806Sgblack@eecs.umich.edu        format = none;
682SN/A        float_format = best;
692521SN/A        precision = -1;
702521SN/A        width = 0;
712SN/A        get_precision = false;
722SN/A        get_width = false;
732SN/A    }
74926SN/A};
75926SN/A
76926SN/Atemplate <typename T>
77926SN/Ainline void
78926SN/A_format_char(std::ostream &out, const T &data, Format &fmt)
79926SN/A{
80926SN/A    using namespace std;
814395SN/A
821805SN/A    out << data;
832SN/A}
842SN/A
851634SN/Atemplate <typename T>
865480Snate@binkert.orginline void
871634SN/A_format_integer(std::ostream &out, const T &data, Format &fmt)
882549SN/A{
895714Shsul@eecs.umich.edu    using namespace std;
901634SN/A
911634SN/A    switch (fmt.base) {
921634SN/A      case Format::hex:
938931Sandreas.hansson@arm.com        out.setf(std::ios::hex, std::ios::basefield);
941634SN/A        break;
958741Sgblack@eecs.umich.edu
968806Sgblack@eecs.umich.edu      case Format::oct:
978806Sgblack@eecs.umich.edu        out.setf(std::ios::oct, std::ios::basefield);
988741Sgblack@eecs.umich.edu        break;
991634SN/A
1001634SN/A      case Format::dec:
1012512SN/A        out.setf(std::ios::dec, std::ios::basefield);
1025480Snate@binkert.org        break;
1032SN/A    }
1042SN/A
1052512SN/A    if (fmt.alternate_form) {
1062512SN/A        if (!fmt.fill_zero)
1072512SN/A            out.setf(std::ios::showbase);
1082512SN/A        else {
109540SN/A            switch (fmt.base) {
1102641SN/A              case Format::hex:
1112522SN/A                out << "0x";
1122641SN/A                fmt.width -= 2;
1132512SN/A                break;
1144986SN/A              case Format::oct:
1152521SN/A                out << "0";
1162641SN/A                fmt.width -= 1;
117873SN/A                break;
118873SN/A              case Format::dec:
119873SN/A                break;
120873SN/A            }
121873SN/A        }
1222630SN/A    }
123873SN/A
124873SN/A    if (fmt.fill_zero)
1252630SN/A        out.fill('0');
126873SN/A
127873SN/A    if (fmt.width > 0)
1282630SN/A        out.width(fmt.width);
129873SN/A
130873SN/A    if (fmt.flush_left && !fmt.fill_zero)
1312630SN/A        out.setf(std::ios::left);
132873SN/A
133873SN/A    if (fmt.print_sign)
1342512SN/A        out.setf(std::ios::showpos);
1352512SN/A
1362512SN/A    if (fmt.uppercase)
1374870SN/A        out.setf(std::ios::uppercase);
138873SN/A
1395480Snate@binkert.org    out << data;
1402630SN/A}
141873SN/A
142873SN/Atemplate <typename T>
143873SN/Ainline void
144873SN/A_format_float(std::ostream &out, const T &data, Format &fmt)
145873SN/A{
1465478SN/A    using namespace std;
147873SN/A
148873SN/A    switch (fmt.float_format) {
1492630SN/A      case Format::scientific:
150873SN/A        if (fmt.precision != -1) {
151873SN/A            if (fmt.width > 0)
1522630SN/A                out.width(fmt.width);
153873SN/A
154873SN/A            if (fmt.precision == 0)
1552630SN/A                fmt.precision = 1;
156873SN/A            else
157873SN/A                out.setf(std::ios::scientific);
1582630SN/A
159873SN/A            out.precision(fmt.precision);
160873SN/A        } else
1612630SN/A            if (fmt.width > 0)
162873SN/A                out.width(fmt.width);
163873SN/A
1642630SN/A        if (fmt.uppercase)
165873SN/A            out.setf(std::ios::uppercase);
166873SN/A        break;
1672630SN/A
168873SN/A      case Format::fixed:
169873SN/A        if (fmt.precision != -1) {
1702630SN/A            if (fmt.width > 0)
171873SN/A                out.width(fmt.width);
172873SN/A
1732630SN/A            out.setf(std::ios::fixed);
174873SN/A            out.precision(fmt.precision);
175873SN/A        } else
1762630SN/A            if (fmt.width > 0)
177873SN/A                out.width(fmt.width);
178873SN/A
1792630SN/A        break;
180873SN/A
181873SN/A      default:
1822114SN/A        if (fmt.precision != -1)
1832114SN/A            out.precision(fmt.precision);
1842114SN/A
1852114SN/A        if (fmt.width > 0)
1862630SN/A            out.width(fmt.width);
1872114SN/A
1882114SN/A        break;
189873SN/A    }
1905480Snate@binkert.org
1912630SN/A    out << data;
192873SN/A}
193873SN/A
1944870SN/Atemplate <typename T>
1952SN/Ainline void
1962512SN/A_format_string(std::ostream &out, const T &data, Format &fmt)
1972SN/A{
1982SN/A    using namespace std;
1992512SN/A
2005480Snate@binkert.org#if defined(__GNUC__) && (__GNUC__ < 3) || 1
2012SN/A    if (fmt.width > 0) {
2022641SN/A        std::stringstream foo;
2032641SN/A        foo << data;
204430SN/A        int flen = foo.str().size();
2052630SN/A
2062641SN/A        if (fmt.width > flen) {
2072SN/A            char *spaces = new char[fmt.width - flen + 1];
208430SN/A            memset(spaces, ' ', fmt.width - flen);
209430SN/A            spaces[fmt.width - flen] = 0;
2102SN/A
211430SN/A            if (fmt.flush_left)
2122SN/A                out << foo.str() << spaces;
213430SN/A            else
2142SN/A                out << spaces << foo.str();
215430SN/A
2162SN/A            delete [] spaces;
217430SN/A        } else
2182SN/A            out << data;
219430SN/A    } else
2202SN/A        out << data;
221430SN/A#else
2222SN/A    if (fmt.width > 0)
223430SN/A        out.width(fmt.width);
2242SN/A    if (fmt.flush_left)
225430SN/A        out.setf(std::ios::left);
2262SN/A
2272SN/A    out << data;
2282SN/A#endif
2292SN/A}
2302SN/A
2312SN/A/////////////////////////////////////////////////////////////////////////////
232430SN/A//
2332SN/A//  The code below controls the actual usage of formats for various types
234430SN/A//
2355478SN/A
236430SN/A//
2372SN/A// character formats
238430SN/A//
2392114SN/Atemplate <typename T>
2402114SN/Ainline void
2417823Ssteve.reinhardt@amd.comformat_char(std::ostream &out, const T &data, Format &fmt)
2422114SN/A{ out << "<bad arg type for char format>"; }
2432114SN/A
2442114SN/Ainline void
2452114SN/Aformat_char(std::ostream &out, char data, Format &fmt)
2462114SN/A{ _format_char(out, data, fmt); }
2472SN/A
2482SN/Ainline void
2494870SN/Aformat_char(std::ostream &out, unsigned char data, Format &fmt)
2502SN/A{ _format_char(out, data, fmt); }
2512512SN/A
252545SN/Ainline void
253545SN/Aformat_char(std::ostream &out, signed char data, Format &fmt)
2542SN/A{ _format_char(out, data, fmt); }
25510905Sandreas.sandberg@arm.com
2562SN/Ainline void
257222SN/Aformat_char(std::ostream &out, short data, Format &fmt)
258222SN/A{ _format_char(out, (char)data, fmt); }
259222SN/A
260222SN/Ainline void
261222SN/Aformat_char(std::ostream &out, unsigned short data, Format &fmt)
262222SN/A{ _format_char(out, (char)data, fmt); }
263222SN/A
264222SN/Ainline void
265222SN/Aformat_char(std::ostream &out, int data, Format &fmt)
266222SN/A{ _format_char(out, (char)data, fmt); }
267222SN/A
268222SN/Ainline void
269222SN/Aformat_char(std::ostream &out, unsigned int data, Format &fmt)
270222SN/A{ _format_char(out, (char)data, fmt); }
271222SN/A
272430SN/Ainline void
2732114SN/Aformat_char(std::ostream &out, long data, Format &fmt)
2742SN/A{ _format_char(out, (char)data, fmt); }
2752SN/A
2762SN/Ainline void
27710905Sandreas.sandberg@arm.comformat_char(std::ostream &out, unsigned long data, Format &fmt)
2782SN/A{ _format_char(out, (char)data, fmt); }
279222SN/A
280222SN/Ainline void
281222SN/Aformat_char(std::ostream &out, long long data, Format &fmt)
282222SN/A{ _format_char(out, (char)data, fmt); }
283222SN/A
284222SN/Ainline void
285222SN/Aformat_char(std::ostream &out, unsigned long long data, Format &fmt)
286222SN/A{ _format_char(out, (char)data, fmt); }
287222SN/A
288222SN/A//
289222SN/A// integer formats
290222SN/A//
291222SN/Atemplate <typename T>
292222SN/Ainline void
293222SN/Aformat_integer(std::ostream &out, const T &data, Format &fmt)
294430SN/A{ _format_integer(out, data, fmt); }
2952114SN/Ainline void
296217SN/Aformat_integer(std::ostream &out, char data, Format &fmt)
2972SN/A{ _format_integer(out, (int)data, fmt); }
298217SN/Ainline void
29910905Sandreas.sandberg@arm.comformat_integer(std::ostream &out, unsigned char data, Format &fmt)
300217SN/A{ _format_integer(out, (int)data, fmt); }
30110905Sandreas.sandberg@arm.cominline void
302217SN/Aformat_integer(std::ostream &out, signed char data, Format &fmt)
303217SN/A{ _format_integer(out, (int)data, fmt); }
304217SN/A#if 0
30510905Sandreas.sandberg@arm.cominline void
306217SN/Aformat_integer(std::ostream &out, short data, Format &fmt)
30710905Sandreas.sandberg@arm.com{ _format_integer(out, data, fmt); }
3082SN/Ainline void
3092SN/Aformat_integer(std::ostream &out, unsigned short data, Format &fmt)
3105480Snate@binkert.org{ _format_integer(out, data, fmt); }
3115480Snate@binkert.orginline void
3122SN/Aformat_integer(std::ostream &out, int data, Format &fmt)
3135480Snate@binkert.org{ _format_integer(out, data, fmt); }
3142SN/Ainline void
315format_integer(std::ostream &out, unsigned int data, Format &fmt)
316{ _format_integer(out, data, fmt); }
317inline void
318format_integer(std::ostream &out, long data, Format &fmt)
319{ _format_integer(out, data, fmt); }
320inline void
321format_integer(std::ostream &out, unsigned long data, Format &fmt)
322{ _format_integer(out, data, fmt); }
323inline void
324format_integer(std::ostream &out, long long data, Format &fmt)
325{ _format_integer(out, data, fmt); }
326inline void
327format_integer(std::ostream &out, unsigned long long data, Format &fmt)
328{ _format_integer(out, data, fmt); }
329#endif
330
331//
332// floating point formats
333//
334template <typename T>
335inline void
336format_float(std::ostream &out, const T &data, Format &fmt)
337{ out << "<bad arg type for float format>"; }
338
339inline void
340format_float(std::ostream &out, float data, Format &fmt)
341{ _format_float(out, data, fmt); }
342
343inline void
344format_float(std::ostream &out, double data, Format &fmt)
345{ _format_float(out, data, fmt); }
346
347//
348// string formats
349//
350template <typename T>
351inline void
352format_string(std::ostream &out, const T &data, Format &fmt)
353{ _format_string(out, data, fmt); }
354
355inline void
356format_string(std::ostream &out, const std::stringstream &data, Format &fmt)
357{ _format_string(out, data.str(), fmt); }
358
359} // namespace cp
360
361#endif // __CPRINTF_FORMATS_HH__
362