home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
text
/
editors
/
'liner_394
/
source
/
search.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-28
|
11KB
|
327 lines
/* Search.c */
/*The routines in this module handle the search/replace functions of 'Liner*/
#include "Globals.h"
#include "SearchWdws.h"
#define MAYBE 2
#define NONONO 3
struct SearchParameters
{
char Search[80],Replace[80];
BYTE rep,cse,partial;
};
struct SearchParameters parameters =
{
"","",FALSE,FALSE,TRUE
};
struct Window *SearchWdw,*ReplAllWdw;
GetSRParameters() /*Opens a window to get the parameters for Search/Replace*/
{
int status;
NewSearchWindow.Screen=(struct Screen *)Screen;
SearchWdw=(struct Window *)OpenWindow(&NewSearchWindow);
if(SearchWdw==NULL)
{
Leave(0,"Can't open the search/replace window!");
return(FALSE);
}
PrintIText(SearchWdw->RPort,&IntuiTextList1,0,0);
ActivateGadget(&SearchFor,SearchWdw,NULL);
/*Activate the Search for... text gadget*/
while((status=MonitorButtons())==NONONO); /*Let user enter info*/
if(status) /*OK, Cancel, or Wait*/
{
parameters.rep = !((SrchRplc.Flags & SELECTED)==FALSE);
parameters.partial = ((PartialWord.Flags & SELECTED)==FALSE);
parameters.cse = !((CaseSensitive.Flags & SELECTED)==FALSE);
strcpy(parameters.Search,SearchForSInfo.Buffer);
strcpy(parameters.Replace,ReplaceWithSInfo.Buffer);
if(status==MAYBE)
status=FALSE;
}
else
{ /*Another gadget was toggled*/
strcpy(SearchForSInfo.Buffer,parameters.Search);
strcpy(ReplaceWithSInfo.Buffer,parameters.Replace);
SrchRplc.Flags = (parameters.rep)
? GADGHIMAGE+GADGIMAGE+SELECTED : GADGHIMAGE+GADGIMAGE;
PartialWord.Flags = (parameters.partial)
? GADGHIMAGE+GADGIMAGE : GADGHIMAGE+GADGIMAGE+SELECTED;
CaseSensitive.Flags = (parameters.cse) ? GADGHIMAGE+GADGIMAGE+SELECTED
: GADGHIMAGE+GADGIMAGE;
}
CloseWindow(SearchWdw);
return(status);
}
MonitorButtons() /*Monitor the IDCMP port*/
{
ULONG Class;
struct Gadget *gadg;
struct IntuiMessage *mesg;
for(;;)
{
Wait(1<<SearchWdw->UserPort->mp_SigBit);
while((mesg=(struct IntuiMessage *)GetMsg(SearchWdw->UserPort))!=NULL)
{
Class=mesg->Class; /*Get the information*/
gadg=mesg->IAddress;
ReplyMsg(mesg); /*Reply to the message*/
switch(Class)
{
case CLOSEWINDOW: /*Close gadget == CANCEL*/
return(FALSE);
case GADGETUP:
switch(gadg->GadgetID)
{
case 8: /*Cancel*/
return(FALSE);
case 7: /*Wait*/
return(MAYBE);
case 6: /*OK*/
return(TRUE);
case 1:
ActivateGadget(&ReplaceWith,SearchWdw,NULL);
/*Activate the Replace with... string gadget when*/
/*the user presses RETURN in the Search for...*/
/*gadget*/
return(NONONO); /*Don't alter a flag :-) */
}
}
}
}
}
extern struct LineItem *SearchText(Item,Pos,string,scase,partial)
/*Search an outline for a particular string of characters*/
struct LineItem *Item; /*Item to start searching on*/
USHORT *Pos; /*Position in that item to start on*/
char *string; /*Search string*/
BYTE scase,partial; /*scase - TRUE if case matters, FALSE otherwise*/
/*partial-TRUE if it may be a part of a word*/
{
int c,found,start,thestart;
struct LineItem *cur,*theitem;
BYTE status=FALSE;
char chr,fchr;
if(!scase) /*If case sensitive, convert the string to all uppercase*/
for(c=0;c<strlen(string);c++)
string[c]=toupper(string[c]);
if(*Pos >= strlen(Item->Text)) /*If at the end of the line*/
{
start=0; /*Start of next line*/
Item=(struct LineItem *)Item->NextItem;
}
else
start=*Pos; /*Else, start at cursor position*/
for(cur=(struct LineItem *)Item;cur != NULL && !status;/*Search until end*/
cur=(struct LineItem *)cur->NextItem) /*or text is found*/
for(c=start;c<strlen(cur->Text) && !status ;++c)
{ /*Loop that searches each line: */
start=0;
if((partial) || ( (!partial) && ((c==0) || (cur->Text[c-1]==' ') )))
/*If partial words are OK, or if not, if the character*/
/*currently being checked is the first letter in a word*/
{
if(!scase) /*If case is important*/
chr=toupper(cur->Text[c]); /*Switch to uppercase (see above)*/
else
chr=cur->Text[c];
if(string[0]==chr) /*If first character matches...*/
{
status=TRUE;
theitem=(struct LineItem *)cur;
thestart=c;
for(found=1;found<strlen(string) && status ;found++)
{ /*see if the rest matches...*/
if(!scase)
fchr=toupper(cur->Text[c+found]);
else
fchr=cur->Text[c+found];
if(fchr!=string[found])
status=FALSE;
} /*If the word is a prefix of another word*/
if(cur->Text[c+found] != ' ' && cur->Text[c+found]!= NULL &&
!partial)
status = FALSE; /*return FALSE*/
}
}
}
if(status) /*If found...*/
{
*Pos=thestart; /*Return the position of the start of the text*/
return(theitem); /*And the item that it is found in*/
} /*(so that the cursor can be moved accordingly)*/
else
return(NULL); /*Otherwise, nothing*/
}
DoSearch(again,arexx) /*Main entry point for 'Search/Replace' and 'Next'*/
BYTE again,arexx; /*Again: TRUE if 'Next', FALSE if 'Search/Replace'*/
{
char Buffer[8],reslt[160],preservation[80];
int status;
UBYTE TempY;
struct LineItem *tempitem,*result;
struct LineItem *firstitem=(struct LineItem *)CurrentItem;
USHORT Pos=(again && again != 100) ? CurX-MinX(CurrentItem)+1 :
CurX-MinX(CurrentItem);
status = (again) ? TRUE : GetSRParameters();
/*If 'Next', search no matter what. Otherwise, depends on user*/
CancelInvs(); /*Cancel text highlighting*/
if(ErrorInTitle) /*Cancel any errors in the title bar*/
TitleErrorCancel();
if(status) /*If it's OK to search*/
{
strcpy(preservation,parameters.Search); /*Store the search string*/
/*so if SearchText turns it to all caps, we'll still have the*/
/*original*/
result=(struct LineItem *) /*Search the text*/
SearchText(CurrentItem,&Pos,parameters.Search,parameters.cse,
parameters.partial);
if(result!=NULL) /*If found...*/
{
/*Place the cursor at the start of the word*/
if(result!=FirstScrnItem || result!=firstitem)
{
FirstScrnItem=CurrentItem=(struct LineItem *)result;
PrintItemList(CurrentItem,1);
}
PlotCursor(MinX(CurrentItem)+Pos,1);
if(parameters.rep) /*If a search and replace*/
{ /*Replace!!!!*/
strcpy(reslt,&(CurrentItem->Text[Pos+strlen(parameters.Search)]));
strins(reslt,parameters.Replace);
CurrentItem->Text[Pos]=NULL;
strins(reslt,CurrentItem->Text);
/*Break the line apart if necessary*/
tempitem=(struct LineItem *)BreakLineApart(CurrentItem,
CurrentItem->NextItem,reslt);
PlotCursor(1,CurY);
Buffer[0]=CSI;
Buffer[1]=0x4b;
WriteConsole(Buffer,2);
TempY=CurY;
if(tempitem==CurrentItem)
PrintItem(CurrentItem);
else
PrintItemList(CurrentItem,CurY);
PlotCursor(MinX(CurrentItem)+Pos,TempY);
CheckModified(); /*Text has been modified*/
}
strcpy(parameters.Search,preservation);
return(TRUE);
}
else /*If it wasn't found*/
{
strcpy(parameters.Search,preservation);
if(!arexx) /*If this wasn't an ARexx command*/
TitleError("Wasn't found!!!");
return(FALSE);
}
}
}
void ModifyParams(search,replace,case_s,partial,s_repl)
char *search,*replace;
BYTE case_s,partial,s_repl;
{
if(search[0]!=NULL)
strcpy(parameters.Search,search);
if(replace[0]!=NULL)
strcpy(parameters.Replace,replace);
if(case_s!=100)
parameters.cse=case_s;
if(partial!=100)
parameters.partial=partial;
if(s_repl!=100)
parameters.rep=s_repl;
}
void ReplaceAll(verify) /*Search/replace entire document at once*/
BYTE verify;
{
BYTE stat;
if(verify)
{
ModifyParams("","",100,100,FALSE);
while(DoSearch(TRUE,TRUE)) /*Search for text*/
{
if(stat=AskChange()) /*Ask user what to do*/
{
if(stat==TRUE) /*Replace*/
{
ModifyParams("","",100,100,TRUE);
DoSearch(100,TRUE);
ModifyParams("","",100,100,FALSE);
} /*Else goto next*/
}
else
return; /*Else cancel*/
}
TitleError("No more found");
}
else /*Do all without verification*/
{
ModifyParams("","",100,100,TRUE);
while(DoSearch(TRUE,TRUE));
}
}
BYTE AskChange() /*Ask user if he wants to do replace*/
{
struct Window *ReplAllWdw;
struct IntuiMessage *mesg;
struct Gadget *gadg;
NewWindowStructure2.Screen=(struct Screen *)Screen; /*'Liner screen*/
if((ReplAllWdw=(struct Window *)OpenWindow(&NewWindowStructure2))==NULL)
return(FALSE); /*Open the window*/
PrintIText(ReplAllWdw->RPort,&IntuiTextList2,0,0);
Wait(1<<ReplAllWdw->UserPort->mp_SigBit); /*Wait for gadget press*/
if((mesg=(struct IntuiMessage *)GetMsg(ReplAllWdw->UserPort))==NULL)
{
CloseWindow(ReplAllWdw);
return(FALSE); /*Get the message*/
}
gadg=(struct Gadget *)mesg->IAddress;/*Get the gadget structure's addr*/
ReplyMsg(mesg); /*Reply to it*/
CloseWindow(ReplAllWdw); /*Close the window*/
return(gadg->GadgetID); /*Return the gadget ID*/
}
/*End of Search.c*/