'=========================================================================== ' Subject: VIEW DIRECTORIES/FILES ZIP/LZH Date: 10-25-99 (18:05) ' Author: Randall L. Glass Code: PB ' Origin: rlglass@yahoo.com Packet: PB.ABC '=========================================================================== '------------------------------------------------------------------------- ' ' Shell BY Randall L Glass ' CopyRight Aug3,1999 ' '--------------------------------------------------------------------------- ' ' Email rlglass@yahoo.com ' '--------------------------------------------------------------------------- ' ' This Program is Freeware ' You may do anything with this program AS long AS you give me credit ' somewhere in the documentation. ' '=========================================================================== ' ' Program to view directoryies and files ,Including ZIP and Lzh ' ' Credit to Author: Jamshid Khoshrangi for his BOYER-MOORE INSTR Code: PB ' Thanks to William Yu FOR his ZipView & LzhView progam. ' ' ' You must SET the value of TEMP in your autoexec.bat file. ' Example SET TEMP = D:\TMP ' ' OR Rewrite the code in the program to set TempDir to your tempory directory. ' And Rewrite the code to your editor or file viewer. ' ' This includes an text viewer to view huge files up to 32700 lines ' Possible size 2.6 Gig ' ' List File Viewer is Faster ' You Can always replace my file viewer with an shell to List.com ' ' Look for SUB viewer ' '---------------------------------------------------------------------------- $DYNAMIC $HUGE $STACK 10000 DEFINT A-Z TYPE ZipType ' Zip File Header Signature AS DWORD Version AS WORD GPBFlag AS WORD ' Not sure Compress AS WORD ' Compression type FileTime AS WORD Filedate AS WORD ' Took a while to figure out CRC32 AS DWORD CompressSize AS DWORD UnCompressSize AS DWORD FileNameLen AS WORD ExtraField AS WORD END TYPE TYPE LZHHead HeadSize AS BYTE CheckSum AS BYTE Id1 AS STRING * 3 Method AS BYTE Id2 AS BYTE CompressSize AS DWORD UnCompressSize AS DWORD FileTime AS WORD FileDate AS WORD Attrs AS BYTE HeaderLevel AS BYTE FileNameLen AS BYTE FileName AS STRING * 12 END TYPE DECLARE Function GetKey%() AS INTEGER DECLARE SUB GetStrLoc() DECLARE SUB BoxBorder () DECLARE SUB Scroll(BYVAL TopRow%,BYVAL TopLeftCol%,BYVAL BottomRow%,BYVAL BottomRightCol%,BYVAL TotalLines%,BYVAL Attr%,BYVAL WhichWay%) DIM ScreenSegment AS shared WORD DIM DirStack$(10),ShellDir$(10) DIM Directory$(1000), DirInfo$(1000) SHARED Directory$(), DirInfo$() SHARED Viewer$,TempDir$,StackPos%,DirStack$() SHARED StartLine$,EndLine$,FileList$,Response$,ExtractCmd$,ExtractReponse$ SHARED DosError??,ShellDir$(),ShellPos%,ExitShell% SHARED NextHandle%,LineSeg??,LinePtr?? IF(PBVScreenCARD AND 1) = 0 THEN ScreenSegment?? = 47104 '&HB800 'color monitor ELSE ScreenSegment?? = 45056 '&HB000 'mono monitor END IF %SIG = &H04034B50 ' Signature %UpArrow = -72:%DownArrow = -80:%Enter = 13:%Escape = 27 %Home = -71:%PageDown = -81:%PageUp = -73:%EndKey = -79 %Up = 6:%Down = 7:%LeftArrow = -75:%RightArrow = -77 %AltHome = -151 %U = 85 %ReadOnly = 1:%Hidden = 2:%System = 4:%Volume = 8:%SubDir = 16:%Archive = 32 %AllFiles = 33 CLS 'Viewer$ = "listr.com" LastDir$ = CURDRIVE$ + ":\" CHDIR LastDir$ IF(PBVScreenCARD AND 1) = 0 THEN ScreenSegment?? = 47104 '&HB800 'color monitor ELSE ScreenSegment?? = 45056 '&HB000 'mono monitor END IF EXIT FAR AT BackHome DO ShellPos% = 0 DosShell LastDir$ BackHome: LOOP WHILE ShellPos% END SUB DosShell(ShellDirectory$) Choice% = 1:DisplayPos% = 1:LowFIle% = 1:HiFile% = 18:Ky% = 0 InfoLine$ = " FileName"+" Size"+" Date" + " Time" PushDir2 ShellDirectory$,ShellDir$(),ShellPos% DO TotalFiles% = 0 RealDir$ = AddSlash$(TrueDir2$(ShellDir$(), ShellPos%)) GetDirAndFiles RealDir$ + "*.*", %SubDir , Directory$(), DirInfo$(), FilesInfo$, TotalFiles% DirNum% = TotalFiles% IF DirNum% > 1 THEN ARRAY SORT Directory$(1) FOR TotalFiles%,TagArray DirInfo$() GetDirAndFiles RealDir$ + "*.*", %AllFiles, Directory$(), DirInfo$(), FilesInfo$, TotalFiles% SortNumber% = TotalFiles - DirNum% IF SortNumber% > 1 THEN FileStart% = DirNum% + 1 ARRAY SORT Directory$(FileStart%) FOR SortNumber%,TagArray DirInfo$() END IF Pick% = ChooseProgram%( DirInfo$(),Directory$(),FilesInfo$,InfoLine$,Choice%,DisplayPos%,LowFile%,HiFile%,Ky%,DirNum%,"Directory") SELECT CASE Ky% CASE %RightArrow,%Enter IF Attrib(RealDir$ + Directory$(Pick%)) = 16 THEN DosShell(Directory$(Pick%)) COLOR 7,1 CLS ELSEIF Attrib(RealDir$ + Directory$(Pick%)) <> 16 THEN Ext$ = Extension$(Directory$(Pick%)) SELECT CASE Ext$ CASE ".ZIP",".LZH" ShowZip(RealDir$ + Directory$(Pick%)) CASE ELSE '".TXT",".DOC" Viewer RealDir$ + Directory$(Pick%) CLS DELAY .2 COLOR 7,0 END SELECT END IF CASE %LeftArrow,%Escape DECR ShellPos% EXIT LOOP CASE %AltHome EXIT FAR END SELECT LOOP END SUB SUB ShowZip(File$) CLS LOCATE 1,1,0 Ext$ = Extension$(File$) File$ = TrueName$(File$) IF ISFALSE FileExist%(File$) THEN EXIT SUB TempDir$ = ENVIRON$("TEMP") + "\dosview" PushDir TempDir$ ViewZip File$ PopDir SHELL "DELTREE /Y " + Rtrim$(RealDir$,"\") + " >NUL" COLOR 7,0 CLS END SUB SUB ViewZip(File$) IF ISFALSE FileExist%(File$) THEN LOCATE 5,15:PRINT File$;" doesn't exist !"; EXIT SUB END IF DIM ArchiveFiles$(1000),ArchiveInfo$(1000),ArchiveDir$(1000) Choice% = 1:DisplayPos% = 1:LowFIle% = 1:HiFile% = 18 Ky% = 0 InfoLine$ = " FileName"+" Size"+" Date" + " Time" CLS Ext$ = Extension$(File$) IF Ext$ = ".ZIP" OR Ext$ = ".LZH" THEN PresentDir$ = CURDIR$ PresentDrive$ = CURDRIVE$ CHDRIVE Left$(File$,1) CHDIR GetDirectory$(File$) SELECT CASE Ext$ CASE ".ZIP" ZipView GetFileName$(File$), ArchiveFiles$(), ArchiveInfo$(), FilesInfo$, Success% CASE ".LZH" LzhView GetFileName$(File$), ArchiveFiles$(), ArchiveInfo$(), FilesInfo$, Success% END SELECT CHDRIVE PresentDrive$ CHDIR PresentDir$ IF ISFALSE Success% THEN EXIT SUB TotalFiles?? = CVWRD(ArchiveFiles$(0)) 'ARRAY SORT ArchiveFiles$(1) FOR TotalFiles??,TAGARRAY ArchiveInfo$() DO Pick% = ChooseProgram%( ArchiveInfo$(),ArchiveFiles$(),FilesInfo$,InfoLine$,Choice%,DisplayPos%,LowFile%,HiFile%,Ky%,0,"") Choice% = Pick% SELECT CASE Ky% CASE %Escape,%LeftArrow EXIT SUB CASE %RightArrow IF Pick% > 0 THEN Pick$ = UCASE$(ArchiveFiles$(Pick%)) RealName$ = GetFileName$(Pick$) PickExt$ = Extension$(Pick$) IF PickExt$ =".ZIP" OR PickExt$ = ".LZH" THEN PushDir "TEMP" RealDir$ = TrueDir$ + "\" IF ISFALSE FileExist%(RealDir$+Pick$) THEN CLS SELECT CASE Ext$ CASE ".ZIP" SHELL "PKUNZIP -e -o " + File$ + " " + Pick$ + " " + RealDir$ + " >NUL" 'SHELL "UNZIP " + File$ + " " + Pick$ + " " + "-d" + RealDir$ '+ " >NUL" CASE ".LZH" SHELL "lha.exe e /pn2 " + File$ + " " + RealDir$ + " "+ Pick$ END SELECT END IF fe% = FetchErrorLevel% IF FetchErrorLevel% > 0 THEN SHELL "DELTREE /Y " + Rtrim$(RealDir$,"\") + " >NUL" EXIT SUB END IF ViewZip RealDir$ + RealName$ SHELL "DELTREE /Y " + Rtrim$(RealDir$,"\") + " >NUL" PopDir CLS DELAY .2 ITERATE LOOP ELSE CLS RealDir$ = TrueDir$ + "\" SELECT CASE Ext$ CASE ".ZIP" SHELL "PKUNZIP -e -o " + File$ + " " + Pick$ + " " + RealDir$ + " >NUL" 'SHELL "UNZIP " + File$ + " " + Pick$ + " " + "-d" + RealDir$ ' + " >NUL" CASE ".LZH" SHELL "lha.exe e /pn2 " + File$ + " " + RealDir$ + " "+ Pick$ END SELECT END IF 'CLS fe% = FetchErrorLevel% IF FetchErrorLevel% > 0 THEN SHELL "DELTREE /Y " + Rtrim$(RealDir$,"\") + " >NUL" EXIT SUB END IF PresentDir$ = CURDIR$ PresentDrive$ = CURDRIVE$ CHDRIVE LEFT$(TrueDir$,1) CHDIR TrueDir$ Viewer RealName$ CLS KILL RealName$ CHDRIVE PresentDrive$ CHDIR PresentDir$ DELAY .2 COLOR 7,0 END IF 'CASE %U END SELECT LOOP END IF END SUB FUNCTION ChooseProgram%(ArchiveInfo$(),ArchiveFile$(),InfoLine1$,InfoLine2$ ,Choice%, DisplayPos%,LowFile%, HiFile%,Ky%,DirNum%,ChooseType$) DIM PrintLine AS STRING * 47 DIM DirLine AS STRING * 80 DisplayLine% = 18 TotalFiles% = CVWRD(ArchiveInfo$(0)) IF TotalFiles% < DisplayLine% THEN HiFile% = TotalFiles% BottomDisplayLine% = DisplayLine% COLOR 7,1 CLS COLOR 0,7 LOCATE 1,1:PRINT SPACE$(80); COLOR 7,1 LOCATE 2,2:PRINT Ltrim$(InfoLine1$) LOCATE 4,2:PRINT InfoLine2$ DO COLOR 15, 1 LinePos% = 0 IF TotalFiles% < 15 THEN BottomDisplayLine% = TotalFiles% IF ScrollIt% = 0 THEN 'POKE$ 0, SaveScreen$ : LOCATE y%, x% 'restore old screen FOR ArchiveFile% = LowFile% TO HiFile% INCR LinePos% LSET PrintLine$ = ArchiveInfo$(ArchiveFile%) IF LinePos% = DisplayPos% THEN QPrint 5 + LinePos%,1, PrintLine$ ,71 ELSE QPRINT 5 + LinePos%,1,PrintLine$,23 END IF NEXT ArchiveFile% LSET PrintLine$ = "" FOR I% = LinePos% + 1 To DisplayLine% QPRINT 5 + I%,1,PrintLine$,23 NEXT I% ELSE LSET PrintLine$ = ArchiveInfo$(Choice%) QPRINT 5 + DisplayPos%,1,PrintLine$,71 END IF DirLine$ = SPACE$(80) MID$(DirLine$,2) = ArchiveFile$(Choice%) COLOR 0,7:LOCATE 25,1:PRINT DirLine$; ScrollIt% = 0 ClearBuffer DO: ky$ = UCASE$(INKEY$): LOOP WHILE ky$ = "" Ky% = ASC(ky$): IF Ky% = 0 THEN Ky% = -ASC(MID$(ky$, 2)) SELECT CASE Ky% CASE %Enter,%RightArrow ChooseProgram% = choice%: EXIT DO CASE %Escape ChooseProgram% = 0: EXIT DO CASE %Home choice% = 1:LowFile% = 1 HiFile% = BottomDisplayLine% DisplayPos% = 1 CASE %EndKey Choice% = TotalFiles% DisplayPos% = MODTYPE(Choice%, BottomDisplayLine%) LowFile% = Choice% - DisplayPos% + 1 HiFile% = TotalFiles% CASE %PageDown INCR Choice%, DisplayLine% INCR LowFile%,DisplayLine% HiFile% = LowFile% + BottomDisplayLine% -1 IF HiFile% > TotalFiles% THEN HiFile% = TotalFiles% IF choice% > TotalFiles% THEN Choice% = TotalFiles% DisplayPos% = ModType(Choice%, BottomDisplayLine%) LowFile% = Choice% - DisplayPos% + 1 HiFile% = TotalFiles% END IF CASE %PageUp DECR Choice%,DisplayLine% DECR LowFile%,DisplayLine% HiFile% = LowFile% + DisplayLine% -1 IF LowFile% < 1 THEN LowFile% = 1:HiFile% = BottomDisplayLine% IF Choice% <=1 THEN Choice% = 1 LowFile% = 1 HiFile% = BottomDisplayLine% DisplayPos% = 1 END IF CASE %DownArrow INCR Choice% IF Choice% <= TotalFiles% THEN INCR DisplayPos% ELSE Choice% = TotalFiles% END IF IF DisplayPos% > BottomDisplayLine% THEN DisplayPos% = BottomDisplayLine% LowFile% = Choice% -BottomDisplayLine% + 1 IF HiFile% >= TotalFiles% THEN HiFile% = TotalFiles% ELSE HiFile% = LowFile% + BottomDisplayLine% -1 END IF PrintAtr BottomDisplayLine%+5, 1, 47, 23 Scroll 5,1, BottomDisplayLine%+4,47, 1,23,%Up ScrollIt% = 1 END IF CASE %UpArrow DECR choice% DECR DisplayPos% IF choice% <=1 THEN choice% = 1 LowFile% = 1 HiFile% = BottomDisplayLine% DisplayPos% = 1 ELSE IF DisplayPos% < 1 THEN DisplayPos% = 1 LowFile% = Choice% HiFile% = Choice% + BottomDisplayLine% -1 IF HiFile% >= TotalFiles% THEN HiFile% = TotalFiles% ELSE HiFile% = LowFile% + BottomDisplayLine% -1 END IF PrintAtr 6, 1, 47, 23 Scroll 5,1, BottomDisplayLine%+4,47, 1,23,%Down ScrollIt% = 1 END IF END IF CASE 48 TO 57,65 TO 90 IF ChooseType$ = "Directory" THEN ScanFiles% = TotalFiles% - Choice% ARRAY SCAN ArchiveInfo$(Choice% + 1) FOR ScanFiles% ,FROM 2 TO 2,=Ky$,To PossibleChoice% IF PossibleChoice% > 0 THEN Choice% = Choice% + PossibleChoice% ELSEIF PossibleChoice% = 0 THEN ARRAY SCAN ArchiveInfo$(1) FOR Choice% - 1 ,FROM 2 TO 2,=Ky$,To PossibleChoice% IF PossibleChoice% > 0 THEN Choice% = PossibleChoice% END IF IF PossibleChoice% > 0 THEN LowFile% = Choice% - DisplayPos% + 1 HiFile% = LowFile% + BottomDisplayLine% -1 IF LowFile% < 1 THEN LowFile% = 1:HiFile% = BottomDisplayLine%:DisplayPos% = Choice% IF HiFile% > TotalFiles% THEN HiFile% = TotalFiles% END IF END IF CASE ELSE EXIT DO END SELECT LOOP COLOR 7,0 END FUNCTION SUB Scroll(BYVAL TopRow%,BYVAL TopLeftCol%,BYVAL BottomRow%,BYVAL BottomRightCol%,BYVAL TotalLines%,BYVAL Attr%,BYVAL WhichWay%) ! PUSH DS ! PUSH BP ! MOV AH,WhichWay% ! MOV AL, TotalLines% ! MOV BH, Attr% ! MOV CH, TopRow% ! MOV CL, TopLeftCol% ! MOV DH, BottomRow% ! MOV DL, BottomRightCol% ! INT &H10 ! POP BP ! POP DS END SUB SUB QPrint(BYVAL Row, BYVAL Col, BYVAL Text$, BYVAL attr) PUBLIC ScreenSeg?? = ScreenSegment?? ! push DS ; save DS for PowerBASIC ! mov ax,Row% ; get the row ! dec al ; convert row to zero base ! mov bl,80 ; get the number of cols ! mul bl ; multiply # of cols * rows ! add ax,Col% ; add the column ! dec al ; convert column to zero base ! mov di,ax ; offset within video page ! shl di,1 ; account for color/attribute ! push WORD PTR Text$ ; push string handle on the stack ! call GetStrLoc ; find the string ! jcxz QPExit ; if it's Null, exit ! mov DS, DX ; put segment in DS ! mov SI, AX ; put offset in SI ! mov ES, ScreenSeg?? ; move to ES ! mov AH, attr ; put attribute in AH WriteChar: ! lodsb ; get Char from string ! stosw ; write Char and attribute to screen ! loop WriteChar ; do it all CX times QPExit: ! pop DS ; restore DS for PowerBASIC END SUB SUB PrintAtr(byval Row%, byval Col%,ByVal LineWidth%, byval Attr%) ScreenSeg?? = ScreenSegment?? ! push ds ;save the good stuff ! mov ax,Row% ; get the row ! dec al ; convert row to zero base ! mov bl,80 ; get the number of cols ! mul bl ; multiply # of cols * rows ! add ax,Col% ; add the column ! dec al ; convert column to zero base ! mov di,ax ; offset within video page ! shl di,1 ; account for color/attribute ! mov es,ScreenSeg?? ;put video segment into ax ! mov ah,Attr% ;the color attribute will be needed ! mov cx,LineWidth% forloop: ! inc di ;increment to the next vidram position ! mov es:[di],ah ;poke the attribute into vidram ! inc di ! loop forloop ;loop until cx = 0 ! pop ds END SUB FUNCTION GetKey%() Public While ISFALSE INSTAT:Wend ky$ = Inkey$ IF len(ky$) = 2 then GetKey% = -ascii(right$(ky$,1)) ELSE GetKey% = ascii(ky$) END IF END FUNCTION SUB ClearBuffer DO:LOOP UNTIL INKEY$ = "" END SUB SUB GetDirAndFiles(Spec$, Attr%, Directory$(), DirInfo$(), FilesInfo$, TotalFiles%) IF Attr% <> %SubDir THEN Attr% = 33 DIM FileName AS STRING * 8 DIM Ext AS STRING * 4 DirFile$ = DIR$(Spec$,Attr%) IF DirFile$ <> "" THEN GetDirInfo DirDate$,DirTime$,DirSize???,DirAttr? IF Attr% = 16 AND DirAttr? = 16 THEN INCR TotalFiles% Directory$(TotalFiles%) = DirFile$ LSET FileName$ = Extract$(DirFile$,".") LSET Ext$ = Extension$(DirFile$) IsDir$ = "" DirInfo$(TotalFiles%) = " " + FileName$ + Ext$ + " " + IsDir$ + " " + " "+DirDate$ + " " + DirTime$ ELSEIF Attr% <> 16 AND DirAttr? <> 16 THEN INCR TotalFiles% Directory$(TotalFiles%) = DirFile$ LSET FileName$ = Extract$(DirFile$,".") LSET Ext$ = Extension$(DirFile$) IsDir$ = " " DirInfo$(TotalFiles%) = " " + FileName$ + Ext$ + " " + IsDir$ + USING$("########",DirSize???) + " "+DirDate$ + " " + DirTime$ END IF END IF DO DirFile$ = DIR$ IF DirFile$ <> "" THEN GetDirInfo DirDate$,DirTime$,DirSize???,DirAttr? IF Attr% = 16 AND DirAttr? = 16 THEN INCR TotalFiles% Directory$(TotalFiles%) = DirFile$ LSET FileName$ = Extract$(DirFile$,".") LSET Ext$ = Extension$(DirFile$) IsDir$ = "" DirInfo$(TotalFiles%) = " " + FileName$ + Ext$ + " " + IsDir$ + " " + " "+DirDate$ + " " + DirTime$ ELSEIF Attr% <> 16 AND DirAttr? <> 16 THEN INCR TotalFiles% Directory$(TotalFiles%) = DirFile$ LSET FileName$ = Extract$(DirFile$,".") LSET Ext$ = Extension$(DirFile$) IsDir$ = " " DirInfo$(TotalFiles%) = " " + FileName$ + Ext$ + " " + IsDir$ + USING$("########",DirSize???) + " "+DirDate$ + " " + DirTime$ END IF ELSE EXIT LOOP END IF LOOP FilesInfo$ = Spec$ + ":" + STR$(TotalFiles%)+" Directories And Files" DirInfo$(0) = MKWRD$(TotalFiles%) Directory$(0) = MKWRD$(TotalFiles%) END SUB SUB GetRegDir(Spec$,Attr%,Directory$(),TotalFiles%) DirFile$ = DIR$(Spec$,Attr%) IF DirFile$ <> "" THEN INCR FileNum% Directory$(FileNum%) = DirFile$ ELSE TotalFiles% = 0 EXIT SUB END IF DO DirFile$ = DIR$ IF DirFile$ <> "" THEN INCR FileNum% Directory$(FileNum%) = DirFile$ ELSE EXIT SUB END IF LOOP END SUB FUNCTION Extension$(File$) FOR I% = LEN(File$) TO 1 STEP -1 Period$ = MID$(File$,I%,1) IF Period$ = "." THEN Extension$ = MID$(File$,I%):EXIT FUNCTION NEXT I% END FUNCTION FUNCTION Trim$(S$) Trim$ = Ltrim$(Rtrim$(S$)) END FUNCTION FUNCTION GetFileName$(F$) FOR I% = LEN(F$) TO 1 STEP -1 Char$ = MID$(F$,I%,1) IF Char$ = "\" OR CHAR$ = "/" THEN GetFileName$ = File$ EXIT FUNCTION ELSE File$ = Char$ + File$ END IF NEXT I% GetFileName$ = File$ END FUNCTION FUNCTION GetDirectory$(D$) Ln% = LEN(D$) FOR I% = Ln% TO 1 STEP -1 Char$ = MID$(D$,I%,1) IF Char$ = "\" OR CHAR$ = "/" THEN EXIT FOR NEXT I% IF I% <> 3 THEN TheDir$ = LEFT$(D$,I%-1) ELSE TheDir$ = LEFT$(D$,I%) END IF GetDirectory$ = TheDir$ END FUNCTION FUNCTION GetLastDir$(D$) Ln% = LEN(D$) Slash$ = RIGHT$(D$,1) IF Slash$ = "\" OR Slash$ = "/" THEN DECR Ln% FOR I% = Ln% TO 1 STEP -1 Char$ = MID$(TheDir$,I%,1) IF Char$ = "\" OR CHAR$ = "/" THEN EXIT FOR NEXT I% IF I% <> 3 THEN TheDir$ = INDEX$(D$,I%,Ln%) ELSE TheDir$ = LEFT$(D$,I%) END IF GetLastDir$ = TheDir$ END FUNCTION FUNCTION INDEX$(M$,StartPos%,LastPos%) INDEX$ = MID$(M$,StartPos%,LastPos% - StartPos% + 1) END FUNCTION FUNCTION GetDirAndSlash$(D$) Ln% = LEN(D$) FOR I% = Ln% TO 1 STEP -1 Char$ = MID$(D$,I%,1) IF Char$ = "\" OR CHAR$ = "/" THEN EXIT FOR NEXT I% IF I% <> 3 THEN TheDir$ = LEFT$(D$,I%) ELSE TheDir$ = LEFT$(D$,I%) END IF GetDirAndSlash$ = TheDir$ END FUNCTION FUNCTION AddSlash$(D$) TheDir$ = TrueName$(D$) IF LEN(TheDir$) > 3 AND RIGHT$(TheDir$,1) <> "\" THEN AddSlash$ = TheDir$ + "\" ELSE AddSlash$ = TheDir$ END IF END FUNCTION FUNCTION FileDirExist%(d$) Ln% = LEN(D$) FOR I% = Ln% TO 1 STEP -1 Char$ = MID$(D$,I%,1) IF Char$ = "\" OR CHAR$ = "/" THEN EXIT FOR NEXT I% FileDirExist% = I% END FUNCTION SUB PushDir(Directory$) IF Directory$ = "" THEN EXIT SUB INCR StackPos% DirStack$(StackPos%) = Directory$ IF DirExist%(TrueDir$) = 0 THEN MKDIR TrueDir$ END SUB SUB PopDir() DECR StackPos% END SUB FUNCTION TrueDir$() D$ = DirStack$(1) FOR I% = 2 to StackPos% IF RIGHT$(DirStack$(I% -1),1) <> "\" THEN D$ = D$ + "\" + DirStack$(I%) ELSE D$ = D$ + DirStack$(I%) END IF NEXT I% TrueDir$ = D$ END FUNCTION SUB PushDir2(Directory$,Stack$(),StackPos2%) PUBLIC IF Directory$ = "" THEN EXIT SUB INCR StackPos2% Stack$(StackPos2%) = Directory$ END SUB SUB PopDir2(StackPos2%) PUBLIC DECR StackPos2% END SUB FUNCTION TrueDir2$(Stack$(), StackPos2%) PUBLIC D$ = Stack$(1) FOR I% = 2 to StackPos2% IF RIGHT$(Stack$(I% -1),1) <> "\" THEN D$ = D$ + "\" + Stack$(I%) ELSE D$ = D$ + Stack$(I%) END IF NEXT I% TrueDir2$ = D$ END FUNCTION FUNCTION DirExist%(Directory$) DirName$ = DIR$(Directory$,16) IF DirName$ = "" THEN EXIT FUNCTION Exists% = ATTRIB(Directory$) Exists% = BIT(Exists%,4) IF Exists% THEN DirExist% = 1 END FUNCTION FUNCTION FileExist%(Directory$) D$ = DIR$(Directory$) IF D$ <> "" THEN FileExist% = 1 END FUNCTION FUNCTION TrueName$(Directory$) DIM DirName2 AS STRING * 128 DirName$ = Directory$ +CHR$(0) DirNamePtr??? = STRPTR32(DirName$) DirNamePtr2??? = VARPTR32(DirName2$) DosError?? = 0 !PUSH DS !LDS SI,DirNamePtr??? !LES DI,DirNamePtr2??? !MOV AH,&H60 !INT &H21 !POP DS !JNC NoError !MOV DosError??,AX NoError: TrueName$ = EXTRACT$(DirName2$,CHR$(0)) END FUNCTION FUNCTION CURDRIVE$ Curdrive$ = LEFT$(CURDIR$,1) END FUNCTION FUNCTION MODTYPE??(Number%,ModNumber%) M% = Number% MOD ModNumber% IF M% = 0 THEN ModType% = ModNumber% ELSE ModType% = M% END IF END FUNCTION SUB LzhView(LzhFile$,ArchiveFiles$(),ArchiveInfo$(), FilesInfo$, Success%) DIM Lzh AS LZHHead DIM FileName AS STRING * 8 DIM Ext AS STRING * 4 FilePos??? = 0: QUIT% = 0 Handle% = FREEFILE OPEN LzhFile$ FOR BINARY AS Handle% RestOfFileSize??? = LOF(Handle%) IF RestOfFileSize??? = 0 THEN CLOSE Handle% PRINT LzhFile$+" has an FileSize of Zero !" Success% = 0 EXIT SUB END IF DO GET Handle%,FilePos???,Lzh IF Lzh.Id1 = "-lh" Or Lzh.Id1 = "-lz" Or Lzh.Id1 = "-lZ" THEN IF Lzh.HeadSize AND (Lzh.HeadSize < RestOfFileSize???) THEN Get Handle%,FilePos??? + Lzh.HeadSize,DirLen?? SEEK Handle%,FilePos??? + Lzh.HeadSize+3 IF DirLen?? > 0 AND DirLen?? < 256 THEN GET$ Handle%,DirLen??-3,Directory$ REPLACE CHR$(255) WITH "\" IN Directory$ ELSE Directory$ = "" END IF INCR FilePos???, Lzh.CompressSize + Lzh.HeadSize + 2 DECR RestOfFileSize???, FilePos??? INCR FileNumber?? File$ = LEFT$(Lzh.FileName,Lzh.FileNameLen) LSET FileName$ = Extract$(File$,".") LSET Ext$ = Extension$(File$) GetDateAndTime Lzh.Filedate,Lzh.FileTime,Filedate$,FileTime$ IF DirLen?? THEN DirSign$ = " + " ELSE DirSign$ = " " END IF ArchiveFiles$(FileNumber??) = Directory$ + File$ ArchiveInfo$(FileNumber??) = DirSign$ + FileName$ + Ext$ + USING$("########",Lzh.UnCompressSize) + " " + Filedate$ + " "+FileTime$ END IF ELSE INCR FilePos???, 2 DECR RestOfFileSize???, FilePos??? END IF Loop UNTIL Lzh.HeadSize = 0 Or Lzh.HeadSize > RestOfFileSize??? OR FilePos??? = RestOfFileSize??? Close Handle% FilesInfo$ = LzhFile$ + ":" + STR$(FileNumber??)+" Files" ArchiveFiles$(0) = MKWRD$(FileNumber??) ArchiveInfo$(0) = MKWRD$(FileNumber??) IF FileNumber?? > 1 THEN ARRAY SORT ArchiveFiles$(1) FOR FileNumber??,TAGARRAY ArchiveInfo$() Success% = 1 END SUB SUB ZipView(ZipFile$,ArchiveFiles$(),ArchiveInfo$(),FilesInfo$,Success%) ' View the ZIP File DIM Zip AS ZipType DIM FileName AS STRING * 8 DIM Ext AS STRING * 4 FileNumber?? = 0 Handle% = FREEFILE OPEN ZipFile$ FOR BINARY AS Handle% FileSize??? = LOF(Handle%) IF FileSize??? = 0 THEN ' Check if files exists ?ZipFile;" has an FileSize of Zeor !" ' if not, exit CLOSE Handle% Success% = 0 EXIT SUB END IF GET$ Handle%,2,PK$ ' Read File Header IF PK$ = "PK" THEN FilePos??? = 0 ELSE SEEK Handle%,2 GET$ Handle%,2,PK$ ' Read File Header IF PK$ = "PK" THEN FilePos??? = 2 ELSE Success% = 0 EXIT SUB END IF END IF DO GET Handle%,FilePos???,Zip ' Read File Header IF (Zip.Signature = %Sig) THEN INCR FilePos???, Zip.CompressSize + 30 + Zip.FileNameLen + ZIP.ExtraField INCR FileNumber?? GET$ Handle%,Zip.FileNameLen,File$ TheFile$ = GetFileName$(File$) IF TheFile$ = "" THEN DECR FileNumber?? ITERATE DO END IF LSET FileName$ = Extract$(TheFile$,".") LSET Ext$ = Extension$(File$) GetDateAndTime Zip.Filedate,Zip.FileTime,Filedate$,FileTime$ ArchiveFiles$(FileNumber??) = File$ IF FileDirExist%(File$) THEN DirSign$ = " + " ELSE DirSign$ = " " END IF ArchiveInfo$(FileNumber??) = DirSign$ + FileName$ + Ext$ + USING$("########",Zip.UnCompressSize) + " "+Filedate$+" "+FileTime$ END IF LOOP WHILE Zip.Signature = %Sig CLOSE Handle% FilesInfo$ = ZipFile$ + ":" + STR$(FileNumber??)+" Files" ArchiveInfo$(0) = MKWRD$(FileNumber??) 'Total Number of FIles ArchiveFiles$(0) = MKWRD$(FileNumber??) IF FileNumber?? > 1 THEN ARRAY SORT ArchiveFiles$(1) FOR FileNumber??,TAGARRAY ArchiveInfo$() Success% = 1 END SUB SUB GetDirInfo(DirDate$,DirTime$,DirSize???,DirAttrib?) PUBLIC LOCAL DirDate??,DirTime??,DirAttr?,Dsize??? ! mov AX, &H2F00 ; function 2Fh, get DTA location ! int &H21 ; call DOS ! MOV AX,ES:[BX + 24] ! MOV DirDate??,AX ! MOV AX,ES:[BX + 22] ! MOV DirTime??,AX ! MOV AX,ES:[BX +26] ! MOV DSize???[0],AX ! MOV AX,ES:[BX +28] ! MOV DSize???[2],AX ! MOV AL,ES:[BX +21] ! MOV DirAttr?,AL DirSize??? = DSize??? DirAttrib? = DirAttr? GetDateAndTime DirDate??,DirTime??,DirDate$,DirTime$ END SUB SUB GetDateAndTime(Filedate??,FileTime??,Filedate$,FileTime$) PUBLIC Year?? = (Filedate?? AND &B1111111000000000):SHIFT RIGHT Year??,9 INCR Year??,1980 Month?? = Filedate?? AND &B0000000111100000:SHIFT RIGHT Month??,5 Day?? = Filedate?? AND &B0000000000011111 Hours?? = FileTime?? AND &B1111100000000000:SHIFT RIGHT Hours??,11 Minutes?? = FileTime?? AND &B0000011111100000:SHIFT RIGHT Minutes??,5 Seconds?? = (FileTime?? AND &B0000000000011111) * 2 Month$ = LTRIM$(STR$(Month??)) Day$ = LTRIM$(STR$(Day??)) IF LEN(Month$) = 1 THEN Month$="0"+Month$ IF LEN(Day$) = 1 THEN Day$ = "0"+Day$ 'IF Hours?? > 12 THEN ' Hours?? = Hours?? -12:AmPm$ = "p & " 'ELSE ' AmPm$ = "a & " 'END IF Hours$ = LTRIM$(STR$(Hours??)) Minutes$ = LTRIM$(STR$(Minutes??)) Seconds$ = LTRIM$(STR$(Seconds??)) IF LEN(Hours$) = 1 THEN Hours$="0"+Hours$ IF LEN(Minutes$) = 1 THEN Minutes$="0"+Minutes$ IF LEN(Seconds$) = 1 THEN Seconds$="0"+Seconds$ Filedate$ = Month$ + "-" + Day$ + "-" + LTRIM$(STR$(Year??)) FileTime$ = Hours$ + ":" + Minutes$ + ":" + Seconds$ 'FileTime$ = Hours$ + ":" + Minutes$ + AmPm$ + Seconds$ +"s" END SUB SUB Viewer(ViewFileName$) DIM LinePt???(32700) NextHandle% = FREEFILE OPEN ViewFIleName$ FOR INPUT AS NextHandle% DO INCR I??? LinePt???(I???) = SEEK(NextHandle%) LINE INPUT #NextHandle%,Dummy$ LOOP UNTIL EOF(NextHandle%) LinePt???(0) = I??? ViewFile LinePt???() CLOSE NextHandle% END SUB SUB ViewFile(FileLines???()) DIM PrintLine AS STRING * 80,Lines AS STRING * 1000 SHARED LineSeg??,LinePtr?? LineSeg?? = VARSEG(Lines$) LinePtr?? = VARPTR(Lines$) DisplayLine% = 23 PrintLine$ = SPACE$(80) LowFile& = 1:HiFile& = 23 TotalLines& = FileLines???(0) DisPlayPos% = 1 HorzPos% = 1 Choice% = 1 IF TotalLines& < DisplayLine% THEN HiFile& = TotalLines& BottomDisplayLine% = DisplayLine% COLOR 7,1 CLS COLOR 0,7 LOCATE 1,1:PRINT SPACE$(80); LOCATE 25,1:PRINT SPACE$(80); COLOR 7,1 DO COLOR 15, 1 LinePos% = 0 IF TotalLines& < 23 THEN BottomDisplayLine% = TotalLines& IF ScrollIt% = 0 THEN WAIT &H3DA,8 FOR ViewLines??? = LowFile& TO HiFile& INCR LinePos% SEEK NextHandle%,FileLines???(ViewLines???) Line Input #NextHandle%, LineInput$ REPLACE CHR$(9) WITH " " IN LineInput$ Lines$ = LineInput$ IF LinePos% = DisplayPos% THEN QuickPrintLine 1 + LinePos%,HorzPos%,71 IF Find% THEN PrintAtr 1 + LinePos%, Find%-HorzPos% + 1,SearchLen%, 48 ELSE QuickPrintLine 1 + LinePos%, HorzPos%,23 END IF NEXT ViewLines??? FOR I% = LinePos% + 1 To DisplayLine% QPRINT 1 + I%, 1 ,PrintLine$,23 NEXT I% ELSE SEEK NextHandle%,FileLines???(Choice&) Line Input #NextHandle%, LineInput$ REPLACE CHR$(9) WITH " " IN LineInput$ Lines$ = LineInput$ QuickPrintLine 1 + DisplayPos%, HorzPos% ,71 END IF COLOR 0,7 LOCATE 1,1 PRINT "ViewFile"; LOCATE 1,10 PRINT ;Choice&; LOCATE 1,18 PRINT ;TotalLines&; LOCATE 1,27:PRINT HorzPos%; LOCATE 1,34:PRINT "1000"; COLOR 7,1 ScrollIt% = 0 ClearBuffer FindLine% = 0:Find% = 0:SearchLen% = 0 DO: ky$ = UCASE$(INKEY$): LOOP WHILE ky$ = "" Ky% = ASC(Ky$) IF Ky%= 0 THEN Ky% = -ASC(Right$(ky$,1)) SELECT CASE Ky% CASE %RightArrow IF HorzPos% < 1000 THEN INCR HorzPos% CASE %LeftArrow IF HorzPos% > 1 THEN DECR HorzPos% CASE %Escape EXIT DO CASE %Home Choice& = 1:LowFile& = 1 HiFile& = BottomDisplayLine% DisplayPos% = 1 CASE %EndKey Choice& = TotalLines& DisplayPos% = ModType2??(Choice&, BottomDisplayLine%) LowFile& = Choice& - DisplayPos% + 1 HiFile& = TotalLines& CASE %PageDown INCR Choice&, DisplayLine% INCR LowFile&,DisplayLine% HiFile& = LowFile& + BottomDisplayLine% -1 IF HiFile& > TotalLines& THEN HiFile& = TotalLines& IF Choice& > TotalLines& THEN Choice& = TotalLines& DisplayPos% = ModType2??(Choice&, BottomDisplayLine%) LowFile& = Choice& - DisplayPos% + 1 HiFile& = TotalLines& END IF CASE %PageUp DECR Choice&,DisplayLine% DECR LowFile&,DisplayLine% HiFile& = LowFile& + DisplayLine% -1 IF LowFile& < 1 THEN LowFile& = 1:HiFile& = BottomDisplayLine% IF Choice& <=1 THEN Choice& = 1 LowFile& = 1 HiFile& = BottomDisplayLine% DisplayPos% = 1 END IF CASE %DownArrow INCR Choice& IF Choice& <= TotalLines& THEN INCR DisplayPos% ELSE Choice& = TotalLines& END IF IF DisplayPos% > BottomDisplayLine% THEN DisplayPos% = BottomDisplayLine% LowFile& = Choice& -BottomDisplayLine% + 1 IF HiFile& >= TotalLines& THEN HiFile& = TotalLines& ELSE HiFile& = LowFile& + BottomDisplayLine% -1 END IF PrintAtr BottomDisplayLine%+1, 1, 80, 23 Scroll 1, 0, BottomDisplayLine%, 79, 1, 23, %Up ScrollIt% = 1 END IF CASE %UpArrow DECR Choice& DECR DisplayPos% IF Choice& <=1 THEN Choice& = 1 LowFile& = 1 HiFile& = BottomDisplayLine% DisplayPos% = 1 ELSE IF DisplayPos% < 1 THEN DisplayPos% = 1 LowFile& = Choice& HiFile& = Choice& + BottomDisplayLine% -1 IF HiFile& >= TotalLines& THEN HiFile& = TotalLines& ELSE HiFile& = LowFile& + BottomDisplayLine% -1 END IF PrintAtr 2, 1, 80, 23 Scroll 1,0, BottomDisplayLine%,79, 1,23,%Down ScrollIt% = 1 END IF END IF CASE 70 'F LOCATE 25,1:COLOR 0,7 PRINT Space$(50); LOCATE 25,1 LINE INPUT; "FIND >";Search$ COLOR 7,1 Search$ = UCASE$(Search$) FOR I??? = Choice& + 1 TO TotalLines& SEEK NextHandle%,FileLines???(I???) Line Input #NextHandle%, LineInput$ REPLACE Chr$(9) WITH " " IN LineInput$ Find% = BINSTR% (1,UCASE$(LineInput$),Search$) IF Find% THEN EXIT FOR NEXT I??? IF Find% = 0 THEN FOR I??? = 1 TO Choice& -1 SEEK NextHandle%,FileLines???(I???) Line Input #NextHandle%, LineInput$ REPLACE Chr$(9) WITH " " IN LineInput$ Find% = BINSTR% (1,UCASE$(LineInput$),Search$) IF Find% THEN EXIT FOR NEXT I??? END IF IF Find% THEN GOSUB ResetValues END IF EXIT SELECT CASE 65 'N FOR I??? = Choice& + 1 TO TotalLines& SEEK NextHandle%,FileLines???(I???) Line Input #NextHandle%, LineInput$ REPLACE Chr$(9) WITH " " IN LineInput$ Find% = BINSTR% (1,UCASE$(LineInput$),Search$) IF Find% THEN EXIT FOR NEXT I??? IF Find% = 0 THEN FOR I??? = 1 TO Choice& -1 SEEK NextHandle%,FileLines???(I???) SEEK NextHandle%,FileLines???(I???) Line Input #NextHandle%, LineInput$ REPLACE Chr$(9) WITH " " IN LineInput$ Find% = BINSTR% (1,UCASE$(LineInput$),Search$) IF Find% THEN EXIT FOR NEXT I??? END IF IF Find% THEN GOSUB ResetValues END IF EXIT SELECT CASE ELSE EXIT DO END SELECT LOOP COLOR 7,0 EXIT SUB ResetValues: SearchLen% = LEN(Search$) Choice& = I??? FindLine% = I??? DisplayPos% = ModType2??(Choice&, BottomDisplayLine%) LowFile& = Choice& - DisplayPos% + 1 HiFile& = LowFile& + BottomDisplayLine% -1 IF LowFile& < 1 THEN LowFile& = 1:HiFile& = BottomDisplayLine%:DisplayPos% = Choice& IF HiFile& > TotalLines& THEN HiFile& = TotalLines& IF HorzPos% > Find% THEN HorzPos% = 1 IF Find% > HorzPos% + 80 -1 THEN HorzPos% = Find% -80 + SearchLen% + 80\SearchLen% -1 RETURN END SUB FUNCTION ModType2??(Number&,ModNumber%) M?? = Number& MOD ModNumber% IF M?? = 0 THEN ModType2?? = ModNumber% ELSE ModType2?? = M?? END IF END FUNCTION SUB QuickPrintLine(BYVAL Row , BYVAL HorzPos%,BYVAL attr) PUBLIC ! push DS ; save DS for PowerBASIC ! mov ax,Row% ; get the row ! dec al ; convert row to zero base ! mov bl,80 ; get the number of cols ! mul bl ; multiply # of cols * rows ! mov di,ax ; offset within video page ! shl di,1 ; account for color/attribute ! mov CX,1000 ! mov BX, 80 ! sub CX, HorzPos% ! CMP CX, 80 ! Jg GoAhead ! SUB BX, CX ! JMP DoIt GoAhead: ! MOV CX,80 ! MOV BX,0 DoIt: ! MOV SI, LinePtr?? ; put segment in DS ! MOV DS, LineSeg?? ! add SI, HorzPos% ! DEC SI ! mov ES, ScreenSegment?? ; move to ES ! mov AH, attr ; put attribute in AH ! jcxz RestOfLine ; if it's Null, exit WriteChar2: ! lodsb ; get Char from string ! stosw ; write Char and attribute to screen ! loop WriteChar2 ; do it all CX times RestOfLine: ! MOV AH, attr ; put attribute in AH ! MOV AL,32 ! MOV CX,BX ! jcxz Quit3 ; if it's Null, Do Rest of Line ! REP stosw Quit3: ! pop DS ; restore DS for PowerBASIC END SUB %SMALLEST.PATTERN = 2 %SMALLEST.BUFFER = 4 FUNCTION BINSTR%(TheStart%, Target$, Rule$) PUBLIC ' ES:DI Target$ ' DS:SI Rule$ PatLen% = LEN(Rule$) BuffLen% = LEN(Target$) IF BuffLen% < %SMALLEST.BUFFER THEN FUNCTION = INSTR(TheStart%, Target$, Rule$) EXIT FUNCTION ELSE IF PatLen% < %SMALLEST.PATTERN THEN FUNCTION = INSTR(TheStart%, Target$, Rule$) EXIT FUNCTION END IF END IF IF TheStart% > BuffLen% THEN ' we might as well not even bother EXIT FUNCTION END IF StackSeg?? = 0 ' We do this for later inline ASM PatSeg?? = STRSEG(Rule$) PatPtr?? = STRPTR(Rule$) BuffSeg?? = STRSEG(Target$) BuffPtr?? = STRPTR(Target$) + TheStart% TrueBuffPtr?? = BuffPtr?? ! cld ! push sp ! push si ;preserve caller's register variables ! push di ! push es ! push ds ! sub sp, 256*2 ;allocate space for SkipTable on our ! ; stack ! mov ax,PatLen% ! and ax,ax ;return an instant match if the ! jz InstantMatch ; pattern 0-length ! mov StackSeg??,ss ! mov es,StackSeg?? ! mov di,sp ;point to SkipBuffer ! mov cx,256 ! rep stosw ! mov es,BuffSeg?? ! mov ds,PatSeg?? ! dec ax ;from now on, we only need ! mov PatLen%,ax ; PatLen% - 1 ' Point to last (rightmost) byte of first potential pattern match ' location in buffer. ! add BuffPtr??, ax ! sub BuffLen%,ax ! jbe NoMatch ! mov si,PatPtr?? ;point to start of pattern ! and ax,ax ;are there any skips to set? ! jz SetSkipDone ;no ! mov di,sp ;point to SkipBuffer SetSkipLoop: ! sub bx,bx ;prepare for word addressing off byte value ! mov bl,ds:[si] ;get the next pattern byte ! inc si ;advance the pattern pointer ! shl bx,1 ;prepare for word look-up ! mov ss:[di+bx],ax ;set the skip value when this byte value ! ;is the mismatch value in the buffer ! dec ax ! jnz SetSkipLoop SetSkipDone: ! mov dl,ds:[si] ;DL=rightmost pattern byte from now on ! dec si ;point to next-to-rightmost byte of pattern ! mov PatPtr??,si ; from now on ' Search the buffer. ! std ;for backward REPZ CMPSB ! mov di,BuffPtr?? ;point to the first search location ! mov cx,BuffLen% ;# of match locations to check SearchLoop: ! mov si,sp ;point SI to SkipTable ' Skip through until there's a match for the rightmost pattern ' byte. ' We jump this way to avoid a FIXUP OVERFLOW under PB... ! jmp QuickSearchLoop InstantMatch: ! mov ax,BuffPtr?? ! jmp short Done ' Compare the pattern and the buffer location, searching from high ' memory toward low (right to left). FullCompare: ! mov BuffPtr??,di ;save the current state of ! mov BuffLen%,cx ; the search ! mov cx,PatLen% ;# of bytes yet to compare ! jcxz Matched ;done if there was only one character ! mov si,PatPtr?? ;point to next-to-rightmost bytes ! dec di ; of buffer location and pattern ! repz cmpsb ;compare the rest of the pattern ! jz Matched ;that's it; we've found a match ' It's a mismatch; let's see what we can learn from it. ! inc di ;compensate for 1-byte overrun of REPZ CMPSB; ! ; point to mismatch location in buffer ! ; # of bytes that did match. ! mov si,BuffPtr?? ! sub si,di ! sub bx,bx ;prepare for word addressing off byte value ! mov bl,es:[di] ;get the value of the mismatch byte in buffer ! add bx,bx ;prepare for word look-up ! add bx,sp ;SP points to SkipTable ! mov cx,ss:[bx] ;get the skip value for this mismatch ! mov ax,1 ;assume we'll just advance to the next ! ; potential match location ! sub cx,si ;is the skip far enough to be worth taking? ! jna MoveAhead ;no, go with the default advance of 1 ! mov ax,cx ;yes; this is the distance to skip ahead from ! ; the last potential match location checked MoveAhead: ' Skip ahead and perform the next comparison, if there's any buffer ' left to check. ! mov di,BuffPtr?? ! add di,ax ;BuffPtr?? += Skip ! mov cx,BuffLen% ! sub cx,ax ;BuffLen% -= Skip; ! ja SearchLoop ;continue if any buffer left ' Return a NULL pointer for no match. NoMatch: ! sub ax,ax ! jmp short Done ' Return start of match in buffer (BuffPtr?? - (PatLen% - 1)). Matched: ! mov ax, BuffPtr?? ! sub ax, TrueBuffPtr?? ! sub ax, PatLen% ! les bx, [bp+&HE] ! add ax, es:[bx] ; Parameter: TheStart% ! inc ax ! mov FUNCTION, ax Done: ! cld ! add sp,256*2 ;deallocate space for SkipTable ! pop ds ! pop es ! pop di ;restore caller's register variables ! pop si ! pop sp EXIT FUNCTION QuickSearchLoop: ! mov bl,es:[di] ;rightmost buffer byte at this location ! cmp dl,bl ;does it match the rightmost pattern byte? ! jz FullCompare ;yes, so keep going ! sub bh,bh ;convert to a word ! add bx,bx ;prepare for look-up in SkipTable ! mov ax,ss:[si+bx] ;get skip value from skip table for this ! ; mismatch value ! add di,ax ;BuffPtr?? += Skip; ! sub cx,ax ;BuffLen% -= Skip; ! ja QuickSearchLoop;continue if any buffer left ! jmp short NoMatch ' Return a pointer to the start of the buffer (for 0-length ' pattern). END FUNCTION