home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0000 - 0009 / ibm0000-0009 / ibm0003.tar / ibm0003 / TPOWER53.ZIP / TPASM.ARC / TPBM.ASM < prev    next >
Encoding:
Assembly Source File  |  1989-07-10  |  7.8 KB  |  273 lines

  1. ;******************************************************
  2. ;            TPBM.ASM 5.07
  3. ;           String handling routines
  4. ;     Copyright (c) TurboPower Software 1987.
  5. ; Portions copyright (c) Sunny Hill Software 1985, 1986
  6. ;     and used under license to    TurboPower Software
  7. ;         All rights reserved.
  8. ;******************************************************
  9.  
  10.     INCLUDE    TPCOMMON.ASM
  11.  
  12. ;******************************************************    Code
  13.  
  14. CODE    SEGMENT    BYTE PUBLIC
  15.  
  16.     ASSUME    CS:CODE
  17.  
  18.     PUBLIC    BMMakeTable, BMSearch, BMSearchUC
  19.  
  20.     EXTRN    UpCasePrim : FAR
  21.  
  22. Upcase    MACRO                ;UpCase    character in AL
  23.     PUSH   BX
  24.     CALL   UpCasePrim
  25.     POP    BX
  26.     ENDM
  27.  
  28. ;******************************************************    BMMakeTable
  29.  
  30. ;  procedure BMMakeTable(MatchString : string; var BT :    BTable);
  31. ;    Build Boyer-Moore link table
  32. ;    BTable is array[0..255] of    byte;
  33.  
  34. MString    EQU    DWORD PTR SS:[BX+8]
  35. BTable    EQU    DWORD PTR SS:[BX+4]
  36.  
  37. BMMakeTable   PROC   FAR
  38.  
  39.     StackFrame
  40.     MOV    DX,DS            ;Save DS in DX
  41.     CLD                ;Go forward
  42.  
  43.     LDS    SI,MString        ;DS:SI => MatchString
  44.     LES    DI,BTable        ;ES:DI => BY
  45.     MOV    BX,DI            ;Save DI in BX
  46.     LODSB                ;AL = length(MatchString)
  47.     MOV    AH,AL            ;Copy it to AH
  48.     MOV    CX,128            ;Number    of words in BT
  49.     REP    STOSW            ;Fill BT with length(MatchString)
  50.     CMP    AL,1            ;Is length(MatchString)    <= 1?
  51.     JBE    MTDONE            ;Yes, we're done
  52.  
  53.     MOV    DI,BX            ;Restore base of table from BX
  54.     MOV    BH,CH            ;BH = 0
  55.     MOV    CL,AL            ;CX = length(MatchString)
  56.     DEC    CX            ;CX = length(MatchString)-1
  57.  
  58. MTnext:    LODSB                ;AL = MatchString[i]
  59.     MOV    BL,AL            ;BL = MatchString[i]
  60.     MOV    ES:[BX+DI],CL        ;BTable[char] =    length(MatchString)-i
  61.     LOOP   MTnext            ;Repeat    for all    characters in MatchString
  62.  
  63. MTDone:    MOV    DS,DX            ;Restore DS from DX
  64.     RET    8
  65.  
  66. BMMakeTable   ENDP
  67.  
  68. ;******************************************************    BMSearch
  69.  
  70. ;  function BMSearch(var Buffer; BufLength : Word; BT :    BTable;    MatchString : string) :    Word;
  71. ;    Search Buffer for MatchString
  72. ;    Return FFFF for failure
  73. ;    Else return number    of bytes searched to find MatchString
  74.  
  75. MString    EQU    DWORD PTR [BP+6]
  76. BTable    EQU    DWORD PTR [BP+10]
  77. BufSize    EQU    WORD PTR    [BP+14]
  78. Buffer    EQU    DWORD PTR [BP+16]
  79. BufOfs    EQU    WORD PTR    [BP+16]
  80.  
  81. BMSearch   PROC      FAR
  82.  
  83.     StackFrameBP
  84.     PUSH   DS            ;Will wipe out DS
  85.     PUSH   BP            ;Will use BP for temp storage later
  86.  
  87.     MOV    CX,BufSize        ;CX = Buffer size
  88.     LES    DI,Buffer        ;ES:DI => Buffer
  89.     LDS    BX,BTable        ;DS:BX => BTable
  90.     MOV    AX,DS            ;Keep BTable segment in    AX a moment
  91.     LDS    SI,MString        ;DS:SI => MatchString
  92.     MOV    BP,AX            ;Keep BTable segment in    BP
  93.  
  94.     XOR    AX,AX            ;AX = 0
  95.     MOV    DX,AX            ;DX = 0
  96.     MOV    DL,[SI]            ;DL = length(MatchString)
  97.     CMP    DL,1            ;Check for trivial cases
  98.     JA     BMSinit            ;Do Boyer-Moore    if longer than one char
  99.     JB     BMSnotFound        ;Fail for empty    string
  100.  
  101.     MOV    AL,[SI+1]        ;AL = one and only char    to find
  102.     MOV    BX,DI            ;Save offset of    Buffer
  103.     CLD                ;Forward
  104.     REPNE  SCASB            ;Scan Buffer for AL
  105.     JNE    BMSnotFound        ;Char wasn't found
  106.     MOV    AX,DI            ;AX holds offset where char was    found
  107.     DEC    AX            ;Back up one
  108.     SUB    AX,BX            ;Subtract base offset of Buffer
  109.     JMP    BMSdone            ;We're done
  110.  
  111. BMSinit:
  112.     DEC    DL            ;DX = length(MatchString)-1
  113.     ADD    SI,DX            ;DS:SI => MatchString[length(MatchString)-1]
  114.     ADD    CX,DI            ;CX = offset of    last char in buffer
  115.     ADD    DI,DX            ;ES:DI => first    position to search
  116.     MOV    DH,[SI+1]        ;DH = MatchString[length(MatchString)]
  117.     STD                ;Go backwards
  118.     JMP    SHORT BMScomp        ;Skip link table first time
  119.  
  120. BMSnext:
  121.     PUSH   DS            ;Save DS a moment
  122.     MOV    DS,BP            ;Get segment of    link table
  123.     XLAT                ;Get size of link at DS:[BX+AL]
  124.     POP    DS            ;Restore DS
  125.     ADD    DI,AX            ;Compute next place to search
  126.  
  127. BMScomp:
  128.     CMP    DI,CX            ;At end    of buffer?
  129.     JAE    BMSnotFound        ;Done if so
  130.     MOV    AL,ES:[DI]        ;AL = next char    to try
  131.     CMP    DH,AL            ;Does it match the end of MatchString?
  132.     JNE    BMSnext            ;If not    same, go back and try again
  133.  
  134.     PUSH   CX            ;Save end of buffer position
  135.     DEC    DI            ;Start comparing one character before
  136.     MOV    CL,DL            ;Compare length(MatchString)-1 characters
  137.     MOV    CH,AH            ;CH = 0
  138.     REPE   CMPSB            ;Compare backwards while matched
  139.     JE     BMSfound            ;Matched!
  140.  
  141.     MOV    AL,DL            ;Restore SI,DI,AL
  142.     SUB    AL,CL
  143.     ADD    SI,AX
  144.     ADD    DI,AX
  145.     INC    DI
  146.     MOV    AL,DH            ;Put matched char back in AL
  147.     POP    CX            ;Restore end of    buffer
  148.     JMP    SHORT BMSnext        ;Try again
  149.  
  150. BMSfound:                ;DI points to start of match
  151.     INC    SP            ;End of    buffer off stack
  152.     INC    SP
  153.     POP    BP            ;Get frame pointer back
  154.     SUB    DI,BufOfs        ;Subtract buffer start address
  155.     MOV    AX,DI
  156.     INC    AX            ;Return    0 if found in first byte
  157.     JMP    SHORT BMSDone2        ;We're done
  158.  
  159. BMSnotFound:
  160.     MOV    AX,0FFFFh        ;Result    = FFFF
  161. BMSDone:                ;Result    returned in AX
  162.     POP    BP
  163. BMSDone2:
  164.     CLD
  165.     POP    DS
  166.     ExitCode 14
  167.  
  168. BMSearch   ENDP
  169.  
  170. ;***************************************************** BMSearchUC
  171.  
  172. ;  function BMSearchUC(var Buffer;
  173. ;               BufLength : Word;
  174. ;               BT : BTable;
  175. ;               MatchString : string) : Word;
  176. ;    Case-insensitive search of    Buffer for MatchString
  177. ;    Return FFFF for failure
  178. ;    Else return number    of bytes searched to find MatchString
  179. ;    Assumes MatchString is already raised to uppercase
  180.  
  181. BMSearchUC   PROC   FAR
  182.  
  183.     StackFrameBP
  184.     PUSH   DS            ;Will wipe out DS
  185.     PUSH   BP            ;Will use BP for temp storage later
  186.  
  187.     MOV    CX,BufSize        ;CX = Buffer size
  188.     LES    DI,Buffer        ;ES:DI => Buffer
  189.     LDS    BX,BTable        ;DS:BX => BTable
  190.     MOV    AX,DS            ;Keep BTable segment in    AX a moment
  191.     LDS    SI,MString        ;DS:SI => MatchString
  192.     MOV    BP,AX            ;Keep BTable segment in    BP
  193.  
  194.     XOR    AX,AX            ;AX = 0
  195.     MOV    DX,AX            ;DX = 0
  196.     MOV    DL,[SI]            ;DL = length(MatchString)
  197.     OR     DL,DL            ;Check for trivial case
  198.     JZ     BMSUnotFound        ;Fail for empty    string
  199.  
  200. BMSUinit:
  201.     DEC    DL            ;DX = length(MatchString)-1
  202.     ADD    SI,DX            ;DS:SI => MatchString[length(MatchString)-1]
  203.     ADD    CX,DI            ;CX = offset of    last char in buffer
  204.     ADD    DI,DX            ;ES:DI => first    position to search
  205.     MOV    DH,[SI+1]        ;DH = MatchString[length(MatchString)]
  206.     STD                ;Go backwards
  207.     JMP    SHORT BMSUcomp        ;Skip link table first time
  208.  
  209. BMSUnext:
  210.     PUSH   DS            ;Save DS a moment
  211.     MOV    DS,BP            ;Get segment of    link table
  212.     XLAT                ;Get size of link at DS:[BX+AL]
  213.     POP    DS            ;Restore DS
  214.     ADD    DI,AX            ;Compute next place to search
  215.  
  216. BMSUcomp:
  217.     CMP    DI,CX            ;At end    of buffer?
  218.     JAE    BMSUnotFound        ;Done if so
  219.     MOV    AL,ES:[DI]        ;AL = next char    to try
  220.     UpCase                ;Raise it to uppercase
  221.     CMP    DH,AL            ;Does it match the end of MatchString?
  222.     JNE    BMSUnext            ;If not    same, go back and try again
  223.  
  224.     PUSH   CX            ;Save end of buffer position
  225.     DEC    DI            ;Start comparing one character before
  226.     MOV    CL,DL            ;Compare length(MatchString)-1 characters
  227.     MOV    CH,AH            ;CH = 0
  228.     JCXZ   BMSUfound        ;Completely matched if CX = 0
  229.  
  230. BMSUcomp2:
  231.     LODSB                ;Next match character in AL
  232.     MOV    AH,ES:[DI]        ;Next buffer character in AH
  233.     DEC    DI            ;Decrement buffer index
  234.     XCHG   AL,AH            ;Uppercase it
  235.     UpCase
  236.     CMP    AH,AL            ;A match?
  237.     LOOPE  BMSUcomp2        ;Loop while AH=AL and CX<>0
  238.     JE     BMSUfound        ;Matched!
  239.  
  240.     XOR    AH,AH            ;Restore SI,DI,AX
  241.     MOV    AL,DL
  242.     SUB    AL,CL
  243.     ADD    SI,AX
  244.     ADD    DI,AX
  245.     INC    DI
  246.     MOV    AL,DH            ;Put matched char back in AL
  247.     POP    CX            ;Restore end of    buffer
  248.     JMP    SHORT BMSUnext        ;Try again
  249.  
  250. BMSUfound:                ;DI points to start of match
  251.     INC    SP            ;End of    buffer off stack
  252.     INC    SP
  253.     POP    BP            ;Get frame pointer back
  254.     SUB    DI,BufOfs        ;Subtract buffer start address
  255.     MOV    AX,DI
  256.     INC    AX            ;Return    0 if found in first byte
  257.     JMP    SHORT BMSUDone2        ;We're done
  258.  
  259. BMSUnotFound:
  260.     MOV    AX,0FFFFh        ;Result    = FFFF
  261. BMSUDone:                ;Result    returned in AX
  262.     POP    BP
  263. BMSUDone2:
  264.     CLD
  265.     POP    DS
  266.     ExitCode 14
  267.  
  268. BMSearchUC   ENDP
  269.  
  270. CODE    ENDS
  271.  
  272.     END
  273.