VNC: Add VNC server to M5
[gem5.git] / src / base / cprintf.cc
index dd8ce858b88b2c2454b574edd772b9f2ea3f223d..4f825c0976b384238a7d7ad24eddc9d10b3dc566 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
@@ -39,232 +39,256 @@ using namespace std;
 
 namespace cp {
 
-ArgList::~ArgList()
+Print::Print(std::ostream &stream, const std::string &format)
+    : stream(stream), format(format.c_str()), ptr(format.c_str()), cont(false)
+{
+    saved_flags = stream.flags();
+    saved_fill = stream.fill();
+    saved_precision = stream.precision();
+}
+
+Print::Print(std::ostream &stream, const char *format)
+    : stream(stream), format(format), ptr(format), cont(false)
+{
+    saved_flags = stream.flags();
+    saved_fill = stream.fill();
+    saved_precision = stream.precision();
+}
+
+Print::~Print()
 {
-    while (!objects.empty()) {
-        delete objects.front();
-        objects.pop_front();
-    }
 }
 
 void
-ArgList::dump(const string &format)
+Print::process()
 {
-    list_t::iterator iter = objects.begin();
-    list_t::iterator end = objects.end();
-
-    const char *p = format.c_str();
-
-    stream->fill(' ');
-    stream->flags((ios::fmtflags)0);
-
-    while (*p) {
-        switch (*p) {
-          case '%': {
-              if (p[1] == '%') {
-                  *stream << '%';
-                  p += 2;
-                  continue;
-              }
-
-              Format fmt;
-              bool done = false;
-              bool end_number = false;
-              bool have_precision = false;
-              int number = 0;
-
-              while (!done) {
-                  ++p;
-                  if (*p >= '0' && *p <= '9') {
-                      if (end_number)
-                          continue;
-                  } else if (number > 0)
-                      end_number = true;
-
-                  switch (*p) {
-                    case 's':
-                      fmt.format = Format::string;
-                      done = true;
-                      break;
-
-                    case 'c':
-                      fmt.format = Format::character;
-                      done = true;
-                      break;
-
-                    case 'l':
-                      continue;
-
-                    case 'p':
-                      fmt.format = Format::integer;
-                      fmt.base = Format::hex;
-                      fmt.alternate_form = true;
-                      done = true;
-                      break;
-
-                    case 'X':
-                      fmt.uppercase = true;
-                    case 'x':
-                      fmt.base = Format::hex;
-                      fmt.format = Format::integer;
-                      done = true;
-                      break;
-
-                    case 'o':
-                      fmt.base = Format::oct;
-                      fmt.format = Format::integer;
-                      done = true;
-                      break;
-
-                    case 'd':
-                    case 'i':
-                    case 'u':
-                      fmt.format = Format::integer;
-                      done = true;
-                      break;
-
-                    case 'G':
-                      fmt.uppercase = true;
-                    case 'g':
-                      fmt.format = Format::floating;
-                      fmt.float_format = Format::best;
-                      done = true;
-                      break;
-
-                    case 'E':
-                      fmt.uppercase = true;
-                    case 'e':
-                      fmt.format = Format::floating;
-                      fmt.float_format = Format::scientific;
-                      done = true;
-                      break;
-
-                    case 'f':
-                      fmt.format = Format::floating;
-                      fmt.float_format = Format::fixed;
-                      done = true;
-                      break;
-
-                    case 'n':
-                      *stream << "we don't do %n!!!\n";
-                      done = true;
-                      break;
-
-                    case '#':
-                      fmt.alternate_form = true;
-                      break;
-
-                    case '-':
-                      fmt.flush_left = true;
-                      break;
-
-                    case '+':
-                      fmt.print_sign = true;
-                      break;
-
-                    case ' ':
-                      fmt.blank_space = true;
-                      break;
-
-                    case '.':
-                      fmt.width = number;
-                      fmt.precision = 0;
-                      have_precision = true;
-                      number = 0;
-                      end_number = false;
-                      break;
-
-                    case '0':
-                      if (number == 0) {
-                          fmt.fill_zero = true;
-                          break;
-                      }
-                    case '1':
-                    case '2':
-                    case '3':
-                    case '4':
-                    case '5':
-                    case '6':
-                    case '7':
-                    case '8':
-                    case '9':
-                      number = number * 10 + (*p - '0');
-                      break;
-
-                    case '%':
-                      assert("we shouldn't get here");
-                      break;
-
-                    default:
-                      done = true;
-                      break;
-                  }
-
-                  if (end_number) {
-                      if (have_precision)
-                          fmt.precision = number;
-                      else
-                          fmt.width = number;
-
-                      end_number = false;
-                      number = 0;
-                  }
-              }
-
-              if (iter != end)
-              {
-                  ios::fmtflags saved_flags = stream->flags();
-                  char old_fill = stream->fill();
-                  int old_precision = stream->precision();
-
-                  (*iter)->process(*stream, fmt);
-
-                  stream->flags(saved_flags);
-                  stream->fill(old_fill);
-                  stream->precision(old_precision);
-
-                  ++iter;
-              } else {
-                  *stream << "<missing arg for format>";
-              }
-
-              ++p;
-          }
+    fmt.clear();
+
+    size_t len;
+
+    while (*ptr) {
+        switch (*ptr) {
+          case '%':
+            if (ptr[1] != '%')
+                goto processing;
+
+            stream.put('%');
+            ptr += 2;
             break;
 
           case '\n':
-            *stream << endl;
-            ++p;
+            stream << endl;
+            ++ptr;
             break;
           case '\r':
-            ++p;
-            if (*p != '\n')
-                *stream << endl;
+            ++ptr;
+            if (*ptr != '\n')
+                stream << endl;
             break;
 
-          default: {
-              size_t len = strcspn(p, "%\n\r\0");
-              stream->write(p, len);
-              p += len;
-          }
+          default:
+            len = strcspn(ptr, "%\n\r\0");
+            stream.write(ptr, len);
+            ptr += len;
             break;
         }
     }
 
-    while (iter != end) {
-        *stream << "<extra arg>";
-        ++iter;
+    return;
+
+  processing:
+    bool done = false;
+    bool end_number = false;
+    bool have_precision = false;
+    int number = 0;
+
+    stream.fill(' ');
+    stream.flags((ios::fmtflags)0);
+
+    while (!done) {
+        ++ptr;
+        if (*ptr >= '0' && *ptr <= '9') {
+            if (end_number)
+                continue;
+        } else if (number > 0)
+            end_number = true;
+
+        switch (*ptr) {
+          case 's':
+            fmt.format = Format::string;
+            done = true;
+            break;
+
+          case 'c':
+            fmt.format = Format::character;
+            done = true;
+            break;
+
+          case 'l':
+            continue;
+
+          case 'p':
+            fmt.format = Format::integer;
+            fmt.base = Format::hex;
+            fmt.alternate_form = true;
+            done = true;
+            break;
+
+          case 'X':
+            fmt.uppercase = true;
+          case 'x':
+            fmt.base = Format::hex;
+            fmt.format = Format::integer;
+            done = true;
+            break;
+
+          case 'o':
+            fmt.base = Format::oct;
+            fmt.format = Format::integer;
+            done = true;
+            break;
+
+          case 'd':
+          case 'i':
+          case 'u':
+            fmt.format = Format::integer;
+            done = true;
+            break;
+
+          case 'G':
+            fmt.uppercase = true;
+          case 'g':
+            fmt.format = Format::floating;
+            fmt.float_format = Format::best;
+            done = true;
+            break;
+
+          case 'E':
+            fmt.uppercase = true;
+          case 'e':
+            fmt.format = Format::floating;
+            fmt.float_format = Format::scientific;
+            done = true;
+            break;
+
+          case 'f':
+            fmt.format = Format::floating;
+            fmt.float_format = Format::fixed;
+            done = true;
+            break;
+
+          case 'n':
+            stream << "we don't do %n!!!\n";
+            done = true;
+            break;
+
+          case '#':
+            fmt.alternate_form = true;
+            break;
+
+          case '-':
+            fmt.flush_left = true;
+            break;
+
+          case '+':
+            fmt.print_sign = true;
+            break;
+
+          case ' ':
+            fmt.blank_space = true;
+            break;
+
+          case '.':
+            fmt.width = number;
+            fmt.precision = 0;
+            have_precision = true;
+            number = 0;
+            end_number = false;
+            break;
+
+          case '0':
+            if (number == 0) {
+                fmt.fill_zero = true;
+                break;
+            }
+          case '1':
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+          case '7':
+          case '8':
+          case '9':
+            number = number * 10 + (*ptr - '0');
+            break;
+
+          case '*':
+            if (have_precision)
+                fmt.get_precision = true;
+            else
+                fmt.get_width = true;
+            break;
+
+          case '%':
+            assert(false && "we shouldn't get here");
+            break;
+
+          default:
+            done = true;
+            break;
+        }
+
+        if (end_number) {
+            if (have_precision)
+                fmt.precision = number;
+            else
+                fmt.width = number;
+
+            end_number = false;
+            number = 0;
+        }
     }
+
+    ++ptr;
 }
 
-string
-ArgList::dumpToString(const string &format)
+void
+Print::end_args()
 {
-    stringstream ss;
+    size_t len;
 
-    dump(ss, format);
+    while (*ptr) {
+        switch (*ptr) {
+          case '%':
+            if (ptr[1] != '%')
+                stream << "<extra arg>";
 
-    return ss.str();
-}
+            stream.put('%');
+            ptr += 2;
+            break;
+
+          case '\n':
+            stream << endl;
+            ++ptr;
+            break;
+          case '\r':
+            ++ptr;
+            if (*ptr != '\n')
+                stream << endl;
+            break;
+
+          default:
+            len = strcspn(ptr, "%\n\r\0");
+            stream.write(ptr, len);
+            ptr += len;
+            break;
+        }
+    }
 
+    stream.flags(saved_flags);
+    stream.fill(saved_fill);
+    stream.precision(saved_precision);
 }
+
+} // namespace cp