home *** CD-ROM | disk | FTP | other *** search
- ; Filter non-text bytes from pipe stream.
-
- INCLUDE "/include/init.i"
-
- ; Local Equs
- ; FilTex uses a buffer split into two 1000 byte parts, the first for writing,
- ; the last part for reading. Reads/Writes are HalfBufSize bytes large max.
-
- DefaultThreshold EQU 4
- BufSize EQU 2000 ; Keep this one < 32K
- HalfBufSize EQU BufSize/2
-
- ; Variable storage
-
- STRUCT ArgArray,(4+1)*4
- LONG InputHandle
- LONG StdOutput
- WORD Threshold
- SIZE
-
- ; Regs
-
- WriteBufIndex EQUR D4
- ReadBufIndex EQUR D5
- ReadBytesLeft EQUR D6
- LatestByte EQUR D7
- BufferPtr EQUR A2
- FilterTablePtr EQUR A3
- ErrorStrPtr EQUR A4
-
- ; Start
-
- STACK 4000
- INIT
-
- ; Let ARP interpret the commandline
-
- MOVE.L ComLineBase(GP),A0
- MOVE.L ComLineSize(GP),D0
- LEA HelpMsg(PC),A1
- LEA ArgArray(GP),A2
- LEA Template(PC),A3
- MOVE.L A1,(A2)
- CALL GADS
- MOVE.L (A2),ErrorStrPtr
- TST.L D0
- BEQ ErrorExit
- BMI ErrorExit
-
- ; Fetch & check the threshold value.
-
- LEA BadThreshold(PC),ErrorStrPtr
- MOVE.W #DefaultThreshold,Threshold(GP)
- MOVE.L ArgArray+4(GP),A0
- MOVE.L A0,D0
- BEQ.S UseDefault
- CALL Atol
- BEQ ErrorExit
- CMP.L #HalfBufSize,D0
- BHI ErrorExit
- MOVE.W D0,Threshold(GP)
- BEQ ErrorExit
- UseDefault:
-
- ; Check if the source is STDIN, if so open that.
-
- MOVE.L ArgArray(GP),A0
- LEA StdinID(PC),A1
- CALL Strcmp
- BNE.S NoStdin
- CALL Input
- MOVE.L D0,InputHandle(GP)
- BRA.S InFileOpened
- NoStdin:
-
- ; Else open a normal source file (Tracked)
-
- LEA SourceOpenError(PC),ErrorStrPtr
- MOVE.L ArgArray(GP),D1
- MOVE.L #MODE_OLDFILE,D2
- CALL ArpOpen
- MOVE.L D0,InputHandle(GP)
- BEQ ErrorExit
- InFileOpened:
-
- ; Fetch the StdOutput
-
- CALL Output
- MOVE.L D0,StdOutput(GP)
-
- ; Alloc tracked mem for the read/write buffer.
-
- LEA OutOfMem(PC),ErrorStrPtr
- MOVE.L #BufSize+1,D0 ; add 1 to allow for LF termination
- MOVEQ #0,D1
- CALL ArpAllocMem
- TST.L D0
- BEQ ErrorExit
- MOVE.L D0,BufferPtr
-
- ; Initialize for the filtered copy loop
-
- LEA FilterTableBase(PC),FilterTablePtr
- MOVEQ #0,WriteBufIndex
-
- ; Read next chunk of bytes.
-
- DoNextRead:
- LEA ReadError(PC),ErrorStrPtr
- MOVEQ #0,ReadBufIndex
- MOVE.W #HalfBufSize,ReadBufIndex
- MOVE.L InputHandle(GP),D1
- MOVE.L BufferPtr,D2
- ADD.L ReadBufIndex,D2
- MOVE.L ReadBufIndex,D3
- CALL Read
- MOVE.W D0,ReadBytesLeft
- BMI ErrorExit
- BEQ.S TryToWriteWriteBuffer
-
- ; Find text bytes.
-
- CheckForTextBytes:
- MOVEQ #0,LatestByte
- MOVE.B 0(BufferPtr,ReadBufIndex.W),LatestByte
- ADDQ.W #1,ReadBufIndex
- SUBQ.W #1,ReadBytesLeft
- TST.B 0(FilterTablePtr,LatestByte.W)
- BEQ.S TryToWriteWriteBuffer
-
- ; Process text bytes
-
- MOVE.B LatestByte,0(BufferPtr,WriteBufIndex.W)
- ADDQ.W #1,WriteBufIndex
- CMP.W #HalfBufSize,WriteBufIndex
- BNE.S CheckReadBufStatus
-
- ; Check if the number of bytes to write equals or exceeds the threshold
-
- TryToWriteWriteBuffer:
- CMP.W Threshold(GP),WriteBufIndex
- BLO.S NeLeWritezPas
-
- ; Check if string is null-terminated (if requested to do so)
-
- TST.L ArgArray+12(GP) ; Check NULT switch
- BEQ.S NoNullCheck
- TST.B LatestByte
- BNE.S NeLeWritezPas
- NoNullCheck:
-
- ; Terminate write with a linefeed if needed & not prohibited
-
- CMP.B #10,-1(BufferPtr,WriteBufIndex.W)
- BEQ.S DoTheWrite
- TST.L ArgArray+8(GP) ; Check NOLF switch
- BNE.S DoTheWrite
- MOVE.B #10,0(BufferPtr,WriteBufIndex.W)
- ADDQ.W #1,WriteBufIndex
-
- ; The actual write to the StdOutput
-
- DoTheWrite:
- LEA WriteError(PC),ErrorStrPtr
- MOVE.L StdOutput(GP),D1
- MOVE.L BufferPtr,D2
- MOVE.W WriteBufIndex,D3
- EXT.L D3
- CALL Write
- CMP.L D0,D3
- BNE.S ErrorExit
-
- ; Check if user hit ^C
-
- SUB.L A1,A1
- CALL CheckAbort
- MOVE.L A1,ErrorStrPtr
- TST.L D0
- BNE.S ErrorExit
- NeLeWritezPas:
-
- ; Reset the write buffer index.
-
- MOVEQ #0,WriteBufIndex
-
- ; Check if no more read bytes left, if so read, exit if last read had zero length
- ; (An adjective, verb and a noun. YOU try 'n make a natural language interpreter!)
-
- CheckReadBufStatus:
- TST.W ReadBytesLeft
- BNE CheckForTextBytes
- CMP.W #HalfBufSize,ReadBufIndex
- BNE DoNextRead
-
- ; Done, cleanup
-
- Exit:
- CLR.W ReturnCode(GP)
- SUB.L ErrorStrPtr,ErrorStrPtr
- ErrorExit:
-
- ; Display error string, if any, and exit
-
- MOVE.L ErrorStrPtr,D0
- BEQ.S NoErrorMsg
- MOVE.L D0,A1
- CALL Puts
- NoErrorMsg:
- RTS
-
- ; The string section
-
- Template:
- DC.B 'File/a,THRESH/k,NOLF/s,NULT/s',0
- HelpMsg:
- DC.B 'FilTex - filter out non-text.',10
- DC.B 'Usage: FilTex <File | STDIN> [THRESH #] [NOLF] [NULT]',0
- StdinID:
- DC.B 'STDIN',0
- BadThreshold:
- DC.B 'Illegal threshold value',0
- SourceOpenError:
- DC.B 'Could not open source file',0
- OutOfMem:
- DC.B 'Out of memory!',0
- ReadError:
- DC.B 'Error while reading',0
- WriteError:
- DC.B 'Error while writing',0
- CNOP 0,4
-
- ; This is the filtering array
-
- DC.B 'TextTab:'
- FilterTableBase:
- ; 0 1 2 3 4 5 6 7 8 9 A B C D E F
- DC.B 000,000,000,000,000,000,000,000,000,$09,$0A,000,000,000,000,000 ;0
- DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;1
- DC.B ' ','!','"','#','$','%','&',$27,'(',')','*','+',',','-','.','/' ;2
- DC.B '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?' ;3
- DC.B 000,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O' ;4
- DC.B 'P','Q','R','S','T','U','V','W','X','Y','Z','[','\',']','^','_' ;5
- DC.B 000,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o' ;6
- DC.B 'p','q','r','s','t','u','v','w','x','y','z','{','|','}','~',000 ;7
- DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;8
- DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;9
- DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;A
- DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;B
- DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;C
- DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;D
- DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;E
- DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;F
- ; 0 1 2 3 4 5 6 7 8 9 A B C D E F
- END
-