	include	ed.inc

	.code

reBraces	equ	1
reAsterisk	equ	2
reDollar	equ	4
rePeriod	equ	10h

	Loc	Len,word,1
	Loc	SearchOptions,word,1
	Loc	Cnt,word,1
	Loc	BracesBegin,word,1
	Loc	BracesEnd,word,1
	Loc	BufPtr,word,1
	Loc	RealLength,word,1
	Loc	Flags,word,1
	Loc	StartCol,word,1
	Loc	EndCol,word,1
	Loc	SaveCurLine,word,1
	Loc	Increment,word,1
	Loc	LineChanged,word,1
	Loc	CurLine,word,1
	Loc	CurCol,word,1
	Loc	FinCol,word,1
	Loc	OrigX,word,1
	Loc	OrigY,word,1
	Loc	MaxOffset,word,1
	Loc	FinLine,word,1
	Loc	Buffer,byte,160

Init	proc	near
	mov	ax,Len
	mov	RealLength,ax
	lea	si,Buffer
	mov	BufPtr,si
	mov	al,ss:[si]
	ret
Init	endp

GetToken	proc	near
	cld
	mov	Flags,0
	mov	cx,RealLength
	mov	si,BufPtr
	jcxz	@@6
	mov	BracesBegin,si
	segss	lodsb
	dec	cx
	mov	BracesEnd,si
	mov	BufPtr,si
	jcxz	@@1
	cmp	al,'['
	je	@@8
	cmp	al,'\'
	jne	@@1
	segss	lodsb
	dec	cx
	mov	BracesEnd,si
	mov	BufPtr,si
	jcxz	@@3
	jmp	@@2
@@1:	cmp	al,'.'
	jne	@@2
	or	Flags,rePeriod
@@2:	jcxz	@@4
	mov	ah,ss:[si]
	cmp	ah,'*'
	je	@@7
	cmp	ah,'+'
	je	@@7
@@3:	mov	RealLength,cx
	mov	ah,0
	clc
	ret
@@4:	mov	RealLength,cx
	mov	ah,0
	cmp	al,'$'
	je	@@5
	clc
	ret
@@5:	or	Flags,reDollar
	ret
@@6:	stc
	ret
@@7:	or	Flags,reAsterisk
	dec	cx
	mov	RealLength,cx
	inc	si
	mov	BufPtr,si
	clc
	ret
@@8:	segss	lodsb
	cmp	al,']'
	loopne	@@8
	je	@@9
	mov	si,BracesEnd
	jmp	@@2
@@9:	or	Flags,reBraces
	mov	RealLength,cx
	mov	BracesEnd,si
	mov	BufPtr,si
	jmp	@@2
GetToken	endp

ProcessBraces	proc	near
	mov	si,BracesBegin
	mov	al,es:[di]
	test	SearchOptions,esIgnoreCase
	jz	@@1
	cmp	al,'A'
	jb	@@1
	cmp	al,'Z'
	ja	@@1
	xor	al,20h
@@1:	mov	dx,BracesEnd
	dec	dx
	cmp	byte ptr ss:[si+1],'^'
	jne	@@2
	inc	si
@@2:	inc	si
	cmp	si,dx
	jae	@@7
	cmp	byte ptr ss:[si],'-'
	je	@@5
	cmp	al,ss:[si]
	jne	@@2
@@3:	mov	si,BracesBegin
	cmp	byte ptr ss:[si+1],'^'
	je	@@8
@@4:	clc
	ret
@@5:	cmp	al,ss:[si-1]
	jb	@@6
	cmp	al,ss:[si+1]
	jbe	@@3
@@6:	inc	si
	jmp	@@2
@@7:	mov	si,BracesBegin
	cmp	byte ptr ss:[si+1],'^'
	je	@@4
@@8:	stc
	ret
ProcessBraces	endp

Compare	proc	near
	mov	ax,CurLine
	mov	FinLine,ax
	mov	SaveCurLine,dx
	lea	ax,[bx+size LineHeader]
	mov	dx,di
	sub	dx,ax
	mov	CurCol,dx
	add	ax,es:[bx].LineLength
	mov	MaxOffset,ax
	mov	LineChanged,0
	cld
	mov	ax,cx
	mov	cx,Len
	push	ax
	dec	cx
	jz	@@7
