Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!uunet!stanford.edu!snorkelwacker.mit.edu!bu.edu!wang!pvr From: pvr@wang.com (Peter Reilley) Newsgroups: alt.sources Subject: BEAV (06/10) ver 1.2 Binary File Editor, new release Keywords: editor binary data Message-ID: Date: 6 Jun 91 13:29:05 GMT Organization: Wang Labs, Lowell MA, USA Lines: 1783 #! /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.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@wang.com <<<<<<<<<<<<<<<<<<<<<<< Well, that about says it.