; SEARCH.ASM for E32 - Copyright (C) 1994 Douglas Herr ; all rights reserved include model.inc public search, search_again, replace extrn locate:near extrn working:near ; 'Working' message extrn display_screen:near, display_current:near extrn close_space:near, open_space:near extrn edit_filename:near extrn rowcount:near extrn tedit:near extrn strlen:near extrn cursoron:near extrn keyifwaiting:near, tprintce:near extrn $strstr:near extrn $stristr:near temp_string equ [ebp-64] include dataseg.inc extrn filesiz:dword ; size of file loaded in XMS memory extrn cursor:dword, inverse:byte, rows:byte extrn dirty_bits:byte extrn zero_sel:word extrn first_row:byte extrn key_status:byte kbdstat db 0 find_mess db " Find: ",0 replace_msg db ' replace? (Yes/No/All)',0 replace_prompt db ' Replace with: ',0 replace_mode db 0 search_len dw 0 replace_len dw 0 bytes_to_add dw 0 was_replaced db 0 save_offset dd offset init_and_save replace_ptr dd ? search_ptr dd ? extrn cur_posn:word extrn breakflag:byte extrn undo_length:word extrn count_start:dword count_bytes equ dword ptr count_start+4 @curseg ends include codeseg.inc search_again label proc enter 64,0 call save_offset mov esi,search_ptr movzx ecx,search_len cmp byte ptr [esi],0 jne short s0 jmp short _ss ; ; This subroutine searches for a string ; search proc near enter 64,0 call save_offset ; save cursor offset jc exit _ss: ; copy saved search string to temp_string mov esi,search_ptr call copy_to_temp_string call get_search_string mov kbdstat,dl ; save keyboard status mov search_len,cx cmp ax,27 je exit ; exit if ESC pressed ; copy search string to storage area mov edi,search_ptr push edi call copy_from_temp_string pop esi ; search_ptr cmp ecx,1 jc short exit s0: call working ; print 'Working' message mov edi,cursor inc edi ; start search one past cursor push fs pop es mov ebx,ecx mov edx,filesiz sub edx,edi ; bytes in file to search jbe short exit test kbdstat,3 ; Shift key pressed? jz short s5 call $stristr jmp short s6 s5: call $strstr s6: jc short exit add eax,cursor inc eax mov cursor,eax ; save bytes to search for rows mov ecx,eax sub ecx,count_start mov count_bytes,ecx mov dh,rows sub dh,first_row shr dh,1 add dh,first_row mov esi,eax ; cursor call locate or dirty_bits,1 call rowcount exit: clc leave ret search endp replace_proc equ [ebp-68] replace proc near enter 68,0 call save_offset r2: mov esi,search_ptr call copy_to_temp_string call get_search_string ; get string to replace mov kbdstat,dl ; save keyboard status cmp ax,27 je replace_exit ; exit if ESC pressed test ecx,ecx jnz short r1 jmp replace_exit r1: mov search_len,cx mov edi,search_ptr call copy_from_temp_string mov esi,replace_ptr call copy_to_temp_string call get_replace_string mov replace_mode,dl ; save keyboard status cmp ax,27 je r2 jcxz r1 mov replace_len,cx sub cx,search_len ; bytes to add ; negative if file is shortened ; zero if len(search) = len(replace) mov eax,offset @curseg:same_length jz short r1a mov eax,offset @curseg:increase jns short r1a mov eax,offset @curseg:decrease neg cx r1a: mov replace_proc,eax mov bytes_to_add,cx mov edi,replace_ptr call copy_from_temp_string mov breakflag,0 ; zero the ^C flag r: call search_again ; search for next occurance test dirty_bits,1 ; flag set if string found jz short replace_exit ; exit if not found call display_screen ; update screen mov dx,cur_posn call cursoron shr breakflag,1 jc short replace_exit cmp replace_mode,0 jne short _replace_string lea esi,replace_msg mov dh,rows inc dh xor dl,dl mov ah,inverse call tprintce r3: shr breakflag,1 jc short replace_exit call keyifwaiting test ax,ax jz r3 shr ah,1 ; filter out extended keycodes jc r3 cmp al,27 je short replace_exit and al,0FFh-32 ; upper case cmp al,'Y' je short _replace_string cmp al,'N' je r cmp al,'A' jne r3 not replace_mode ; change to continuous ; & fall into _replace_string _replace_string: call [replace_proc] call display_current and dirty_bits,11111110b jmp r replace_exit: test was_replaced,1 jz short r_exit mov dh,rows sub dh,first_row shr dh,1 add dh,first_row mov esi,cursor ; cursor call locate or dirty_bits,1 r_exit: clc leave ret replace endp ; ; SUBROUTINES ; get_replace_string: lea esi,replace_prompt jmp short g0 get_search_string: lea esi,find_mess g0: call edit_filename mov es,zero_sel mov dl,es:[417h] ; get kbd status and dl,11b ; DL <> 0 if shift key pressed near_ret: ret ; ; replace search string at cursor ; called indirectly by replace_proc ; decrease: ; net file size decrease if len(search) > len(replace) movzx eax,bytes_to_add ; remove EAX bytes from file call close_space jmp short same_length increase: ; net file size increase if len(search) < len(replace) movzx eax,bytes_to_add call open_space same_length: ; copy replacement string to file mov esi,replace_ptr movzx ecx,replace_len mov edi,cursor add cursor,ecx push fs pop es cld rep movsb mov was_replaced,1 or dirty_bits,10000000b ret ; ; initialize search_ptr and replace_ptr init_and_save: mov save_offset,offset @curseg:save_only mov ebx,128 sys GetMemNear mov search_ptr,esi mov byte ptr [esi],0 add esi,64 mov replace_ptr,esi mov byte ptr [esi],0 ; ; save absolute cursor offset for count_start ; save_only: mov eax,cursor mov count_start,eax cld ret copy_to_temp_string: lea edi,temp_string push ss pop es mov ecx,64/4 rep movsd push ds pop es ret copy_from_temp_string: lea esi,temp_string push ds push es push ecx push ds pop es push ss pop ds cld mov ecx,64/4 rep movsd pop ecx pop es pop ds ret @curseg ends end