/*
 * 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 "base/cprintf.hh"

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

#include "base/compiler.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;
            M5_FALLTHROUGH;
          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;
            M5_FALLTHROUGH;
          case 'g':
            fmt.format = Format::floating;
            fmt.float_format = Format::best;
            done = true;
            break;

          case 'E':
            fmt.uppercase = true;
            M5_FALLTHROUGH;
          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;
            }
            M5_FALLTHROUGH;
          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
