X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fbase%2Fcprintf.hh;h=94a74728da6266407943259a89b70f078c68cfb5;hb=97887eb6dc9e548c9b5719727fd4783ef157917c;hp=9967b0578379de46ec7cc3526f92c314d160b3fb;hpb=b48a8fb34706972c7474f2390029ec9f5b8c94f3;p=gem5.git diff --git a/src/base/cprintf.hh b/src/base/cprintf.hh index 9967b0578..94a74728d 100644 --- a/src/base/cprintf.hh +++ b/src/base/cprintf.hh @@ -1,5 +1,6 @@ /* - * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2014 ARM Limited + * Copyright (c) 2002-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,11 +28,13 @@ * * Authors: Nathan Binkert * Steve Reinhardt + * Andreas Sandberg */ -#ifndef __CPRINTF_HH__ -#define __CPRINTF_HH__ +#ifndef __BASE_CPRINTF_HH__ +#define __BASE_CPRINTF_HH__ +#include #include #include #include @@ -40,131 +43,149 @@ namespace cp { -class ArgList +struct Print { - private: - class Base + protected: + std::ostream &stream; + const char *format; + const char *ptr; + bool cont; + + std::ios::fmtflags saved_flags; + char saved_fill; + int saved_precision; + + Format fmt; + void process(); + void process_flag(); + + public: + Print(std::ostream &stream, const std::string &format); + Print(std::ostream &stream, const char *format); + ~Print(); + + int + get_number(int data) { - public: - virtual ~Base() {} - virtual void process(std::ostream &out, Format &fmt) = 0; - }; + return data; + } + + template + int + get_number(const T& data) + { + return 0; + } template - class Node : public Base + void + add_arg(const T &data) { - public: - const T &data; - - public: - Node(const T &d) : data(d) {} - virtual void process(std::ostream &out, Format &fmt) { - switch (fmt.format) { - case Format::character: - format_char(out, data, fmt); - break; - - case Format::integer: - format_integer(out, data, fmt); - break; - - case Format::floating: - format_float(out, data, fmt); - break; - - case Format::string: - format_string(out, data, fmt); - break; - - default: - out << ""; - break; - } + if (!cont) + process(); + + if (fmt.get_width) { + fmt.get_width = false; + cont = true; + fmt.width = get_number(data); + return; + } + + if (fmt.get_precision) { + fmt.get_precision = false; + cont = true; + fmt.precision = get_number(data); + return; } - }; - typedef std::list list_t; + switch (fmt.format) { + case Format::character: + format_char(stream, data, fmt); + break; - protected: - list_t objects; - std::ostream *stream; + case Format::integer: + format_integer(stream, data, fmt); + break; - public: - ArgList() : stream(&std::cout) {} - ~ArgList(); + case Format::floating: + format_float(stream, data, fmt); + break; - template - void append(const T &data) { - Base *obj = new ArgList::Node(data); - objects.push_back(obj); - } + case Format::string: + format_string(stream, data, fmt); + break; - template - void prepend(const T &data) { - Base *obj = new ArgList::Node(data); - objects.push_front(obj); + default: + stream << ""; + break; + } } - void dump(const std::string &format); - void dump(std::ostream &strm, const std::string &fmt) - { stream = &strm; dump(fmt); } + void end_args(); +}; - std::string dumpToString(const std::string &format); +} // namespace cp - friend ArgList &operator<<(std::ostream &str, ArgList &list); -}; +inline void +ccprintf(cp::Print &print) +{ + print.end_args(); +} -template -inline ArgList & -operator,(ArgList &alist, const T &data) + +template void +ccprintf(cp::Print &print, const T &value, const Args &...args) { - alist.append(data); - return alist; + print.add_arg(value); + + ccprintf(print, args...); } -class ArgListNull { -}; -inline ArgList & -operator,(ArgList &alist, ArgListNull) -{ return alist; } +template void +ccprintf(std::ostream &stream, const char *format, const Args &...args) +{ + cp::Print print(stream, format); + + ccprintf(print, args...); +} -// -// cprintf(format, args, ...) prints to cout -// (analogous to printf()) -// -inline void -__cprintf(const std::string &format, ArgList &args) -{ args.dump(format); delete &args; } -#define __cprintf__(format, args...) \ - cp::__cprintf(format, (*(new cp::ArgList), args)) -#define cprintf(args...) \ - __cprintf__(args, cp::ArgListNull()) - -// -// ccprintf(stream, format, args, ...) prints to the specified stream -// (analogous to fprintf()) -// -inline void -__ccprintf(std::ostream &stream, const std::string &format, ArgList &args) -{ args.dump(stream, format); delete &args; } -#define __ccprintf__(stream, format, args...) \ - cp::__ccprintf(stream, format, (*(new cp::ArgList), args)) -#define ccprintf(stream, args...) \ - __ccprintf__(stream, args, cp::ArgListNull()) - -// -// csprintf(format, args, ...) returns a string -// (roughly analogous to sprintf()) -// -inline std::string -__csprintf(const std::string &format, ArgList &args) -{ std::string s = args.dumpToString(format); delete &args; return s; } -#define __csprintf__(format, args...) \ - cp::__csprintf(format, (*(new cp::ArgList), args)) -#define csprintf(args...) \ - __csprintf__(args, cp::ArgListNull()) +template void +cprintf(const char *format, const Args &...args) +{ + ccprintf(std::cout, format, args...); +} + +template std::string +csprintf(const char *format, const Args &...args) +{ + std::stringstream stream; + ccprintf(stream, format, args...); + return stream.str(); +} + +/* + * functions again with std::string. We have both so we don't waste + * time converting const char * to std::string since we don't take + * advantage of it. + */ +template void +ccprintf(std::ostream &stream, const std::string &format, const Args &...args) +{ + ccprintf(stream, format.c_str(), args...); +} + +template void +cprintf(const std::string &format, const Args &...args) +{ + ccprintf(std::cout, format.c_str(), args...); +} + +template std::string +csprintf(const std::string &format, const Args &...args) +{ + return csprintf(format.c_str(), args...); } #endif // __CPRINTF_HH__