home *** CD-ROM | disk | FTP | other *** search
- ; HISTORY.ASM
- ; (c) 1989, 1990 Ashok P. Nadkarni
- ;
- ; This module implements the history feature of the cmdedit program.
- ; DFA stopped lines of length less than min_length being stored on stack
- ; (December 1990).
-
- INCLUDE common.inc
- INCLUDE buffers.inc
-
- PUBLIC hist_top
- PUBLIC hist_init
- PUBLIC hist_fwd
- PUBLIC hist_back
- PUBLIC hist_fwd_match
- PUBLIC hist_bck_match
- PUBLIC remember
- PUBLIC hist_type
- PUBLIC execute_auto_recall
- PUBLIC execute_rsthist
- PUBLIC hist_ptr
- PUBLIC history
-
- CSEG SEGMENT PARA PUBLIC 'CODE'
-
-
- EXTRN linebuf:BYTE ;line buffer
- EXTRN lastchar:WORD
- EXTRN dot:WORD ;current position in line buffer
- EXTRN min_length:WORD ;added by dfa
-
-
- ; The history stack is maintained as a string stack using the functions in
- ; the string stack library. The top and bottom of the stack are always
- ; zero length strings (the bottom is always a zero length sentinel
- ; implemented by the string stack package but the top is explicitly
- ; maintained by the history code.
- history $string_stack 2 DUP (<>) ;Buffer descriptors
- hist_ptr DW ? ;Ptr to current buffer descriptor
-
- DGROUP GROUP CSEG
-
- EXTRN bell:PROC
- EXTRN set_disp_marks:PROC
- EXTRN erase_to_dot:PROC
-
- ASSUME CS:DGROUP,DS:DGROUP,ES:DGROUP,SS:DGROUP
-
-
- ;+
- ; FUNCTION : hist_init
- ;
- ; Initializes the various data structures associated with the
- ; command history buffers. CALLER MUST ENSURE PASSED ADDRESSES ARE VALID
- ; AND BUFFER IS LARGE ENOUGH.
- ;
- ; Parameters:
- ; AX - length of buffer in bytes
- ; BX - address of buffer
- ; CX - 0 if DOS buffer, any other value if application buffer
- ;
- ; Returns:
- ; Nothing.
- ; Registers destroyed : BX,CX
- ;-
- hist_init proc near
- push bx
- mov bx,offset DGROUP:history ;bx := address of buffer descriptors
- jcxz @hist_init_1 ;if DOS, bx OK
- add bx,TYPE $string_stack ;else point to application descriptor
- @hist_init_1:
- xchg ax,cx ;CX = buffer size
- pop ax ;AX = Buffer address
- ;BX points to appropriate descriptor
- call near ptr strstk_init ;Initialize buffer and descriptor
- xor al,al ;Push a zero length string onto stack
- mov cl,1 ;Force onto stack
- call near ptr strstk_push ;Assumes no errors
- ret
- hist_init endp
-
-
- ;+
- ; FUNCTION : execute_rsthist
- execute_rsthist proc near
- mov bx,offset DGROUP:history ;bx := address of buffer descriptors
- jcxz @execute_rsthist_1 ;if DOS, bx OK
- add bx,TYPE $string_stack ;else point to application descriptor
- @execute_rsthist_1:
- call near ptr strstk_reset ;Initialize buffer and descriptor
- xor al,al ;Push a zero length string onto stack
- mov cl,1 ;Force onto stack
- call near ptr strstk_push ;Assumes no errors
- ret
- execute_rsthist endp
-
-
-
- ;+
- ; FUNCTION : hist_type
- ;
- ; Sets the hist_ptr global to point at the descriptor for the
- ; current caller (DOS or application).
- ;
- ; Parameters:
- ; CX = 0 if DOS, anything else for application
- ;
- ; Returns:
- ; Nothing.
- ; Registers destroyed : BX
- ;-
- hist_type proc near
- mov bx,offset DGROUP:history ;address of first descriptor
- mov hist_ptr,bx
- ret
- hist_type endp
-
-
- ;+
- ; FUNCTION : hist_top
- ;
- ; Resets the history pointer to the null string at top of history stack.
- ; The line buffer itslef is NOT changed.
- ; Parameters:
- ; None.
- ;
- ; Returns:
- ; Nothing.
- ; Registers destroyed: BX
- ;-
- hist_top proc near
- mov bx,hist_ptr ;Point to current descriptor
- call near ptr strstk_settop ;Set to top of history stack.
-
- ret
- hist_top endp
-
-
- ;+
- ; FUNCTION : hist_back
- ;
- ; Gets the previous history line (if there is one) and stores it
- ; in the line buffer. Also makes it the current line.
- ;
- ; Parameters:
- ; None.
- ;
- ; Returns:
- ; Nothing.
- ; Registers destroyed: AX,BX,CX
- ;-
- hist_back proc near
- mov dot,offset DGROUP:linebuf
- jmp hist_bck_match ;Will return to caller
- hist_back endp
-
-
-
- ;+
- ; FUNCTION : hist_fwd
- ;
- ; Gets the next history line (if there is one) and stores it
- ; in the line buffer. Also makes it the current line.
- ;
- ; Parameters:
- ; None.
- ;
- ; Returns:
- ; Nothing.
- ; Registers destroyed :
- ;-
- hist_fwd proc near
- mov dot,offset DGROUP:linebuf
- jmp hist_fwd_match ;Will return to caller
- hist_fwd endp
-
-
-
- ;+
- ;
- ; FUNCTION : hist_copy
- ;
- ; Copies the current history line into the line buffer. The dot
- ; is set to the beginning of the line.
- ;
- ; Parameters:
- ; BX = points to the beginning of a line in the history buffer.
- ;
- ; Returns:
- ; Nothing.
- ;
- ; Registers destroyed:
- ;-
- hist_copy proc near
- mov bx,hist_ptr ;Current descriptor
- mov ax,offset DGROUP:linebuf ;the history line storage
- push ax ;Remember
- mov dot,ax ;Cursor will be at the beginning of line
- xchg ax,dx ;dx->first char in line (parameter)
- mov ax,lastchar ;ax->upper limit (parameter)
- call near ptr set_disp_marks ;Indicate changed range
- ;No registers destroyed
- mov ax,dx ;Restore beginning of line
- sub cx,LINEBUF_SIZE ;cx<-max length of line
- push cx ;Save it
- call near ptr strstk_copy ;Copy history line into linebuf
- ;AX == length of history string
- pop cx ;
- jnc @hist_copy_90 ;Jump if no error from strstk_copy
- call near ptr bell ;History line too long for buffer
- mov ax,cx ;Number of bytes = max length of line
- @hist_copy_90:
- pop dx ;dx->beginning of line
- add ax,dx ;ax->end
- mov lastchar,ax ;Update end of line
- call near ptr set_disp_marks ;Indicate changed range
- ;No registers destroyed
- ret
- hist_copy endp
-
-
-
- ;+
- ;
- ; FUNCTION : remember
- ;
- ; Saves the line buffer in the history area. If the line already
- ; exists, it is moved to the top of the stack.
- ; Added by dfa: lines less than min_length are ignored.
- ;
- ; Parameters:
- ; None.
- ;
- ; Returns:
- ; Nothing.
- ;
- ; Registers destroyed:
- ; AX,BX,CX,DX
- ;-
- remember proc near
- mov bx,hist_ptr ;Descriptor
- call near ptr strstk_settop ;Reset stack pointer
- mov ax,offset DGROUP:linebuf ;AX->line to be stored
- mov cx,lastchar
- sub cx,ax ;CX<-length of line
- cmp cx,min_length ;these two lines added by dfa
- jb @remember_20 ;ignore request if line length too short
- call near ptr strstk_bck_find ;Look for it in history
- ; buffer. Note that if it is a
- ; null string, the sentinel at
- ; top of the stack is not found
- ; which is at it should be.
- jc @remember_10 ;Not in stack
- call near ptr strstk_kill ;If found delete it from stack
- @remember_10:
- call near ptr strstk_settop ;Point to sentinel at top of stack
- call near ptr strstk_kill ;Delete it
- mov dx,offset DGROUP:linebuf ;String to be remembered
- mov ax,lastchar ;Length of string
- sub ax,dx ;AX(AL)<-length of string
- mov cl,1 ;Force the push
- call near ptr strstk_push ;ignore success/fail status
- xor ax,ax ;Zero length sentinel
- mov cl,1
- call near ptr strstk_push ;Push it
- @remember_20: ; label added by dfa
- ret
- remember endp
-
-
-
- ;+
- ;
- ; FUNCTION : hist_fwd_match, hist_bck_match
- ;
- ; Looks fwd/back thru the history buffer starting from the current
- ; history location looking for a line whose first n chracters match
- ; the n characters before the current position in the line buffer.
- ;
- ; Parameters:
- ; None.
- ;
- ; Returns:
- ; CF = 0 if match found
- ; 1 if no match
- ;
- ; Registers destroyed:
- ;-
- hist_match proc near
- hist_fwd_match LABEL near
- mov dx,offset DGROUP:strstk_fwd_match
- jmp short @hist_match_10
- hist_bck_match label near
- mov dx,offset DGROUP:strstk_bck_match
- @hist_match_10:
- mov bx,hist_ptr ;Descriptor address
- mov ax,offset DGROUP:linebuf ;start of pattern
- mov cx,dot ;Current position in linebuffer
- sub cx,ax ;Number of chars to match
- push cx ;Save
- push ax
- call dx ;Will set CF if no match, else sets
- ; 'current' to matched string
- pushf ;Remember flags
- jc @hist_match_20 ;No match
- call near ptr hist_copy ;Copy and display the history line
- ;Now reset it to original position
- @hist_match_20:
- popf ;Restore flags
- pop ax ;Line address
- pop cx ;Restore count
- pushf ;Save flags
- add ax,cx ;AX->dot
- mov dot,ax
- popf ;Restore flags
- jnc @hist_match_99 ;If match was found, exit
- mov ax,lastchar ;AX->end-of-line
- call erase_to_dot ;Else delete remaining chars in the
- ; line (chars between AX and dot)
- stc ;Indicate no match
- @hist_match_99:
- ret
- hist_match endp
-
-
-
- ;+
- ; FUNCTION : execute_auto_recall
- ;
- ; This function looks backward through the history buffer for a
- ; line with a prefix that matches the characters to the left of
- ; the dot. The search begins with the CURRENT history line. ie.
- ; if the current history line has a matching prefix, the current
- ; pointer is not changed. If no match is found, the history stack
- ; is reset.
- ;
- ; Parameters:
- ; None.
- ;
- ; Returns:
- ; CF = 0 if match found
- ; 1 if no match
- ; Register(s) destroyed:
- ; AX,BX,CX,DX
- ;-
- execute_auto_recall proc near
- mov bx,hist_ptr ;BX->current history stack descriptor
- mov ax,offset DGROUP:linebuf ;AX->pattern
- mov cx,dot
- sub cx,ax ;CX<-length of pattern
- call near ptr strstk_prefix ;Current history line matches?
- jne @execute_auto_recall_50 ;No
- clc ;Yes, current line matches
- jmp short @execute_auto_recall_99
-
- @execute_auto_recall_50:
- call near ptr hist_bck_match ;Search backward
- jnc @execute_auto_recall_99 ;Found a match
- ; No match, reset history stack pointer
- mov bx,hist_ptr ;BX->current history stack descriptor
- call near ptr hist_top ;Reset history stack
- stc ;Indicate no match
- @execute_auto_recall_99:
- ret
- execute_auto_recall endp
-
- CSEG ENDS
-
- END
-