Loader: Use address mask provided to load*Symbols when loading the symbols from the...
[gem5.git] / src / base / cprintf.hh
index dd2256e699d6a2e016465bf60bf253df3a6c101d..2920e210d3ec8809783307991a26bdcf1b6abac9 100644 (file)
@@ -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
  *          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
+  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();
+
+  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 <typename T>
+    int
+    get_number(const T& data)
+    {
+        return 0;
+    }
 
     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;
-            }
+        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<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;
 
-template<class T>
-inline ArgList &
-operator,(ArgList &alist, const T &data)
+inline void
+ccprintf(std::ostream &stream, const char *format, const CPrintfArgsList &args)
 {
-    alist.append(data);
-    return alist;
+    cp::Print print(stream, format);
+    args.add_args(print);
 }
 
-class ArgListNull {
-};
+inline void
+ccprintf(std::ostream &stream, const char *format, CPRINTF_DECLARATION)
+{
+    cp::Print print(stream, format);
+    VARARGS_ADDARGS(print);
+}
+
+inline void
+cprintf(const char *format, CPRINTF_DECLARATION)
+{
+    ccprintf(std::cout, format, VARARGS_ALLARGS);
+}
 
-inline ArgList &
-operator,(ArgList &alist, ArgListNull)
-{ return alist; }
+inline std::string
+csprintf(const char *format, CPRINTF_DECLARATION)
+{
+    std::stringstream stream;
+    ccprintf(stream, format, VARARGS_ALLARGS);
+    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.
+ */
+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.c_str(), 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.c_str(), VARARGS_ALLARGS);
+}
 
+inline std::string
+csprintf(const std::string &format, CPRINTF_DECLARATION)
+{
+    std::stringstream stream;
+    ccprintf(stream, format.c_str(), VARARGS_ALLARGS);
+    return stream.str();
 }
 
 #endif // __CPRINTF_HH__