/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
* Copyright (c) 2001-2006 The Regents of The University of Michigan
* All rights reserved.
*
*
* Authors: Nathan Binkert
* Steve Reinhardt
+ * Andrew Bardsley
*/
-#include <ctype.h>
+#include <cctype>
#include <fstream>
#include <iostream>
-#include <list>
+#include <sstream>
#include <string>
-#include <vector>
#include "base/misc.hh"
#include "base/output.hh"
#include "base/str.hh"
#include "base/trace.hh"
-#include "base/varargs.hh"
-
-using namespace std;
-
-namespace Trace {
-const string DefaultName("global");
-FlagVec flags(NumFlags, false);
-bool enabled = false;
-//
-// This variable holds the output stream for debug information. Other
-// than setting up/redirecting this stream, do *NOT* reference this
-// directly; use DebugOut() (see below) to access this stream for
-// output.
-//
-ostream *dprintf_stream = &cerr;
-ostream &
-output()
+const std::string &name()
{
- return *dprintf_stream;
-}
+ static const std::string default_name("global");
-void
-setOutput(const string &filename)
-{
- dprintf_stream = simout.find(filename);
+ return default_name;
}
-ObjectMatch ignore;
-
-void
-dprintf(Tick when, const std::string &name, const char *format,
- CPRINTF_DEFINITION)
+namespace Trace
{
- if (!name.empty() && ignore.match(name))
- return;
- std::ostream &os = *dprintf_stream;
+bool enabled = false;
- string fmt = "";
- CPrintfArgsList args(VARARGS_ALLARGS);
+// This variable holds the output logger for debug information. Other
+// than setting up/redirecting this logger, do *NOT* reference this
+// directly
- if (!name.empty()) {
- fmt = "%s: " + fmt;
- args.push_front(name);
- }
+Logger *debug_logger = NULL;
- if (when != (Tick)-1) {
- fmt = "%7d: " + fmt;
- args.push_front(when);
- }
+Logger *
+getDebugLogger()
+{
+ /* Set a default logger to cerr when no other logger is set */
+ if (!debug_logger)
+ debug_logger = new OstreamLogger(std::cerr);
- fmt += format;
+ return debug_logger;
+}
- ccprintf(os, fmt.c_str(), args);
- os.flush();
+std::ostream &
+output()
+{
+ return getDebugLogger()->getOstream();
}
void
-dump(Tick when, const std::string &name, const void *d, int len)
+setDebugLogger(Logger *logger)
{
- if (!name.empty() && ignore.match(name))
- return;
-
- std::ostream &os = *dprintf_stream;
-
- string fmt = "";
- CPrintfArgsList args;
+ if (!logger)
+ warn("Trying to set debug logger to NULL\n");
+ else
+ debug_logger = logger;
+}
- if (!name.empty()) {
- fmt = "%s: " + fmt;
- args.push_front(name);
- }
+ObjectMatch ignore;
- if (when != (Tick)-1) {
- fmt = "%7d: " + fmt;
- args.push_front(when);
- }
+void
+Logger::dump(Tick when, const std::string &name, const void *d, int len)
+{
+ if (!name.empty() && ignore.match(name))
+ return;
const char *data = static_cast<const char *>(d);
int c, i, j;
+
for (i = 0; i < len; i += 16) {
- ccprintf(os, fmt, args);
- ccprintf(os, "%08x ", i);
+ std::ostringstream line;
+
+ ccprintf(line, "%08x ", i);
c = len - i;
if (c > 16) c = 16;
for (j = 0; j < c; j++) {
- ccprintf(os, "%02x ", data[i + j] & 0xff);
+ ccprintf(line, "%02x ", data[i + j] & 0xff);
if ((j & 0xf) == 7 && j > 0)
- ccprintf(os, " ");
+ ccprintf(line, " ");
}
for (; j < 16; j++)
- ccprintf(os, " ");
- ccprintf(os, " ");
+ ccprintf(line, " ");
+ ccprintf(line, " ");
for (j = 0; j < c; j++) {
int ch = data[i + j] & 0x7f;
- ccprintf(os, "%c", (char)(isprint(ch) ? ch : ' '));
+ ccprintf(line, "%c", (char)(isprint(ch) ? ch : ' '));
}
- ccprintf(os, "\n");
+ ccprintf(line, "\n");
+ logMessage(when, name, line.str());
if (c < 16)
break;
}
}
-bool
-changeFlag(const char *s, bool value)
-{
- using namespace Trace;
- std::string str(s);
-
- for (int i = 0; i < numFlagStrings; ++i) {
- if (str != flagStrings[i])
- continue;
-
- if (i < NumFlags) {
- flags[i] = value;
- } else {
- i -= NumFlags;
-
- const Flags *flagVec = compoundFlags[i];
- for (int j = 0; flagVec[j] != -1; ++j) {
- if (flagVec[j] < NumFlags)
- flags[flagVec[j]] = value;
- }
- }
-
- return true;
- }
-
- // the flag was not found.
- return false;
-}
-
void
-dumpStatus()
+OstreamLogger::logMessage(Tick when, const std::string &name,
+ const std::string &message)
{
- using namespace Trace;
- for (int i = 0; i < numFlagStrings; ++i) {
- if (flags[i])
- cprintf("%s\n", flagStrings[i]);
- }
-}
-
-/* namespace Trace */ }
+ if (!name.empty() && ignore.match(name))
+ return;
+ if (when != MaxTick)
+ ccprintf(stream, "%7d: ", when);
-// add a set of functions that can easily be invoked from gdb
-extern "C" {
- void
- setTraceFlag(const char *string)
- {
- Trace::changeFlag(string, true);
- }
+ if (!name.empty())
+ stream << name << ": ";
- void
- clearTraceFlag(const char *string)
- {
- Trace::changeFlag(string, false);
- }
+ stream << message;
+ stream.flush();
+}
- void
- dumpTraceStatus()
- {
- Trace::dumpStatus();
- }
-/* extern "C" */ }
+} // namespace Trace