home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpm
/
list
/
ep-src.ark
/
FGET.MAC
< prev
next >
Wrap
Text File
|
1988-05-21
|
8KB
|
500 lines
include BDSYM.EQU
include EPDATA
IOBUFSIZ equ 2+2+2+SECSIZ
.comment `
/* FGET.C - file stack functions for EP */
/* flnum should be set to 0 before 1st call */
struct _ebuf {
int _fd;
int _nleft;
char *_nextp;
char _buff[SECSIZ];
/* char _flags;*/
};
struct _ebuf fl[8];
int flnum;
fopen(filename)
char *filename;
{ struct _ebuf *iobuf;
iobuf = fl[flnum];
if ((iobuf -> _fd = open(filename,0))<0) return ERROR;
iobuf -> _nleft = 0;
/* iobuf -> _flags = _READ;*/
flnum++;
return iobuf -> _fd;
}
`
fopen::
pop d
pop h
push h
push d
;unlike C version, open the file first, so don't have to save *filename
lxi d,0
push d
push h
call open##
pop d
pop d
;check for error
mov a,h
ora a
rm ;can assume HL = -1 if error
;ok, so save FD
push h
; iobuf = fl[flnum];
lhld _flnum
push h
mov a,l
cpi 8
cnc eperror##
pop h
lxi d,IOBUFSIZ ;86H
call usmul
lxi d,fl
dad d
shld _iob
;
; if ((iobuf -> _fd = open(filename,0))<0) return ERROR;
;already open -- stow the FD
pop d
mov m,e
inx h
mov m,d
; iobuf -> _nleft = 0;
inx h
xra a
mov m,a
inx h
mov m,a
; flnum++;
;now treat as byte var.
lxi h,_flnum
inr m
; return iobuf -> _fd;
;DE still has FD
;}
xchg
ret
_iob: dw 0
_flnum: dw 0
.comment `
getc()
{ struct _ebuf *iobuf;
char c;
while (flnum>0)
{
iobuf = fl[flnum-1];
if (!iobuf->_nleft--) /* if buffer empty, fill it up first */
{
if (read(iobuf -> _fd, iobuf -> _buff, 1) <= 0)
{ fabort(iobuf -> _fd);
flnum--;
continue;
}
iobuf -> _nleft = SECSIZ - 1;
iobuf -> _nextp = iobuf -> _buff;
}
if ((c = *iobuf->_nextp++) != CPMEOF) return c;
else flnum--;
}
return EOF;
}
`
getc::
; while (flnum>0)
; {
.ge1:
lxi h,-1 ;for error ret
lda _flnum
ora a
rz
; iobuf = fl[flnum-1];
;assume current value in _iob is valid
;
; if (!iobuf->_nleft--) /* if buffer empty, fill it up first */
lhld _iob
inx h ;past _fd
inx h
mov e,m ;load _nleft
inx h
mov d,m
;DE = *_nleft and HL = ->_nleft + 1
;check here for none
mov a,d
ora e
jnz .ge3
;*_nleft now updated at .ge3
; {
; if (read(iobuf -> _fd, iobuf -> _buff, 1) <= 0)
lxi d,1
push d
; lhld _iob
; lxi d,6
; dad d
inx h ;past high byte of _nleft
inx h ;past _nextp
inx h
push h ;this is _buff
lhld _iob
mov e,m ;load _fd
inx h
mov d,m
push d
call read##
pop d
pop d
pop d
;HL = 0 for eof? go read embedding file
;HL = ERROR? same (but this is not right)
dcx h
mov a,h
ora a
;if ok, go update pointers and return the character
jp .ge2
; { fabort(iobuf -> _fd);
;to here when can't read any more chars, or get CPMEOF
.ge4:
lhld _iob
; mov d,m
; inx h
; mov e,m
; push d
mov a,m
call fabort##
; pop d
; flnum--;
lxi h,_flnum
dcr m
;also update _iob
lhld _iob
lxi d,-IOBUFSIZ
dad d
shld _iob
; continue;
; }
jmp .ge1
; iobuf -> _nleft = SECSIZ - 1;
.ge2: lhld _iob
inx h
inx h
mvi m,SECSIZ - 1
inx h
mvi m,0
; iobuf -> _nextp = iobuf -> _buff;
; }
inx h
;HL = ->_nextp
mov d,h
mov e,l
inx d
inx d
;DE = ->_buff
;we may as well go ahead and load the character
ldax d
inx d
mov m,e
inx h
mov m,d
;go directly to check for CPMEOF with char in A
jmp .ge3x
; if ((c = *iobuf->_nextp++) != CPMEOF) return c;
.ge3:
;now DE = *_nleft and HL = ->_nleft + 1
;decr *_nleft
dcx d
;and store
mov m,d
dcx h
mov m,e
;move pointer to _nextp and load
inx h
inx h
mov e,m
inx h
mov d,m
;get char at _nextp
ldax d
;incr *_nextp
inx d
;and store back
mov m,d
dcx h
mov m,e
.ge3x:
cpi 1AH
jz .ge4
mov l,a
mvi h,0
ret
; else flnum--;
; }
;.ge4: cf. above
.comment `
/****************************************************************/
/* Modified version of standard library function 'fgets'. */
/* (Needed to prevent overflow when dealing with WordStar */
/* document files, since b7 of CR or LF may be set, and */
/* this conceals the end of line from regular fgets.) */
/****************************************************************/
char *fgets(s)
char *s;
{ int count, c;
char *cptr;
count = MAXLINE - 2;
cptr = s;
if ( (c = getc()) == EOF ) return NULL;
/* This way, the 8A page break is effaced. Change this if need it. */
do
{ if (c == SOFTSP) continue;
if ((*cptr++ = (c & 0x7F)) == '\n')
{ if (cptr>s+1 && *(cptr-2) == '\r')
*(--cptr - 1) = '\n';
break;
}
} while (count-- && (c=getc()) != EOF );
/*if (c == CPMEOF) ungetc(c,iobuf); push back control-Z */
/* right-trim blanks and tabs */
while (cptr>s+1 && ((c = *(cptr-2)) == ' ') || c == '\t')
*(--cptr - 1) = '\n';
*cptr = '\0';
return s;
}
`
fgets::
pop d
pop h
push h
push d
push b
;C holds c
;B holds the last c gotten, or 0 if none
mvi b,0 ;no last c, so far
shld _fgs
shld _cptr ;cf. below
; count = MAXLINE - 2;
lxi h,MAXLINE-2
shld _count
; cptr = s;
; if ( (c = getc()) == EOF ) return NULL;
call getc
mov c,l
inx h
mov a,h
ora l
jnz .fg1
;(HL = NULL = 0)
pop b
ret
;/* This way, the 8A page break is effaced. Change this if need it. */
; do
; { if (c == SOFTSP) continue;
.fg1:
mov a,c
cpi SOFTSP
jz .fg4
; if ((*cptr++ = (c & 0x7F)) == '\n')
.fg2:
ani 7fh
lhld _cptr
mov m,a
inx h
shld _cptr
cpi 0ah
jnz .fg4
; { if (cptr>s+1 && *(cptr-2) == '\r')
;If this is the first time through the loop,
; cptr = s+1, but then the last c in B will be zero.
;Also, *(cptr-2) is the last c, so the above conditions
; are met iff B = 0dh.
mov a,b
cpi 0dh
jnz .fg5
; lhld _cptr
; xchg
; lhld _fgs
; inx h
; call agbu
; jnc .fg3 (== .fg5)
;
; lhld _cptr
; dcx h
; dcx h
; mov a,m
; cpi 0DH
; jnz .fg3
; *(--cptr - 1) = '\n';
; break;
; }
; lhld _cptr
;here we got a CR-LF
;point to the LF
dcx h
;now this is the end of the string
shld _cptr
;point to the CR
dcx h
;write a LF over it
mvi m,0ah
jmp .fg5
; } while (count-- && (c=getc()) != EOF );
.fg4:
lhld _count
mov a,h
ora l
dcx h
shld _count
; jz .fg5
;(don't try to trim over long lines)
jz .fg7
;last c = old c
mov b,c
call getc
mov c,l
inx h ;check for eof or error
mov a,h
ora l
jnz .fg1
;To get here, the file must not have been terminated with CR-LF.
;This is not in the c-version, but the best thing seems to add a NL:
lhld _cptr
mvi m,0ah
inx h
shld _cptr
;
;/* right-trim blanks and tabs */
; while (cptr>s+1 && ((c = *(cptr-2)) == ' ') || c == '\t')
; *(--cptr - 1) = '\n';
;
.fg5:
;We depart from the c-version:
;
;First, mark before the beginning of the string with a nul,
; saving the byte here
lhld _fgs
dcx h
mov c,m
mvi m,0
xchg
;Then starting at the last c stored, which was a LF, at cptr-1, ...
lhld _cptr
dcx h
.fgtrim:
;go back until preceding is not blank or tab
dcx h
mov a,m
cpi ' '
jz .fgtrim
cpi 9
jz .fgtrim
;write LF over last blank or tab char, or over LF itself if there were none
inx h
mvi m,0ah
;and cptr points after the LF
inx h
shld _cptr
;Restore the byte before the string
xchg
mov m,c
; *cptr = '\0';
.fg7:
lhld _cptr
mvi m,0
;
; return s;
lhld _fgs
;}
.fg8:
pop b
ret
_fgs: dw 0
_count: dw 0
_cptr: dw 0
end