summaryrefslogtreecommitdiff
path: root/src/base/cprintf.hh
diff options
context:
space:
mode:
authorNathan Binkert <binkertn@umich.edu>2007-02-07 22:11:30 -0800
committerNathan Binkert <binkertn@umich.edu>2007-02-07 22:11:30 -0800
commit1f834b569c8a39f44882c2f2010a9f0ecffdaab1 (patch)
tree5d4ea11cf603704442e9216c1ab22e9f3e0c297e /src/base/cprintf.hh
parentaf698e8b0506b17dfa9eb6d1e96888cf54041a09 (diff)
downloadgem5-1f834b569c8a39f44882c2f2010a9f0ecffdaab1.tar.xz
Get rid of the gross operator,()/variadic macro hack
that made ccprintf and friends work, turn it into a normal function (though it still has a slightly strange implementation.) All instances of variadic macros are not yet removed, but I know how, and it will happen. One side effect of this new implementation is that a cprintf statement can now only have 16 parameters, though it's easy enough to raise this number if needed. --HG-- extra : convert_revision : 85cb3c17f8e2ecf9cd2f31ea80a760a28ea127a7
Diffstat (limited to 'src/base/cprintf.hh')
-rw-r--r--src/base/cprintf.hh205
1 files changed, 99 insertions, 106 deletions
diff --git a/src/base/cprintf.hh b/src/base/cprintf.hh
index dd2256e69..7f8e33367 100644
--- a/src/base/cprintf.hh
+++ b/src/base/cprintf.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * 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
@@ -29,142 +29,135 @@
* Steve Reinhardt
*/
-#ifndef __CPRINTF_HH__
-#define __CPRINTF_HH__
+#ifndef __BASE_CPRINTF_HH__
+#define __BASE_CPRINTF_HH__
+#include <ios>
#include <iostream>
#include <list>
#include <string>
+#include "base/varargs.hh"
#include "base/cprintf_formats.hh"
namespace cp {
-class ArgList
+#define CPRINTF_DECLARATION VARARGS_DECLARATION(cp::Print)
+#define CPRINTF_DEFINITION VARARGS_DEFINITION(cp::Print)
+
+struct Print
{
- private:
- class Base
- {
- public:
- virtual ~Base() {}
- virtual void process(std::ostream &out, Format &fmt) = 0;
- };
+ protected:
+ std::ostream &stream;
+ const char *format;
+ const char *ptr;
+
+ std::ios::fmtflags saved_flags;
+ char saved_fill;
+ int saved_precision;
+
+ void process(Format &fmt);
+
+ public:
+ Print(std::ostream &stream, const std::string &format);
+ Print(std::ostream &stream, const char *format);
+ ~Print();
template <typename T>
- 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 << "<bad format>";
- break;
- }
- }
- };
+ Format fmt;
+ process(fmt);
- typedef std::list<Base *> 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<class T>
- void append(const T &data) {
- Base *obj = new ArgList::Node<T>(data);
- objects.push_back(obj);
- }
+ case Format::string:
+ format_string(stream, data, fmt);
+ break;
- template<class T>
- void prepend(const T &data) {
- Base *obj = new ArgList::Node<T>(data);
- objects.push_front(obj);
+ default:
+ stream << "<bad format>";
+ 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);
+/* end namespace cp */ }
- friend ArgList &operator<<(std::ostream &str, ArgList &list);
-};
+typedef VarArgs::List<cp::Print> CPrintfArgsList;
+
+inline void
+ccprintf(std::ostream &stream, const char *format, const CPrintfArgsList &args)
+{
+ cp::Print print(stream, format);
+ args.add_args(print);
+}
-template<class T>
-inline ArgList &
-operator,(ArgList &alist, const T &data)
+inline void
+ccprintf(std::ostream &stream, const char *format, CPRINTF_DECLARATION)
{
- alist.append(data);
- return alist;
+ cp::Print print(stream, format);
+ VARARGS_ADDARGS(print);
}
-class ArgListNull {
-};
+inline void
+cprintf(const char *format, CPRINTF_DECLARATION)
+{
+ ccprintf(std::cout, format, VARARGS_ALLARGS);
+}
+
+inline std::string
+csprintf(const char *format, CPRINTF_DECLARATION)
+{
+ std::stringstream stream;
+ ccprintf(stream, format, VARARGS_ALLARGS);
+ return stream.str();
+}
-inline ArgList &
-operator,(ArgList &alist, ArgListNull)
-{ return alist; }
+/*
+ * 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.
+ */
+inline void
+ccprintf(std::ostream &stream, const std::string &format,
+ const CPrintfArgsList &args)
+{
+ ccprintf(stream, format.c_str(), 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, ...) \
- cp::__cprintf(format, (*(new cp::ArgList), __VA_ARGS__))
-#define cprintf(...) \
- __cprintf__(__VA_ARGS__, cp::ArgListNull())
-
-//
-// ccprintf(stream, format, args, ...) prints to the specified stream
-// (analogous to fprintf())
-//
+ccprintf(std::ostream &stream, const std::string &format, CPRINTF_DECLARATION)
+{
+ ccprintf(stream, format, VARARGS_ALLARGS);
+}
+
inline void
-__ccprintf(std::ostream &stream, const std::string &format, ArgList &args)
-{ args.dump(stream, format); delete &args; }
-#define __ccprintf__(stream, format, ...) \
- cp::__ccprintf(stream, format, (*(new cp::ArgList), __VA_ARGS__))
-#define ccprintf(stream, ...) \
- __ccprintf__(stream, __VA_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, ...) \
- cp::__csprintf(format, (*(new cp::ArgList), __VA_ARGS__))
-#define csprintf(...) \
- __csprintf__(__VA_ARGS__, cp::ArgListNull())
+cprintf(const std::string &format, CPRINTF_DECLARATION)
+{
+ ccprintf(std::cout, format, VARARGS_ALLARGS);
+}
+inline std::string
+csprintf(const std::string &format, CPRINTF_DECLARATION)
+{
+ std::stringstream stream;
+ ccprintf(stream, format, VARARGS_ALLARGS);
+ return stream.str();
}
#endif // __CPRINTF_HH__