diff options
Diffstat (limited to 'src/base/cprintf.cc')
-rw-r--r-- | src/base/cprintf.cc | 427 |
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 */ } |