summaryrefslogtreecommitdiff
path: root/src/base/cprintf.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/cprintf.cc')
-rw-r--r--src/base/cprintf.cc427
1 files changed, 221 insertions, 206 deletions
diff --git a/src/base/cprintf.cc b/src/base/cprintf.cc
index dd8ce858b..d4ba9ca21 100644
--- a/src/base/cprintf.cc
+++ b/src/base/cprintf.cc
@@ -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,247 @@ 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())
+{
+ 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)
+{
+ 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(Format &fmt)
{
- 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;
- }
+ 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 '%':
+ 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;
+ }
}
+
+ ++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);
}
+
+/* end namespace cp */ }