#include "less.h"
extern int squeeze;
extern int chopline;
extern int hshift;
extern int quit_if_one_screen;
extern int sigs;
extern int ignore_eoi;
extern int status_col;
extern POSITION start_attnpos;
extern POSITION end_attnpos;
#if HILITE_SEARCH
extern int hilite_search;
extern int size_linebuf;
#endif
public POSITION
forw_line(curr_pos)
POSITION curr_pos;
{
POSITION base_pos;
POSITION new_pos;
register int c;
int blankline;
int endline;
int backchars;
if (curr_pos == NULL_POSITION)
{
null_line();
return (NULL_POSITION);
}
#if HILITE_SEARCH
if (hilite_search == OPT_ONPLUS || status_col)
prep_hilite(curr_pos, curr_pos + 3*size_linebuf,
ignore_eoi ? 1 : -1);
#endif
if (ch_seek(curr_pos))
{
null_line();
return (NULL_POSITION);
}
base_pos = curr_pos;
for (;;)
{
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
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);
while (base_pos < curr_pos)
{
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
c = ch_forw_get();
backchars = pappend(c, base_pos);
base_pos++;
if (backchars > 0)
{
pshift_all();
base_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');
for (;;)
{
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
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
{
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);
if (squeeze && blankline)
{
while ((c = ch_forw_get()) == '\n' || c == '\r')
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
if (c != EOI)
(void) ch_back_get();
new_pos = ch_tell();
}
return (new_pos);
}
public POSITION
back_line(curr_pos)
POSITION curr_pos;
{
POSITION new_pos, begin_new_pos;
int c;
int endline;
int backchars;
if (curr_pos == NULL_POSITION || curr_pos <= ch_zero())
{
null_line();
return (NULL_POSITION);
}
#if HILITE_SEARCH
if (hilite_search == OPT_ONPLUS || status_col)
prep_hilite((curr_pos < 3*size_linebuf) ?
0 : curr_pos - 3*size_linebuf, curr_pos, -1);
#endif
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')
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
if (c == EOI)
{
null_line();
return (NULL_POSITION);
}
(void) ch_forw_get();
}
}
for (;;)
{
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
c = ch_back_get();
if (c == '\n')
{
new_pos = ch_tell() + 1;
break;
}
if (c == EOI)
{
new_pos = ch_tell();
break;
}
}
if (ch_seek(new_pos))
{
null_line();
return (NULL_POSITION);
}
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 (NULL_POSITION);
}
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);
return (begin_new_pos);
}
public void
set_attnpos(pos)
POSITION pos;
{
int c;
if (pos != NULL_POSITION)
{
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;
}