home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
text
/
jed
/
src
/
jed.lha
/
find.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-16
|
9KB
|
464 lines
/*
* FIND.C
* (c) 1993 J.Harper
*/
#include "jed.h"
#include "jed_protos.h"
Prototype VALUE * cmd_find (LONG, VALUE *);
Prototype VALUE * cmd_replace (LONG, VALUE *);
Prototype BOOL findcol0 (STRPTR);
Local UBYTE SearchBuff[100];
Local UBYTE ReplaceBuff[100];
Local BOOL WildSearch;
Local BOOL CaseSearch;
#ifndef NOREGEXP
Local BOOL RESearch;
Local BOOL findREprev(VOID);
Local BOOL replaceitRE(VOID);
Local BOOL findREnext(VOID);
#endif
Local BOOL findnext(VOID);
Local BOOL findprev(VOID);
Local BOOL replaceit(VOID);
Local BOOL mystrcmp(STRPTR, STRPTR);
Local BOOL mystricmp(STRPTR, STRPTR);
/*
* (find `s' searchstring)
* (find `w' bool)
* (find `c' bool)
* (find `n')
* (find `p')
* (find `r' bool)
*/
VALUE *
cmd_find(LONG argc, VALUE *argv)
{
if(TPLATE2(VTF_STRING, VTF_ANY))
{
switch(*(ARG1.val_Value.String))
{
case 's':
if(ARG2.val_Type == VTF_STRING)
{
strncpy(SearchBuff, ARG2.val_Value.String, 99);
setnumres(TRUE);
}
else
settitle("syntax error: argument 2 should be a string");
break;
case 'w':
WildSearch = ARG2.val_Value.Number;
setnumres(TRUE);
break;
case 'c':
CaseSearch = ARG2.val_Value.Number;
setnumres(TRUE);
break;
case 'n':
#ifndef NOREGEXP
setnumres(RESearch ? findREnext() : findnext());
#else
setnumres(findnext());
#endif
resyncxy();
break;
case 'p':
#ifndef NOREGEXP
setnumres(RESearch ? findREprev() : findprev());
#else
setnumres(findprev());
#endif
resyncxy();
break;
#ifndef NOREGEXP
case 'r':
RESearch = ARG2.val_Value.Number;
setnumres(TRUE);
break;
#endif
default:
settitlefmt("error: incorrect find argument %s", (LONG)ARG1.val_Value.String);
break;
}
}
return(&RES);
}
/*
* (replace `s' repstring)
* (replace `r')
*/
VALUE *
cmd_replace(LONG argc, VALUE *argv)
{
if(TPLATE2(VTF_STRING, VTF_ANY))
{
switch(*(ARG1.val_Value.String))
{
case 's':
if(ARG2.val_Type == VTF_STRING)
{
strncpy(ReplaceBuff, ARG2.val_Value.String, 99);
setnumres(TRUE);
}
else
settitle("syntax error: argument 2 should be a string");
break;
case 'r':
if(padcursor()) /* primarily to update undo-buffer */
{
#ifndef NOREGEXP
setnumres(RESearch ? replaceitRE() : replaceit());
#else
setnumres(replaceit());
#endif
resyncxy();
}
else
setnumres(FALSE);
break;
}
}
return(&RES);
}
Local BOOL
findnext(VOID)
{
UBYTE parsed[202];
STRPTR find;
VW *vw = CurrVW;
LONG linenum = vw->vw_CursorPos.pos_Line;
LINE *line = vw->vw_Tx->tx_Lines + linenum;
LONG i = vw->vw_CursorPos.pos_Col + 1;
LONG (*cmpfunc)(STRPTR, STRPTR);
if(WildSearch)
{
LONG prc;
if(CaseSearch)
{
prc = ParsePattern(SearchBuff, parsed, 202);
cmpfunc = MatchPattern;
}
else
{
prc = ParsePatternNoCase(SearchBuff, parsed, 202);
cmpfunc = MatchPatternNoCase;
}
if(prc < 0)
{
settitle("error: can't parse pattern for wildcard search");
return(FALSE);
}
find = parsed;
}
else
{
find = SearchBuff;
cmpfunc = CaseSearch ? mystrcmp : mystricmp;
}
while(linenum < vw->vw_Tx->tx_NumLines)
{
while(i < line->ln_Strlen)
{
if(cmpfunc(find, line->ln_Line + i))
{
setautomark();
vw->vw_CursorPos.pos_Col = i;
vw->vw_CursorPos.pos_Line = linenum;
return(TRUE);
}
i++;
}
line++;
linenum++;
i = 0;
}
settitlefmt("can't find %s", (LONG)SearchBuff);
return(FALSE);
}
Local BOOL
findprev(VOID)
{
UBYTE parsed[202];
STRPTR find;
VW *vw = CurrVW;
LONG linenum = vw->vw_CursorPos.pos_Line;
LINE *line = vw->vw_Tx->tx_Lines + linenum;
LONG i = vw->vw_CursorPos.pos_Col - 1;
LONG (*cmpfunc)(STRPTR, STRPTR);
if(WildSearch)
{
LONG prc;
if(CaseSearch)
{
prc = ParsePattern(SearchBuff, parsed, 202);
cmpfunc = MatchPattern;
}
else
{
prc = ParsePatternNoCase(SearchBuff, parsed, 202);
cmpfunc = MatchPatternNoCase;
}
if(prc < 0)
{
settitle("error: can't parse pattern for wildcard search");
return(FALSE);
}
find = parsed;
}
else
{
find = SearchBuff;
cmpfunc = CaseSearch ? mystrcmp : mystricmp;
}
while(linenum >= 0)
{
while(i >= 0)
{
if(cmpfunc(find, line->ln_Line + i))
{
setautomark();
vw->vw_CursorPos.pos_Col = i;
vw->vw_CursorPos.pos_Line = linenum;
return(TRUE);
}
i--;
}
line--;
linenum--;
i = line->ln_Strlen - 2;
}
settitlefmt("can't find %s", (LONG)SearchBuff);
return(FALSE);
}
#ifndef NOREGEXP
Local BOOL
findREnext(VOID)
{
VW *vw = CurrVW;
BOOL rc = FALSE;
if(vw->vw_LastRE.prog)
free(vw->vw_LastRE.prog);
if(vw->vw_LastRE.prog = regcomp(SearchBuff))
{
LONG linenum = vw->vw_CursorPos.pos_Line;
LINE *line = vw->vw_Tx->tx_Lines + linenum;
STRPTR tstr = line->ln_Line;
if(vw->vw_CursorPos.pos_Col >= line->ln_Strlen)
tstr += line->ln_Strlen;
else
tstr += vw->vw_CursorPos.pos_Col + 1;
if(*SearchBuff == '^')
{
line++;
linenum++;
tstr = line->ln_Line;
}
while(!rc && (vw->vw_Tx->tx_NumLines > linenum))
{
if(regexec(vw->vw_LastRE.prog, tstr))
rc = TRUE;
else
{
linenum++;
line++;
tstr = line->ln_Line;
}
}
if(rc)
{
vw->vw_CursorPos.pos_Line = linenum;
vw->vw_CursorPos.pos_Col = vw->vw_LastRE.prog->startp[0] - line->ln_Line;
vw->vw_LastRE.matchpos = vw->vw_CursorPos;
vw->vw_LastRE.changes = vw->vw_Tx->tx_Changes;
}
else
{
free(vw->vw_LastRE.prog);
vw->vw_LastRE.prog = NULL;
settitle("can't find match");
}
}
return(rc);
}
Local BOOL
findREprev(VOID)
{
VW *vw = CurrVW;
BOOL rc = FALSE;
if(vw->vw_LastRE.prog)
free(vw->vw_LastRE.prog);
if(vw->vw_LastRE.prog = regcomp(SearchBuff))
{
LONG linenum = vw->vw_CursorPos.pos_Line;
LINE *line = vw->vw_Tx->tx_Lines + linenum;
STRPTR tstr = line->ln_Line;
if(vw->vw_CursorPos.pos_Col >= line->ln_Strlen)
tstr += line->ln_Strlen;
else
tstr += vw->vw_CursorPos.pos_Col + 1;
if(*SearchBuff == '^')
{
line--;
linenum--;
tstr = line->ln_Line;
}
while(!rc && (linenum > 0))
{
if(regexec(vw->vw_LastRE.prog, tstr))
rc = TRUE;
else
{
linenum--;
line--;
tstr = line->ln_Line;
}
}
if(rc)
{
vw->vw_CursorPos.pos_Line = linenum;
vw->vw_CursorPos.pos_Col = vw->vw_LastRE.prog->startp[0] - line->ln_Line;
vw->vw_LastRE.matchpos = vw->vw_CursorPos;
vw->vw_LastRE.changes = vw->vw_Tx->tx_Changes;
}
else
{
free(vw->vw_LastRE.prog);
vw->vw_LastRE.prog = NULL;
settitle("can't find match");
}
}
return(rc);
}
#endif /* NOREGEXP */
BOOL
findcol0(STRPTR str)
{
VW *vw = CurrVW;
TX *tx = vw->vw_Tx;
LINE *line = tx->tx_Lines;
LONG linenum = 0;
while(linenum < tx->tx_NumLines)
{
if(mystrcmp(str, line->ln_Line))
{
setautomark();
vw->vw_CursorPos.pos_Col = 0;
vw->vw_CursorPos.pos_Line = linenum;
vw->vw_StartLine = linenum;
vw->vw_RefreshType |= RFF_ALL;
return(TRUE);
}
linenum++;
line++;
}
return(FALSE);
}
Local BOOL
replaceit(VOID)
{
VW *vw = CurrVW;
LINE *line = vw->vw_Tx->tx_Lines + vw->vw_CursorPos.pos_Line;
WORD x = vw->vw_CursorPos.pos_Col;
BOOL rc = FALSE;
if((x < line->ln_Strlen) && (mystricmp(SearchBuff, line->ln_Line + x)))
{
WORD serlen = strlen(SearchBuff);
setrefresh(RFF_LINEFROM, x, vw->vw_CursorPos.pos_Line);
deletechars(strlen(SearchBuff));
rc = insertstr(ReplaceBuff);
vw->vw_Tx->tx_Changes++;
}
else
settitle("string under cursor doesn't match string in search buffer");
return(rc);
}
#ifndef NOREGEXP
Local BOOL
replaceitRE(VOID)
{
VW *vw = CurrVW;
BOOL rc = FALSE;
if(vw->vw_LastRE.prog)
{
if(vw->vw_LastRE.changes == vw->vw_Tx->tx_Changes)
{
if((vw->vw_CursorPos.pos_Line == vw->vw_LastRE.matchpos.pos_Line) && (vw->vw_CursorPos.pos_Col == vw->vw_LastRE.matchpos.pos_Col))
{
LONG replen = regsublen(vw->vw_LastRE.prog, ReplaceBuff);
STRPTR repstr;
setrefresh(RFF_LINEFROM, vw->vw_CursorPos.pos_Col, vw->vw_CursorPos.pos_Line);
deletechars(vw->vw_LastRE.prog->endp[0] - vw->vw_LastRE.prog->startp[0]);
if(replen && (repstr = AllocVec(replen, 0)))
{
regsub(vw->vw_LastRE.prog, ReplaceBuff, repstr);
rc = insertstr(repstr);
FreeVec(repstr);
}
else if(replen)
settitle(NoMemMsg);
vw->vw_Tx->tx_Changes++;
}
else
settitle("error: cursor not at match position");
}
else
{
free(vw->vw_LastRE.prog);
vw->vw_LastRE.prog = NULL;
settitle("error: file has changed since last RE match");
}
}
else
settitle("error: must match the RE before replacing it");
return(rc);
}
void
regerror(char *err)
{
settitle(err);
}
#endif /* NOREGEXP */
/*
* These functions return TRUE if the strings match, if str1 ends before
* str2 they are still considered to be matching.
*/
Local BOOL
mystrcmp(STRPTR str1, STRPTR str2)
{
while(*str1 && (*str1 == *str2++))
str1++;
if(!(*str1))
return(TRUE);
return(FALSE);
}
Local BOOL
mystricmp(STRPTR str1, STRPTR str2)
{
while(*str1 && ((toupper(*str1) == toupper(*str2++))))
str1++;
if(!(*str1))
return(TRUE);
return(FALSE);
}