
#include	"sysdef.h"

/*	General text searching						*/



/*+	vtfnext()							*/
/*+	vtprfnext()							*/
/*+	vtflast()							*/
/*+	vtprflast()							*/
/*+	vtrepnext()							*/
/*+	vtsetpat()							*/
/*+	vtsetrep()							*/
/*+	fnext(srpat,srlen,stopline)					*/
/*+	flast(srpat,srlen)						*/
/*+	repnext(old,new,stopline)					*/
/*+	vtsent()							*/
/*+	vtdorep()							*/
/*+	vtepara()							*/
/*+	vtnpara()							*/



#include	"scerrd.h"
#include	"tempio.h"
#define	then
#define	CR	015
#define	FF	014
#define	LF	012
#define	SPACE	040
#define	TAB	011

extern int  chposition,*curline,curposition,*loclow,*lochigh ;

static CHAR repstr[]  = "Replacement String ? " ;
static CHAR srchstr[] = "Search string ? " ;
static CHAR nullstr[] = {0,0} ;

struct	patline	{
		CHAR c[64] ;
		int  len ;
		} ;

struct	pat	{
		struct patline oldpat ;
		struct patline newpat ;
		struct patline newcomp ;
		struct patline oldcomp ;
		struct patline readbuffer ;
		} ;

extern struct pat patbuf ;




vtfnext(mode)
{
	extern int *maxline ;

	register int status ;
	if ( patbuf.oldpat.len && patbuf.oldcomp.len )
	  then
	   status = xxfnext(patbuf.oldcomp.c,patbuf.oldcomp.len,*maxline,mode);
	  else	status = vtprfnext(mode) ;
	if ( status == 0 ) then macfinish() ;
	return( status ) ;
}
			
vtprfnext(mode)
{
	extern int *maxline ;

	if ( getoldpat(nullstr) )
	  then
	   return(xxfnext(patbuf.oldcomp.c,patbuf.oldcomp.len,*maxline,mode)) ;
	  else	return( 0 ) ;
}


vtflast()
{
	register int status ;
	if ( patbuf.oldpat.len && patbuf.oldcomp.len )
	  then	status = xxflast(patbuf.oldcomp.c,patbuf.oldcomp.len) ;
	  else	status = vtprflast() ;
	if ( status == 0 ) then macfinish() ;
	return( status ) ;
}
			

vtprflast()
{
	if ( getoldpat(nullstr) )
	  then	return( xxflast(patbuf.oldcomp.c,patbuf.oldcomp.len) ) ;
	  else	return( 0 ) ;
}


vtrepnext()
{
	extern int *maxline ;
	register int status ;

	if ( patbuf.oldpat.len == 0 )
	  then if ( getoldpat(nullstr) == 0 ) then return(0) ;
	if ( patbuf.newpat.len && patbuf.newcomp.len )
	  then	return( repnext(&patbuf.oldcomp,&patbuf.newcomp,*maxline) ) ;
	  else	{
	    status = getnewpat(nullstr) ;
	    if ( status )
	       then return(repnext(&patbuf.oldcomp,&patbuf.newcomp,*maxline));
	       else return( status ) ;
		}
}


vtsetpat()
{
	return( getoldpat(nullstr) ) ;
}

vtsetrep()
{
	return( getnewpat(nullstr) ) ;
}



/*	GETOLDPAT	read and 'compile' the sreach string from TT	*/
/*	GTENEWPAT	read the replacement string from TT		*/



static getoldpat(def)
CHAR *def ;
{
	register int i,status ;

	ceol24() ;
	if ((patbuf.oldpat.len=lgetdef(patbuf.oldpat.c,srchstr,def))==0)
	  then	{
		scwarning(w_badpt) ;
		status = 0 ;
		}
	  else	{
		i=scompile(patbuf.oldpat.c,patbuf.oldpat.len,patbuf.oldcomp.c);
		if ( (patbuf.oldcomp.len=i) == 0 )
		  then	{
			scwarning(w_badpt) ;
			status = 0 ;
			}
		  else	status = 1 ;
		}
	goback() ;
	return(status) ;
}


static getnewpat(def)
CHAR *def ;
{
	register status ;
	register int i ;
	register CHAR *cp,*dp ;

	ceol24() ;
	patbuf.newpat.len=lgetdef(patbuf.newpat.c,repstr,def) ;
	if ( patbuf.newpat.len )
	  then	{
		status = patbuf.newpat.len ;
		cp = patbuf.newpat.c ;
		dp = patbuf.newcomp.c ;
		for (i=patbuf.newpat.len; i>0; i-- ) *dp++ = *cp++ ;
		}
	  else	{
		scwarning(w_badpt) ;
		status = 0 ;
		}
	goback() ;
	patbuf.newcomp.len = patbuf.newpat.len ;
	return( status ) ;
}




xxfnext(srpat,srlen,stopline,mode)
CHAR *srpat ;
int srlen,stopline,mode ;
{
	register int status ;
	extern int working() ;

	settimerast(2,working) ;
	status = ( mode ) ?fnext(srpat,srlen,stopline)
			  :not_fnext(srpat,srlen,stopline) ;
	cantimerast() ;
	return( status ) ;
}

