home *** CD-ROM | disk | FTP | other *** search
- \ TAIL PROGRAM, BY TOM ALMY.
-
- \ THIS PROGRAM IS COPYRIGHT (C) 1985 BY TOM ALMY,
- \ ALL RIGHTS RESERVED.
- \ Users of ForthCMP are given permission to use or distribute this
- \ program, as long as no charge is made and the credit message is maintained.
-
- 100 MSDOS
- HEX 1000 DECIMAL CONSTANT BUFSIZ
- INCLUDE FILTER
-
-
- \ DATA DECLARATIONS
- 0 CONSTANT FALSE
- -1 CONSTANT TRUE
- CONTROL J CONSTANT NL \ line delimiter character
- VARIABLE +FLAG \ flags in option string
- VARIABLE CFLAG
- VARIABLE RFLAG
- 2VARIABLE LCOUNT
- 2VARIABLE OFFSET \ Offset into file of pointer
- VARIABLE RLINEBUF \ reverse line buffer
-
- \ MESSAGES
- 0 0 IN/OUT
- : NOTICE CONSOLE
- ." TAIL PRINTING PROGRAM " CR
- ." COPYRIGHT (C) 1985 BY THOMAS ALMY " CR ;
-
- 0 0 IN/OUT
- : USAGE CONSOLE CR
- ." USAGE: TAIL [-[+][n][C][R]] [srcfile] [destfile]" CR
- ." where srcfile is an ascii source file, or - for standard input" CR
- ." and destfile is output file." CR
- ." + --> type leading lines instead of tail" CR
- ." n --> line count (default to 10)" CR
- ." C --> `n' is character count" CR
- ." R --> output lines backwards (+ or C ignored)" CR
- ABORT ;
-
- 0 1 IN/OUT
- : MORE-LINES? ( -- true if more lines )
- LCOUNT 2@ 2DUP OR -ROT -1. D+ LCOUNT 2! ;
-
- 1 0 IN/OUT
- : ?DIE IF CONSOLE ." I/O ERROR" ABORT THEN ;
-
-
-
- \ routines for reverse reading
-
- 0 1 IN/OUT
- : BACKREAD ( -- bofflag )
- OFFSET 2@ OR 0= IF TRUE EXIT THEN ( backed up to start already )
- OFFSET 2@ BUFSIZ 0 D- OFFSET 2!
- infile OFFSET 2@ 0 FSEEK 2DROP ( back file up )
- infile inbuffer @ BUFSIZ FREAD DUP BUFSIZ <> ?DIE
- inbuffer @ + DUP inbufend ! inbufptr ! ( start at end of buffer )
- FALSE
- ;
-
- 0 0 IN/OUT
- : INIT-REVERSE
- infile 0 0 2 FSEEK OFFSET 2! ( compute file size )
- OFFSET 2+ @ BUFSIZ 1- AND ?DUP IF ( short first buffer? )
- DUP NEGATE OFFSET 2+ +! ( adjust offset )
- infile OFFSET 2@ 0 FSEEK 2DROP
- infile inbuffer @ 2 PICK FREAD TUCK <> ?DIE
- inbuffer @ + DUP inbufend ! inbufptr !
- ELSE
- inbuffer @ inbufptr !
- BACKREAD DROP
- THEN ;
-
- 0 1 IN/OUT
- : -KEY ( -- key or -1 if BOF )
- inbuffer @ inbufptr @ = IF BACKREAD IF TRUE EXIT THEN THEN
- -1 inbufptr +!
- inbufptr @ C@ ;
-
-
- \ Copying routines
- 0 0 IN/OUT
- : +COPY \ Copy in forward direction
- CFLAG @ IF ( by character )
- BEGIN
- MORE-LINES? WHILE ( non-zero so move a character )
- KEY DUP 0< NOT IF EMIT ELSE DROP EXIT THEN
- REPEAT
- ELSE ( by line )
- BEGIN
- MORE-LINES? WHILE ( non-zero so move a line )
- BEGIN KEY DUP 0< IF DROP EXIT THEN
- DUP NL <> WHILE
- EMIT
- REPEAT EMIT
- REPEAT THEN ;
-
-
- 0 0 IN/OUT
- : RCOPY \ Reverse copy
- 2 ALLOT
- HERE RLINEBUF !
- 256 ALLOT ( allot our storage )
- INIT-REVERSE ( will go backwards )
- -KEY 0< IF EXIT THEN ( quit if nothing )
- BEGIN MORE-LINES? WHILE RLINEBUF @ ( end of line )
- BEGIN -KEY DUP 0< NOT OVER NL <> AND WHILE
- OVER C! 1+ REPEAT ( buffer, key ) SWAP
- BEGIN DUP RLINEBUF @ <> WHILE
- 1- DUP C@ EMIT
- REPEAT DROP
- NL EMIT
- TRUE = IF EXIT THEN
- REPEAT ;
-
-
-
- 0 0 IN/OUT
- : BACK-LINES \ Search backwards from end by lines
- INIT-REVERSE
- BEGIN BEGIN -KEY DUP 0< IF DROP EXIT THEN
- NL = UNTIL
- MORE-LINES? 0= UNTIL
- KEY DROP ;
-
- 0 0 IN/OUT
- : BACK-CHARS \ Tricky search backwards by characters
- infile 0 0 2 FSEEK LCOUNT 2@ DMIN DNEGATE
- infile -ROT 1 FSEEK 2DROP ;
-
- 0 0 IN/OUT
- : -COPY \ Copy final lines/characters
- CFLAG @ IF BACK-CHARS ELSE BACK-LINES THEN
- BEGIN KEY DUP 0< NOT WHILE
- EMIT REPEAT DROP ;
-
-
- \ Parse Command stream
-
- 1 0 IN/OUT
- : BAD-OPTION \ Just print the error message then quit
- CONSOLE CR ." BAD OPTION - " EMIT USAGE ;
-
- 0 0 IN/OUT
- : READ-OPTIONS
- +FLAG OFF
- CFLAG OFF
- RFLAG OFF
- 10. LCOUNT 2!
- OPTIONSTRING 2@ 0 ?DO COUNT
- DUP ASCII a >= IF BL - THEN CASE
- ASCII C OF CFLAG ON 1 ENDOF
- ASCII + OF +FLAG ON 1 ENDOF
- ASCII R OF RFLAG ON 1 ENDOF
- DUP ASCII 0 >= OVER ASCII 9 <= AND IF
- DROP DUP >R 2- 0. ROT CONVERT -ROT LCOUNT 2! DUP R> - 1+ 0
- ELSE BAD-OPTION THEN ENDCASE
- +LOOP DROP ;
-
-
- 1 1 IN/OUT
- CODE SERIAL? ( handle -- TRUE if serial device )
- HEX
- AX BX MOV
- 4400 # AX MOV
- 21 INT
- DX AX MOV
- 80 # AX AND
- RET
- END-CODE
-
- \ MAIN ROUTINE
- : MAIN
- SETBUFS
- NOTICE
- SETFILES infile HCB>H SERIAL? OR IF USAGE THEN
- READ-OPTIONS
- RFLAG @ IF
- RCOPY
- ELSE
- +FLAG @ IF
- +COPY
- ELSE
- -COPY
- THEN
- THEN
- BYE ;
-
- INCLUDE DOS2
- INCLUDE FORTHLIB
- END
-