home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
utils
/
filutl
/
gf10.lbr
/
GF.ZZ0
/
GF.Z80
Wrap
Text File
|
1989-02-28
|
7KB
|
245 lines
;
;**********************************************************************
; GF is a generalized file filter program for ZCPR systems.
;
; Purpose: GF allows the user to change any single character from an
; input file to any other character in the resulting an output
; file.
;
; Author: Dave Ramsey Date: December 12, 1988
;
; Assembler Used: SLR's Z80ASM
;
;**********************************************************************
;
;PDL for Filter follows:
;
;Begin FILTER
; Get ptr to cmd line
; Parse cmd line
; If number args = 4 then
; open input file (arg[1])
; if open error then
; abort with message "can't open input file" arg[1]
; endif
; open output file (arg[2])
; target = control(arg[3])
; replacement = control(arg[4])
; while not eof(input file) do
; inchar = getnextchar(input file)
; if inchar = target then
; inchar = replacement
; endif
; putnextchar(output file)
; end while
; else
; show help
; endif
;end FILTER
;
;
;**********************************************************************
;
VERSION equ 10 ;defines current version of GF
FCB0 equ 5Ch
FCB1 equ 6Ch
BDOSEV equ 0005h ;BDOS entry vector
BOOTEV equ 0000h ;system warm start entry vector
CR equ 0Dh ;carriage return = ASCII char 13
LF equ 0Ah ;line feed = ASCII char 10
TBUFF equ 080h
;
;
ext print,fi0$open,f0$get,fo1$open,f1$put,fi0$close,fo1$close
ext caps,z3init,argv,pstr,cout,crlf
;
;
main:
jp start
db 'Z3ENV'
z3eadr ds 2
;
start:
ld hl,z3eadr
call z3init ;initialize Z3 environment
;
; setup program stack here...
;
ld hl,0
add hl,sp ;save current sp
ld (oldsp),hl
ld hl,BDOSEV+1 ;get BDOS address...
ld a,h
sub a,8 ;our stack = BDOS - 2K (to save CCP)
ld h,a ;set page address of stack
xor a
ld l,a ;put on a page boundary
;
; check for help request
;
ld a,(FCB0+1)
cp a,'/'
jr z,help
cp a,' '
jr nz,start2
help:
ld hl,usage
call pstr
jp fini2
;
; parse the command tail...
;
start2:
ld de,argtbl
ld hl,TBUFF+1 ;cmd tail is in TBUFF
xor a ;do not NULL terminate args
call argv
jr z,start3 ;if parsing error occurred, show help
ld hl,parserr
call pstr
jp fini2
start3:
ld a,(argtbl+1)
cp a,4
jr z,openin ;if wrong # of args, show help
ld hl,argcount
call pstr
jp fini2
;
; open input file specified in arg #1
;
openin:
ld de,FCB0
call fi0$open ;open file in infcb for input
jp z,openout ;if ok, goto start
call print ;else print error msg and abort
db 'Input file not found.',0
jp fini2
;
; open output file specified in arg #2
;
openout:
ld de,FCB1
call fo1$open ;open file in outfcb for output
jp z,getargs
call print
db 'Unable to open specified output file.',0
jp fini1
getargs:
;
; here we would set values from cmd line for target and replacement
; chars...
;
ld hl,(arg3) ;point at 3rd cmd line arg
ld a,(hl)
call control ;convert search arg
ld (oldchar),a ;save converted char
;
ld hl,(arg4) ;point at 4th cmd line arg
ld a,(hl)
call control ;convert replacement arg
ld (newchar),a ;save converted char
loop: ;while not eof do
call f0$get ; get next input byte
jp nz,finish ; if not zero, error - process error
ld hl,oldchar
cp a,(hl) ; input byte = search char?
jr nz,loop2 ; if no, continue processing
ld a,(newchar) ; else replace with new char
;
loop2: call f1$put ; put next byte in output file
jr loop ;endwhile
;
finish:
call fo1$close ;close output file
fini1:
call fi0$close ;close input file
fini2: ld hl,(oldsp) ;get old stack pointer
ld sp,hl ;restore BDOS stack pointer
ret ;return to CCP
;
;****************************************************************
;
; CONTROL routine: returns the cmd line arg pointed to by HL
; as a character in A. Converts cmd line string ^c to the
; equivalent control character.
;
;Begin CONTROL
; temp = charptr passed in from caller
; if *charptr == '^' then
; ++charptr
; convert to uppercase(*charptr)
; if *charptr == `^` then
; temp = *charptr
; else
; temp = *charptr - 64 /* convert to control */
; endif
; else if *charptr == '~' then
; ++charptr
; if *charptr == '~' then
; temp = *charptr
; else
; temp = *charptr + 32 /* convert to lowercase */
; endif
; return temp
;end CONTROL
;
;****************************************************************
;
control:
ld a,(hl) ;get initial arg
cp a,'^' ;is it control trigger?
jr nz,contr2 ;if not, check for lowercase flag
inc hl
ld a,(hl) ;else get next byte in arg
cp a,'^' ;trap '^^' sequence...
jr z,contr3 ;let caller use '^' char...
call caps ;else capitalize it, and then
sub a,040h ;subtract 64 to get ASCII ctrl code
ret
;
; check here for lowercase trigger...
contr2:
cp a,'~' ;`~` is our lowercase flag
jr nz,contr3 ;if it's not `~` it's just a plain char
inc hl
ld a,(hl)
cp a,'~' ;trap `~~` sequence and let caller use
jr z,contr3 ;the `~` char...
add a,020h ;add 32 to make it lowercase
contr3:
ret ;return from control char conversion
;
; data areas:
;
usage: db 'GF, Version ',VERSION/10+'0','.',VERSION MOD 10+'0'
db ' - A Generalized Filter.',CR,LF
db 'Syntax:',CR,LF
db ' GF du:fn1 du:fn2 oldch newch',CR,LF
db ' Where:',CR,LF
db ' du:fn1 is the input file spec;',CR,LF
db ' du:fn2 is the output file spec;',CR,LF
db ' oldchar is the search character; and',CR,LF
db ' newchar is the replacement character.',CR,LF,
db ' A ^ character before either oldchar or newchar',CR,LF
db ' tells GF to convert it to a control character.',CR,LF
db ' A ~ character before either oldchar or newchar',CR,LF
db ' tells GF to convert it to lowercase.',CR,LF
db ' i.e. ^M is a carriage return and ~M is an "m"',CR,LF,LF,0
;
parserr db 'Parsing error!',CR,LF,0
argcount db 'Incorrect number of arguments!',CR,LF,0
;
oldsp ds 2
oldchar ds 1
newchar ds 1
argtbl db 4 ;max number of args expected
ds 1 ;number of args actually found
ds 2 ;pointer to arg1
ds 2 ;pointer to arg2
arg3 ds 2 ;pointer to arg3
arg4 ds 2 ;pointer to arg4
;
end