@@1:	segss	lodsb
	cmp	al,0dh
	jne	@@2
	cmp	di,MaxOffset
	jne	@@5
	inc	FinLine
	mov	ax,FinLine
	mov	LineChanged,ax
	push	cx si
	Invoke	FindLine
	Invoke	UseCurPage
	pop	si cx
	jc	@@5
	cmp	bx,dx
	je	@@5
	lea	di,[bx+size LineHeader]
	mov	ax,di
	add	ax,es:[bx].LineLength
	mov	MaxOffset,ax
	jmp	@@3
@@2:	cmp	di,MaxOffset
	jae	@@5
	test	SearchOptions,esIgnoreCase
	jz	@@4
	cmp	al,'a'
	jb	@@4
	cmp	al,'z'
	ja	@@4
	xor	al,es:[di]
	inc	di
	and	al,0dfh
	jnz	@@5
@@3:	loop	@@1
	jmp	@@7
@@4:	scasb
	je	@@3
@@5:	cmp	LineChanged,0
	je	@@6
	mov	ax,CurLine
	Invoke	FindLine
	Invoke	UseCurPage
@@6:	mov	di,SaveCurLine
	pop	cx
	stc
	ret
@@7:	test	SearchOptions,esSelectedText
	jz	@@8
	mov	ax,ds:BlockEnd.Y
	cmp	ax,FinLine
	jb	@@5
	ja	@@8
	lea	ax,[bx+size LineHeader]
	mov	si,di
	sub	si,ax
	cmp	si,ds:BlockEnd.X
	jae	@@5
@@8:	test	SearchOptions,esWholeWordsOnly
	jz	@@10
	cmp	LineChanged,0
	jne	@@5
	mov	si,di
	sub	si,Len
	dec	si
	lea	ax,[bx+size LineHeader]
	cmp	si,ax
	jbe	@@9
	push	di
	mov	di,bx
	mov	bx,si
	Invoke	CheckDelim
	Invoke	SetEditDS
	mov	bx,di
	pop	di
	jnz	@@5
@@9:	xchg	bx,di
	Invoke	CheckDelim
	Invoke	SetEditDS
	xchg	bx,di
	jnz	@@5
@@10:	pop	ax
	mov	dx,di
	sub	dx,bx
	sub	dx,size LineHeader-1
	mov	FinCol,dx
	mov	dx,SaveCurLine
	clc
	ret
Compare	endp

CompareChar	proc	near
	test	Flags,reBraces+rePeriod
	jnz	@@1
	cmp	al,es:[di]
	je	@@4
	test	SearchOptions,esIgnoreCase
	jz	@@3
	cmp	al,'a'
	jb	@@3
	cmp	al,'z'
	ja	@@3
	xor	al,20h
	cmp	al,es:[di]
	je	@@4
	jmp	@@3
@@1:	test	Flags,reBraces
	jz	@@2
	call	ProcessBraces
	jnc	@@4
	jmp	@@3
@@2:	test	Flags,rePeriod
	jnz	@@4
@@3:	stc
	ret
@@4:	clc
	ret
CompareChar	endp

RegCompare	proc	near
	push	di
	push	cx si
	push	Cnt
	push	Flags
	push	BufPtr
	push	RealLength
	push	BracesBegin
	push	BracesEnd
	push	di
	mov	ax,RealLength
	test	ax,ax
	jz	@@8
	mov	ax,EndCol
	sub	ax,di
	jz	@@9
	jg	@@1
	neg	ax
@@1:	mov	Cnt,ax
	jns	@@2
	call	GetToken
	jc	@@8
	jmp	@@9
@@2:	call	GetToken
	jc	@@8
	test	Flags,reDollar
	jnz	@@10
	test	Flags,reAsterisk
	jnz	@@3
	call	CompareChar
	jc	@@9
	add	di,Increment
	dec	Cnt
	jl	@@9
	jmp	@@2
@@3:	cmp	ah,'*'
	je	@@4
	call	CompareChar
	jc	@@9
	add	di,Increment
	dec	Cnt
	jle	@@9
@@4:	push	Cnt
	sub	di,Increment
	inc	Cnt
@@5:	add	di,Increment
	dec	Cnt
	jle	@@6
	call	CompareChar
	jnc	@@5
@@6:	pop	si
	pop	ax
	push	di
