#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "posixstat.h"
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif
#include <stdio.h>
#ifdef __MSDOS__
# include <pc.h>
#endif
#include "rldefs.h"
#include "tcap.h"
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
#if !defined (strchr) && !defined (__STDC__)
extern char *strchr (), *strrchr ();
#endif
#if defined (HACK_TERMCAP_MOTION)
extern char *term_forward_char;
#endif
static void update_line __P((char *, char *, int, int, int, int));
static void space_to_eol __P((int));
static void delete_chars __P((int));
static void insert_some_chars __P((char *, int));
static void cr __P((void));
static int *inv_lbreaks, *vis_lbreaks;
static int inv_lbsize, vis_lbsize;
#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
VFunction *rl_redisplay_function = rl_redisplay;
int rl_display_fixed = 0;
int _rl_suppress_redisplay = 0;
char *rl_display_prompt = (char *)NULL;
int _rl_last_c_pos = 0;
int _rl_last_v_pos = 0;
int _rl_vis_botlin = 0;
static int last_lmargin;
static char *visible_line = (char *)NULL;
static char *invisible_line = (char *)NULL;
static char msg_buf[128];
static int forced_display;
static int line_size = 1024;
static char *local_prompt, *local_prompt_prefix;
static int visible_length, prefix_length;
static int visible_wrap_offset;
static int wrap_offset;
static int last_invisible;
static int visible_first_line_len;
static char *
expand_prompt (pmt, lp, lip)
char *pmt;
int *lp, *lip;
{
char *r, *ret, *p;
int l, rl, last, ignoring;
if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
{
r = savestring (pmt);
if (lp)
*lp = strlen (r);
return r;
}
l = strlen (pmt);
r = ret = xmalloc (l + 1);
for (rl = ignoring = last = 0, p = pmt; p && *p; p++)
{
if (*p == RL_PROMPT_START_IGNORE)
{
ignoring++;
continue;
}
else if (ignoring && *p == RL_PROMPT_END_IGNORE)
{
ignoring = 0;
last = r - ret - 1;
continue;
}
else
{
*r++ = *p;
if (!ignoring)
rl++;
}
}
*r = '\0';
if (lp)
*lp = rl;
if (lip)
*lip = last;
return ret;
}
char *
_rl_strip_prompt (pmt)
char *pmt;
{
char *ret;
ret = expand_prompt (pmt, (int *)NULL, (int *)NULL);
return ret;
}
int
rl_expand_prompt (prompt)
char *prompt;
{
char *p, *t;
int c;
if (local_prompt)
free (local_prompt);
if (local_prompt_prefix)
free (local_prompt_prefix);
local_prompt = local_prompt_prefix = (char *)0;
last_invisible = visible_length = 0;
if (prompt == 0 || *prompt == 0)
return (0);
p = strrchr (prompt, '\n');
if (!p)
{
local_prompt = expand_prompt (prompt, &visible_length, &last_invisible);
local_prompt_prefix = (char *)0;
return (visible_length);
}
else
{
t = ++p;
local_prompt = expand_prompt (p, &visible_length, &last_invisible);
c = *t; *t = '\0';
local_prompt_prefix = expand_prompt (prompt, &prefix_length, (int *)NULL);
*t = c;
return (prefix_length);
}
}
static void
init_line_structures (minsize)
int minsize;
{
register int n;
if (invisible_line == 0)
{
if (line_size < minsize)
line_size = minsize;
visible_line = xmalloc (line_size);
invisible_line = xmalloc (line_size);
}
else if (line_size < minsize)
{
line_size *= 2;
if (line_size < minsize)
line_size = minsize;
visible_line = xrealloc (visible_line, line_size);
invisible_line = xrealloc (invisible_line, line_size);
}
for (n = minsize; n < line_size; n++)
{
visible_line[n] = 0;
invisible_line[n] = 1;
}
if (vis_lbreaks == 0)
{
inv_lbsize = vis_lbsize = 256;
inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
inv_lbreaks[0] = vis_lbreaks[0] = 0;
}
}
void
rl_redisplay ()
{
register int in, out, c, linenum, cursor_linenum;
register char *line;
int c_pos, inv_botlin, lb_botlin, lb_linenum;
int newlines, lpos, temp;
char *prompt_this_line;
if (!readline_echoing_p)
return;
if (!rl_display_prompt)
rl_display_prompt = "";
if (invisible_line == 0)
{
init_line_structures (0);
rl_on_new_line ();
}
c_pos = -1;
line = invisible_line;
out = inv_botlin = 0;
if (_rl_mark_modified_lines && current_history () && rl_undo_list)
{
line[out++] = '*';
line[out] = '\0';
}
if (visible_line[0] != invisible_line[0])
rl_display_fixed = 0;
if (rl_display_prompt == rl_prompt || local_prompt)
{
int local_len = local_prompt ? strlen (local_prompt) : 0;
if (local_prompt_prefix && forced_display)
_rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
if (local_len > 0)
{
temp = local_len + out + 2;
if (temp >= line_size)
{
line_size = (temp + 1024) - (temp % 1024);
visible_line = xrealloc (visible_line, line_size);
line = invisible_line = xrealloc (invisible_line, line_size);
}
strncpy (line + out, local_prompt, local_len);
out += local_len;
}
line[out] = '\0';
wrap_offset = local_len - visible_length;
}
else
{
int pmtlen;
prompt_this_line = strrchr (rl_display_prompt, '\n');
if (!prompt_this_line)
prompt_this_line = rl_display_prompt;
else
{
prompt_this_line++;
pmtlen = prompt_this_line - rl_display_prompt;
if (forced_display)
{
_rl_output_some_chars (rl_display_prompt, pmtlen);
if (pmtlen < 2 || prompt_this_line[-2] != '\r')
cr ();
}
}
pmtlen = strlen (prompt_this_line);
temp = pmtlen + out + 2;
if (temp >= line_size)
{
line_size = (temp + 1024) - (temp % 1024);
visible_line = xrealloc (visible_line, line_size);
line = invisible_line = xrealloc (invisible_line, line_size);
}
strncpy (line + out, prompt_this_line, pmtlen);
out += pmtlen;
line[out] = '\0';
wrap_offset = 0;
}
#define CHECK_INV_LBREAKS() \
do { \
if (newlines >= (inv_lbsize - 2)) \
{ \
inv_lbsize *= 2; \
inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
} \
} while (0)
#define CHECK_LPOS() \
do { \
lpos++; \
if (lpos >= screenwidth) \
{ \
if (newlines >= (inv_lbsize - 2)) \
{ \
inv_lbsize *= 2; \
inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
} \
inv_lbreaks[++newlines] = out; \
lpos = 0; \
} \
} while (0)
inv_lbreaks[newlines = 0] = 0;
lpos = out - wrap_offset;
while (lpos >= screenwidth)
{
temp = ((newlines + 1) * screenwidth) + ((newlines == 0) ? wrap_offset : 0);
inv_lbreaks[++newlines] = temp;
lpos -= screenwidth;
}
lb_linenum = 0;
for (in = 0; in < rl_end; in++)
{
c = (unsigned char)rl_line_buffer[in];
if (out + 8 >= line_size)
{
line_size *= 2;
visible_line = xrealloc (visible_line, line_size);
invisible_line = xrealloc (invisible_line, line_size);
line = invisible_line;
}
if (in == rl_point)
{
c_pos = out;
lb_linenum = newlines;
}
if (META_CHAR (c))
{
if (_rl_output_meta_chars == 0)
{
sprintf (line + out, "\\%o", c);
if (lpos + 4 >= screenwidth)
{
temp = screenwidth - lpos;
CHECK_INV_LBREAKS ();
inv_lbreaks[++newlines] = out + temp;
lpos = 4 - temp;
}
else
lpos += 4;
out += 4;
}
else
{
line[out++] = c;
CHECK_LPOS();
}
}
#if defined (DISPLAY_TABS)
else if (c == '\t')
{
register int temp, newout;
#if 0
newout = (out | (int)7) + 1;
#else
newout = out + 8 - lpos % 8;
#endif
temp = newout - out;
if (lpos + temp >= screenwidth)
{
register int temp2;
temp2 = screenwidth - lpos;
CHECK_INV_LBREAKS ();
inv_lbreaks[++newlines] = out + temp2;
lpos = temp - temp2;
while (out < newout)
line[out++] = ' ';
}
else
{
while (out < newout)
line[out++] = ' ';
lpos += temp;
}
}
#endif
else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && term_up && *term_up)
{
line[out++] = '\0';
CHECK_INV_LBREAKS ();
inv_lbreaks[++newlines] = out;
lpos = 0;
}
else if (CTRL_CHAR (c) || c == RUBOUT)
{
line[out++] = '^';
CHECK_LPOS();
line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
CHECK_LPOS();
}
else
{
line[out++] = c;
CHECK_LPOS();
}
}
line[out] = '\0';
if (c_pos < 0)
{
c_pos = out;
lb_linenum = newlines;
}
inv_botlin = lb_botlin = newlines;
CHECK_INV_LBREAKS ();
inv_lbreaks[newlines+1] = out;
cursor_linenum = lb_linenum;
if (_rl_horizontal_scroll_mode == 0 && term_up && *term_up)
{
int nleft, pos, changed_screen_line;
if (!rl_display_fixed || forced_display)
{
forced_display = 0;
if (out >= screenchars)
out = screenchars - 1;
#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
for (linenum = 0; linenum <= inv_botlin; linenum++)
{
update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
if (linenum == 0 &&
inv_botlin == 0 && _rl_last_c_pos == out &&
(wrap_offset > visible_wrap_offset) &&
(_rl_last_c_pos < visible_first_line_len))
{
nleft = screenwidth + wrap_offset - _rl_last_c_pos;
if (nleft)
_rl_clear_to_eol (nleft);
}
if (linenum == 0)
visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
}
if (_rl_vis_botlin > inv_botlin)
{
char *tt;
for (; linenum <= _rl_vis_botlin; linenum++)
{
tt = VIS_CHARS (linenum);
_rl_move_vert (linenum);
_rl_move_cursor_relative (0, tt);
_rl_clear_to_eol
((linenum == _rl_vis_botlin) ? strlen (tt) : screenwidth);
}
}
_rl_vis_botlin = inv_botlin;
changed_screen_line = _rl_last_v_pos != cursor_linenum;
if (changed_screen_line)
{
_rl_move_vert (cursor_linenum);
if (cursor_linenum == 0 && wrap_offset)
_rl_last_c_pos += wrap_offset;
}
nleft = visible_length + wrap_offset;
if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
_rl_last_c_pos <= last_invisible && local_prompt)
{
#if defined (__MSDOS__)
putc ('\r', rl_outstream);
#else
if (term_cr)
tputs (term_cr, 1, _rl_output_character_function);
#endif
_rl_output_some_chars (local_prompt, nleft);
_rl_last_c_pos = nleft;
}
pos = inv_lbreaks[cursor_linenum];
nleft = c_pos - pos;
if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
{
_rl_backspace (_rl_last_c_pos - nleft);
_rl_last_c_pos = nleft;
}
if (nleft != _rl_last_c_pos)
_rl_move_cursor_relative (nleft, &invisible_line[pos]);
}
}
else
{
#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
int lmargin, ndisp, nleft, phys_c_pos, t;
_rl_last_v_pos = 0;
ndisp = c_pos - wrap_offset;
nleft = visible_length + wrap_offset;
phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset);
t = screenwidth / 3;
if (phys_c_pos > screenwidth - 2)
{
lmargin = c_pos - (2 * t);
if (lmargin < 0)
lmargin = 0;
if (wrap_offset && lmargin > 0 && lmargin < nleft)
lmargin = nleft;
}
else if (ndisp < screenwidth - 2)
lmargin = 0;
else if (phys_c_pos < 1)
{
lmargin = ((c_pos - 1) / t) * t;
if (wrap_offset && lmargin > 0 && lmargin < nleft)
lmargin = nleft;
}
else
lmargin = last_lmargin;
if (lmargin > 0)
line[lmargin] = '<';
t = lmargin + M_OFFSET (lmargin, wrap_offset) + screenwidth;
if (t < out)
line[t - 1] = '>';
if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
{
forced_display = 0;
update_line (&visible_line[last_lmargin],
&invisible_line[lmargin],
0,
screenwidth + visible_wrap_offset,
screenwidth + (lmargin ? 0 : wrap_offset),
0);
t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
(_rl_last_c_pos == out) &&
t < visible_first_line_len)
{
nleft = screenwidth - t;
_rl_clear_to_eol (nleft);
}
visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
if (visible_first_line_len > screenwidth)
visible_first_line_len = screenwidth;
_rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
last_lmargin = lmargin;
}
}
fflush (rl_outstream);
{
char *temp = visible_line;
int *itemp = vis_lbreaks, ntemp = vis_lbsize;
visible_line = invisible_line;
invisible_line = temp;
vis_lbreaks = inv_lbreaks;
inv_lbreaks = itemp;
vis_lbsize = inv_lbsize;
inv_lbsize = ntemp;
rl_display_fixed = 0;
if (_rl_horizontal_scroll_mode && last_lmargin)
visible_wrap_offset = 0;
else
visible_wrap_offset = wrap_offset;
}
}
static void
update_line (old, new, current_line, omax, nmax, inv_botlin)
register char *old, *new;
int current_line, omax, nmax, inv_botlin;
{
register char *ofd, *ols, *oe, *nfd, *nls, *ne;
int temp, lendiff, wsatend, od, nd;
int current_invis_chars;
temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
if (temp == screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
&& _rl_last_v_pos == current_line - 1)
{
if (new[0])
putc (new[0], rl_outstream);
else
putc (' ', rl_outstream);
_rl_last_c_pos = 1;
_rl_last_v_pos++;
if (old[0] && new[0])
old[0] = new[0];
}
for (ofd = old, nfd = new;
(ofd - old < omax) && *ofd && (*ofd == *nfd);
ofd++, nfd++)
;
for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
if (ofd == oe && nfd == ne)
return;
wsatend = 1;
ols = oe - 1;
nls = ne - 1;
while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
{
if (*ols != ' ')
wsatend = 0;
ols--;
nls--;
}
if (wsatend)
{
ols = oe;
nls = ne;
}
else if (*ols != *nls)
{
if (*ols)
ols++;
if (*nls)
nls++;
}
current_invis_chars = W_OFFSET (current_line, wrap_offset);
if (_rl_last_v_pos != current_line)
{
_rl_move_vert (current_line);
if (current_line == 0 && visible_wrap_offset)
_rl_last_c_pos += visible_wrap_offset;
}
lendiff = local_prompt ? strlen (local_prompt) : 0;
od = ofd - old;
if (current_line == 0 && !_rl_horizontal_scroll_mode &&
term_cr && lendiff > visible_length && _rl_last_c_pos > 0 &&
od > lendiff && _rl_last_c_pos < last_invisible)
{
#if defined (__MSDOS__)
putc ('\r', rl_outstream);
#else
tputs (term_cr, 1, _rl_output_character_function);
#endif
_rl_output_some_chars (local_prompt, lendiff);
_rl_last_c_pos = lendiff;
}
_rl_move_cursor_relative (od, old);
lendiff = (nls - nfd) - (ols - ofd);
if (current_line == 0 && !_rl_horizontal_scroll_mode &&
current_invis_chars != visible_wrap_offset)
lendiff += visible_wrap_offset - current_invis_chars;
temp = ne - nfd;
if (lendiff > 0)
{
int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!_rl_term_autowrap || !gl))
{
if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
lendiff <= visible_length || !current_invis_chars))
{
insert_some_chars (nfd, lendiff);
_rl_last_c_pos += lendiff;
}
else if (*ols == 0)
{
_rl_output_some_chars (nfd, lendiff);
_rl_last_c_pos += lendiff;
}
else
{
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += temp;
return;
}
temp = nls - nfd;
if ((temp - lendiff) > 0)
{
_rl_output_some_chars (nfd + lendiff, temp - lendiff);
_rl_last_c_pos += temp - lendiff;
}
}
else
{
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += temp;
}
}
else
{
if (term_dc && (2 * temp) >= -lendiff)
{
if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
-lendiff == visible_wrap_offset)
lendiff = 0;
if (lendiff)
delete_chars (-lendiff);
temp = nls - nfd;
if (temp > 0)
{
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += temp;
}
}
else
{
if (temp > 0)
{
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += temp;
}
lendiff = (oe - old) - (ne - new);
if (lendiff)
{
if (_rl_term_autowrap && current_line < inv_botlin)
space_to_eol (lendiff);
else
_rl_clear_to_eol (lendiff);
}
}
}
}
int
rl_on_new_line ()
{
if (visible_line)
visible_line[0] = '\0';
_rl_last_c_pos = _rl_last_v_pos = 0;
_rl_vis_botlin = last_lmargin = 0;
if (vis_lbreaks)
vis_lbreaks[0] = vis_lbreaks[1] = 0;
visible_wrap_offset = 0;
return 0;
}
int
rl_on_new_line_with_prompt ()
{
int prompt_size, i, l, real_screenwidth, newlines;
char *prompt_last_line;
prompt_size = strlen (rl_prompt) + 1;
init_line_structures (prompt_size);
strcpy (visible_line, rl_prompt);
strcpy (invisible_line, rl_prompt);
prompt_last_line = strrchr (rl_prompt, '\n');
if (!prompt_last_line)
prompt_last_line = rl_prompt;
l = strlen (prompt_last_line);
_rl_last_c_pos = l;
real_screenwidth = screenwidth + (_rl_term_autowrap ? 0 : 1);
_rl_last_v_pos = l / real_screenwidth;
if (l > 0 && (l % real_screenwidth) == 0)
_rl_output_some_chars ("\n", 1);
last_lmargin = 0;
newlines = 0; i = 0;
while (i <= l)
{
_rl_vis_botlin = newlines;
vis_lbreaks[newlines++] = i;
i += real_screenwidth;
}
vis_lbreaks[newlines] = l;
visible_wrap_offset = 0;
return 0;
}
int
rl_forced_update_display ()
{
if (visible_line)
{
register char *temp = visible_line;
while (*temp)
*temp++ = '\0';
}
rl_on_new_line ();
forced_display++;
(*rl_redisplay_function) ();
return 0;
}
void
_rl_move_cursor_relative (new, data)
int new;
char *data;
{
register int i;
if (_rl_last_c_pos == new) return;
i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
if (new == 0 || CR_FASTER (new, _rl_last_c_pos) ||
(_rl_term_autowrap && i == screenwidth))
{
#if defined (__MSDOS__)
putc ('\r', rl_outstream);
#else
tputs (term_cr, 1, _rl_output_character_function);
#endif
_rl_last_c_pos = 0;
}
if (_rl_last_c_pos < new)
{
#if defined (HACK_TERMCAP_MOTION)
if (term_forward_char)
for (i = _rl_last_c_pos; i < new; i++)
tputs (term_forward_char, 1, _rl_output_character_function);
else
for (i = _rl_last_c_pos; i < new; i++)
putc (data[i], rl_outstream);
#else
for (i = _rl_last_c_pos; i < new; i++)
putc (data[i], rl_outstream);
#endif
}
else if (_rl_last_c_pos > new)
_rl_backspace (_rl_last_c_pos - new);
_rl_last_c_pos = new;
}
void
_rl_move_vert (to)
int to;
{
register int delta, i;
if (_rl_last_v_pos == to || to > screenheight)
return;
if ((delta = to - _rl_last_v_pos) > 0)
{
for (i = 0; i < delta; i++)
putc ('\n', rl_outstream);
#if defined (__MSDOS__)
putc ('\r', rl_outstream);
#else
tputs (term_cr, 1, _rl_output_character_function);
#endif
_rl_last_c_pos = 0;
}
else
{
#ifdef __MSDOS__
int row, col;
i = fflush (rl_outstream);
ScreenGetCursor (&row, &col);
ScreenSetCursor ((row + to - _rl_last_v_pos), col);
delta = i;
#else
if (term_up && *term_up)
for (i = 0; i < -delta; i++)
tputs (term_up, 1, _rl_output_character_function);
#endif
}
_rl_last_v_pos = to;
}
int
rl_show_char (c)
int c;
{
int n = 1;
if (META_CHAR (c) && (_rl_output_meta_chars == 0))
{
fprintf (rl_outstream, "M-");
n += 2;
c = UNMETA (c);
}
#if defined (DISPLAY_TABS)
if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
#else
if (CTRL_CHAR (c) || c == RUBOUT)
#endif
{
fprintf (rl_outstream, "C-");
n += 2;
c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
}
putc (c, rl_outstream);
fflush (rl_outstream);
return n;
}
int
rl_character_len (c, pos)
register int c, pos;
{
unsigned char uc;
uc = (unsigned char)c;
if (META_CHAR (uc))
return ((_rl_output_meta_chars == 0) ? 4 : 1);
if (uc == '\t')
{
#if defined (DISPLAY_TABS)
return (((pos | 7) + 1) - pos);
#else
return (2);
#endif
}
if (CTRL_CHAR (c) || c == RUBOUT)
return (2);
return ((isprint (uc)) ? 1 : 2);
}
#if defined (USE_VARARGS)
int
#if defined (PREFER_STDARG)
rl_message (const char *format, ...)
#else
rl_message (va_alist)
va_dcl
#endif
{
va_list args;
#if defined (PREFER_VARARGS)
char *format;
#endif
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
format = va_arg (args, char *);
#endif
vsprintf (msg_buf, format, args);
va_end (args);
rl_display_prompt = msg_buf;
(*rl_redisplay_function) ();
return 0;
}
#else
int
rl_message (format, arg1, arg2)
char *format;
{
sprintf (msg_buf, format, arg1, arg2);
rl_display_prompt = msg_buf;
(*rl_redisplay_function) ();
return 0;
}
#endif
int
rl_clear_message ()
{
rl_display_prompt = rl_prompt;
(*rl_redisplay_function) ();
return 0;
}
int
rl_reset_line_state ()
{
rl_on_new_line ();
rl_display_prompt = rl_prompt ? rl_prompt : "";
forced_display = 1;
return 0;
}
static char *saved_local_prompt;
static char *saved_local_prefix;
static int saved_last_invisible;
static int saved_visible_length;
void
rl_save_prompt ()
{
saved_local_prompt = local_prompt;
saved_local_prefix = local_prompt_prefix;
saved_last_invisible = last_invisible;
saved_visible_length = visible_length;
local_prompt = local_prompt_prefix = (char *)0;
last_invisible = visible_length = 0;
}
void
rl_restore_prompt ()
{
if (local_prompt)
free (local_prompt);
if (local_prompt_prefix)
free (local_prompt_prefix);
local_prompt = saved_local_prompt;
local_prompt_prefix = saved_local_prefix;
last_invisible = saved_last_invisible;
visible_length = saved_visible_length;
}
char *
_rl_make_prompt_for_search (pchar)
int pchar;
{
int len;
char *pmt;
rl_save_prompt ();
if (saved_local_prompt == 0)
{
len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
pmt = xmalloc (len + 2);
if (len)
strcpy (pmt, rl_prompt);
pmt[len] = pchar;
pmt[len+1] = '\0';
}
else
{
len = *saved_local_prompt ? strlen (saved_local_prompt) : 0;
pmt = xmalloc (len + 2);
if (len)
strcpy (pmt, saved_local_prompt);
pmt[len] = pchar;
pmt[len+1] = '\0';
local_prompt = savestring (pmt);
last_invisible = saved_last_invisible;
visible_length = saved_visible_length + 1;
}
return pmt;
}
void
_rl_erase_at_end_of_line (l)
int l;
{
register int i;
_rl_backspace (l);
for (i = 0; i < l; i++)
putc (' ', rl_outstream);
_rl_backspace (l);
for (i = 0; i < l; i++)
visible_line[--_rl_last_c_pos] = '\0';
rl_display_fixed++;
}
void
_rl_clear_to_eol (count)
int count;
{
#ifndef __MSDOS__
if (term_clreol)
tputs (term_clreol, 1, _rl_output_character_function);
else
#endif
if (count)
space_to_eol (count);
}
static void
space_to_eol (count)
int count;
{
register int i;
for (i = 0; i < count; i++)
putc (' ', rl_outstream);
_rl_last_c_pos += count;
}
void
_rl_clear_screen ()
{
#if defined (__GO32__)
ScreenClear ();
ScreenSetCursor (0, 0);
#else
if (term_clrpag)
tputs (term_clrpag, 1, _rl_output_character_function);
else
crlf ();
#endif
}
static void
insert_some_chars (string, count)
char *string;
int count;
{
#ifdef __MSDOS__
_rl_output_some_chars (string, count);
#else
if (term_IC)
{
char *buffer;
buffer = tgoto (term_IC, 0, count);
tputs (buffer, 1, _rl_output_character_function);
_rl_output_some_chars (string, count);
}
else
{
register int i;
if (term_im && *term_im)
tputs (term_im, 1, _rl_output_character_function);
if (term_ic && *term_ic)
{
for (i = count; i--; )
tputs (term_ic, 1, _rl_output_character_function);
}
_rl_output_some_chars (string, count);
if (term_ei && *term_ei)
tputs (term_ei, 1, _rl_output_character_function);
}
#endif
}
static void
delete_chars (count)
int count;
{
if (count > screenwidth)
return;
#ifndef __MSDOS__
if (term_DC && *term_DC)
{
char *buffer;
buffer = tgoto (term_DC, count, count);
tputs (buffer, count, _rl_output_character_function);
}
else
{
if (term_dc && *term_dc)
while (count--)
tputs (term_dc, 1, _rl_output_character_function);
}
#endif
}
void
_rl_update_final ()
{
int full_lines;
full_lines = 0;
if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
{
_rl_vis_botlin--;
full_lines = 1;
}
_rl_move_vert (_rl_vis_botlin);
if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == screenwidth))
{
char *last_line;
#if 0
last_line = &visible_line[inv_lbreaks[_rl_vis_botlin]];
#else
last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
#endif
_rl_move_cursor_relative (screenwidth - 1, last_line);
_rl_clear_to_eol (0);
putc (last_line[screenwidth - 1], rl_outstream);
}
_rl_vis_botlin = 0;
crlf ();
fflush (rl_outstream);
rl_display_fixed++;
}
static void
cr ()
{
if (term_cr)
{
#if defined (__MSDOS__)
putc ('\r', rl_outstream);
#else
tputs (term_cr, 1, _rl_output_character_function);
#endif
_rl_last_c_pos = 0;
}
}
static void
redraw_prompt (t)
char *t;
{
char *oldp, *oldl, *oldlprefix;
int oldlen, oldlast, oldplen;
oldp = rl_display_prompt;
oldl = local_prompt;
oldlprefix = local_prompt_prefix;
oldlen = visible_length;
oldplen = prefix_length;
oldlast = last_invisible;
rl_display_prompt = t;
local_prompt = expand_prompt (t, &visible_length, &last_invisible);
local_prompt_prefix = (char *)NULL;
rl_forced_update_display ();
rl_display_prompt = oldp;
local_prompt = oldl;
local_prompt_prefix = oldlprefix;
visible_length = oldlen;
prefix_length = oldplen;
last_invisible = oldlast;
}
void
_rl_redisplay_after_sigwinch ()
{
char *t;
if (term_cr)
{
#if defined (__MSDOS__)
putc ('\r', rl_outstream);
#else
tputs (term_cr, 1, _rl_output_character_function);
#endif
_rl_last_c_pos = 0;
#if defined (__MSDOS__)
space_to_eol (screenwidth);
putc ('\r', rl_outstream);
#else
if (term_clreol)
tputs (term_clreol, 1, _rl_output_character_function);
else
{
space_to_eol (screenwidth);
tputs (term_cr, 1, _rl_output_character_function);
}
#endif
if (_rl_last_v_pos > 0)
_rl_move_vert (0);
}
else
crlf ();
t = strrchr (rl_display_prompt, '\n');
if (t)
redraw_prompt (++t);
else
rl_forced_update_display ();
}
void
_rl_clean_up_for_exit ()
{
if (readline_echoing_p)
{
_rl_move_vert (_rl_vis_botlin);
_rl_vis_botlin = 0;
fflush (rl_outstream);
rl_restart_output (1, 0);
}
}
void
_rl_erase_entire_line ()
{
cr ();
_rl_clear_to_eol (0);
cr ();
fflush (rl_outstream);
}
int
_rl_current_display_line ()
{
int ret, nleft;
if (rl_display_prompt == rl_prompt)
nleft = _rl_last_c_pos - screenwidth - rl_visible_prompt_length;
else
nleft = _rl_last_c_pos - screenwidth;
if (nleft > 0)
ret = 1 + nleft / screenwidth;
else
ret = 0;
return ret;
}