/*
 * 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
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 */

#include <cassert>
#include <iomanip>
#include <iostream>
#include <sstream>

#include "base/cprintf.hh"

using namespace std;

namespace cp {

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()
{
}

void
Print::process()
{
    fmt.clear();

    size_t len;

    while (*ptr) {
        switch (*ptr) {
          case '%':
            if (ptr[1] != '%') {
                process_flag();
                return;
            }
            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;
        }
    }
}

void
Print::process_flag()
{
    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;
        }

        if (done) {
            if ((fmt.format == Format::integer) && have_precision) {
                // specified a . but not a float, set width
                fmt.width = fmt.precision;
                // precision requries digits for width, must fill with 0
                fmt.fill_zero = true;
            } else if ((fmt.format == Format::floating) && !have_precision &&
                        fmt.fill_zero) {
                // ambiguous case, matching printf
                fmt.precision = fmt.width;
            }
        }
    } // end while

    ++ptr;
}

void
Print::end_args()
{
    size_t len;

    while (*ptr) {
        switch (*ptr) {
          case '%':
            if (ptr[1] != '%')
                stream << "<extra arg>";

            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
