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