//
// aegis - project change supervisor
// Copyright (C) 2004-2006, 2008 Peter Miller
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// .
//
#include
#include
printer_wrap::~printer_wrap()
{
if (column != 0)
putch('\n');
delete deeper;
deeper = 0;
buflen = 0;
bufmax = 0;
delete [] buffer;
buffer = 0;
}
printer_wrap::printer_wrap(printer *arg) :
deeper(arg),
start_of_line(true),
continuation_line(false),
column(0),
buflen(0),
bufwidth(0),
bufmax(0),
buffer(0)
{
}
void
printer_wrap::stash_inner(char c)
{
if (buflen >= bufmax)
{
size_t new_bufmax = bufmax * 2 + 32;
char *new_buffer = new char[new_bufmax];
memcpy(new_buffer, buffer, buflen);
delete [] buffer;
buffer = new_buffer;
bufmax = new_bufmax;
}
buffer[buflen++] = c;
if (c == '\t')
bufwidth += 8;
else
bufwidth++;
}
void
printer_wrap::emit_buffer()
{
if (!buflen)
return;
//
// We have to decide if the word in the buffer makes the line wrap
// or not. The current output position in the deeper output in
// represented by "column", and the length of the current work is
// represented by "buflen". If we need to wrap, we add " \\\n\t\t",
// so we have to wrap at column 78 or earlier.
//
if (column != 0)
{
if (column + buflen > maximum_line_width)
{
deeper->puts(" \\\n\t\t");
column = 16;
continuation_line = true;
}
else
{
deeper->putch(' ');
++column;
}
}
column += bufwidth;
deeper->write(buffer, buflen);
start_of_line = false;
buflen = 0;
bufwidth = 0;
}
void
printer_wrap::putch(char c)
{
switch (c)
{
case '\n':
emit_buffer();
deeper->putch('\n');
column = 0;
start_of_line = true;
continuation_line = false;
break;
case ' ':
case '\t':
if (start_of_line && !continuation_line)
stash_inner(c);
else
emit_buffer();
break;
default:
stash_inner(c);
start_of_line = false;
break;
}
}