home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pcmagazi / 1990 / 16 / history.asm < prev    next >
Assembly Source File  |  1990-04-29  |  9KB  |  364 lines

  1. ; HISTORY.ASM
  2. ; (c) 1989, 1990 Ashok P. Nadkarni
  3. ;
  4. ; This module implements the history feature of the cmdedit program.
  5.  
  6.     INCLUDE common.inc
  7.     INCLUDE    buffers.inc
  8.  
  9.     PUBLIC    hist_top
  10.     PUBLIC    hist_init
  11.     PUBLIC    hist_fwd
  12.     PUBLIC    hist_back
  13.     PUBLIC    hist_fwd_match
  14.     PUBLIC    hist_bck_match
  15.     PUBLIC    remember
  16.     PUBLIC    hist_type
  17.     PUBLIC    execute_auto_recall
  18.     PUBLIC    execute_rsthist
  19.     PUBLIC    hist_ptr
  20.     PUBLIC    history
  21.  
  22. CSEG    SEGMENT    PARA PUBLIC 'CODE'
  23.  
  24.  
  25.     EXTRN    linebuf:BYTE        ;line buffer
  26.     EXTRN    lastchar:WORD
  27.     EXTRN    dot:WORD        ;current position in line buffer
  28.  
  29.  
  30. ; The history stack is maintained as a string stack using the functions in
  31. ; the string stack library. The top and bottom of the stack are always
  32. ; zero length strings (the bottom is always a zero length sentinel
  33. ; implemented by the string stack package but the top is explicitly 
  34. ; maintained by the history code.
  35. history    $string_stack 2 DUP (<>)    ;Buffer descriptors
  36. hist_ptr    DW    ?        ;Ptr to current buffer descriptor
  37.  
  38.  
  39. DGROUP    GROUP    CSEG
  40.  
  41.     EXTRN    bell:PROC
  42.     EXTRN    set_disp_marks:PROC
  43.     EXTRN    erase_to_dot:PROC
  44.  
  45.     ASSUME    CS:DGROUP,DS:DGROUP,ES:DGROUP,SS:DGROUP
  46.  
  47.  
  48. ;+
  49. ; FUNCTION : hist_init
  50. ;
  51. ; Initializes the various data structures associated with the
  52. ; command history buffers. CALLER MUST ENSURE PASSED ADDRESSES ARE VALID
  53. ; AND BUFFER IS LARGE ENOUGH.
  54. ;
  55. ; Parameters:
  56. ;    AX     - length of buffer in bytes
  57. ;    BX    - address of buffer
  58. ;    CX    - 0 if DOS buffer, any other value if application buffer
  59. ; Returns:
  60. ;    Nothing.
  61. ; Registers destroyed : BX,CX
  62. ;-
  63. hist_init proc    near
  64.     push    bx
  65.     mov    bx,offset DGROUP:history ;bx := address of buffer descriptors
  66.     jcxz    @hist_init_1        ;if DOS, bx OK
  67.     add    bx,TYPE $string_stack    ;else point to application descriptor
  68. @hist_init_1:
  69.     xchg    ax,cx            ;CX = buffer size
  70.     pop    ax            ;AX = Buffer address
  71.                     ;BX points to appropriate descriptor
  72.     call    near ptr strstk_init    ;Initialize buffer and descriptor
  73.     xor    al,al            ;Push a zero length string onto stack
  74.     mov    cl,1            ;Force onto stack
  75.     call    near ptr strstk_push    ;Assumes no errors
  76.     ret
  77. hist_init    endp
  78.  
  79.  
  80. ;+
  81. ; FUNCTION : execute_rsthist
  82. execute_rsthist proc    near
  83.     mov    bx,offset DGROUP:history ;bx := address of buffer descriptors
  84.     jcxz    @execute_rsthist_1    ;if DOS, bx OK
  85.     add    bx,TYPE $string_stack    ;else point to application descriptor
  86. @execute_rsthist_1:
  87.     call    near ptr strstk_reset    ;Initialize buffer and descriptor
  88.     xor    al,al            ;Push a zero length string onto stack
  89.     mov    cl,1            ;Force onto stack
  90.     call    near ptr strstk_push    ;Assumes no errors
  91.     ret
  92. execute_rsthist    endp
  93.  
  94.  
  95.  
  96. ;+
  97. ; FUNCTION : hist_type
  98. ;
  99. ;    Sets the hist_ptr global to point at the descriptor for the
  100. ;    current caller (DOS or application).
  101. ;
  102. ; Parameters:
  103. ;    CX =    0 if DOS, anything else for application
  104. ;
  105. ; Returns:
  106. ;    Nothing.
  107. ; Registers destroyed : BX
  108. ;-
  109. hist_type proc near
  110.     mov    bx,offset DGROUP:history ;address of first descriptor
  111.     mov    hist_ptr,bx
  112.     ret
  113. hist_type endp
  114.  
  115.  
  116. ;+
  117. ; FUNCTION : hist_top
  118. ;
  119. ;    Resets the history pointer to the null string at top of history stack.
  120. ;    The line buffer itslef is NOT changed.
  121. ; Parameters:
  122. ;    None.
  123. ;
  124. ; Returns:
  125. ;    Nothing.
  126. ; Registers destroyed:  BX
  127. ;-
  128. hist_top proc near
  129.     mov    bx,hist_ptr        ;Point to current descriptor
  130.     call    near ptr strstk_settop    ;Set to top of history stack.
  131.  
  132.     ret
  133. hist_top endp
  134.  
  135.  
  136. ;+
  137. ; FUNCTION : hist_back
  138. ;
  139. ;    Gets the previous history line (if there is one) and stores it
  140. ;    in the line buffer. Also makes it the current line.
  141. ;
  142. ; Parameters:
  143. ;    None.
  144. ;
  145. ; Returns:
  146. ;    Nothing.
  147. ; Registers destroyed: AX,BX,CX
  148. ;-
  149. hist_back proc near
  150.     mov    dot,offset DGROUP:linebuf
  151.     jmp    hist_bck_match        ;Will return to caller
  152. hist_back endp
  153.  
  154.  
  155.  
  156. ;+
  157. ; FUNCTION : hist_fwd
  158. ;
  159. ;    Gets the next history line (if there is one) and stores it
  160. ;    in the line buffer. Also makes it the current line.
  161. ;
  162. ; Parameters:
  163. ;    None.
  164. ;
  165. ; Returns:
  166. ;    Nothing.
  167. ; Registers destroyed :
  168. ;-
  169. hist_fwd proc near
  170.     mov    dot,offset DGROUP:linebuf
  171.     jmp    hist_fwd_match        ;Will return to caller
  172. hist_fwd endp
  173.  
  174.  
  175.  
  176. ;+
  177. ; FUNCTION : hist_copy
  178. ;
  179. ;    Copies the current history line into the line buffer. The dot
  180. ;    is set to the beginning of the line.
  181. ;
  182. ; Parameters:
  183. ;    BX =    points to the beginning of a line in the history buffer.
  184. ;
  185. ; Returns:
  186. ;    Nothing.
  187. ;
  188. ; Registers destroyed: 
  189. ;-
  190. hist_copy proc near
  191.     mov    bx,hist_ptr    ;Current descriptor
  192.     mov    ax,offset DGROUP:linebuf ;the history line storage
  193.     push    ax        ;Remember
  194.     mov    dot,ax        ;Cursor will be at the beginning of line
  195.     xchg    ax,dx        ;dx->first char in line (parameter)
  196.     mov    ax,lastchar    ;ax->upper limit (parameter)
  197.     call    near ptr set_disp_marks ;Indicate changed range
  198.                 ;No registers destroyed
  199.     mov    ax,dx        ;Restore beginning of line
  200.     sub    cx,LINEBUF_SIZE    ;cx<-max length of line
  201.     push    cx        ;Save it
  202.     call    near ptr strstk_copy ;Copy history line into linebuf
  203.                 ;AX == length of history string
  204.     pop    cx        ;
  205.     jnc    @hist_copy_90    ;Jump if no error from strstk_copy
  206.     call    near ptr bell    ;History line too long for buffer
  207.     mov    ax,cx        ;Number of bytes = max length of line
  208. @hist_copy_90:
  209.     pop    dx        ;dx->beginning of line
  210.     add    ax,dx        ;ax->end
  211.     mov    lastchar,ax    ;Update end of line
  212.     call    near ptr set_disp_marks ;Indicate changed range
  213.                 ;No registers destroyed
  214.     ret
  215. hist_copy endp
  216.  
  217.  
  218.  
  219. ;+
  220. ; FUNCTION : remember
  221. ;
  222. ;    Saves the line buffer in the history area. If the line already
  223. ;    exists, it is moved to the top of the stack.
  224. ;
  225. ; Parameters:
  226. ;    None.
  227. ;
  228. ; Returns:
  229. ;    Nothing.
  230. ;
  231. ; Registers destroyed:
  232. ;    AX,BX,CX,DX
  233. ;-
  234. remember proc near
  235.     mov    bx,hist_ptr        ;Descriptor
  236.     call    near ptr strstk_settop    ;Reset stack pointer
  237.     mov    ax,offset DGROUP:linebuf ;AX->line to be stored
  238.     mov    cx,lastchar
  239.     sub    cx,ax            ;CX<-length of line
  240.     call    near ptr strstk_bck_find ;Look for it in history
  241. ;                      buffer. Note that if it is a
  242. ;                      null string, the sentinel at
  243. ;                      top of the stack is not found
  244. ;                      which is at it should be.
  245.     jc    @remember_10        ;Not in stack
  246.     call    near ptr strstk_kill    ;If found delete it from stack
  247. @remember_10:
  248.     call    near ptr strstk_settop    ;Point to sentinel at top of stack
  249.     call    near ptr strstk_kill    ;Delete it
  250.     mov    dx,offset DGROUP:linebuf ;String to be remembered
  251.     mov    ax,lastchar        ;Length of string
  252.     sub    ax,dx            ;AX(AL)<-length of string
  253.     mov    cl,1            ;Force the push
  254.     call    near ptr strstk_push    ;ignore success/fail status
  255.     xor    ax,ax            ;Zero length sentinel
  256.     mov    cl,1
  257.     call    near ptr strstk_push    ;Push it
  258.     ret
  259. remember endp
  260.  
  261.  
  262.  
  263. ;+
  264. ; FUNCTION : hist_fwd_match, hist_bck_match
  265. ;
  266. ;    Looks fwd/back thru the history buffer starting from the current
  267. ;    history location looking for a line whose first n chracters match
  268. ;    the n characters before the current position in the line buffer.
  269. ;
  270. ; Parameters:
  271. ;    None.
  272. ;
  273. ; Returns:
  274. ;    CF    = 0 if match found
  275. ;          1 if no match
  276. ;
  277. ; Registers destroyed:
  278. ;-
  279. hist_match proc near
  280. hist_fwd_match LABEL near
  281.     mov    dx,offset DGROUP:strstk_fwd_match
  282.     jmp    short @hist_match_10
  283. hist_bck_match label near
  284.     mov    dx,offset DGROUP:strstk_bck_match
  285. @hist_match_10:
  286.     mov    bx,hist_ptr    ;Descriptor address
  287.     mov    ax,offset DGROUP:linebuf ;start of pattern
  288.     mov    cx,dot        ;Current position in linebuffer
  289.     sub    cx,ax        ;Number of chars to match
  290.     push    cx        ;Save
  291.     push    ax
  292.     call    dx        ;Will set CF if no match, else sets
  293.                 ; 'current' to matched string
  294.     pushf            ;Remember flags
  295.     jc    @hist_match_20    ;No match
  296.     call    near ptr hist_copy ;Copy and display the history line
  297.                 ;Now reset it to original position
  298. @hist_match_20:
  299.     popf            ;Restore flags
  300.     pop    ax        ;Line address
  301.     pop    cx        ;Restore count
  302.     pushf            ;Save flags
  303.     add    ax,cx        ;AX->dot
  304.     mov    dot,ax
  305.     popf            ;Restore flags
  306.     jnc    @hist_match_99    ;If match was found, exit
  307.     mov    ax,lastchar    ;AX->end-of-line
  308.     call    erase_to_dot    ;Else delete remaining chars in the
  309. ;                 line (chars between AX and dot)
  310.     stc            ;Indicate no match
  311. @hist_match_99:
  312.     ret
  313. hist_match endp
  314.  
  315.  
  316.  
  317. ;+
  318. ; FUNCTION : execute_auto_recall
  319. ;
  320. ;    This function looks backward through the history buffer for a
  321. ;    line with a prefix that matches the characters to the left of
  322. ;    the dot. The search begins with the CURRENT history line. ie.
  323. ;    if the current history line has a matching prefix, the current
  324. ;    pointer is not changed. If no match is found, the history stack
  325. ;    is reset.
  326. ;
  327. ; Parameters:
  328. ;    None.
  329. ;
  330. ; Returns:
  331. ;    CF    = 0 if match found
  332. ;          1 if no match
  333. ; Register(s) destroyed:
  334. ;    AX,BX,CX,DX
  335. ;-
  336. execute_auto_recall proc near
  337.     mov    bx,hist_ptr        ;BX->current history stack descriptor
  338.     mov    ax,offset DGROUP:linebuf ;AX->pattern
  339.     mov    cx,dot
  340.     sub    cx,ax            ;CX<-length of pattern
  341.     call    near ptr strstk_prefix    ;Current history line matches?
  342.     jne    @execute_auto_recall_50    ;No
  343.     clc                ;Yes, current line matches
  344.     jmp    short @execute_auto_recall_99
  345.  
  346. @execute_auto_recall_50:
  347.     call    near ptr hist_bck_match    ;Search backward
  348.     jnc    @execute_auto_recall_99    ;Found a match
  349. ;    No match, reset history stack pointer
  350.     mov    bx,hist_ptr        ;BX->current history stack descriptor
  351.     call    near ptr hist_top    ;Reset history stack
  352.     stc                ;Indicate no match
  353. @execute_auto_recall_99:
  354.     ret
  355. execute_auto_recall endp
  356.  
  357. CSEG    ENDS
  358.  
  359.     END
  360.