@@7:	call	RegCompare
	jnc	@@11
	sub	di,Increment
	inc	Cnt
	cmp	si,Cnt
	jae	@@7
	jmp	@@9
@@8:	clc
	jmp	@@11
@@9:	stc
	jmp	@@11
@@10:	cmp	Cnt,0
	jne	@@9
	lea	ax,[bx+size LineHeader]
	add	ax,es:[bx].LineLength
	cmp	ax,di
	jne	@@9
	jmp	@@8
@@11:	pop	ax
	pop	BracesEnd
	pop	BracesBegin
	pop	RealLength
	pop	BufPtr
	pop	Flags
	pop	Cnt
	pop	si cx
	jc	@@12
	pop	ax
	ret
@@12:	pop	di
	ret
RegCompare	endp

DoSearch	proc	near
	test	SearchOptions,esRegularExprs
	jz	@@1
	jmp	@@15
@@1:	dec	cx
	jle	@@6
	lea	si,Buffer
	cld
	cmp	byte ptr ss:[si],0dh
	jne	@@3
	add	di,cx
	mov	dx,di
	inc	Len
	call	Compare
	jc	@@2
	dec	Len
	inc	CurCol
	jmp	@@14
@@2:	dec	Len
	jmp	@@6
@@3:	test	SearchOptions,esBackward
	jz	@@9
	add	di,cx
	dec	di
@@4:	jcxz	@@6
	lea	si,Buffer
	cld
	segss	lodsb
	test	SearchOptions,esIgnoreCase
	jz	@@7
	cmp	al,'a'
	jb	@@7
	cmp	al,'z'
	ja	@@7
	mov	ah,al
@@5:	mov	al,es:[di]
	dec	di
	xor	al,ah
	and	al,0dfh
	loopnz	@@5
	jz	@@8
@@6:	stc
	ret
@@7:	std
	repne	scasb
	cld
	jne	@@6
@@8:	mov	dx,di
	inc	di
	inc	di
	call	Compare
	jc	@@4
	jmp	@@14
@@9:	jcxz	@@6
	lea	si,Buffer
	cld
	segss	lodsb
	test	SearchOptions,esIgnoreCase
	jz	@@12
	cmp	al,'a'
	jb	@@12
	cmp	al,'z'
	ja	@@12
	mov	ah,al
@@10:	mov	al,es:[di]
	inc	di
	xor	al,ah
	and	al,0dfh
	loopnz	@@10
	jz	@@13
@@11:	jmp	@@6
@@12:	repne	scasb
	jne	@@11
@@13:	mov	dx,di
	call	Compare
	jc	@@9
@@14:	clc
	ret
@@15:	test	cx,cx
	jl	@@19
	mov	ax,CurLine
	mov	FinLine,ax
	mov	ax,di
	sub	ax,bx
	sub	ax,size LineHeader-1
	mov	CurCol,ax
	mov	ax,di
	add	ax,cx
	dec	ax
	mov	EndCol,ax
	call	Init
	cmp	al,'^'
	jne	@@16
	lea	ax,[bx+size LineHeader]
	cmp	di,ax
	jne	@@19
	inc	BufPtr
	dec	RealLength
	jz	@@21
	call	RegCompare
	jc	@@19
	jmp	@@21
@@16:	cmp	al,'$'
	jne	@@17
	dec	RealLength
	jnz	@@19
	mov	ax,es:[bx].LineLength
	inc	ax
	mov	CurCol,ax
	lea	di,[bx+size LineHeader-1]
	add	di,ax
	cmp	di,EndCol
	jne	@@19
	jmp	@@21
@@17:	cmp	Increment,1
	je	@@20
	dec	di
	xchg	di,EndCol
	dec	di
@@18:	mov	ax,di
	sub	ax,bx
	sub	ax,size LineHeader-2
	mov	CurCol,ax
	call	Init
	call	RegCompare
	jnc	@@21
	mov	di,ax
	dec	di
	cmp	di,EndCol
	ja	@@18
@@19:	jmp	@@6
@@20:	mov	ax,di
	sub	ax,bx
	sub	ax,size LineHeader-1
	mov	CurCol,ax
	call	Init
	call	RegCompare
	jnc	@@21
	mov	di,ax
	inc	di
	cmp	di,EndCol
	jb	@@20
	jmp	@@19
