#include "less.h"
extern int squeeze;
extern int chopline;
extern int hshift;
extern int quit_if_one_screen;
extern int ignore_eoi;
extern int status_col;
extern off_t start_attnpos;
extern off_t end_attnpos;
extern int hilite_search;
extern int size_linebuf;
off_t
forw_line(off_t curr_pos)
{
off_t base_pos;
off_t new_pos;
int c;
int blankline;
int endline;
int backchars;
get_forw_line:
if (curr_pos == -1) {
null_line();
return (-1);
}
if (hilite_search == OPT_ONPLUS || is_filtering() || status_col)
prep_hilite(curr_pos, curr_pos + 3*size_linebuf,
ignore_eoi ? 1 : -1);
if (ch_seek(curr_pos)) {
null_line();
return (-1);
}
base_pos = curr_pos;
for (;;) {
if (abort_sigs()) {
null_line();
return (-1);
}
c = ch_back_get();
if (c == EOI)
break;
if (c == '\n') {
(void) ch_forw_get();
break;
}
--base_pos;
}
prewind();
plinenum(base_pos);
(void) ch_seek(base_pos);
new_pos = base_pos;
while (new_pos < curr_pos) {
if (abort_sigs()) {
null_line();
return (-1);
}
c = ch_forw_get();
backchars = pappend(c, new_pos);
new_pos++;
if (backchars > 0) {
pshift_all();
new_pos -= backchars;
while (--backchars >= 0)
(void) ch_back_get();
}
}
(void) pflushmbc();
pshift_all();
c = ch_forw_get();
if (c == EOI) {
null_line();
return (-1);
}
blankline = (c == '\n' || c == '\r');
for (;;) {
if (abort_sigs()) {
null_line();
return (-1);
}
if (c == '\n' || c == EOI) {
backchars = pflushmbc();
new_pos = ch_tell();
if (backchars > 0 && !chopline && hshift == 0) {
new_pos -= backchars + 1;
endline = FALSE;
} else
endline = TRUE;
break;
}
if (c != '\r')
blankline = 0;
backchars = pappend(c, ch_tell()-1);
if (backchars > 0) {
if (chopline || hshift > 0) {
do {
if (abort_sigs()) {
null_line();
return (-1);
}
c = ch_forw_get();
} while (c != '\n' && c != EOI);
new_pos = ch_tell();
endline = TRUE;
quit_if_one_screen = FALSE;
} else {
new_pos = ch_tell() - backchars;
endline = FALSE;
}
break;
}
c = ch_forw_get();
}
pdone(endline, 1);
if (is_filtered(base_pos)) {
curr_pos = new_pos;
goto get_forw_line;
}
if (status_col && is_hilited(base_pos, ch_tell()-1, 1, NULL))
set_status_col('*');
if (squeeze && blankline) {
while ((c = ch_forw_get()) == '\n' || c == '\r')
if (abort_sigs()) {
null_line();
return (-1);
}
if (c != EOI)
(void) ch_back_get();
new_pos = ch_tell();
}
return (new_pos);
}
off_t
back_line(off_t curr_pos)
{
off_t new_pos, begin_new_pos, base_pos;
int c;
int endline;
int backchars;
get_back_line:
if (curr_pos == -1 || curr_pos <= ch_zero()) {
null_line();
return (-1);
}
if (hilite_search == OPT_ONPLUS || is_filtering() || status_col)
prep_hilite((curr_pos < 3*size_linebuf) ?
0 : curr_pos - 3*size_linebuf, curr_pos, -1);
if (ch_seek(curr_pos-1)) {
null_line();
return (-1);
}
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')
if (abort_sigs()) {
null_line();
return (-1);
}
if (c == EOI) {
null_line();
return (-1);
}
(void) ch_forw_get();
}
}
for (;;) {
if (abort_sigs()) {
null_line();
return (-1);
}
c = ch_back_get();
if (c == '\n') {
base_pos = ch_tell() + 1;
break;
}
if (c == EOI) {
base_pos = ch_tell();
break;
}
}
new_pos = base_pos;
if (ch_seek(new_pos)) {
null_line();
return (-1);
}
endline = FALSE;
prewind();
plinenum(new_pos);
loop:
begin_new_pos = new_pos;
(void) ch_seek(new_pos);
do {
c = ch_forw_get();
if (c == EOI || abort_sigs()) {
null_line();
return (-1);
}
new_pos++;
if (c == '\n') {
backchars = pflushmbc();
if (backchars > 0 && !chopline && hshift == 0) {
backchars++;
goto shift;
}
endline = TRUE;
break;
}
backchars = pappend(c, ch_tell()-1);
if (backchars > 0) {
if (chopline || hshift > 0) {
endline = TRUE;
quit_if_one_screen = FALSE;
break;
}
shift:
pshift_all();
while (backchars-- > 0) {
(void) ch_back_get();
new_pos--;
}
goto loop;
}
} while (new_pos < curr_pos);
pdone(endline, 0);
if (is_filtered(base_pos)) {
curr_pos = begin_new_pos;
goto get_back_line;
}
if (status_col && curr_pos > 0 &&
is_hilited(base_pos, curr_pos-1, 1, NULL))
set_status_col('*');
return (begin_new_pos);
}
void
set_attnpos(off_t pos)
{
int c;
if (pos != -1) {
if (ch_seek(pos))
return;
for (;;) {
c = ch_forw_get();
if (c == EOI)
return;
if (c != '\n' && c != '\r')
break;
pos++;
}
}
start_attnpos = pos;
for (;;) {
c = ch_forw_get();
pos++;
if (c == EOI || c == '\n' || c == '\r')
break;
}
end_attnpos = pos;
}