cprintf.hh revision 2621
12381SN/A/*
210342SCurtis.Dunham@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
38949Sandreas.hansson@arm.com * All rights reserved.
48949Sandreas.hansson@arm.com *
58949Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68949Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78949Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88949Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98949Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108949Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118949Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128949Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
138949Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
142592SN/A * this software without specific prior written permission.
157636Ssteve.reinhardt@amd.com *
162381SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172381SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222381SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262381SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272381SN/A */
282381SN/A
292381SN/A#ifndef __CPRINTF_HH__
302381SN/A#define __CPRINTF_HH__
312381SN/A
322381SN/A#include <iostream>
332381SN/A#include <list>
342381SN/A#include <string>
352381SN/A
362381SN/A#include "base/cprintf_formats.hh"
372381SN/A
382381SN/Anamespace cp {
392381SN/A
402665Ssaidi@eecs.umich.educlass ArgList
412665Ssaidi@eecs.umich.edu{
422665Ssaidi@eecs.umich.edu  private:
432665Ssaidi@eecs.umich.edu    class Base
449031Sandreas.hansson@arm.com    {
452381SN/A      public:
462381SN/A        virtual ~Base() {}
472381SN/A        virtual void process(std::ostream &out, Format &fmt) = 0;
482381SN/A    };
492662Sstever@eecs.umich.edu
502381SN/A    template <typename T>
512381SN/A    class Node : public Base
522381SN/A    {
532381SN/A      public:
542381SN/A        const T &data;
558229Snate@binkert.org
563348Sbinkertn@umich.edu      public:
573348Sbinkertn@umich.edu        Node(const T &d) : data(d) {}
583348Sbinkertn@umich.edu        virtual void process(std::ostream &out, Format &fmt) {
595735Snate@binkert.org            switch (fmt.format) {
604024Sbinkertn@umich.edu              case Format::character:
615735Snate@binkert.org                format_char(out, data, fmt);
623940Ssaidi@eecs.umich.edu                break;
635314Sstever@gmail.com
646216Snate@binkert.org              case Format::integer:
652392SN/A                format_integer(out, data, fmt);
664167Sbinkertn@umich.edu                break;
672394SN/A
688737Skoansin.tan@gmail.com              case Format::floating:
693349Sbinkertn@umich.edu                format_float(out, data, fmt);
702394SN/A                break;
712812Srdreslin@umich.edu
722812Srdreslin@umich.edu              case Format::string:
734022Sstever@eecs.umich.edu                format_string(out, data, fmt);
744022Sstever@eecs.umich.edu                break;
755735Snate@binkert.org
765735Snate@binkert.org              default:
774022Sstever@eecs.umich.edu                out << "<bad format>";
785735Snate@binkert.org                break;
795735Snate@binkert.org            }
805735Snate@binkert.org        }
814022Sstever@eecs.umich.edu    };
824022Sstever@eecs.umich.edu
834022Sstever@eecs.umich.edu    typedef std::list<Base *> list_t;
844022Sstever@eecs.umich.edu
854473Sstever@eecs.umich.edu  protected:
865319Sstever@gmail.com    list_t objects;
874022Sstever@eecs.umich.edu    std::ostream *stream;
884022Sstever@eecs.umich.edu
894022Sstever@eecs.umich.edu  public:
904022Sstever@eecs.umich.edu    ArgList() : stream(&std::cout) {}
914022Sstever@eecs.umich.edu    ~ArgList();
924022Sstever@eecs.umich.edu
934022Sstever@eecs.umich.edu    template<class T>
949018Sandreas.hansson@arm.com    void append(const T &data) {
959018Sandreas.hansson@arm.com        Base *obj = new ArgList::Node<T>(data);
969018Sandreas.hansson@arm.com        objects.push_back(obj);
979018Sandreas.hansson@arm.com    }
989018Sandreas.hansson@arm.com
999018Sandreas.hansson@arm.com    template<class T>
1009018Sandreas.hansson@arm.com    void prepend(const T &data) {
1019018Sandreas.hansson@arm.com        Base *obj = new ArgList::Node<T>(data);
1024022Sstever@eecs.umich.edu        objects.push_front(obj);
1034022Sstever@eecs.umich.edu    }
1044022Sstever@eecs.umich.edu
1057465Ssteve.reinhardt@amd.com    void dump(const std::string &format);
1064628Sstever@eecs.umich.edu    void dump(std::ostream &strm, const std::string &fmt)
1077465Ssteve.reinhardt@amd.com        { stream = &strm; dump(fmt); }
1087465Ssteve.reinhardt@amd.com
1094022Sstever@eecs.umich.edu    std::string dumpToString(const std::string &format);
1104022Sstever@eecs.umich.edu
1114626Sstever@eecs.umich.edu    friend ArgList &operator<<(std::ostream &str, ArgList &list);
1124626Sstever@eecs.umich.edu};
1137669Ssteve.reinhardt@amd.com
1144626Sstever@eecs.umich.edutemplate<class T>
1154040Ssaidi@eecs.umich.eduinline ArgList &
1164040Ssaidi@eecs.umich.eduoperator,(ArgList &alist, const T &data)
1175650Sgblack@eecs.umich.edu{
1185650Sgblack@eecs.umich.edu    alist.append(data);
1194870Sstever@eecs.umich.edu    return alist;
1204870Sstever@eecs.umich.edu}
1214870Sstever@eecs.umich.edu
1224870Sstever@eecs.umich.educlass ArgListNull {
1234870Sstever@eecs.umich.edu};
1244870Sstever@eecs.umich.edu
1258436SBrad.Beckmann@amd.cominline ArgList &
1268436SBrad.Beckmann@amd.comoperator,(ArgList &alist, ArgListNull)
1275314Sstever@gmail.com{ return alist; }
1285314Sstever@gmail.com
1298184Ssomayeh@cs.wisc.edu//
1308716Snilay@cs.wisc.edu// cprintf(format, args, ...) prints to cout
1314022Sstever@eecs.umich.edu// (analogous to printf())
1324022Sstever@eecs.umich.edu//
1334022Sstever@eecs.umich.eduinline void
1344022Sstever@eecs.umich.edu__cprintf(const std::string &format, ArgList &args)
1355735Snate@binkert.org{ args.dump(format); delete &args; }
1365735Snate@binkert.org#define __cprintf__(format, args...) \
1375735Snate@binkert.org    cp::__cprintf(format, (*(new cp::ArgList), args))
1384022Sstever@eecs.umich.edu#define cprintf(args...) \
1394022Sstever@eecs.umich.edu    __cprintf__(args, cp::ArgListNull())
1404626Sstever@eecs.umich.edu
1414626Sstever@eecs.umich.edu//
1427465Ssteve.reinhardt@amd.com// ccprintf(stream, format, args, ...) prints to the specified stream
1434022Sstever@eecs.umich.edu// (analogous to fprintf())
1444626Sstever@eecs.umich.edu//
1454626Sstever@eecs.umich.eduinline void
1464626Sstever@eecs.umich.edu__ccprintf(std::ostream &stream, const std::string &format, ArgList &args)
1474626Sstever@eecs.umich.edu{ args.dump(stream, format); delete &args; }
1484022Sstever@eecs.umich.edu#define __ccprintf__(stream, format, args...) \
1494022Sstever@eecs.umich.edu    cp::__ccprintf(stream, format, (*(new cp::ArgList), args))
1506076Sgblack@eecs.umich.edu#define ccprintf(stream, args...) \
1514626Sstever@eecs.umich.edu    __ccprintf__(stream, args, cp::ArgListNull())
1524870Sstever@eecs.umich.edu
1535314Sstever@gmail.com//
1548184Ssomayeh@cs.wisc.edu// csprintf(format, args, ...) returns a string
1554022Sstever@eecs.umich.edu// (roughly analogous to sprintf())
1564022Sstever@eecs.umich.edu//
1574022Sstever@eecs.umich.eduinline std::string
1585735Snate@binkert.org__csprintf(const std::string &format, ArgList &args)
1595735Snate@binkert.org{ std::string s = args.dumpToString(format); delete &args; return s; }
1605735Snate@binkert.org#define __csprintf__(format, args...) \
1615735Snate@binkert.org    cp::__csprintf(format, (*(new cp::ArgList), args))
1625735Snate@binkert.org#define csprintf(args...) \
1635735Snate@binkert.org    __csprintf__(args, cp::ArgListNull())
1645735Snate@binkert.org
1654022Sstever@eecs.umich.edutemplate<class T>
1665735Snate@binkert.orginline ArgList &
1675735Snate@binkert.orgoperator<<(ArgList &list, const T &data)
1684022Sstever@eecs.umich.edu{
1695735Snate@binkert.org    list.append(data);
1704022Sstever@eecs.umich.edu    return list;
1714022Sstever@eecs.umich.edu}
1724022Sstever@eecs.umich.edu
1735735Snate@binkert.orginline ArgList &
1744022Sstever@eecs.umich.eduoperator<<(std::ostream &str, ArgList &list)
1754022Sstever@eecs.umich.edu{
1764022Sstever@eecs.umich.edu    list.stream = &str;
1774022Sstever@eecs.umich.edu    return list;
1784022Sstever@eecs.umich.edu}
1794022Sstever@eecs.umich.edu
1805735Snate@binkert.orgclass ArgListTemp
1815735Snate@binkert.org{
1825735Snate@binkert.org  private:
1834022Sstever@eecs.umich.edu    std::string format;
1844022Sstever@eecs.umich.edu    ArgList *args;
1854022Sstever@eecs.umich.edu
1864022Sstever@eecs.umich.edu  public:
1874022Sstever@eecs.umich.edu    ArgListTemp(const std::string &f) : format(f) { args = new ArgList; }
1884022Sstever@eecs.umich.edu    ~ArgListTemp() { args->dump(format); delete args; }
1897465Ssteve.reinhardt@amd.com
1907465Ssteve.reinhardt@amd.com    operator ArgList *() { return args; }
1914022Sstever@eecs.umich.edu};
1924022Sstever@eecs.umich.edu
1934870Sstever@eecs.umich.edu#define cformat(format) \
1944022Sstever@eecs.umich.edu    (*((cp::ArgList *)cp::ArgListTemp(format)))
1954022Sstever@eecs.umich.edu}
1964022Sstever@eecs.umich.edu
1974626Sstever@eecs.umich.edu#endif // __CPRINTF_HH__
1986102Sgblack@eecs.umich.edu