@@21:	mov	ax,di
	sub	ax,bx
	sub	ax,size LineHeader-1
	cmp	Increment,1
	je	@@22
	inc	ax
	xchg	ax,CurCol
@@22:	mov	FinCol,ax
	ret
DoSearch	endp

	Entry	SearchText
	Invoke	SetTempPos
	Invoke	SetEditDS
	mov	ax,ds:TempPos.Y
	mov	OrigY,ax
	mov	ax,ds:TempPos.X
	mov	OrigX,ax
	les	bx,ds:LParam
	mov	ax,es:[bx]
	mov	SearchOptions,ax
	test	ax,esBackward
	jz	@@1
	test	ax,esEntireScope
	jnz	@@1
	mov	ax,ds:CursorPos.Y
	or	ax,ds:CursorPos.X
	dec	ax
	jz	@@6
@@1:	mov	al,es:[bx+2]
	mov	ah,0
	mov	Len,ax
	mov	cx,ax
	lea	di,Buffer
	lea	si,[bx+3]
	jcxz	@@6
	push	ds
	push	ss es
	pop	ds es
	cld
@@2:	lodsb
	cmp	al,0ah
	jne	@@3
	dec	Len
	jmp	@@5
@@3:	test	SearchOptions,esIgnoreCase
	jz	@@4
	cmp	al,'A'
	jl	@@4
	cmp	al,'Z'
	jg	@@4
	xor	al,20h
@@4:	stosb
@@5:	loop	@@2
	jmp	@@7
@@6:	jmp	@@36
@@7:	push	ss
	pop	ds
	test	SearchOptions,esRegularExprs
	jz	@@10
	mov	Increment,1
	test	SearchOptions,esBackward
	jz	@@10
	mov	cx,Len
	mov	si,di
	sub	si,cx
	cmp	byte ptr [si],'^'
	je	@@10
	cmp	byte ptr [di-1],'$'
	je	@@10
	mov	RealLength,cx
	mov	BufPtr,di
	shr	cx,1
	rep	movsw
	rcl	cx,1
	rep	movsb
	mov	ax,-1
	mov	Increment,ax
	push	ax
@@8:	push	BufPtr
	call	GetToken
	jnc	@@8
	lea	di,Buffer
	pop	cx
@@9:	pop	ax
	cmp	ax,-1
	je	@@10
	sub	cx,ax
	mov	si,ax
	cld
	rep	movsb
	mov	cx,ax
	jmp	@@9
@@10:	pop	ds
	push	ds:CursorPos.X ds:CursorPos.Y
	test	SearchOptions,esSelectedText
	jnz	@@11
	jmp	@@24
@@11:	Invoke	BlockShown
	Invoke	SetEditDS
	jz	@@13
	test	SearchOptions,esEntireScope
	jz	@@14
	test	SearchOptions,esBackward
	jz	@@12
	mov	ax,ds:BlockEnd.X
	mov	ds:TempPos.X,ax
	mov	ax,ds:BlockEnd.Y
	mov	ds:TempPos.Y,ax
	jmp	@@18
@@12:	mov	ax,ds:BlockBeg.X
	mov	ds:TempPos.X,ax
	mov	ax,ds:BlockBeg.Y
	mov	ds:TempPos.Y,ax
	jmp	@@18
@@13:	pop	ds:CursorPos.Y ds:CursorPos.X
	jmp	@@36
@@14:	test	SearchOptions,esBackward
	jz	@@20
	Invoke	SetTempPos
	Invoke	SetEditDS
	mov	ax,ds:TempPos.Y
	mov	bx,ds:TempPos.X
	cmp	ax,ds:BlockBeg.Y
	jb	@@13
	ja	@@15
	cmp	bx,ds:BlockBeg.X
	jb	@@13
@@15:	cmp	ax,ds:BlockEnd.Y
	jb	@@18
	je	@@16
	mov	ax,ds:BlockEnd.Y
	mov	ds:TempPos.Y,ax
	jmp	@@17
@@16:	cmp	bx,ds:BlockEnd.X
	jbe	@@18
@@17:	mov	bx,ds:BlockEnd.X
	mov	ds:TempPos.X,bx
@@18:	jmp	@@29
@@19:	jmp	@@13
@@20:	Invoke	SetTempPos
	Invoke	SetEditDS
	mov	ax,ds:TempPos.Y
	mov	bx,ds:TempPos.X
	cmp	ax,ds:BlockEnd.Y
	ja	@@19
	jb	@@21
	cmp	bx,ds:BlockEnd.X
	jae	@@19
