#include "less.h"
extern int squeeze;
extern int hshift;
extern int quit_if_one_screen;
extern int ignore_eoi;
extern int status_col;
extern int wordwrap;
extern POSITION start_attnpos;
extern POSITION end_attnpos;
#if HILITE_SEARCH
extern int hilite_search;
extern int show_attn;
#endif
static void init_status_col(POSITION base_pos, POSITION disp_pos, POSITION edisp_pos, POSITION eol_pos)
{
int hl_before = (chop_line() && disp_pos != NULL_POSITION) ?
is_hilited_attr(base_pos, disp_pos, TRUE, NULL) : 0;
int hl_after = (chop_line() && edisp_pos != NULL_POSITION) ?
is_hilited_attr(edisp_pos, eol_pos, TRUE, NULL) : 0;
int attr;
char ch;
if (hl_before && hl_after)
{
attr = hl_after;
ch = '=';
} else if (hl_before)
{
attr = hl_before;
ch = '<';
} else if (hl_after)
{
attr = hl_after;
ch = '>';
} else if (disp_pos != NULL_POSITION)
{
attr = is_hilited_attr(disp_pos, edisp_pos, TRUE, NULL);
ch = '*';
} else
{
attr = 0;
}
if (attr)
set_status_col(ch, attr);
}
public POSITION forw_line_seg(POSITION curr_pos, lbool skipeol, lbool rscroll, lbool nochop, POSITION *p_linepos, lbool *p_newline)
{
POSITION base_pos;
POSITION new_pos;
POSITION edisp_pos;
int c;
lbool blankline;
lbool endline;
lbool chopped;
int backchars;
POSITION wrap_pos;
lbool skipped_leading;
if (p_linepos != NULL)
*p_linepos = NULL_POSITION;
get_forw_line:
if (curr_pos == NULL_POSITION)
{
null_line();
return (NULL_POSITION);
}
#if HILITE_SEARCH
if (hilite_search == OPT_ONPLUS || is_filtering() || status_col)
{
prep_hilite(curr_pos, NULL_POSITION, 1);
}
#endif
if (ch_seek(curr_pos))
{
null_line();
return (NULL_POSITION);
}
base_pos = curr_pos;
for (;;)
{
c = ch_back_get();
if (c == EOI)
break;
if (c == '\n')
{
(void) ch_forw_get();
break;
}
--base_pos;
}
prewind();
plinestart(base_pos);
(void) ch_seek(base_pos);
new_pos = base_pos;
while (new_pos < curr_pos)
{
c = ch_forw_get();
if (c == EOI)
{
null_line();
return (NULL_POSITION);
}
backchars = pappend((char) c, new_pos);
new_pos++;
if (backchars > 0)
{
pshift_all();
if (wordwrap && (c == ' ' || c == '\t'))
{
do
{
new_pos++;
c = ch_forw_get();
} while (c == ' ' || c == '\t');
backchars = 1;
}
new_pos -= backchars;
while (--backchars >= 0)
(void) ch_back_get();
}
}
(void) pflushmbc();
pshift_all();
c = ch_forw_get();
if (c == EOI)
{
null_line();
return (NULL_POSITION);
}
blankline = (c == '\n' || c == '\r');
wrap_pos = NULL_POSITION;
skipped_leading = FALSE;
chopped = FALSE;
for (;;)
{
if (c == '\n' || c == EOI)
{
backchars = pflushmbc();
new_pos = ch_tell();
if (backchars > 0 && (nochop || !chop_line()) && hshift == 0)
{
new_pos -= backchars + 1;
endline = FALSE;
} else
endline = TRUE;
edisp_pos = new_pos;
break;
}
if (c != '\r')
blankline = FALSE;
backchars = pappend((char) c, ch_tell()-1);
if (backchars > 0)
{
if (skipeol)
{
edisp_pos = ch_tell() - backchars;
do
{
c = ch_forw_get();
} while (c != '\n' && c != EOI);
new_pos = ch_tell();
endline = TRUE;
quit_if_one_screen = FALSE;
chopped = TRUE;
} else
{
if (!wordwrap)
new_pos = ch_tell() - backchars;
else
{
if (c == ' ' || c == '\t')
{
do
{
new_pos = ch_tell();
c = ch_forw_get();
} while (c == ' ' || c == '\t');
if (c == '\r')
c = ch_forw_get();
if (c == '\n')
new_pos = ch_tell();
} else if (wrap_pos == NULL_POSITION)
new_pos = ch_tell() - backchars;
else
{
new_pos = wrap_pos;
loadc();
}
}
endline = FALSE;
edisp_pos = new_pos;
}
break;
}
if (wordwrap)
{
if (c == ' ' || c == '\t')
{
if (skipped_leading)
{
wrap_pos = ch_tell();
savec();
}
} else
skipped_leading = TRUE;
}
c = ch_forw_get();
}
#if HILITE_SEARCH
if (blankline && show_attn)
{
pappend_b(' ', ch_tell()-1, TRUE);
}
#endif
pdone(endline, rscroll && chopped, TRUE);
#if HILITE_SEARCH
if (is_filtered(base_pos))
{
curr_pos = new_pos;
goto get_forw_line;
}
if (status_col)
init_status_col(base_pos, line_position(), edisp_pos, new_pos);
#endif
if (squeeze && blankline)
{
while ((c = ch_forw_get()) == '\n' || c == '\r')
continue;
if (c != EOI)
(void) ch_back_get();
new_pos = ch_tell();
}
if (p_linepos != NULL)
*p_linepos = curr_pos;
if (p_newline != NULL)
*p_newline = endline;
return (new_pos);
}
public POSITION forw_line(POSITION curr_pos, POSITION *p_linepos, lbool *p_newline)
{
return forw_line_seg(curr_pos, (chop_line() || hshift > 0), TRUE, FALSE, p_linepos, p_newline);
}
public POSITION back_line(POSITION curr_pos, lbool *p_newline)
{
POSITION base_pos;
POSITION new_pos;
POSITION edisp_pos;
POSITION begin_new_pos;
int c;
lbool endline;
lbool chopped;
int backchars;
POSITION wrap_pos;
lbool skipped_leading;
get_back_line:
if (curr_pos == NULL_POSITION || curr_pos <= ch_zero())
{
null_line();
return (NULL_POSITION);
}
if (ch_seek(curr_pos-1))
{
null_line();
return (NULL_POSITION);
}
if (squeeze)
{
(void) ch_forw_get();
c = ch_forw_get();
(void) ch_back_get();
(void) ch_back_get();
if (c == '\n' || c == '\r')
{
while ((c = ch_back_get()) == '\n' || c == '\r')
continue;
if (c == EOI)
{
null_line();
return (NULL_POSITION);
}
(void) ch_forw_get();
}
}
for (;;)
{
c = ch_back_get();
if (c == '\n')
{
base_pos = ch_tell() + 1;
break;
}
if (c == EOI)
{
base_pos = ch_tell();
break;
}
}
#if HILITE_SEARCH
if (hilite_search == OPT_ONPLUS || is_filtering() || status_col)
prep_hilite(base_pos, NULL_POSITION, 1);
#endif
new_pos = base_pos;
if (ch_seek(new_pos))
{
null_line();
return (NULL_POSITION);
}
endline = FALSE;
prewind();
plinestart(new_pos);
if (p_newline != NULL)
*p_newline = TRUE;
loop:
wrap_pos = NULL_POSITION;
skipped_leading = FALSE;
begin_new_pos = new_pos;
(void) ch_seek(new_pos);
chopped = FALSE;
for (;;)
{
c = ch_forw_get();
if (c == EOI)
{
null_line();
return (NULL_POSITION);
}
new_pos++;
if (c == '\n')
{
backchars = pflushmbc();
if (backchars > 0 && !chop_line() && hshift == 0)
{
backchars++;
goto shift;
}
endline = TRUE;
edisp_pos = new_pos;
break;
}
backchars = pappend((char) c, ch_tell()-1);
if (backchars > 0)
{
if (chop_line() || hshift > 0)
{
endline = TRUE;
chopped = TRUE;
quit_if_one_screen = FALSE;
edisp_pos = new_pos;
break;
}
if (p_newline != NULL)
*p_newline = FALSE;
shift:
if (!wordwrap)
{
pshift_all();
new_pos -= backchars;
} else
{
if (c == ' ' || c == '\t')
{
for (;;)
{
c = ch_forw_get();
if (c == ' ' || c == '\t')
new_pos++;
else
{
if (c == '\r')
{
c = ch_forw_get();
if (c == '\n')
new_pos++;
}
if (c == '\n')
new_pos++;
edisp_pos = new_pos;
break;
}
}
if (new_pos >= curr_pos)
{
edisp_pos = new_pos;
break;
}
pshift_all();
} else
{
pshift_all();
if (wrap_pos == NULL_POSITION)
new_pos -= backchars;
else
new_pos = wrap_pos;
}
}
goto loop;
}
if (wordwrap)
{
if (c == ' ' || c == '\t')
{
if (skipped_leading)
wrap_pos = new_pos;
} else
skipped_leading = TRUE;
}
if (new_pos >= curr_pos)
{
edisp_pos = new_pos;
break;
}
}
pdone(endline, chopped, FALSE);
#if HILITE_SEARCH
if (is_filtered(base_pos))
{
curr_pos = begin_new_pos;
goto get_back_line;
}
if (status_col)
init_status_col(base_pos, line_position(), edisp_pos, new_pos);
#endif
return (begin_new_pos);
}
public void set_attnpos(POSITION pos)
{
int c;
if (pos != NULL_POSITION)
{
if (ch_seek(pos))
return;
for (;;)
{
c = ch_forw_get();
if (c == EOI)
break;
if (c == '\n' || c == '\r')
{
(void) ch_back_get();
break;
}
pos++;
}
end_attnpos = pos;
for (;;)
{
c = ch_back_get();
if (c == EOI || c == '\n' || c == '\r')
break;
pos--;
}
}
start_attnpos = pos;
}