pvr@wang.com (Peter Reilley) (02/28/91)
#! /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@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