@@21:	cmp	ax,ds:BlockBeg.Y
	ja	@@29
	je	@@22
	mov	ax,ds:BlockBeg.Y
	mov	ds:TempPos.Y,ax
	jmp	@@23
@@22:	cmp	bx,ds:BlockBeg.X
	jae	@@27
@@23:	mov	bx,ds:BlockBeg.X
	mov	ds:TempPos.X,bx
	jmp	@@29
@@24:	test	SearchOptions,esEntireScope
	jz	@@26
	test	SearchOptions,esBackward
	jz	@@25
	Invoke	EndCursorRaw
	jmp	@@28
@@25:	mov	ax,1
	mov	ds:TempPos.X,ax
	mov	ds:TempPos.Y,ax
	jmp	@@29
@@26:	test	SearchOptions,esBackward
	jnz	@@28
@@27:	Invoke	CursorCharRight
	Invoke	SetEditDS
	mov	ax,ds:CursorPos.X
	dec	ax
	jle	@@28
	mov	ds:CursorPos.X,ax
@@28:	Invoke	SetTempPos
	Invoke	SetEditDS
@@29:	mov	ax,ds:TempPos.Y
	mov	CurLine,ax
	pop	ds:CursorPos.Y ds:CursorPos.X
@@30:	mov	ax,ds:TempPos.Y
	push	ax
	Invoke	FindLine
	Invoke	UseCurPage
	pop	ax
	jc	@@36
	cmp	bx,dx
	je	@@36
	mov	cx,es:[bx].LineLength
	inc	cx
	test	SearchOptions,esBackward
	jnz	@@31
	push	ds:TempPos.X
	pop	StartCol
	test	SearchOptions,esSelectedText
	jz	@@37
	cmp	ax,ds:BlockEnd.Y
	ja	@@36
	jne	@@37
	mov	cx,ds:BlockEnd.X
	jmp	@@37
@@31:	mov	StartCol,1
	cmp	cx,ds:TempPos.X
	jbe	@@32
	mov	cx,ds:TempPos.X
@@32:	test	SearchOptions,esSelectedText
	jz	@@37
	cmp	ax,ds:BlockBeg.Y
	ja	@@37
	jb	@@36
	mov	di,ds:BlockBeg.X
	mov	StartCol,di
	jmp	@@37
@@33:	test	SearchOptions,esBackward
	jnz	@@35
	inc	ds:TempPos.Y
	inc	CurLine
	mov	ds:TempPos.X,1
@@34:	jmp	@@30
@@35:	mov	ds:TempPos.X,-1
	dec	ds:TempPos.Y
	dec	CurLine
	jnz	@@34
@@36:	mov	ax,-1
	mov	ds:ReturnCode,ax
	mov	ds:SearchPos,ax
	jmp	@@43
@@37:	lea	di,[bx+size LineHeader-1]
	add	di,StartCol
	sub	cx,StartCol
	inc	cx
	call	DoSearch
	jc	@@33
	Invoke	SetEditDS
	mov	ax,CurLine
	mov	dx,CurCol
	mov	si,FinLine
	mov	di,FinCol
	test	SearchOptions,esBackward
	jz	@@38
	xchg	ax,si
	xchg	dx,di
@@38:	cmp	si,OrigY
	jne	@@42
	cmp	di,OrigX
	jne	@@42
	push	ds:CursorPos.X ds:CursorPos.Y
	test	SearchOptions,esBackward
	jz	@@39
	Invoke	CursorCharLeft
	Invoke	SetEditDS
	jmp	@@40
@@39:	Invoke	CursorCharRight
	Invoke	SetEditDS
@@40:	pop	ax dx
	cmp	ax,ds:CursorPos.Y
	jne	@@41
	cmp	dx,ds:CursorPos.X
	jne	@@41
	jmp	@@36
@@41:	push	dx ax
	jmp	@@28
@@42:	push	ax dx
	mov	ds:TempPos.Y,si
	mov	ds:TempPos.X,di
	Invoke	MoveToTempPos
	Invoke	SetEditDS
	pop	ds:SearchPos ds:TempPos.Y
	sub	ax,ax
@@43:	cmp	ax,0
	Exit	SearchText

	end
