home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
CMDS
/
beav.1.40.lzh
/
BEAV140
/
search.c
< prev
next >
Wrap
Text File
|
1995-06-14
|
25KB
|
984 lines
/*
* Search commands.
* The functions in this file implement the
* search commands (both plain and incremental searches
* are supported) and the query-replace command.
*/
#include "def.h"
char replaceit ();
char forwsrch ();
char backsrch ();
char readpattern ();
void next_pat ();
extern char MSG_sch_str[];
extern char MSG_bsrc_str[];
extern char MSG_rpl_str[];
extern char MSG_pat_fnd[];
extern char MSG_no_srch[];
extern char MSG_fnd_at[];
extern char MSG_no_rpl[];
extern char MSG_1_rpl[];
extern char MSG_n_rpl[];
extern char MSG_srcing[];
extern char MSG_curs[];
extern char MSG_cmp_end[];
extern char MSG_cmp_term[];
extern char MSG_cmp_dif[];
extern char MSG_only_2[];
extern char MSG_cmping[];
extern char MSG_not_fnd[];
#if RUNCHK
extern char ERR_rdpat[];
extern char ERR_mask[];
extern char ERR_m_cl[];
#endif
#define CCHR(x) ((x)-'@')
#define SRCH_BEGIN (0) /* Search sub-codes. */
#define SRCH_FORW (-1)
#define SRCH_BACK (-2)
#define SRCH_PREV (-3)
#define SRCH_NEXT (-4)
#define SRCH_NOPR (-5)
#define SRCH_ACCM (-6)
typedef struct
{
int s_code;
LINE *s_dotp;
short s_doto;
} SRCHCOM;
#define MAX_PAT 260
extern ROW_FMT hex_s_8_fmt;
extern ROW_FMT ascii_s_fmt;
bool recall_flag = FALSE;
bool read_pat_mode = FALSE;
bool srch_mode = FALSE;
bool rplc_mode = FALSE;
bool dont_repeat = FALSE; /* used to prevent toggling commands from */
/* failing in read_pattern */
static char srch_patb[MAX_PAT];
static char srch_maskb[MAX_PAT];
static char rplc_patb[MAX_PAT];
static char rplc_maskb[MAX_PAT];
static LINE *srch_pat = (LINE *) srch_patb;
static LINE *srch_mask = (LINE *) srch_maskb;
static LINE *cur_pat;
static LINE *cur_mask;
static LINE *rplc_pat = (LINE *) rplc_patb;
static LINE *rplc_mask = (LINE *) rplc_maskb;
static int old_srch_pat_size = 0; /* for pattern recall */
static int old_rplc_pat_size = 0;
static ROW_FMT *old_fmt = &hex_s_8_fmt;
char *cur_prompt;
int srch_lastdir = SRCH_NOPR; /* Last search flags. */
/*
* Search forward.
* Get a search string from the user, and search for it,
* starting at ".". If found, "." gets moved to the
* first matched character, and display does all the hard stuff.
* If not found, it just prints a message.
*/
char
forwsearch ()
{
register char s;
char buf[NCOL], buf1[NCOL];
srch_mode = TRUE;
rplc_mode = FALSE;
cur_prompt = MSG_sch_str;
if ((s = readpattern ()) != TRUE)
{
srch_mode = FALSE;
eerase (); /* clear message line */
return (s);
}
if (forwsrch () == FALSE)
{
writ_echo (MSG_not_fnd);
srch_mode = FALSE;
return (FALSE);
}
srch_lastdir = SRCH_FORW;
curwp->w_flag |= WFMODE; /* update mode line */
curwp->w_unit_offset = 0;
/* build format */
sprintf (buf1, MSG_pat_fnd, R_POS_FMT (curwp));
sprintf (buf, buf1, curwp->w_dotp->l_file_offset +
curwp->w_doto);
writ_echo (buf);
srch_mode = FALSE;
return (TRUE);
}
/*
* Reverse search.
* Get a search string from the user, and search, starting at "."
* and proceeding toward the front of the buffer. If found "." is left
* pointing at the first character of the pattern [the last character that
* was matched].
*/
char
backsearch ()
{
register char s;
char buf[NCOL], buf1[NCOL];
srch_mode = TRUE;
rplc_mode = FALSE;
cur_prompt = MSG_bsrc_str;
if ((s = readpattern ()) != TRUE)
{
srch_mode = FALSE;
eerase (); /* clear message line */
return (s);
}
if (backsrch () == FALSE)
{
writ_echo (MSG_not_fnd);
srch_mode = FALSE;
return (FALSE);
}
srch_lastdir = SRCH_BACK;
curwp->w_flag |= WFMODE; /* update mode line */
curwp->w_unit_offset = 0;
sprintf (buf1, MSG_pat_fnd, R_POS_FMT (curwp));
sprintf (buf, buf1, curwp->w_dotp->l_file_offset +
curwp->w_doto);
writ_echo (buf);
srch_mode = FALSE;
return (TRUE);
}
/*
* Search again, using the same search string
* and direction as the last search command. The direction
* has been saved in "srch_lastdir", so you know which way
* to go.
*/
char
searchagain ()
{
char buf[NCOL], buf1[NCOL];
long dot_pos;
srch_mode = TRUE;
rplc_mode = FALSE;
dot_pos = DOT_POS (curwp);
if (srch_lastdir == SRCH_FORW)
{
/* advance one unit so we don't find the same thing again */
move_ptr (curwp, dot_pos + 1, TRUE, FALSE, FALSE);
if (forwsrch () == FALSE)
{ /* go back to orig pt */
move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE);
writ_echo (MSG_not_fnd);
srch_mode = FALSE;
return (FALSE);
}
curwp->w_flag |= WFMODE;/* update mode line */
curwp->w_unit_offset = 0;
sprintf (buf1, MSG_pat_fnd, R_POS_FMT (curwp));
sprintf (buf, buf1, curwp->w_dotp->l_file_offset +
curwp->w_doto);
writ_echo (buf);
srch_mode = FALSE;
return (TRUE);
}
if (srch_lastdir == SRCH_BACK)
{
/* step back one unit so we don't find the same thing again */
move_ptr (curwp, dot_pos - 1, TRUE, FALSE, FALSE);
if (backsrch () == FALSE)
{ /* go back to orig pt */
move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE);
writ_echo (MSG_not_fnd);
srch_mode = FALSE;
return (FALSE);
}
curwp->w_flag |= WFMODE;/* update mode line */
curwp->w_unit_offset = 0;
sprintf (buf1, MSG_pat_fnd, R_POS_FMT (curwp));
sprintf (buf, buf1, curwp->w_dotp->l_file_offset +
curwp->w_doto);
writ_echo (buf);
srch_mode = FALSE;
return (TRUE);
}
writ_echo (MSG_no_srch);
srch_mode = FALSE;
return (FALSE);
}
/*
* Query Replace.
* Replace strings selectively. Does a search and replace operation.
* A space or a comma replaces the string, a period replaces and quits,
* an n doesn't replace, a C-G quits.
* (note typical hack to add a function with minimal code)
*/
char
queryrepl (f, n, k)
int f, n, k;
{
register char s;
srch_mode = FALSE;
rplc_mode = TRUE;
cur_prompt = MSG_sch_str;
if (s = readpattern ())
{
replaceit ();
}
srch_mode = FALSE;
rplc_mode = FALSE;
return (s);
}
char
replaceit ()
{
int rcnt = 0; /* Replacements made so far */
int plen; /* length of found string */
int rlen; /* length of replace string */
long abs_dot_p; /* absolute dot position */
long abs_mark_p; /* absolute mark position */
char buf[NCOL], buf1[NCOL];
/*
* Search forward repeatedly, checking each time whether to insert
* or not. The "!" case makes the check always true, so it gets put
* into a tighter loop for efficiency.
*
* If we change the line that is the remembered value of dot, then
* it is possible for the remembered value to move. This causes great
* pain when trying to return to the non-existant line.
*
* possible fixes:
* 1) put a single, relocated marker in the WINDOW structure, handled
* like mark. The problem now becomes a what if two are needed...
* 2) link markers into a list that gets updated (auto structures for
* the nodes)
* 3) Expand the mark into a stack of marks and add pushmark, popmark.
*/
plen = srch_pat->l_used;
rlen = rplc_pat->l_used;
abs_dot_p = DOT_POS (curwp);/* save current dot position */
if (curwp->w_markp != NULL) /* mark may not be set */
abs_mark_p = MARK_POS (curwp);
while (forwsrch () == TRUE)
{
retry:
sprintf (buf1, MSG_fnd_at, R_POS_FMT (curwp));
sprintf (buf, buf1, DOT_POS (curwp));
writ_echo (buf);
curwp->w_flag |= WFMODE;/* update mode line */
update ();
switch (ttgetc ())
{
case 'r':
case 'R':
case ' ':
case ',':
/* update has fixedup the dot position so move to found byte */
/* go and do the replace */
if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
return (FALSE);
/* begin searching after replace string */
move_ptr (curwp, (long) rlen, TRUE, FALSE, TRUE);
rcnt++;
break;
case 'o':
case 'O':
case '.':
if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
return (FALSE);
/* begin searching after replace string */
move_ptr (curwp, (long) rlen, TRUE, FALSE, TRUE);
rcnt++;
goto stopsearch;
case 'q':
case 'Q':
case CCHR ('G'):
ctrlg (FALSE, 0, KRANDOM);
goto stopsearch;
case 'a':
case 'A':
case '!':
do
{
if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
return (FALSE);
/* begin searching after replace string */
move_ptr (curwp, (long) rlen, TRUE, FALSE, TRUE);
rcnt++;
}
while (forwsrch () == TRUE);
goto stopsearch;
case 's':
case 'S':
case 'n':
/* begin searching after this byte */
move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
break;
default:
ttbeep ();
goto retry;
}
}
stopsearch:
move_ptr (curwp, abs_dot_p, TRUE, TRUE, FALSE);
if (curwp->w_markp != NULL)
{
swapmark ();
/* insure that the mark points to the same byte as before */
if (abs_mark_p > abs_dot_p)
move_ptr (curwp, abs_mark_p + rlen - plen, TRUE, FALSE, FALSE);
else
move_ptr (curwp, abs_mark_p, TRUE, FALSE, FALSE);
swapmark ();
}
curwp->w_flag |= WFHARD;
update ();
if (rcnt == 0)
{
writ_echo (MSG_no_rpl);
}
else if (rcnt == 1)
{
writ_echo (MSG_1_rpl);
}
else
{
sprintf (buf1, MSG_n_rpl, R_POS_FMT (curwp));
sprintf (buf, buf1, (ulong) rcnt);
writ_echo (buf);
}
flush_count += rcnt; /* jam for auto write buffers */
return (TRUE);
}
/*
* This routine does the real work of a
* forward search. The pattern is sitting in the external
* variable "srch_pat" the mask if in "srch_mask".
* If found, dot is updated, the window system
* is notified of the change, and TRUE is returned. If the
* string isn't found, FALSE is returned.
*/
char
forwsrch ()
{
register LINE *save_dotp, *save2_dotp;
register int save_doto, save2_doto;
register D8 *pat_ptr, *mask_ptr;
register int i, j, pat_cnt;
register D8 first_pat, first_mask;
char buf[NCOL], buf1[NCOL];
save_dotp = curwp->w_dotp; /* save dot position for later */
save_doto = curwp->w_doto;
pat_ptr = srch_pat->l_text;
mask_ptr = srch_mask->l_text;
pat_cnt = srch_pat->l_used;
first_mask = mask_ptr[0];
first_pat = pat_ptr[0] | first_mask;
j = (int) DOT_POS (curwp) & 0xffff;
do
{
if ((j++ & 0x2ff) == 0)
{
sprintf (buf1, MSG_srcing, R_POS_FMT (curwp));
sprintf (buf, buf1, DOT_POS (curwp));
writ_echo (buf);
/* check if we should quit */
if (ttkeyready ())
{
if (ttgetc () == CTL_G)
break;
}
}
if (first_pat ==
((DOT_CHAR (curwp) | first_mask) & 0xff))
{
save2_dotp = curwp->w_dotp; /* save dot position for later */
save2_doto = curwp->w_doto;
for (i = 1; i < pat_cnt; i++)
{
if (!move_ptr (curwp, 1L, TRUE, FALSE, TRUE) ||
((pat_ptr[i] & ~mask_ptr[i]) !=
(DOT_CHAR (curwp) & ~mask_ptr[i])))
{ /* not found */
curwp->w_dotp = save2_dotp; /* restore dot position */
curwp->w_doto = save2_doto;
break;
}
}
if (i == pat_cnt) /* found */
{ /* move back to the first matching unit */
move_ptr (curwp, -(long) pat_cnt + 1, TRUE, FALSE, TRUE);
wind_on_dot (curwp);
return (TRUE);
}
}
}
while (move_ptr (curwp, 1L, TRUE, FALSE, TRUE));
curwp->w_dotp = save_dotp; /* restore dot position */
curwp->w_doto = save_doto;
return (FALSE);
}
/*
* This routine does the real work of a
* backward search. The pattern is sitting in the external
* variable "srch_pat". If found, dot is updated, the window system
* is notified of the change, and TRUE is returned. If the
* string isn't found, FALSE is returned.
*/
char
backsrch ()
{
register LINE *save_dotp, *save_p;
register LPOS save_doto, save_o;
register D8 *pat_ptr, *mask_ptr;
register int i, j, pat_cnt;
register char first_pat, first_mask;
char buf[NCOL], buf1[NCOL];
save_dotp = curwp->w_dotp; /* save dot position for later */
save_doto = curwp->w_doto;
pat_ptr = srch_pat->l_text;
mask_ptr = srch_mask->l_text;
pat_cnt = srch_pat->l_used;
first_mask = mask_ptr[0];
first_pat = pat_ptr[0] | first_mask;
j = (int) DOT_POS (curwp) & 0xffff;
do
{
/* check if we should quit */
if (ttkeyready ())
{
if (ttgetc () == CTL_G)
break;
}
if ((j-- & 0x2ff) == 0)
{
sprintf (buf1, MSG_srcing, R_POS_FMT (curwp));
sprintf (buf, buf1, DOT_POS (curwp));
writ_echo (buf);
}
if (first_pat ==
(curwp->w_dotp->l_text[curwp->w_doto] | first_mask))
{
save_p = curwp->w_dotp;
save_o = curwp->w_doto;
for (i = 1; i < pat_cnt; i++)
{
if (!move_ptr (curwp, 1L, TRUE, FALSE, TRUE) ||
((pat_ptr[i] & ~mask_ptr[i]) !=
(DOT_CHAR (curwp) & ~mask_ptr[i])))
{ /* not found */
curwp->w_dotp = save_p; /* restore ptr to continue */
curwp->w_doto = save_o;
break;
}
}
if (i == pat_cnt) /* found */
{ /* move back to the first matching unit */
move_ptr (curwp, -(long) pat_cnt + 1, TRUE, FALSE, TRUE);
wind_on_dot (curwp);
return (TRUE);
}
}
}
while (move_ptr (curwp, -1L, TRUE, FALSE, TRUE));
curwp->w_dotp = save_dotp; /* restore dot position */
curwp->w_doto = save_doto;
return (FALSE);
}
/*
* Read a pattern.
* Display and edit in the form of the current window.
* Slide the displayed line back and forth when the cursor hits a boundary.
* Manage the mask buffer. When a '*' (wild card) is entered mask all
* bits in that unit and display all '?'s.
*/
char
readpattern ()
{
int cod, mask_cod, curs_pos, curs_pos1, prt_siz, i, doto, loff;
WINDOW srch_wind, *save_wind;
BUFFER srch_buf, *save_buf;
LINE head_line;
int r_type, siz_prompt2, u_off;
bool first_time, stat;
char disp_buf[180], mask_buf[180], buf1[NCOL];
save_wind = curwp; /* save current window for later */
save_buf = curbp; /* save current buffer for later */
curwp = &srch_wind; /* search window is current window during
search */
curbp = &srch_buf;
cur_pat = srch_pat; /* set global variables for LINE finctions */
cur_mask = srch_mask;
recall_flag = FALSE;
first_time = TRUE;
read_pat_mode = TRUE;
curwp->w_wndp = NULL;
curwp->w_bufp = curbp;
curwp->w_linep = cur_pat;
curwp->w_loff = 0;
curwp->w_dotp = cur_pat;
curwp->w_doto = 0;
curwp->w_unit_offset = 0;
curwp->w_toprow = 24;
curwp->w_ntrows = 1;
curwp->w_intel_mode = save_wind->w_intel_mode;
curwp->w_disp_shift = 0;
if (R_TYPE (save_wind) == TEXT)
curwp->w_fmt_ptr = &ascii_s_fmt;
else
curwp->w_fmt_ptr = save_wind->w_fmt_ptr->r_srch_fmt;
srch_buf.b_bufp = NULL;
srch_buf.b_linep = &head_line;
srch_buf.b_unit_offset = 0; /* unit offset pvr */
srch_buf.b_markp = NULL;
srch_buf.b_marko = 0;
srch_buf.b_flag = 0;
srch_buf.b_nwnd = 1;
srch_buf.b_fname[0] = 0;
srch_buf.b_bname[0] = 0;
head_line.l_fp = cur_pat;
head_line.l_bp = cur_pat;
head_line.l_file_offset = 0;/* pvr */
head_line.l_used = 0;
head_line.l_size = 0;
cur_pat->l_fp = &head_line;
cur_pat->l_bp = &head_line;
cur_pat->l_size = 266; /* leave some extra past 256 */
cur_pat->l_used = 0;
cur_pat->l_file_offset = 0;
cur_mask->l_fp = &head_line;
cur_mask->l_bp = &head_line;
cur_mask->l_size = 266; /* leave some extra past 256 */
cur_mask->l_used = 0;
cur_mask->l_file_offset = 0;
rplc_pat->l_fp = &head_line;
rplc_pat->l_bp = &head_line;
rplc_pat->l_size = 266; /* leave some extra past 256 */
rplc_pat->l_used = 0;
rplc_pat->l_file_offset = 0;
rplc_mask->l_fp = &head_line;
rplc_mask->l_bp = &head_line;
rplc_mask->l_size = 266; /* leave some extra past 256 */
rplc_mask->l_used = 0;
rplc_mask->l_file_offset = 0;
sprintf (buf1, MSG_curs, cur_prompt, R_BYTE_FMT (curwp),
R_BYTE_FMT (curwp), R_BYTE_FMT (curwp));
sprintf (disp_buf, buf1, curwp->w_doto,
curwp->w_fmt_ptr->r_chr_per_u - curwp->w_unit_offset - 1,
curwp->w_dotp->l_used);
siz_prompt2 = strlen (disp_buf); /* save prompt length for later */
for (i = siz_prompt2; i < NCOL; i++) /* clear rest of buffer */
disp_buf[i] = ' ';
writ_echo (disp_buf);
r_type = R_TYPE (curwp);
while (TRUE)
{
/* position cursor */
curs_pos = curwp->w_doto - curwp->w_loff;
if (curwp->w_fmt_ptr->r_size == 1)
{
curs_pos = curs_pos >> 1;
}
else if (curwp->w_fmt_ptr->r_size == 3)
{
curs_pos = curs_pos >> 2;
}
curs_pos1 = curwp->w_fmt_ptr->r_positions[curs_pos] +
curwp->w_unit_offset + siz_prompt2;
ttmove (nrow - 1, curs_pos1);
ttflush ();
cod = getkey ();
if (cod == 0x014D || cod == 0x014A) /* check for return or linefeed */
{
if ((rplc_mode == TRUE) && (cur_prompt == MSG_sch_str))
{
next_pat ();
dont_repeat = FALSE; /* fix up */
goto next_loop;
}
else
{
old_srch_pat_size = srch_pat->l_used; /* save for restore */
if (rplc_mode == TRUE)
old_rplc_pat_size = rplc_pat->l_used;
old_fmt = curwp->w_fmt_ptr;
curwp = save_wind; /* restore current window */
curbp = save_buf; /* restore current buffer */
read_pat_mode = FALSE;
return (TRUE);
}
}
if ((cod >= ' ') && (cod < 0x7f))
{
if ((r_type == ASCII) || (r_type == EBCDIC))
{
mask_cod = '9'; /* use 9 as dummy char that will get through */
}
else if ((r_type == DECIMAL) || (r_type == FLOAT))
{
mask_cod = '0'; /* clear mask byte */
}
else if (cod == '?')
{
cod = '0';
switch (r_type)
{
case OCTAL:
if (curwp->w_unit_offset == 0) /* if first char */
{
if (R_SIZE (curwp) == WORDS)
mask_cod = '1';
else
mask_cod = '3';
}
else
mask_cod = '7';
break;
case HEX:
mask_cod = 'F';
break;
case BINARY:
mask_cod = '1';
break;
#if RUNCHK
default:
printf (ERR_rdpat);
break;
#endif
}
}
else
{
mask_cod = '0';
}
}
else
mask_cod = cod; /* must be control; do the same to the mask */
/* save current dot and window positions */
doto = curwp->w_doto;
u_off = curwp->w_unit_offset;
loff = curwp->w_loff;
stat = execute (cod, FALSE, 1);
if (stat == ABORT)
{
old_srch_pat_size = srch_pat->l_used; /* save for restore */
if (rplc_mode == TRUE)
old_rplc_pat_size = rplc_pat->l_used;
old_fmt = curwp->w_fmt_ptr;
curwp = save_wind; /* restore current window */
curbp = save_buf; /* restore current buffer */
read_pat_mode = FALSE;
return (FALSE);
}
/* If key is recall then reset the size variables */
if (first_time)
{
first_time = FALSE;
if (recall_flag)
{
srch_pat->l_used = old_srch_pat_size;
srch_mask->l_used = old_srch_pat_size;
rplc_pat->l_used = old_rplc_pat_size;
rplc_mask->l_used = old_rplc_pat_size;
curwp->w_fmt_ptr = old_fmt;
recall_flag = FALSE;
}
}
/* if it was a toggling command, don't do it again */
if (!dont_repeat &&
(stat == TRUE))
{
head_line.l_fp = cur_mask; /* point to mask */
head_line.l_bp = cur_mask;
curwp->w_linep = cur_mask;
curwp->w_dotp = cur_mask;
curwp->w_loff = loff;
curwp->w_doto = doto;
curwp->w_unit_offset = u_off;
execute (mask_cod, FALSE, 1);
head_line.l_fp = cur_pat; /* restore pointers */
head_line.l_bp = cur_pat;
curwp->w_linep = cur_pat;
curwp->w_dotp = cur_pat;
}
else
dont_repeat = FALSE;
/* limit at 256 bytes */
if (cur_pat->l_used >= 256)
{
cur_mask->l_used = 255;
cur_pat->l_used = 255;
if (curwp->w_doto >= 256)
{
move_ptr (curwp, 255L, TRUE, TRUE, FALSE); /* last position */
}
}
/* if buffer is size locked then replace pattern must be the */
/* same size as the search pattern */
if (rplc_mode && (save_buf->b_flag & BFSLOCK))
{
rplc_pat->l_used = srch_pat->l_used;
rplc_mask->l_used = srch_pat->l_used;
}
r_type = R_TYPE (curwp);
#if RUNCHK
/* check that the pattern and the mask are the same size */
if (cur_pat->l_used != cur_mask->l_used)
{
printf (ERR_mask, cur_pat->l_used, cur_mask->l_used);
}
/* check that in ascii mode the byte that will be set to zero */
/* is the dummy char 9 */
/* if (((r_type == ASCII) &&
(cur_mask -> l_text[curwp -> w_doto - 1] != '9'))
||
((r_type == EBCDIC) &&
(cur_mask -> l_text[curwp -> w_doto - 1] != to_ebcdic('9'))))
printf (ERR_m_cl);
*/
#endif
if (((r_type == ASCII) ||
(r_type == EBCDIC)) &&
((cod >= ' ') && (cod < 0x7f)))
cur_mask->l_text[doto] = 0; /* clear mask byte */
next_loop:
sprintf (buf1, MSG_curs, cur_prompt, R_BYTE_FMT (curwp),
R_BYTE_FMT (curwp), R_BYTE_FMT (curwp));
sprintf (disp_buf, buf1, curwp->w_doto,
curwp->w_fmt_ptr->r_chr_per_u - curwp->w_unit_offset - 1,
curwp->w_dotp->l_used);
siz_prompt2 = strlen (disp_buf); /* save prompt length for later */
for (i = siz_prompt2; i < NCOL; i++)
{
disp_buf[i] = ' ';
mask_buf[i] = ' ';
}
if ((curbp->b_flag & BFSLOCK) &&
(rplc_pat->l_used != srch_pat->l_used))
{
rplc_pat->l_used = srch_pat->l_used;
/* if dot is past the end then move it back, replace string only */
if (DOT_POS (curwp) > srch_pat->l_used)
move_ptr (curwp, (long) srch_pat->l_used, TRUE, TRUE, FALSE);
}
wind_on_dot (curwp);
/* figure number of bytes to convert to text */
if ((cur_pat->l_used - curwp->w_loff) <
(prt_siz = curwp->w_fmt_ptr->r_bytes))
prt_siz = cur_pat->l_used - curwp->w_loff;
bin_to_text (&cur_pat->l_text[curwp->w_loff],
&disp_buf[siz_prompt2],
prt_siz, curwp->w_fmt_ptr);
/* change any char to a ? if any bit is set in the mask buffer */
if ((r_type != ASCII) && (r_type != EBCDIC))
{
/* print the contents of the mask to a invisible buffer */
bin_to_text (&cur_mask->l_text[curwp->w_loff],
&mask_buf[siz_prompt2],
prt_siz, curwp->w_fmt_ptr);
for (i = siz_prompt2; (disp_buf[i] != 0) && (i < NCOL); i++)
{
if ((mask_buf[i] != '0') &&
(mask_buf[i] != ' '))
disp_buf[i] = '?';
}
}
else
{
for (i = 0; i < prt_siz; i++)
{
if (cur_mask->l_text[curwp->w_loff + i] != 0)
disp_buf[i + siz_prompt2] = '?';
}
}
writ_echo (disp_buf);
}
}
/*
* Recall the last contents of the search string
*/
bool
recall ()
{
recall_flag = TRUE;
return (TRUE);
}
/*
* Switch between search pattern and replace pattern and their
* respective masks
*/
void
next_pat ()
{
if (cur_pat == srch_pat)
{
cur_prompt = MSG_rpl_str;
cur_pat = rplc_pat; /* point to replace pattern */
cur_mask = rplc_mask;
}
else
{
cur_prompt = MSG_sch_str;
cur_pat = srch_pat; /* point to search pattern */
cur_mask = srch_mask;
}
curwp->w_dotp = cur_pat;
curwp->w_linep = cur_pat;
curbp->b_linep->l_fp = cur_pat;
curbp->b_linep->l_bp = cur_pat;
if (curwp->w_doto > cur_pat->l_used)
{
curwp->w_doto = cur_pat->l_used;
curwp->w_unit_offset = 0;
}
if (curwp->w_loff > cur_pat->l_used)
curwp->w_loff = cur_pat->l_used;
dont_repeat = TRUE;
}
/*
* Compare the contents of two windows.
* There must be exactly two windows displayed.
* The bytes under the cursor in each window are compared and if
* a difference is found then the loop is stopped with the dot
* position in each window pointing to the difference.
* The two windows can be pointing at the same or different buffers.
*/
bool
compare ()
{
WINDOW *wp1, *wp2;
bool move1, move2;
int j;
char *term_str = MSG_cmp_dif;
char buf[NCOL], buf1[NCOL];
if (wheadp->w_wndp->w_wndp != NULL)
{
writ_echo (MSG_only_2);
return (FALSE);
}
wp1 = wheadp;
wp2 = wheadp->w_wndp;
j = (int) DOT_POS (curwp) & 0xffff;
wp1->w_flag |= WFMOVE;
wp2->w_flag |= WFMOVE;
while (DOT_CHAR (wp1) == DOT_CHAR (wp2))
{
if ((j++ & 0xff) == 0)
{
sprintf (buf1, MSG_cmping, R_POS_FMT (curwp));
sprintf (buf, buf1, DOT_POS (curwp));
writ_echo (buf);
/* check if we should quit */
if (ttkeyready ())
{
if (ttgetc () == CTL_G)
{
term_str = MSG_cmp_term;
break;
}
}
}
move1 = move_ptr (wp1, 1L, TRUE, FALSE, TRUE);
move2 = move_ptr (wp2, 1L, TRUE, FALSE, TRUE);
if (!(move1 && move2))
{
term_str = MSG_cmp_end;
break;
}
}
writ_echo (term_str);
wind_on_dot (wp1);
wind_on_dot (wp2);
return (TRUE);
}