Logo Search packages:      
Sourcecode: beav version File versions  Download package

search.c

/*
*       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)

00048 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);
}

Generated by  Doxygen 1.6.0   Back to index