home *** CD-ROM | disk | FTP | other *** search
- /*
- * The functions in this file implement commands that search in the forward
- * and backward directions. There are no special characters in the search
- * strings. Probably should have a regular expression search, or something
- * like that.
- *
- * REVISION HISTORY:
- *
- * ? Steve Wilhite, 1-Dec-85
- * - massive cleanup on code.
- *
- * Andy Poggio, 1 Apr 86 - added query replace
- */
-
- #include <stdio.h>
- #include "ed.h"
-
- /*
- * Query replace. Replace pattern with new one at user's discretion.
- * Bound to META-%.
- */
- qreplace(f, n)
- {
- register int s;
- short olen, repall;
- char newpat[ NPAT];
-
- if ((s = readpattern("Replace old string", 0)) != TRUE)
- return (s);
- olen = strlen( pat);
- if((s = mlreply( "with new string: ", newpat, sizeof newpat)) == ABORT)
- return( s);
-
- repall = FALSE;
- while( search()) {
-
- if( repall) s = TRUE;
- else {
- mlwrite("Replace?");
- update();
- askuser:
- switch( (*term.t_getchar)()) {
-
- case '\0177':
- case '':
- case 'n':
- s = FALSE; /* don't replace */
- break;
-
- case 'a':
- repall = TRUE;
- case ' ':
- case 'y':
- s = TRUE; /* replace */
- break;
-
- case '\007':
- s = ABORT;
- break;
-
- default:
- mlwrite(
- "y or <SP>: replace; n or <DEL>: don't; a: all; <^G>: abort");
- update();
- goto askuser;
- break;
- }
- }
-
- if( s == TRUE) {
- backdel( TRUE, olen); /* delete old string */
- s = linsertstr( newpat); /* and insert the new */
- }
- if( s == ABORT)
- break;
- }
- mlwrite("");
- return( s);
- }
-
- /*
- * Search forward. Get a search string from the user, and search, beginning at
- * ".", for the string. If found, reset the "." to be just after the match
- * string, and [perhaps] repaint the display. Bound to "C-S".
- */
- forwsearch(f, n)
- {
- register int s;
-
- if ((s = readpattern("Search", 0)) != TRUE)
- return (s);
-
- s = search();
- if( ! s) mlwrite("Not found");
- return( s);
- }
-
- search()
- {
- register LINE *clp;
- register int cbo;
- register LINE *tlp;
- register int tbo;
- register int c;
- register char *pp;
-
- clp = curwp->w_dotp;
- cbo = curwp->w_doto;
-
- while (clp != curbp->b_linep)
- {
- if (cbo == llength(clp))
- {
- clp = lforw(clp);
- cbo = 0;
- c = '\n';
- }
- else
- c = lgetc(clp, cbo++);
-
- if (eq(c, pat[0]) != FALSE)
- {
- tlp = clp;
- tbo = cbo;
- pp = &pat[1];
-
- while (*pp != 0)
- {
- if (tlp == curbp->b_linep)
- goto fail;
-
- if (tbo == llength(tlp))
- {
- tlp = lforw(tlp);
- tbo = 0;
- c = '\n';
- }
- else
- c = lgetc(tlp, tbo++);
-
- if (eq(c, *pp++) == FALSE)
- goto fail;
- }
-
- curwp->w_dotp = tlp;
- curwp->w_doto = tbo;
- curwp->w_flag |= WFMOVE;
- return (TRUE);
- }
- fail:;
- }
- return (FALSE);
- }
-
- /*
- * 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
- j matched]. Bound to "C-R".
- */
- backsearch(f, n)
- {
- register LINE *clp;
- register int cbo;
- register LINE *tlp;
- register int tbo;
- register int c;
- register char *epp;
- register char *pp;
- register int s;
-
- if ((s = readpattern("Reverse search", 0)) != TRUE)
- return (s);
-
- for (epp = &pat[0]; epp[1] != 0; ++epp)
- ;
-
- clp = curwp->w_dotp;
- cbo = curwp->w_doto;
-
- for (;;)
- {
- if (cbo == 0)
- {
- clp = lback(clp);
-
- if (clp == curbp->b_linep)
- {
- mlwrite("Not found");
- return (FALSE);
- }
-
- cbo = llength(clp)+1;
- }
-
- if (--cbo == llength(clp))
- c = '\n';
- else
- c = lgetc(clp, cbo);
-
- if (eq(c, *epp) != FALSE)
- {
- tlp = clp;
- tbo = cbo;
- pp = epp;
-
- while (pp != &pat[0])
- {
- if (tbo == 0)
- {
- tlp = lback(tlp);
- if (tlp == curbp->b_linep)
- goto fail;
-
- tbo = llength(tlp)+1;
- }
-
- if (--tbo == llength(tlp))
- c = '\n';
- else
- c = lgetc(tlp, tbo);
-
- if (eq(c, *--pp) == FALSE)
- goto fail;
- }
-
- curwp->w_dotp = tlp;
- curwp->w_doto = tbo;
- curwp->w_flag |= WFMOVE;
- return (TRUE);
- }
- fail:;
- }
- }
-
- /*
- * Compare two characters. The "bc" comes from the buffer. It has it's case
- * folded out. The "pc" is from the pattern.
- */
- eq(bc, pc)
- int bc;
- int pc;
- {
- if (bc>='a' && bc<='z')
- bc -= 0x20;
-
- if (pc>='a' && pc<='z')
- pc -= 0x20;
-
- if (bc == pc)
- return (TRUE);
-
- return (FALSE);
- }
-
- /*
- * Read a pattern. If newpat == 0, do the following.
- * Stash it in the external variable "pat". The "pat" is not
- * updated if the user types in an empty line. If the user typed an empty line,
- * and there is no old pattern, it is an error. Display the old pattern, in the
- * style of Jeff Lomicka. There is some do-it-yourself control expansion.
- * If netpat != 0, ignore the old pattern.
- */
- readpattern(prompt, newpat)
- char *prompt, *newpat;
- {
- register char *cp1;
- register char *cp2;
- register int c;
- register int s;
- char tpat[NPAT+20];
-
- cp1 = &tpat[0]; /* Copy prompt */
- cp2 = prompt;
-
- while ((c = *cp2++) != '\0')
- *cp1++ = c;
-
- if ((newpat == 0) && (pat[0] != '\0')) /* Old pattern */
- {
- *cp1++ = ' ';
- *cp1++ = '[';
- cp2 = &pat[0];
-
- while ((c = *cp2++) != 0)
- {
- if (cp1 < &tpat[NPAT+20-6]) /* "??]: \0" */
- {
- if (c<0x20 || c==0x7F) {
- *cp1++ = '^';
- c ^= 0x40;
- }
- else if (c == '%') /* Map "%" to */
- *cp1++ = c; /* "%%". */
-
- *cp1++ = c;
- }
- }
-
- *cp1++ = ']';
- }
-
- *cp1++ = ':'; /* Finish prompt */
- *cp1++ = ' ';
- *cp1++ = '\0';
- s = mlreply(tpat, newpat ? newpat : tpat, NPAT); /* Read pattern */
-
- if (s == TRUE) { /* Specified */
- if( newpat == 0) strcpy(pat, tpat);
- } else if (s == FALSE && newpat == 0 && pat[0] != 0)/* CR, but old one */
- s = TRUE;
-
- return (s);
- }
-
-