BEAV, a full featured binary file editor, part 08 of 11
Peter Reilley
pvr at wang.com
Thu Feb 28 07:53:03 AEST 1991
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 8 (of 11)."
# Contents: search.c
# Wrapped by pvr at elf on Wed Feb 27 14:16:50 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'search.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'search.c'\"
else
echo shar: Extracting \"'search.c'\" \(30053 characters\)
sed "s/^X//" >'search.c' <<'END_OF_FILE'
X/*
X* Search commands.
X* The functions in this file implement the
X* search commands (both plain and incremental searches
X* are supported) and the query-replace command.
X*/
X#include "def.h"
X
Xchar replaceit ();
Xchar forwsrch ();
Xchar backsrch ();
Xchar readpattern ();
Xvoid next_pat ();
X
Xextern char MSG_sch_str[];
Xextern char MSG_bsrc_str[];
Xextern char MSG_rpl_str[];
Xextern char MSG_pat_fnd[];
Xextern char MSG_no_srch[];
Xextern char MSG_fnd_at[];
Xextern char MSG_no_rpl[];
Xextern char MSG_1_rpl[];
Xextern char MSG_n_rpl[];
Xextern char MSG_srcing[];
Xextern char MSG_curs[];
Xextern char MSG_cmp_end[];
Xextern char MSG_cmp_term[];
Xextern char MSG_cmp_dif[];
Xextern char MSG_only_2[];
Xextern char MSG_cmping[];
Xextern char MSG_not_fnd[];
X#if RUNCHK
Xextern char ERR_rdpat[];
Xextern char ERR_mask[];
Xextern char ERR_m_cl[];
X#endif
X
X#include "lintfunc.dec"
X#define CCHR(x) ((x)-'@')
X
X#define SRCH_BEGIN (0) /* Search sub-codes. */
X#define SRCH_FORW (-1)
X#define SRCH_BACK (-2)
X#define SRCH_PREV (-3)
X#define SRCH_NEXT (-4)
X#define SRCH_NOPR (-5)
X#define SRCH_ACCM (-6)
X
Xtypedef struct
X{
X int s_code;
X LINE * s_dotp;
X short s_doto;
X}SRCHCOM;
X
X#define MAX_PAT 260
X
Xextern ROW_FMT hex_s_8_fmt;
Xextern ROW_FMT ascii_s_fmt;
X
Xbool recall_flag = FALSE;
Xbool read_pat_mode = FALSE;
Xbool srch_mode = FALSE;
Xbool rplc_mode = FALSE;
Xbool dont_repeat = FALSE; /* used to prevent toggling commands from */
X /* failing in read_pattern */
Xstatic char srch_patb[MAX_PAT];
Xstatic char srch_maskb[MAX_PAT];
Xstatic char rplc_patb[MAX_PAT];
Xstatic char rplc_maskb[MAX_PAT];
X
Xstatic LINE *srch_pat = (LINE *)srch_patb;
Xstatic LINE *srch_mask = (LINE *)srch_maskb;
Xstatic LINE *cur_pat;
Xstatic LINE *cur_mask;
Xstatic LINE *rplc_pat = (LINE *)rplc_patb;
Xstatic LINE *rplc_mask = (LINE *)rplc_maskb;
X
Xstatic int old_srch_pat_size = 0;/* for pattern recall */
Xstatic int old_rplc_pat_size = 0;
Xstatic ROW_FMT *old_fmt = &hex_s_8_fmt;
X
X char *cur_prompt;
X
Xstatic SRCHCOM cmds[NSRCH];
Xstatic int cip;
X
Xint srch_lastdir = SRCH_NOPR;/* Last search flags. */
X
X/*
X* Search forward.
X* Get a search string from the user, and search for it,
X* starting at ".". If found, "." gets moved to the
X* first matched character, and display does all the hard stuff.
X* If not found, it just prints a message.
X*/
Xchar forwsearch ()
X{
X register char s;
X char buf[80], buf1[30];
X
X srch_mode = TRUE;
X rplc_mode = FALSE;
X cur_prompt = MSG_sch_str;
X if ((s = readpattern ()) != TRUE)
X {
X srch_mode = FALSE;
X eerase (); /* clear message line */
X return (s);
X }
X if (forwsrch () == FALSE)
X {
X writ_echo (MSG_not_fnd);
X srch_mode = FALSE;
X return (FALSE);
X }
X srch_lastdir = SRCH_FORW;
X curwp -> w_flag |= WFMODE; /* update mode line */
X curwp -> w_unit_offset = 0;
X /* build format */
X sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
X sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
X curwp -> w_doto);
X writ_echo (buf);
X srch_mode = FALSE;
X return (TRUE);
X}
X
X
X/*
X* Reverse search.
X* Get a search string from the user, and search, starting at "."
X* and proceeding toward the front of the buffer. If found "." is left
X* pointing at the first character of the pattern [the last character that
X* was matched].
X*/
Xchar backsearch ()
X{
X register char s;
X char buf[80], buf1[30];
X
X srch_mode = TRUE;
X rplc_mode = FALSE;
X cur_prompt = MSG_bsrc_str;
X if ((s = readpattern ()) != TRUE)
X {
X srch_mode = FALSE;
X eerase (); /* clear message line */
X return (s);
X }
X if (backsrch () == FALSE)
X {
X writ_echo (MSG_not_fnd);
X srch_mode = FALSE;
X return (FALSE);
X }
X srch_lastdir = SRCH_BACK;
X curwp -> w_flag |= WFMODE; /* update mode line */
X curwp -> w_unit_offset = 0;
X sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
X sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
X curwp -> w_doto);
X writ_echo (buf);
X srch_mode = FALSE;
X return (TRUE);
X}
X
X
X/*
X* Search again, using the same search string
X* and direction as the last search command. The direction
X* has been saved in "srch_lastdir", so you know which way
X* to go.
X*/
Xchar searchagain ()
X{
X char buf[80], buf1[30];
X long dot_pos;
X srch_mode = TRUE;
X rplc_mode = FALSE;
X
X dot_pos = DOT_POS(curwp);
X if (srch_lastdir == SRCH_FORW)
X {
X /* advance one unit so we don't find the same thing again */
X move_ptr (curwp, dot_pos + 1, TRUE, FALSE, FALSE);
X if (forwsrch () == FALSE)
X { /* go back to orig pt */
X move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE);
X writ_echo (MSG_not_fnd);
X srch_mode = FALSE;
X return (FALSE);
X }
X curwp -> w_flag |= WFMODE; /* update mode line */
X curwp -> w_unit_offset = 0;
X sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
X sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
X curwp -> w_doto);
X writ_echo (buf);
X srch_mode = FALSE;
X return (TRUE);
X }
X if (srch_lastdir == SRCH_BACK)
X {
X /* step back one unit so we don't find the same thing again */
X move_ptr (curwp, dot_pos - 1, TRUE, FALSE, FALSE);
X if (backsrch () == FALSE)
X { /* go back to orig pt */
X move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE);
X writ_echo (MSG_not_fnd);
X srch_mode = FALSE;
X return (FALSE);
X }
X curwp -> w_flag |= WFMODE; /* update mode line */
X curwp -> w_unit_offset = 0;
X sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
X sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
X curwp -> w_doto);
X writ_echo (buf);
X srch_mode = FALSE;
X return (TRUE);
X }
X writ_echo (MSG_no_srch);
X srch_mode = FALSE;
X return (FALSE);
X}
X
X
X/*
X* Query Replace.
X* Replace strings selectively. Does a search and replace operation.
X* A space or a comma replaces the string, a period replaces and quits,
X* an n doesn't replace, a C-G quits.
X* (note typical hack to add a function with minimal code)
X*/
Xchar queryrepl (f, n, k)
X{
X
X register char s;
X
X srch_mode = FALSE;
X rplc_mode = TRUE;
X cur_prompt = MSG_sch_str;
X if (s = readpattern ())
X {
X replaceit ();
X }
X srch_mode = FALSE;
X rplc_mode = FALSE;
X return (s);
X}
X
X
Xchar replaceit ()
X{
X register int s;
X int rcnt = 0; /* Replacements made so far */
X int plen; /* length of found string */
X int rlen; /* length of replace string */
X long abs_dot_p; /* absolute dot position */
X long abs_mark_p; /* absolute mark position */
X char buf[80], buf1[80];
X
X /*
X * Search forward repeatedly, checking each time whether to insert
X * or not. The "!" case makes the check always true, so it gets put
X * into a tighter loop for efficiency.
X *
X * If we change the line that is the remembered value of dot, then
X * it is possible for the remembered value to move. This causes great
X * pain when trying to return to the non-existant line.
X *
X * possible fixes:
X * 1) put a single, relocated marker in the WINDOW structure, handled
X * like mark. The problem now becomes a what if two are needed...
X * 2) link markers into a list that gets updated (auto structures for
X * the nodes)
X * 3) Expand the mark into a stack of marks and add pushmark, popmark.
X */
X
X plen = srch_pat -> l_used;
X rlen = rplc_pat -> l_used;
X
X abs_dot_p = DOT_POS(curwp); /* save current dot position */
X abs_mark_p = MARK_POS(curwp);
X
X while (forwsrch () == TRUE)
X {
Xretry:
X sprintf (buf1, MSG_fnd_at, R_POS_FMT(curwp));
X sprintf (buf, buf1, DOT_POS(curwp));
X writ_echo (buf);
X curwp -> w_flag |= WFMODE; /* update mode line */
X update ();
X switch (ttgetc ())
X {
X case 'r':
X case 'R':
X case ' ':
X case ',':
X /* update has fixedup the dot position so move to found byte */
X /* go and do the replace */
X if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
X return (FALSE);
X /* begin searching after replace string */
X move_ptr (curwp, (long)rlen, TRUE, FALSE, TRUE);
X rcnt++;
X break;
X
X case 'o':
X case 'O':
X case '.':
X if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
X return (FALSE);
X /* begin searching after replace string */
X move_ptr (curwp, (long)rlen, TRUE, FALSE, TRUE);
X rcnt++;
X goto stopsearch;
X
X case 'q':
X case 'Q':
X case CCHR ('G'):
X ctrlg (FALSE, 0, KRANDOM);
X goto stopsearch;
X
X case 'a':
X case 'A':
X case '!':
X do
X {
X if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
X return (FALSE);
X /* begin searching after replace string */
X move_ptr (curwp, (long)rlen, TRUE, FALSE, TRUE);
X rcnt++;
X }
X while (forwsrch () == TRUE);
X goto stopsearch;
X
X case 's':
X case 'S':
X case 'n':
X /* begin searching after this byte */
X move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
X break;
X
X default:
X ttbeep ();
X goto retry;
X }
X }
X
Xstopsearch:
X move_ptr (curwp, abs_dot_p, TRUE, TRUE, FALSE);
X if (curwp -> w_markp != NULL)
X {
X swapmark ();
X /* insure that the mark points to the same byte as before */
X if (abs_mark_p > abs_dot_p)
X move_ptr (curwp, abs_mark_p + rlen - plen, TRUE, FALSE, FALSE);
X else
X move_ptr (curwp, abs_mark_p, TRUE, FALSE, FALSE);
X swapmark ();
X }
X curwp -> w_flag |= WFHARD;
X update ();
X if (rcnt == 0)
X {
X writ_echo (MSG_no_rpl);
X }
X else if (rcnt == 1)
X {
X writ_echo (MSG_1_rpl);
X }
X else
X {
X sprintf (buf1, MSG_n_rpl, R_POS_FMT(curwp));
X sprintf (buf, buf1, (ulong)rcnt);
X writ_echo (buf);
X }
X flush_count += rcnt; /* jam for auto write buffers */
X return (TRUE);
X}
X
X
X/*
X* This routine does the real work of a
X* forward search. The pattern is sitting in the external
X* variable "srch_pat" the mask if in "srch_mask".
X* If found, dot is updated, the window system
X* is notified of the change, and TRUE is returned. If the
X* string isn't found, FALSE is returned.
X*/
Xchar forwsrch ()
X{
X register LINE *save_dotp, *save2_dotp;
X register int save_doto, save2_doto;
X register char *pat_ptr, *mask_ptr;
X register int i, j, pat_cnt;
X register char first_pat, first_mask;
X char buf[80], buf1[40];
X
X save_dotp = curwp -> w_dotp; /* save dot position for later */
X save_doto = curwp -> w_doto;
X pat_ptr = srch_pat -> l_text;
X mask_ptr = srch_mask -> l_text;
X pat_cnt = srch_pat -> l_used;
X first_mask = mask_ptr[0];
X first_pat = pat_ptr[0] | first_mask;
X j = (int)DOT_POS(curwp) & 0xffff;
X
X do
X {
X if ((j++ & 0x2ff) == 0)
X {
X sprintf (buf1, MSG_srcing, R_POS_FMT(curwp));
X sprintf (buf, buf1, DOT_POS(curwp));
X writ_echo (buf);
X /* check if we should quit */
X if (ttkeyready ())
X {
X ttgetc (); /* through away char that was struck */
X break;
X }
X }
X if (first_pat ==
X ((DOT_CHAR(curwp) | first_mask) & 0xff))
X {
X save2_dotp = curwp -> w_dotp; /* save dot position for later */
X save2_doto = curwp -> w_doto;
X for (i = 1; i < pat_cnt; i++)
X {
X if (!move_ptr (curwp, 1L, TRUE, FALSE, TRUE) ||
X ((pat_ptr[i] & ~mask_ptr[i]) !=
X (DOT_CHAR(curwp) & ~mask_ptr[i])))
X { /* not found */
X curwp -> w_dotp = save2_dotp; /* restore dot position */
X curwp -> w_doto = save2_doto;
X break;
X }
X }
X if (i == pat_cnt) /* found */
X { /* move back to the first matching unit */
X move_ptr (curwp, -(long)pat_cnt + 1, TRUE, FALSE, TRUE);
X wind_on_dot (curwp);
X return (TRUE);
X }
X }
X }
X while (move_ptr (curwp, 1L, TRUE, FALSE, TRUE));
X
X curwp -> w_dotp = save_dotp; /* restore dot position */
X curwp -> w_doto = save_doto;
X return (FALSE);
X}
X
X
X/*
X* This routine does the real work of a
X* backward search. The pattern is sitting in the external
X* variable "srch_pat". If found, dot is updated, the window system
X* is notified of the change, and TRUE is returned. If the
X* string isn't found, FALSE is returned.
X*/
Xchar backsrch ()
X{
X register LINE *save_dotp, *save_p;
X register int save_doto, save_o;
X register char *pat_ptr, *mask_ptr;
X register int i, j, pat_cnt;
X register char first_pat, first_mask;
X char buf[80], buf1[40];
X
X save_dotp = curwp -> w_dotp; /* save dot position for later */
X save_doto = curwp -> w_doto;
X pat_ptr = srch_pat -> l_text;
X mask_ptr = srch_mask -> l_text;
X pat_cnt = srch_pat -> l_used;
X first_mask = mask_ptr[0];
X first_pat = pat_ptr[0] | first_mask;
X j = (int)DOT_POS(curwp) & 0xffff;
X
X do
X {
X /* check if we should quit */
X if (ttkeyready ())
X {
X ttgetc (); /* through away char that was struck */
X break;
X }
X if ((j-- & 0x2ff) == 0)
X {
X sprintf (buf1, MSG_srcing, R_POS_FMT(curwp));
X sprintf (buf, buf1, DOT_POS(curwp));
X writ_echo (buf);
X }
X if (first_pat ==
X (curwp -> w_dotp -> l_text[curwp -> w_doto] | first_mask))
X {
X
X save_p = curwp -> w_dotp;
X save_o = curwp -> w_doto;
X for (i = 1; i < pat_cnt; i++)
X {
X if (!move_ptr (curwp, 1L, TRUE, FALSE, TRUE) ||
X ((pat_ptr[i] & ~mask_ptr[i]) !=
X (DOT_CHAR(curwp) & ~mask_ptr[i])))
X { /* not found */
X curwp -> w_dotp = save_p; /* restore ptr to continue */
X curwp -> w_doto = save_o;
X break;
X }
X }
X if (i == pat_cnt) /* found */
X { /* move back to the first matching unit */
X move_ptr (curwp, -(long)pat_cnt + 1, TRUE, FALSE, TRUE);
X wind_on_dot (curwp);
X return (TRUE);
X }
X }
X }
X while (move_ptr (curwp, -1L, TRUE, FALSE, TRUE));
X
X curwp -> w_dotp = save_dotp; /* restore dot position */
X curwp -> w_doto = save_doto;
X return (FALSE);
X}
X
X/*
X* Read a pattern.
X* Display and edit in the form of the current window.
X* Slide the displayed line back and forth when the cursor hits a boundary.
X* Manage the mask buffer. When a '*' (wild card) is entered mask all
X* bits in that unit and display all '?'s.
X*/
Xchar readpattern ()
X{
X int cod, mask_cod, curs_pos, curs_pos1, prt_siz, i, doto, loff;
X WINDOW srch_wind, *save_wind;
X BUFFER srch_buf, *save_buf;
X LINE head_line, *line_ptr1, *line_ptr2;
X char disp_buf[120],
X mask_buf[120],
X buf1[80],
X siz_prompt2,
X r_type,
X first_time,
X u_off,
X stat;
X
X
X save_wind = curwp; /* save current window for later */
X save_buf = curbp; /* save current buffer for later */
X
X curwp = &srch_wind; /* search window is current window during
X search */
X curbp = &srch_buf;
X cur_pat = srch_pat; /* set global variables for LINE finctions */
X cur_mask = srch_mask;
X
X recall_flag = FALSE;
X first_time = TRUE;
X read_pat_mode = TRUE;
X curwp -> w_wndp = NULL;
X curwp -> w_bufp = curbp;
X curwp -> w_linep = cur_pat;
X curwp -> w_loff = 0;
X curwp -> w_dotp = cur_pat;
X curwp -> w_doto = 0;
X curwp -> w_unit_offset = 0;
X curwp -> w_toprow = 24;
X curwp -> w_ntrows = 1;
X curwp -> w_intel_mode = save_wind -> w_intel_mode;
X curwp -> w_disp_shift = 0;
X if (R_TYPE(save_wind) == TEXT)
X curwp -> w_fmt_ptr = &ascii_s_fmt;
X else
X curwp -> w_fmt_ptr = save_wind -> w_fmt_ptr -> r_srch_fmt;
X
X srch_buf.b_bufp = NULL;
X srch_buf.b_linep = &head_line;
X srch_buf.b_unit_offset = 0; /* unit offset pvr */
X srch_buf.b_markp = NULL;
X srch_buf.b_marko = 0;
X srch_buf.b_flag = 0;
X srch_buf.b_nwnd = 1;
X srch_buf.b_fname[0] = 0;
X srch_buf.b_bname[0] = 0;
X
X head_line.l_fp = cur_pat;
X head_line.l_bp = cur_pat;
X head_line.l_file_offset = 0; /* pvr */
X head_line.l_used = 0;
X head_line.l_size = 0;
X
X cur_pat -> l_fp = &head_line;
X cur_pat -> l_bp = &head_line;
X cur_pat -> l_size = 266; /* leave some extra past 256 */
X cur_pat -> l_used = 0;
X cur_pat -> l_file_offset = 0;
X
X cur_mask -> l_fp = &head_line;
X cur_mask -> l_bp = &head_line;
X cur_mask -> l_size = 266; /* leave some extra past 256 */
X cur_mask -> l_used = 0;
X cur_mask -> l_file_offset = 0;
X
X rplc_pat -> l_fp = &head_line;
X rplc_pat -> l_bp = &head_line;
X rplc_pat -> l_size = 266; /* leave some extra past 256 */
X rplc_pat -> l_used = 0;
X rplc_pat -> l_file_offset = 0;
X
X rplc_mask -> l_fp = &head_line;
X rplc_mask -> l_bp = &head_line;
X rplc_mask -> l_size = 266; /* leave some extra past 256 */
X rplc_mask -> l_used = 0;
X rplc_mask -> l_file_offset = 0;
X
X sprintf (buf1, MSG_curs, cur_prompt, R_BYTE_FMT(curwp),
X R_BYTE_FMT(curwp), R_BYTE_FMT(curwp));
X sprintf (disp_buf, buf1, curwp -> w_doto,
X curwp -> w_fmt_ptr -> r_chr_per_u - curwp -> w_unit_offset - 1,
X curwp -> w_dotp -> l_used);
X
X siz_prompt2 = strlen (disp_buf); /* save prompt length for later */
X
X for (i = siz_prompt2; i < NCOL; i++) /* clear rest of buffer */
X disp_buf [i] = ' ';
X
X writ_echo (disp_buf);
X
X r_type = R_TYPE(curwp);
X
X while (TRUE)
X {
X /* position cursor */
X curs_pos = curwp -> w_doto - curwp -> w_loff;
X if (curwp -> w_fmt_ptr -> r_size == 1)
X {
X curs_pos >>= 1;
X }
X else if (curwp -> w_fmt_ptr -> r_size == 3)
X {
X curs_pos >>= 2;
X }
X curs_pos1 = curwp -> w_fmt_ptr -> r_positions[curs_pos] +
X curwp -> w_unit_offset + siz_prompt2;
X ttmove (nrow - 1, curs_pos1);
X ttflush ();
X
X cod = getkey ();
X
X if (cod == 0x014D) /* check for return */
X {
X if ((rplc_mode == TRUE) && (cur_prompt == MSG_sch_str))
X {
X next_pat ();
X dont_repeat = FALSE; /* fix up */
X goto next_loop;
X }
X else
X {
X old_srch_pat_size = srch_pat -> l_used; /* save for restore */
X if (rplc_mode == TRUE)
X old_rplc_pat_size = rplc_pat -> l_used;
X
X old_fmt = curwp -> w_fmt_ptr;
X curwp = save_wind; /* restore current window */
X curbp = save_buf; /* restore current buffer */
X read_pat_mode = FALSE;
X return (TRUE);
X }
X }
X
X if ((cod >= ' ') && (cod < 0x7f))
X {
X if ((r_type == ASCII) || (r_type == EBCDIC))
X {
X mask_cod = '9'; /* use 9 as dummy char that will get through */
X }
X else if (r_type == DECIMAL)
X {
X mask_cod = '0'; /* clear mask byte */
X }
X else if (cod == '?')
X {
X cod = '0';
X switch (r_type)
X {
X case OCTAL:
X if (curwp -> w_unit_offset == 0) /* if first char */
X {
X if (R_SIZE(curwp) == WORDS)
X mask_cod = '1';
X else
X mask_cod = '3';
X }
X else
X mask_cod = '7';
X break;
X
X case HEX:
X mask_cod = 'F';
X break;
X
X case BINARY:
X mask_cod = '1';
X break;
X#if RUNCHK
X default:
X printf (ERR_rdpat);
X break;
X#endif
X }
X }
X else
X {
X mask_cod = '0';
X }
X }
X else
X mask_cod = cod; /* must be control; do the same to the mask */
X
X /* save current dot and window positions */
X doto = curwp -> w_doto;
X u_off = curwp -> w_unit_offset;
X loff = curwp -> w_loff;
X stat = execute (cod, FALSE, 1);
X
X if (stat == ABORT)
X {
X old_srch_pat_size = srch_pat -> l_used; /* save for restore */
X if (rplc_mode == TRUE)
X old_rplc_pat_size = rplc_pat -> l_used;
X old_fmt = curwp -> w_fmt_ptr;
X curwp = save_wind; /* restore current window */
X curbp = save_buf; /* restore current buffer */
X read_pat_mode = FALSE;
X return (FALSE);
X }
X
X /* If key is recall then reset the size variables */
X if (first_time)
X {
X first_time = FALSE;
X if (recall_flag)
X {
X srch_pat -> l_used = old_srch_pat_size;
X srch_mask -> l_used = old_srch_pat_size;
X rplc_pat -> l_used = old_rplc_pat_size;
X rplc_mask -> l_used = old_rplc_pat_size;
X curwp -> w_fmt_ptr = old_fmt;
X recall_flag = FALSE;
X }
X }
X
X /* if it was a toggling command, don't do it again */
X if (!dont_repeat &&
X (stat == TRUE))
X {
X head_line.l_fp = cur_mask; /* point to mask */
X head_line.l_bp = cur_mask;
X curwp -> w_linep = cur_mask;
X curwp -> w_dotp = cur_mask;
X curwp -> w_loff = loff;
X curwp -> w_doto = doto;
X curwp -> w_unit_offset = u_off;
X execute (mask_cod, FALSE, 1);
X
X head_line.l_fp = cur_pat; /* restore pointers */
X head_line.l_bp = cur_pat;
X curwp -> w_linep = cur_pat;
X curwp -> w_dotp = cur_pat;
X }
X else
X dont_repeat = FALSE;
X
X /* limit at 256 bytes */
X if (cur_pat -> l_used >= 256)
X {
X cur_mask -> l_used = 255;
X cur_pat -> l_used = 255;
X if (curwp -> w_doto >= 256)
X {
X move_ptr (curwp, 255L, TRUE, TRUE, FALSE); /* last position */
X }
X }
X
X /* if buffer is size locked then replace pattern must be the */
X /* same size as the search pattern */
X if (rplc_mode && (save_buf -> b_flag & BFSLOCK))
X {
X rplc_pat -> l_used = srch_pat -> l_used;
X rplc_mask -> l_used = srch_pat -> l_used;
X }
X
X r_type = R_TYPE(curwp);
X#if RUNCHK
X /* check that the pattern and the mask are the same size */
X if (cur_pat -> l_used != cur_mask -> l_used)
X {
X printf (ERR_mask, cur_pat -> l_used, cur_mask -> l_used);
X }
X
X /* check that in ascii mode the byte that will be set to zero */
X /* is the dummy char 9 */
X/* if (((r_type == ASCII) &&
X (cur_mask -> l_text[curwp -> w_doto - 1] != '9'))
X ||
X ((r_type == EBCDIC) &&
X (cur_mask -> l_text[curwp -> w_doto - 1] != to_ebcdic('9'))))
X printf (ERR_m_cl);
X*/
X#endif
X if (((r_type == ASCII) ||
X (r_type == EBCDIC)) &&
X ((cod >= ' ') && (cod < 0x7f)))
X cur_mask -> l_text[doto] = 0; /* clear mask byte */
X
Xnext_loop:
X sprintf (buf1, MSG_curs, cur_prompt, R_BYTE_FMT(curwp),
X R_BYTE_FMT(curwp), R_BYTE_FMT(curwp));
X sprintf (disp_buf, buf1, curwp -> w_doto,
X curwp -> w_fmt_ptr -> r_chr_per_u - curwp -> w_unit_offset - 1,
X curwp -> w_dotp -> l_used);
X
X siz_prompt2 = strlen (disp_buf); /* save prompt length for later */
X
X for (i = siz_prompt2; i < NCOL; i++)
X {
X disp_buf [i] = ' ';
X mask_buf [i] = ' ';
X }
X
X if ((curbp -> b_flag & BFSLOCK) &&
X (rplc_pat -> l_used != srch_pat -> l_used))
X {
X rplc_pat -> l_used = srch_pat -> l_used;
X /* if dot is past the end then move it back, replace string only */
X if (DOT_POS(curwp) > srch_pat -> l_used)
X move_ptr (curwp, (long)srch_pat -> l_used, TRUE, TRUE, FALSE);
X }
X
X wind_on_dot (curwp);
X
X /* figure number of bytes to convert to text */
X if ((cur_pat -> l_used - curwp -> w_loff) <
X (prt_siz = curwp -> w_fmt_ptr -> r_bytes))
X prt_siz = cur_pat -> l_used - curwp -> w_loff;
X
X bin_to_text (&cur_pat -> l_text[curwp -> w_loff],
X &disp_buf[siz_prompt2],
X prt_siz, curwp -> w_fmt_ptr);
X
X /* change any char to a ? if any bit is set in the mask buffer */
X if ((r_type != ASCII) && (r_type != EBCDIC))
X {
X /* print the contents of the mask to a invisible buffer */
X bin_to_text (&cur_mask -> l_text[curwp -> w_loff],
X &mask_buf[siz_prompt2],
X prt_siz, curwp -> w_fmt_ptr);
X
X for (i = siz_prompt2; (disp_buf[i] != 0) && (i < NCOL); i++)
X {
X if ((mask_buf[i] != '0') &&
X (mask_buf[i] != ' '))
X disp_buf[i] = '?';
X }
X }
X else
X {
X for (i = 0; i < prt_siz; i++)
X {
X if (cur_mask -> l_text[curwp -> w_loff + i] != 0)
X disp_buf[i + siz_prompt2] = '?';
X }
X }
X writ_echo (disp_buf);
X }
X}
X
X/*
X* Recall the last contents of the search string
X*/
Xbool recall ()
X {
X recall_flag = TRUE;
X return (TRUE);
X }
X
X/*
X* Switch between search pattern and replace pattern and their
X* respective masks
X*/
Xvoid next_pat ()
X{
X if (cur_pat == srch_pat)
X {
X cur_prompt = MSG_rpl_str;
X cur_pat = rplc_pat; /* point to replace pattern */
X cur_mask = rplc_mask;
X }
X else
X {
X cur_prompt = MSG_sch_str;
X cur_pat = srch_pat; /* point to search pattern */
X cur_mask = srch_mask;
X }
X curwp -> w_dotp = cur_pat;
X curwp -> w_linep = cur_pat;
X curbp -> b_linep -> l_fp = cur_pat;
X curbp -> b_linep -> l_bp = cur_pat;
X
X if (curwp -> w_doto > cur_pat -> l_used)
X {
X curwp -> w_doto = cur_pat -> l_used;
X curwp -> w_unit_offset = 0;
X }
X if (curwp -> w_loff > cur_pat -> l_used)
X curwp -> w_loff = cur_pat -> l_used;
X dont_repeat = TRUE;
X}
X
X/*
X* Compare the contents of two windows.
X* There must be exactly two windows displayed.
X* The bytes under the cursor in each window are compared and if
X* a difference is found then the loop is stopped with the dot
X* position in each window pointing to the difference.
X* The two windows can be pointing at the same or different buffers.
X*/
Xbool compare ()
X
X {
X WINDOW *wp1, *wp2;
X bool move1, move2;
X int j;
X char *term_str = MSG_cmp_dif;
X char buf[80], buf1[60];
X
X if (wheadp -> w_wndp -> w_wndp != NULL)
X {
X writ_echo (MSG_only_2);
X return (FALSE);
X }
X
X wp1 = wheadp;
X wp2 = wheadp -> w_wndp;
X j = (int)DOT_POS(curwp) & 0xffff;
X
X wp1 -> w_flag |= WFMOVE;
X wp2 -> w_flag |= WFMOVE;
X
X while (DOT_CHAR(wp1) == DOT_CHAR(wp2))
X {
X if ((j++ & 0xff) == 0)
X {
X sprintf (buf1, MSG_cmping, R_POS_FMT(curwp));
X sprintf (buf, buf1, DOT_POS(curwp));
X writ_echo (buf);
X /* check if we should quit */
X if (ttkeyready ())
X {
X ttgetc (); /* through away char that was struck */
X term_str = MSG_cmp_term;
X break;
X }
X }
X move1 = move_ptr (wp1, 1L, TRUE, FALSE, TRUE);
X move2 = move_ptr (wp2, 1L, TRUE, FALSE, TRUE);
X
X if (!(move1 && move2))
X {
X term_str = MSG_cmp_end;
X break;
X }
X }
X writ_echo (term_str);
X wind_on_dot (wp1);
X wind_on_dot (wp2);
X return (TRUE);
X }
END_OF_FILE
if test 30053 -ne `wc -c <'search.c'`; then
echo shar: \"'search.c'\" unpacked with wrong size!
fi
chmod +x 'search.c'
# end of 'search.c'
fi
echo shar: End of archive 8 \(of 11\).
cp /dev/null ark8isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 11 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
More information about the Alt.sources
mailing list