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.
- * prabhaker mateti, 3/2/86, - ^S/^R in search to next forw/backsearch
- */
-
- #include "ed.h"
-
- static char NOTFOUND[] = "Not found";
-
- /*
- * 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;
-
- s = readpattern("Forward Search");
- if ((s == ABORT) || (s == FALSE)) return (s);
- if (s == 0x12) return (bsearch(f, n));
- return(fsearch(f, n));
- }
-
-
- fsearch(f, n)
- {
- 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:;
- }
-
- mlwrite(NOTFOUND);
- 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 int s;
-
- s = readpattern("Backward Search");
- if ((s == ABORT) || (s == FALSE)) return (s);
- if (s == 0x13) return (fsearch(f, n));
- return(bsearch(f, n));
- }
-
-
- bsearch(f, n)
- {
- register LINE *clp;
- register int cbo;
- register LINE *tlp;
- register int tbo;
- register int c;
- register char *epp;
- register char *pp;
-
- 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(NOTFOUND);
- 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. 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.
- * Returns: ABORT, TRUE, FALSE, FORWARD, REVERSE
- */
- readpattern(prompt)
- char *prompt;
- {
- register char *cp1;
- register char *cp2;
- register int c;
- register int s;
- register int i;
- char tpat[NPAT+20];
-
- cp1 = &tpat[0]; /* Copy prompt */
- cp2 = prompt;
-
- while ((c = *cp2++) != '\0')
- *cp1++ = c;
-
- if (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, tpat, NPAT); /* Read pattern */
-
- if (s == TRUE) /* Specified */
- {
- i = strlen(tpat); /* i will be > 0, because mlreply */
- c = tpat[i-1]; /* was true */
- if ((c == 0x12) || (c == 0x13)) {
- tpat[--i] = (char) 0;
- s = c;
- }
- if (i > 0) strcpy(pat, tpat);
- } else if (s == FALSE && pat[0] != 0) /* CR, but old one */
- s = TRUE;
-
- return (s);
- }
-
- /* -eof- */
-