fnext(srpat,srlen,stopline)
CHAR *srpat ;
int srlen,stopline ;
{
	register int offset,pos ;
	int oldcurline,status ;
	extern int *curline,chposition,curposition,*lochigh,*maxline,worklength ;
	extern int read_only ;
	extern CHAR workbuffer[] ;
	extern struct textline *textpointer() ;
	struct textline *tp ;
	

	status = 0 ;			/* assume the search will fail	*/
	oldcurline = *curline ;		/* save the old current line #	*/
	offset = chposition+1 ;
	if ((pos=finstr(&workbuffer[offset],worklength-offset,srpat,srlen))==0)
	  then	{
	    offset = 0 ;
	    scunloadline() ;
	    while ( ++(*curline) < stopline ) {
		tp = textpointer( *curline ) ;
		if (testcc() || read_only
			     ||	(pos=finstr(tp->c,tp->len,srpat,srlen)))
		  then	break ;
		  }
		}
	cantimerast() ;
	if ( pos == 0 )
	  then	{
		*curline = oldcurline ;
		scloadline() ;
		scwarning( w_nopat ) ;
		status = 0 ;
		}
	  else	{
		if ( *curline > *lochigh ) then cnpage( *curline ) ;
		if ( *curline != oldcurline ) then scloadline() ;
		chposition = pos + offset - 1 ;
		fixposition() ;
		scmove() ;
		status = chposition+1 ;
		}
	return( status ) ;
}

		


xxflast(srpat,srlen)
CHAR *srpat ;
int srlen ;
{
	register int status ;
	extern int working() ;

	settimerast(2,working) ;
	status = flast(srpat,srlen) ;
	cantimerast() ;
	return( status ) ;
}

flast(srpat,srlen)
CHAR *srpat ;
int srlen ;
{
	register int i,size ;
	register CHAR *cp ;
	int oldcurline,pos,status,temp ;
	extern int *curline,chposition,curposition,*loclow,*maxline,worklength ;
	extern CHAR workbuffer[] ;


	status = 0 ;			/* assume the search will fail	*/
	oldcurline = *curline ;		/* save the old current line #	*/
	size = chposition ;
	scunloadline() ;
	scloadline() ;
	cp = workbuffer ;
	while ( *curline > 0 ) {
		if ((pos=finstr(cp,size,srpat,srlen)) != 0 || testcc()) break ;
		if ( --(*curline) > 0 ) then scloadline() ;
		size = worklength ;
		}
	if ( pos == 0 )
	  then	{
		*curline = oldcurline ;
		scloadline() ;
		scwarning( w_nopat ) ;
		status = 0 ;
		}
	  else	{
		if ( *curline < *loclow ) then cnpage( *curline ) ;
		scloadline() ;
		temp = size ;
		size = 0 ;
		cp = &workbuffer[temp] ;
		for ( i=temp; i > 0; i-- )
		  if ((pos=finstr(--cp,++size,srpat,srlen)) != 0) then break ;
		if ( pos != 0 )
		  then	{
			chposition = i - 1 ;
			fixposition() ;
			scmove() ;
			status = chposition ;
			}
		}
	return( status ) ;
}



/*	REPNEXT		replace next occurance of pattern		*/

repnext(old,new,stopline)
struct patline *old,*new ;
int stopline ;
{
	extern int chposition,curposition,read_only ;
	register CHAR *cp,*np ;
	register int i ;
	int oldchposition,pos ;
	CHAR ch,savebuffer[64] ;


	if ( ( pos = fnext( old->c,old->len,stopline ) ) == 0 )
	  then	return(0) ;
	  else	{
		if ( read_only ) then return(0) ;
		oldchposition = chposition ;
		pos-- ;
		cp = savebuffer ;
		for ( i=64; i>0; i-- ) *cp++ = 0 ;
		cp = savebuffer ;
		for ( i=old->len; i>0; i-- ) *cp++ = remchar(pos);
		cp = savebuffer ;
		np = new->c ;
		for ( i=new->len; i>0; i-- ) {
			if ( ( *np & 0300 ) == 0300 )
			  then	ch = *cp++ ;
			  else	ch = *np++ ;
			svinsert(pos++,&ch,1) ;
		}
		chposition = oldchposition ;
		fixposition() ;
		scmove() ;
		lkill() ;
		partdump() ;
		chposition = oldchposition + new->len - 1 ;
		fixposition() ;
		scmove() ;
		return(1) ;
		}
}


vtdorep()
{
	CHAR savetext[64] ;
	register CHAR *cp,*dp ;
	register int i ;
	int oldchposition,oldcurposition,oldcurline ;

	dp = savetext ;
	cp = patbuf.oldpat.c ;
	for (i=patbuf.oldpat.len; i>0; i--) *dp++ = *cp++ ;
	*dp = 0 ;
	if ( getoldpat(savetext) == 0 ) then return(0) ;
	dp = savetext ;
	cp = patbuf.newpat.c ;
	for (i=patbuf.newpat.len; i>0; i--) *dp++ = *cp++ ;
	*dp = 0 ;
	if ( getnewpat(savetext) == 0 ) then return(0) ;

	oldchposition = chposition ;
	oldcurposition = curposition ;
	oldcurline = *curline ;
	creset() ;
	while ( repnext(&patbuf.oldpat,&patbuf.newpat,(*lochigh)+1) ) ;
	scunloadline() ;
	chposition = oldchposition ;
	curposition = oldcurposition ;
	*curline = oldcurline ;
	scloadline() ;
	scmove() ;
	return(1) ;
}
		  





static not_fnext(srpat,srlen,stopline)
CHAR *srpat ;
int srlen,stopline ;
{
	int status ;
	extern int *curline, *lochigh ;
	extern int read_only ;
	extern struct textline *textpointer() ;
	struct textline *tp ;
	
	status = 0 ;			/* assume the search will fail	*/
	scunloadline() ;
	while ( ++(*curline) < stopline ) {
		tp = textpointer( *curline ) ;
		if (testcc() || read_only
			     ||	finstr(tp->c,tp->len,srpat,srlen) == 0 )
		  then	break ;
		} ;
	creset() ;
	cantimerast() ;
	if ( *curline > *lochigh ) then cnpage( *curline ) ;
	scloadline() ;
	scmove() ;
	return( 1 ) ;
}
