#include "input.h"

#include <iostream>
#include <cstring>

using namespace std;

// aids mixing cin.getline with cin >> by avoiding
// reading empty lines when cin >> leaves the '\n'
// behind.  otherwise behaves as cin.getline
//
// peeks at next character in buffer, if it's a
// newline ('\n'), we remove it from the buffer.
// either way we do a getline as instructed.
//
void get_line(char str[],      // out
              const long MAX,  // in
              istream & strm)  // in (def = cin)
{
    if (strm.tie() != nullptr)
    {
        strm.tie()->flush();   // HP's compiler doesn't prompt for peeking
    }
    if (strm.peek() == '\n')
    {
        strm.ignore();
    }
    strm.getline(str, MAX);
    return;
}

char * new_n_cat(char * & old_s, long & old_l, const char new_s[], long new_l)
{
    char * dyn = old_s;
    if (new_l > 0)
    {
        dyn = new char [old_l+new_l+1];
        if (dyn != nullptr)
        {
            if (old_s != nullptr)
            {
                strcpy(dyn, old_s);
                delete [] old_s;
                old_s = nullptr;
            }
            else
            {
                dyn[0] = '\0';
            }
            strcat(dyn, new_s);
            old_l += new_l;
        }
    }
    return dyn;
}

// a get_line to work with a dynamic string
void get_line(char * & str, istream & strm)
{
    const long MAX = 500;
    char buffer[MAX], *dyn;
    long had;
    had = 0;
    dyn = nullptr;
    get_line(buffer, MAX, strm);
    while (strm.fail())   // getline sets fail when
                          // it reads a full MAX-1
    {
        strm.clear();
        dyn = new_n_cat(dyn, had, buffer, strm.gcount());
        get_line(buffer, MAX, strm);
    }
    delete [] str;    // must assume it was an array!
    str = new_n_cat(dyn, had, buffer, strm.gcount());
    return;
}
