home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD2.mdf
/
c
/
newemacs
/
search.c
< prev
next >
Wrap
Text File
|
1979-12-31
|
8KB
|
363 lines
/*
* 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.
*/
#include <stdio.h>
#include "ed.h"
/*
* 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 "M-S".
*/
forwsearch(f, n)
{
register LINE *clp;
register int cbo;
register LINE *tlp;
register int tbo;
register int c;
register char *pp;
register int s;
if ((s=readpattern("Search")) != TRUE)
return (s);
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)) {
tlp = clp;
tbo = cbo;
pp = pat+1;
while (*pp) {
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++))
goto fail;
}
curwp->w_dotp = tlp;
curwp->w_doto = tbo;
curwp->w_flag |= WFMOVE;
return (TRUE);
}
fail: ;
}
mlwrite("Not found");
scr_co(0x07) ;
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 matched]. Bound to "M-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")) != TRUE)
return (s);
for (epp = pat; epp[1]; ++epp)
;
clp = curwp->w_dotp;
cbo = curwp->w_doto;
for (;;) {
if (!cbo) {
clp = lback(clp);
if (clp == curbp->b_linep) {
mlwrite("Not found");
scr_co(0x07) ;
return (FALSE);
}
cbo = llength(clp)+1;
}
if (--cbo == llength(clp))
c = '\n';
else
c = lgetc(clp, cbo);
if (eq(c, *epp)) {
tlp = clp;
tbo = cbo;
pp = epp;
while (pp != pat) {
if (!tbo) {
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))
goto fail;
}
curwp->w_dotp = tlp;
curwp->w_doto = tbo;
curwp->w_flag |= WFMOVE;
return (TRUE);
}
fail: ;
}
}
/*
* Compare two characters: "bc" is the buffer character, "pc" is the
* pattern character. If pattern character is upper case, buffer character
* must also be upper case; else, case is irrelevant.
*/
eq(bc, pc)
register int bc;
register int pc;
{
if ('A'<=pc && pc<='Z') return (bc==pc);
if (bc>='a' && bc<='z') bc -= 0x20;
if (pc>='a' && pc<='z') pc -= 0x20;
return (bc == pc);
}
/*
* 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.
*/
readpattern(prompt)
char *prompt;
{
register char *cp1;
register char *cp2;
register int c;
register int s;
char tpat[NPAT+20];
cp1 = tpat; /* Copy prompt */
cp2 = prompt;
while (c = *cp2++)
*cp1++ = c;
if (*pat) { /* Old pattern */
*cp1++ = ' ';
*cp1++ = '[';
cp2 = pat;
while (c = *cp2++) {
if (cp1 < tpat+NPAT+14) { /* "??]: \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 */
strcpy(pat, tpat);
else if (s==FALSE && *pat) /* CR, but old one */
s = TRUE;
return (s);
}
/*
* Query and replace.
* 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,
* delete N characters backwards where N
* is the length of the search string,
* insert the replacement string,
* and repaint the display.
*/
query_replace(f, n)
{
register LINE *clp;
register int cbo;
register LINE *tlp;
register int tbo;
register int c;
register int s;
register char *pp;
register int found;
char s_pat[NPAT];
if ((s=readpattern("Query Replace")) != TRUE) return (s);
strcpy(s_pat,pat);
*pat = '\0';
if ((s=readpattern("With")) != TRUE) return (s);
found = 0;
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, *s_pat)) {
tlp = clp;
tbo = cbo;
pp = s_pat+1;
while (*pp) {
if (tlp == curbp->b_linep) goto done;
if (tbo == llength(tlp)) {
tlp = lforw(tlp);
tbo = 0;
c = '\n';
} else c = lgetc(tlp, tbo++);
if (!eq(c, *pp++)) goto fail;
}
curwp->w_dotp = tlp;
curwp->w_doto = tbo;
curwp->w_flag |= WFMOVE;
mlwrite("Replace ? (Y/N):");
update();
c = scr_ci() ;
if (c=='y' || c=='Y' || c==' ') {
for (pp=s_pat; *pp; pp++) backdel(FALSE,1);
for (pp=pat; *pp; pp++) linsert(1,*pp);
}
else if (c==0x07) {
scr_co(0x07) ;
goto done;
}
found = 1;
if (f && !--n) break;
}
fail: ;
}
if (!found) {
mlwrite("Not found");
scr_co(0x07) ;
strcpy(pat,s_pat);
return (FALSE);
}
done:
movecursor(NROW, 0);
scr_clrl() ;
strcpy(pat,s_pat);
return (found);
}
/*
* Search and replace.
* 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,
* delete N characters backwards where N
* is the length of the search string,
* insert the replacement string,
* and repaint the display.
*/
search_replace(f, n)
{
register LINE *clp;
register int cbo;
register LINE *tlp;
register int tbo;
register int c;
register int s;
register char *pp;
register int found;
char s_pat[NPAT];
if ((s=readpattern("Replace")) != TRUE) return (s);
strcpy(s_pat,pat);
*pat = '\0';
if ((s=readpattern("With")) != TRUE) return (s);
found = 0;
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, *s_pat)) {
tlp = clp;
tbo = cbo;
pp = s_pat+1;
while (*pp) {
if (tlp == curbp->b_linep) goto done;
if (tbo == llength(tlp)) {
tlp = lforw(tlp);
tbo = 0;
c = '\n';
} else c = lgetc(tlp, tbo++);
if (!eq(c, *pp++)) goto fail;
}
curwp->w_dotp = tlp;
curwp->w_doto = tbo;
curwp->w_flag |= WFMOVE;
for (pp=s_pat; *pp; pp++) backdel(FALSE,1);
for (pp=pat; *pp; pp++) linsert(1,*pp);
found = 1;
if (f && !--n) break;
}
fail: ;
}
if (!found) {
mlwrite("Not found");
scr_co(0x07) ;
strcpy(pat,s_pat);
return (FALSE);
}
done:
movecursor(NROW, 0);
scr_clrl() ;
strcpy(pat,s_pat);
return (found);
}