BEAV (06/10) ver 1.2 Binary File Editor, new release
Peter Reilley
pvr at wang.com
Thu Jun 6 23:29:05 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 6 (of 10)."
# Contents: file.c search.c
# Wrapped by pvr at elf on Thu Mar 14 08:16:47 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'file.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'file.c'\"
else
echo shar: Extracting \"'file.c'\" \(21304 characters\)
sed "s/^X//" >'file.c' <<'END_OF_FILE'
X/*
X* File commands.
X*/
X#include "def.h"
X
Xchar load_file ();
Xchar readin ();
Xvoid makename ();
Xbool writeout ();
Xbool parse_f_name ();
X
Xextern char MSG_rd_file[];
Xextern char MSG_trash[];
Xextern char MSG_ins_file[];
Xextern char MSG_not_fnd[];
Xextern char MSG_visit[];
Xextern char MSG_view[];
Xextern char MSG_buf_ex[];
Xextern char MSG_old_buf[];
Xextern char MSG_buf_nam[];
Xextern char MSG_cnt_cr[];
Xextern char MSG_reading[];
Xextern char MSG_read_lx[];
Xextern char MSG_no_mem_rd[];
Xextern char MSG_wr_file[];
Xextern char MSG_no_fn[];
Xextern char MSG_bk_err[];
Xextern char MSG_writing[];
Xextern char MSG_wrot_1[];
Xextern char MSG_wrot_n[];
Xextern char MSG_fil_nam[];
Xextern char MSG_null[];
Xextern char ERR_parse_fn[];
Xextern char ERR_addr_neg[];
Xextern char ERR_f_size[];
X
X#include "lintfunc.dec"
X
Xstatic int ughlyflag = FALSE;
X
X/*
X* Read a file into the current
X* buffer. This is really easy; all you do it
X* find the name of the file, and call the standard
X* "read a file into the current buffer" code.
X*/
Xchar fileread ()
X{
X register char s;
X char fname[NFILEN];
X A32 start, end;
X
X if ((s = ereply (MSG_rd_file, fname, NFILEN, NULL)) != TRUE)
X return (s);
X if (parse_f_name (fname, &start, &end))
X {
X adjustcase (fname);
X return (readin (fname, start, end));
X }
X return (TRUE);
X}
X
X
X/* insert file into current buffer - use readin, and yank
X*/
Xchar fileinsert ()
X{
X register char s;
X char bname[NBUFN],
X fname[NFILEN];
X A32 start, end;
X register char *trash = MSG_trash;
X
X strcpy (bname, curbp -> b_bname);/* save current buffer */
X if ((s = _usebuffer (trash)) == 0)/* temp buffer */
X return (s);
X if ((s = ereply (MSG_ins_file, fname, NFILEN, NULL)) != TRUE)
X return (s);
X /* if file name and starting and ending addresses are good */
X if (parse_f_name (fname, &start, &end))
X {
X adjustcase (fname);
X if ((s = readin (fname, start, end)) == 0)
X {
X writ_echo (MSG_not_fnd);
X _usebuffer (bname);
X _killbuffer (trash);
X return (s);
X }
X if ((s = _usebuffer (bname)) == 0)
X {
X _killbuffer (trash);
X return (s);
X }
X if ((s = _yankbuffer (trash)) == 0)
X {
X _killbuffer (trash);
X return (s);
X }
X writ_echo (okmsg);
X }
X else
X {
X _usebuffer (bname);
X _killbuffer (trash);
X return (FALSE);
X }
X if ((s = _killbuffer (trash)) == 0)
X return (s);
X wind_on_dot (curwp);
X return (s);
X}
X
X
X/*
X* Select a file for editing.
X* Look around to see if you can find the
X* fine in another buffer; if you can find it
X* just switch to the buffer. If you cannot find
X* the file, create a new buffer, read in the
X* text, and switch to the new buffer.
X*
X* also various hacked versions for auto load, and
X* file-vist with auto window split, and readonly (view-file) (jam)
X*/
Xchar file_visit (f, n, k)
X{
X char fname[NFILEN];
X char s;
X A32 start, end;
X if ((s = ereply (MSG_visit, fname, NFILEN, NULL)) != TRUE)
X return (s);
X if (!parse_f_name (fname, &start, &end))
X return (FALSE);
X
X splitwind ();
X return (load_file (fname, start, end));
X}
X
X
X/* like filevisit, only read only
X*/
Xchar viewfile ()
X{
X char fname[NFILEN];
X char s;
X A32 start, end;
X
X if ((s = ereply (MSG_view, fname, NFILEN, NULL)) != TRUE)
X return (s);
X ughlyflag = TRUE;
X if (!parse_f_name (fname, &start, &end))
X return (FALSE);
X
X s = load_file (fname, start, end);
X if (s)
X curbp -> b_flag |= BFVIEW;
X ughlyflag = FALSE;
X return (s);
X}
X
X
Xchar filevisit ()
X{
X char fname[NFILEN];
X char s;
X A32 start, end;
X
X if ((s = ereply (MSG_visit, fname, NFILEN, NULL)) != TRUE)
X return (s);
X if (!parse_f_name (fname, &start, &end))
X return (FALSE);
X
X return (load_file (fname, start, end));
X}
X
X
Xchar load_file (fname, start, end) /* jam */
Xchar *fname;
XA32 start, end;
X{
X register BUFFER * bp;
X register WINDOW * wp;
X register LINE * lp;
X register int i;
X char s;
X char bname[NBUFN];
X extern int initial_load; /* jam */
X static int append = 0;
X
X adjustcase (fname);
X for (bp = bheadp; bp != NULL; bp = bp -> b_bufp)
X {
X if (strcmp (bp -> b_fname, fname) == 0)
X {
X if (ughlyflag == TRUE)
X {
X writ_echo (MSG_buf_ex);
X return (FALSE);
X }
X if (--curbp -> b_nwnd == 0)
X {
X curbp -> buf_type = BFILE;
X curbp -> b_dotp = curwp -> w_dotp;
X curbp -> b_doto = curwp -> w_doto;
X curbp -> b_unit_offset = curwp -> w_unit_offset;
X curbp -> b_markp = curwp -> w_markp;
X curbp -> b_marko = curwp -> w_marko;
X }
X curbp = bp;
X curwp -> w_bufp = bp;
X if (bp -> b_nwnd++ == 0)
X {
X curwp -> w_dotp = bp -> b_dotp;
X curwp -> w_doto = bp -> b_doto;
X curwp -> w_unit_offset = bp -> b_unit_offset;
X curwp -> w_markp = bp -> b_markp;
X curwp -> w_marko = bp -> b_marko;
X }
X else
X {
X wp = wheadp;
X while (wp != NULL)
X {
X if (wp != curwp && wp -> w_bufp == bp)
X {
X curwp -> w_dotp = wp -> w_dotp;
X curwp -> w_doto = wp -> w_doto;
X curwp -> w_unit_offset = wp -> w_unit_offset;
X curwp -> w_markp = wp -> w_markp;
X curwp -> w_marko = wp -> w_marko;
X break;
X }
X wp = wp -> w_wndp;
X }
X }
X lp = curwp -> w_dotp;
X i = curwp -> w_ntrows / 2;
X while (i-- && lback (lp) != curbp -> b_linep)
X lp = lback (lp);
X curwp -> w_linep = lp;
X curwp -> w_flag |= WFMODE | WFHARD;
X if (kbdmop == NULL)
X {
X writ_echo (MSG_old_buf);
X }
X return (TRUE);
X }
X }
X
X makename (bname, fname); /* New buffer name. */
X while ((bp = bfind (bname, FALSE)) != NULL)
X {
X if (initial_load) /* patch old name */
X {
X funky_name (bname, append++);
X bp = NULL;
X break;
X }
X s = ereply (MSG_buf_nam, bname, NBUFN, NULL);
X if (s == ABORT) /* ^G to just quit */
X return (s);
X if (strcmp (bp -> b_bname, bname) == 0 || s == FALSE)
X {
X /* CR to clobber it */
X makename (bname, fname);
X break;
X }
X }
X if (bp == NULL && (bp = bfind (bname, TRUE)) == NULL)
X {
X writ_echo (MSG_cnt_cr);
X return (FALSE);
X }
X if (--curbp -> b_nwnd == 0)
X {
X /* Undisplay. */
X curbp -> buf_type = BFILE;
X curbp -> b_dotp = curwp -> w_dotp;
X curbp -> b_doto = curwp -> w_doto;
X curbp -> b_unit_offset = curwp -> w_unit_offset;
X curbp -> b_markp = curwp -> w_markp;
X curbp -> b_marko = curwp -> w_marko;
X }
X curbp = bp; /* Switch to it. */
X curwp -> w_bufp = bp;
X curbp -> b_nwnd++;
X return (readin (fname, start, end)); /* Read it in. */
X}
X
X
X/*
X* Read the file "fname" into the current buffer.
X* Make all of the text in the buffer go away, after checking
X* for unsaved changes. This is called by the "read" command, the
X* "visit" command, and the mainline (for "beav file"). If the
X* BACKUP conditional is set, then this routine also does the read
X* end of backup processing. The BFBAK flag, if set in a buffer,
X* says that a backup should be taken. It is set when a file is
X* read in, but not on a new file (you don't need to make a backup
X* copy of nothing). Return a standard status. Print a summary
X* (lines read, error message) out as well.
X*/
Xchar readin (fname, start, end)
Xchar fname[];
XA32 start, end;
X{
X register LINE * lp1;
X register LINE * lp2;
X register char i;
X register WINDOW * wp;
X register BUFFER * bp;
X register char s, m;
X long byte_cnt;
X char line[NLINE];
X int num_chars, req_chars;
X char buf[80], buf1[80];
X A32 temp;
X
X m = TRUE;
X byte_cnt = 0;
X bp = curbp; /* Cheap. */
X if ((s = bclear (bp)) != TRUE)/* Might be old. */
X return (s);
X#if BACKUP
X bp -> b_flag &= ~(BFCHG | BFBAK);/* No change, backup. */
X#else
X bp -> b_flag &= ~BFCHG; /* No change. */
X#endif
X if ((start == 0L) && (end == MAXPOS))
X strcpy (bp -> b_fname, fname);
X else
X strcpy (bp -> b_fname, MSG_null);
X if ((s = ffropen (fname)) == FIOERR || s == FIOFNF)/* jam */
X goto out;
X bp -> b_file_size = file_len (); /* get the file lenth */
X sprintf (buf, MSG_reading, fname);/* jam */
X writ_echo (buf);
X temp = ffseek (start);
X if (temp != start)
X {
X sprintf (buf1, ERR_f_size, R_POS_FMT(curwp));
X sprintf (buf, buf1, temp);
X writ_echo (buf);
X return (FALSE);
X }
X /* only read the requested number of characters */
X if ((end - start) > NLINE)
X req_chars = NLINE;
X else
X req_chars = (int)(end - start);
X
X while ((s = ffgetline (line, req_chars, &num_chars)) == FIOSUC)
X {
X if ((lp1 = lalloc(num_chars)) == NULL)
X {
X bp -> b_flag |= BFVIEW; /* if no memory set to read only mode */
X m = FALSE; /* flag memory allocation error */
X break;
X }
X /* this code breaks rules for knowing how lines * are stored and linked
X together, oh well */
X lp2 = lback (curbp -> b_linep);
X lp2 -> l_fp = lp1;
X lp1 -> l_fp = curbp -> b_linep;
X lp1 -> l_bp = lp2;
X curbp -> b_linep -> l_bp = lp1;
X for (i = 0; i < num_chars; ++i)
X lputc (lp1, i, line[i]);
X lp1 -> l_used = num_chars; /* number of bytes in this line */
X lp1 -> l_file_offset = byte_cnt; /* file offset from begining */
X byte_cnt += (long) num_chars; /* number of bytes read in */
X start += (long) num_chars;
X if (end <= start)
X break;
X /* stop reading after the requested number of characters */
X if (end < start + req_chars)
X {
X req_chars = end - start;
X }
X }
X ffclose (); /* Ignore errors. */
X if (s == FIOEOF && kbdmop == NULL)
X {
X /* Don't zap an error. */
X sprintf (buf1, MSG_read_lx, R_POS_FMT(curwp));
X sprintf (buf, buf1, byte_cnt);
X writ_echo (buf);
X }
X if (m == FALSE && kbdmop == NULL)
X {
X /* Don't zap an error. */
X sprintf (buf1, MSG_no_mem_rd, R_POS_FMT(curwp));
X sprintf (buf, buf1, byte_cnt);
X writ_echo (buf);
X }
X
X#if BACKUP
X curbp -> b_flag |= BFBAK; /* Need a backup. */
X#endif
Xout:
X for (wp = wheadp; wp != NULL; wp = wp -> w_wndp)
X {
X if (wp -> w_bufp == curbp)
X {
X wp -> w_linep = lforw (curbp -> b_linep);
X wp -> w_dotp = lforw (curbp -> b_linep);
X wp -> w_doto = 0;
X wp -> w_unit_offset = 0;
X wp -> w_markp = NULL;
X wp -> w_marko = 0;
X wp -> w_flag |= WFMODE | WFHARD;
X }
X }
X if (s == FIOERR || s == FIOFNF)/* False if error. */
X return (FALSE);
X /* so tell yank-buffer about it */
X if (blistp -> b_nwnd != 0) /* update buffer display */
X listbuffers ();
X return (TRUE);
X}
X
X
X/*
X* Take a file name, and from it
X* fabricate a buffer name. This routine knows
X* about the syntax of file names on the target system.
X* BDC1 left scan delimiter.
X* BDC2 optional second left scan delimiter.
X* BDC3 optional right scan delimiter.
X*/
Xvoid makename (bname, fname)
Xchar bname[];
Xchar fname[];
X{
X register char *cp1;
X register char *cp2;
X
X cp1 = &fname[0];
X while (*cp1 != 0)
X ++cp1;
X#ifdef BDC2
X while (cp1 != &fname[0] && cp1[-1] != BDC1 && cp1[-1] != BDC2)
X --cp1;
X#else
X while (cp1 != &fname[0] && cp1[-1] != BDC1)
X --cp1;
X#endif
X cp2 = &bname[0];
X#ifdef BDC3
X while (cp2 != &bname[NBUFN - 1] && *cp1 != 0 && *cp1 != BDC3)
X *cp2++ = *cp1++;
X#else
X while (cp2 != &bname[NBUFN - 1] && *cp1 != 0)
X *cp2++ = *cp1++;
X#endif
X *cp2 = 0;
X}
X
X
X/*
X* Ask for a file name, and write the
X* contents of the current buffer to that file.
X* Update the remembered file name and clear the
X* buffer changed flag. This handling of file names
X* is different from the earlier versions, and
X* is more compatable with Gosling EMACS than
X* with ITS EMACS.
X*/
Xchar filewrite ()
X{
X register WINDOW * wp;
X register char s;
X char fname[NFILEN];
X A32 start, end;
X
X if ((s = ereply (MSG_wr_file, fname, NFILEN, NULL)) != TRUE)
X return (s);
X if (!parse_f_name (fname, &start, &end))
X return (FALSE);
X
X adjustcase (fname);
X if ((s = writeout (fname, start, end)) == TRUE)
X {
X strcpy (curbp -> b_fname, fname);
X curbp -> b_flag &= ~BFCHG;
X wp = wheadp; /* Update mode lines. */
X while (wp != NULL)
X {
X if (wp -> w_bufp == curbp)
X wp -> w_flag |= WFMODE;
X wp = wp -> w_wndp;
X }
X }
X
X#if BACKUP
X curbp -> b_flag &= ~BFBAK; /* No backup. */
X#endif
X return (s);
X}
X
X
X/*
X* Save the contents of the current buffer back into
X* its associated file. Do nothing if there have been no changes
X* (is this a bug, or a feature). Error if there is no remembered
X* file name. If this is the first write since the read or visit,
X* thet a backup copy of the file is made.
X*/
Xchar filesave ()
X{
X register WINDOW * wp;
X register char s;
X
X if ((curbp -> b_flag & BFCHG) == 0)/* Return, no changes. */
X return (TRUE);
X if (curbp -> b_fname[0] == 0)/* Must have a name. */
X {
X if (!(curbp -> b_flag & BFSAV))/* yanked buffer */
X {
X writ_echo (MSG_no_fn);
X }
X return (FALSE);
X }
X#if BACKUP
X if ((curbp -> b_flag & BFBAK) != 0)
X {
X s = fbackupfile (curbp -> b_fname);
X if (s == ABORT) /* Hard error. */
X return (s);
X if (s == FALSE /* Softer error. */
X && (s = eyesno (MSG_bk_err)) != TRUE)
X return (s);
X }
X
X#endif
X if ((s = writeout (curbp -> b_fname, 0L, MAXPOS)) == TRUE)
X {
X curbp -> b_flag &= ~BFCHG;/* No change. */
X curbp -> b_flag &= ~BFBAD;/* if it was trashed, forget it now */
X wp = wheadp; /* Update mode lines. */
X while (wp != NULL)
X {
X if (wp -> w_bufp == curbp)
X wp -> w_flag |= WFMODE;
X wp = wp -> w_wndp;
X }
X }
X
X#if BACKUP
X curbp -> b_flag &= ~BFBAK; /* No backup. */
X#endif
X return (s);
X}
X
X/*
X* This function performs the details of file
X* writing. Uses the file management routines in the
X* "fileio.c" package. The number of lines written is
X* displayed. Sadly, it looks inside a LINE; provide
X* a macro for this. Most of the grief is error
X* checking of some sort.
X*/
Xbool writeout (fn, start, end)
Xchar *fn;
XA32 start, end;
X{
X register int s, num_chars;
X register LINE * lp;
X register long nbytes;
X char buf[80], buf1[80];
X A32 temp;
X
X if ((s = ffwopen (fn)) != FIOSUC)/* Open writes message. */
X return (FALSE);
X temp = ffseek (start);
X if (temp != start)
X {
X sprintf (buf1, ERR_f_size, R_POS_FMT(curwp));
X sprintf (buf, buf1, temp);
X writ_echo (buf);
X return (FALSE);
X }
X sprintf (buf, MSG_writing, fn);/* jam */
X writ_echo (buf);
X
X /* insure that the help screen reflects the latest bindings */
X if (curbp == blistp)
X wallchart ();
X
X lp = lforw (curbp -> b_linep);/* First line. */
X nbytes = 0; /* Number of bytes. */
X temp = end - start; /* number of bytes to write */
X while (lp != curbp -> b_linep)
X {
X if (curbp == blistp)
X {
X /* special list buffer */
X num_chars = HENDCOL; /* limit line length */
X lp -> l_text[num_chars - 1] = '\n';
X }
X else
X {
X /* standard buffer */
X if (nbytes + (long)llength (lp) > temp)
X num_chars = (int)(temp - nbytes);
X else
X num_chars = llength (lp);
X }
X if ((s = ffputline (&lp -> l_text[0], num_chars)) != FIOSUC)
X break;
X nbytes += num_chars;
X if (temp <= nbytes)
X break;
X lp = lforw (lp);
X }
X if (s == FIOSUC)
X {
X /* No write error. */
X s = ffclose ();
X if (s == FIOSUC && kbdmop == NULL)
X {
X if (nbytes == 1)
X {
X writ_echo (MSG_wrot_1);
X }
X else
X {
X sprintf (buf1, MSG_wrot_n, R_POS_FMT(curwp));
X sprintf (buf, buf1, (long) nbytes);
X writ_echo (buf);
X }
X }
X }
X else /* Ignore close error */
X ffclose (); /* if a write error. */
X if (s != FIOSUC) /* Some sort of error. */
X return (FALSE);
X curbp -> b_file_size = nbytes; /* update file size */
X if (blistp -> b_nwnd != 0) /* update buffer display */
X listbuffers ();
X return (TRUE);
X}
X
X/*
X* The command allows the user
X* to modify the file name associated with
X* the current buffer. It is like the "f" command
X* in UNIX "ed". The operation is simple; just zap
X* the name in the BUFFER structure, and mark the windows
X* as needing an update. You can type a blank line at the
X* prompt if you wish.
X*/
Xchar filename ()
X{
X register WINDOW * wp;
X register char s;
X char fname[NFILEN];
X A32 start, end;
X
X if ((s = ereply (MSG_fil_nam, fname, NFILEN, NULL)) == ABORT)
X return (s);
X if (!parse_f_name (fname, &start, &end))
X return (FALSE);
X
X adjustcase (fname);
X curbp -> b_flag |= BFCHG; /* jam - on name change, set modify */
X BUF_START(curwp) = start;
X l_fix_up (NULL); /* adjust file offsets from first line */
X strcpy (curbp -> b_fname, fname);/* Fix name. */
X wp = wheadp; /* Update mode lines. */
X while (wp != NULL)
X {
X if (wp -> w_bufp == curbp)
X wp -> w_flag |= WFMODE;
X wp = wp -> w_wndp;
X }
X#if BACKUP
X curbp -> b_flag &= ~BFBAK; /* No backup. */
X#endif
X return (TRUE);
X}
X
X/*
X* Get the length parameters that were entered with the file name.
X* There can be the file name only.
X* There can be a file name and a starting position.
X* There can be a name a starting position and an ending position.
X* There can be a name a starting position and a length.
X*
X* input:
X* fn pointer to file name string to parse.
X*
X* output:
X* fn pointer to null terminated file name.
X* start pointer to the starting point in file (default = 0)
X* end pointer to the end point in file (default = -1)
X* return FALSE if file name or addresses are bad.
X*/
Xbool parse_f_name (fn, start, end)
Xchar *fn;
XA32 *start, *end;
X {
X char buf[NFILEN], buf1[80], fmt[10];
X int i_cnt;
X A32 temp;
X
X /* build up format string according to the current screen format */
X sprintf (fmt, "%s %s %s", "%s", R_POS_FMT(curwp), R_POS_FMT(curwp));
X
X *start = 0L;
X *end = MAXPOS;
X sscanf (fn, fmt, buf, start, end);
X
X if (*end != MAXPOS)
X {
X for (i_cnt = strlen (fn) - 1; i_cnt >= 0; i_cnt--)
X {
X if (fn[i_cnt] == '+')
X {
X *end += *start;
X break;
X }
X }
X }
X /* start should preceed end */
X if (*start > *end)
X {
X sprintf (buf1, ERR_parse_fn, R_POS_FMT(curwp), R_POS_FMT(curwp));
X sprintf (buf, buf1, *start, *end);
X writ_echo (buf);
X return (FALSE);
X }
X
X /* error if addresses are negative */
X if ((*start < 0) || (*end < 0))
X {
X writ_echo (ERR_addr_neg);
X return (FALSE);
X }
X
X /* deposit null terminated file name */
X strcpy (fn, buf);
X return (TRUE);
X }
END_OF_FILE
if test 21304 -ne `wc -c <'file.c'`; then
echo shar: \"'file.c'\" unpacked with wrong size!
fi
chmod +x 'file.c'
# end of 'file.c'
fi
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 6 \(of 10\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 10 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
--
>>>>>>>>>>>>>>>> Peter Reilley ..... pvr at wang.com <<<<<<<<<<<<<<<<<<<<<<<
Well, that about says it.
More information about the Alt.sources
mailing list