?? clib.arc
字號:
/*
** Open file on specified fd.
*/
_open(fn, mode, fd) char *fn, *mode; int *fd; {
int rw, tfd;
switch(mode[0]) {
case 'r': {
if(mode[1] == '+') rw = 2; else rw = 0;
if ((tfd = _bdos2((OPEN<<8)|rw, NULL, NULL, fn)) < 0) return (NO);
break;
}
case 'w': {
if(mode[1] == '+') rw = 2; else rw = 1;
create:
if((tfd = _bdos2((CREATE<<8), NULL, ARCHIVE, fn)) < 0) return (NO);
_bdos2(CLOSE<<8, tfd, NULL, NULL);
if((tfd = _bdos2((OPEN<<8)|rw, NULL, NULL, fn)) < 0) return (NO);
break;
}
case 'a': {
if(mode[1] == '+') rw = 2; else rw = 1;
if((tfd = _bdos2((OPEN<<8)|rw, NULL, NULL, fn)) < 0) goto create;
if(_bdos2((SEEK<<8)|FROM_END, tfd, NULL, 0) < 0) return (NO);
break;
}
default: return (NO);
}
_empty(tfd, YES);
if(isatty(tfd)) _bufuse[tfd] = NULL;
*fd = tfd;
_cons [tfd] = NULL;
_nextc [tfd] = EOF;
_status[tfd] = OPNBIT;
return (YES);
}
/*
** Binary-stream input of one byte from fd.
*/
_read(fd) int fd; {
unsigned char ch;
if(_nextc[fd] != EOF) {
ch = _nextc[fd];
_nextc[fd] = EOF;
return (ch);
}
if(iscons(fd)) return (_getkey());
if(_bufuse[fd]) return(_readbuf(fd));
switch(_bdos2(READ<<8, fd, 1, &ch)) {
case 1: return (ch);
case 0: _seteof(fd); return (EOF);
default: _seterr(fd); return (EOF);
}
}
/*
** Fill buffer if necessary, and return next byte.
*/
_readbuf(fd) int fd; {
int got, chunk;
char *ptr, *max;
if(_bufuse[fd] == OUT && _flush(fd)) return (EOF);
while(YES) {
ptr = _bufnxt[fd];
if(ptr < _bufend[fd]) {++_bufnxt[fd]; return (*ptr);}
if(_bufeof[fd]) {_seteof(fd); return (EOF);}
max = (ptr = _bufend[fd] = _bufptr[fd]) + _bufsiz[fd];
do { /* avoid DMA problem on physical 64K boundary */
if((max - ptr) < 512) chunk = max - ptr;
else chunk = 512;
ptr += (got = _bdos2(READ<<8, fd, chunk, ptr));
if(got < chunk) {_bufeof[fd] = YES; break;}
} while(ptr < max);
_bufend[fd] = ptr;
_bufnxt[fd] = _bufptr[fd];
_bufuse[fd] = IN;
}
}
/*
** Binary-Stream output of one byte to fd.
*/
_write(ch, fd) int ch, fd; {
if(_bufuse[fd]) return(_writebuf(ch, fd));
if(_bdos2(WRITE<<8, fd, 1, &ch) != 1) {
_seterr(fd);
return (EOF);
}
return (ch);
}
/*
** Empty buffer if necessary, and store ch in buffer.
*/
_writebuf(ch, fd) int ch, fd; {
char *ptr;
if(_bufuse[fd] == IN && _backup(fd)) return (EOF);
while(YES) {
ptr = _bufnxt[fd];
if(ptr < (_bufptr[fd] + _bufsiz[fd])) {
*ptr = ch;
++_bufnxt[fd];
_bufuse[fd] = OUT;
return (ch);
}
if(_flush(fd)) return (EOF);
}
}
/*
** Flush buffer to DOS if dirty buffer.
** Reset buffer pointers in any case.
*/
_flush(fd) int fd; {
int i, j, k, chunk;
if(_bufuse[fd] == OUT) {
i = _bufnxt[fd] - _bufptr[fd];
k = 0;
while(i > 0) { /* avoid DMA problem on physical 64K boundary */
if(i < 512) chunk = i;
else chunk = 512;
k += (j = _bdos2(WRITE<<8, fd, chunk, _bufptr[fd] + k));
if(j < chunk) {_seterr(fd); return (EOF);}
i -= j;
}
}
_empty(fd, YES);
return (NULL);
}
/*
** Adjust DOS file position to current point.
*/
_adjust(fd) int fd; {
if(_bufuse[fd] == OUT) return (_flush(fd));
if(_bufuse[fd] == IN ) return (_backup(fd));
}
/*
** Backup DOS file position to current point.
*/
_backup(fd) int fd; {
int hi, lo;
if(lo = _bufnxt[fd] - _bufend[fd]) {
hi = -1;
if(!_seek(FROM_CUR, fd, &hi, &lo)) {
_seterr(fd);
return (EOF);
}
}
_empty(fd, YES);
return (NULL);
}
/*
** Set buffer controls to empty status.
*/
_empty(fd, mt) int fd, mt; {
_bufnxt[fd] = _bufend[fd] = _bufptr[fd];
_bufeof[fd] = NO;
if(mt) _bufuse[fd] = EMPTY;
}
/*
** Return fd's open mode, else NULL.
*/
_mode(fd) char *fd; {
if(fd < MAXFILES) return (_status[fd]);
return (NULL);
}
/*
** Set eof status for fd and
*/
_seteof(fd) int fd; {
_status[fd] |= EOFBIT;
}
/*
** Clear eof status for fd.
*/
_clreof(fd) int fd; {
_status[fd] &= ~EOFBIT;
}
/*
** Set error status for fd.
*/
_seterr(fd) int fd; {
_status[fd] |= ERRBIT;
}
/*
** Clear error status for fd.
*/
_clrerr(fd) int fd; {
_status[fd] &= ~ERRBIT;
}
/*
** Allocate n bytes of (possibly zeroed) memory.
** Entry: n = Size of the items in bytes.
** clear = "true" if clearing is desired.
** Returns the address of the allocated block of memory
** or NULL if the requested amount of space is not available.
*/
_alloc(n, clear) unsigned n, clear; {
char *oldptr;
if(n < avail(YES)) {
if(clear) pad(_memptr, NULL, n);
oldptr = _memptr;
_memptr += n;
return (oldptr);
}
return (NULL);
}
/*
** Issue extended BDOS function and return result.
** Entry: ax = function code and sub-function
** bx, cx, dx = other parameters
*/
_bdos2(ax, bx, cx, dx) int ax, bx, cx, dx; {
#asm
push bx ; preserve secondary register
mov dx,[bp+4]
mov cx,[bp+6]
mov bx,[bp+8]
mov ax,[bp+10] ; load DOS function number
int 21h ; call bdos
jnc __bdos21 ; no error
neg ax ; make error code negative
__bdos21:
pop bx ; restore secondary register
#endasm
}
/*
** Issue LSEEK call
*/
_seek(org, fd, hi, lo) int org, fd, hi, lo; {
#asm
push bx ; preserve secondary register
mov bx,[bp+4]
mov dx,[bx] ; get lo part of destination
mov bx,[bp+6]
mov cx,[bx] ; get hi part of destination
mov bx,[bp+8] ; get file descriptor
mov al,[bp+10] ; get origin code for seek
mov ah,42h ; move-file-pointer function
int 21h ; call bdos
jnc __seek1 ; error?
xor ax,ax ; yes, return false
jmp __seek2
__seek1: ; no, set hi and lo
mov bx,[bp+4] ; get address of lo
mov [bx],ax ; store low part of new position
mov bx,[bp+6] ; get address of hi
mov [bx],dx ; store high part of new position
mov ax,1 ; return true
__seek2:
pop bx ; restore secondary register
#endasm
}
/*
** Test for keyboard input
*/
_hitkey() {
#asm
mov ah,1 ; sub-service = test keyboard
int 16h ; call bdos keyboard services
jnz __hit1
xor ax,ax ; nothing there, return false
jmp __hit2
__hit1:
mov ax,1 ; character ready, return true
__hit2:
#endasm
}
/*
** Return next keyboard character
*/
_getkey() {
#asm
mov ah,0 ; sub-service = read keyboard
int 16h ; call bdos keyboard services
or al,al ; special character?
jnz __get2 ; no
mov al,ah ; yes, move it to al
cmp al,3 ; ctl-2 (simulated null)?
jne __get1 ; no
xor al,al ; yes, report zero
jmp __get2
__get1:
add al,113 ; offset to range 128-245
__get2:
xor ah,ah ; zero ah
#endasm
}
>>> CTELL.C 566
#include "stdio.h"
#include "clib.h"
extern int _bufuse[];
/*
** Return offset to current 128-byte record.
*/
ctell(fd) int fd; {
int hi, lo;
if(!_mode(fd) || !_bufuse[fd]) return (-1);
if(_adjust(fd)) return (-1);
hi = lo = 0;
_seek(FROM_CUR, fd, &hi, &lo);
return ((hi << 9) | ((lo >> 7) & 511));
}
/*
** Return offset to next byte in current 128-byte record.
*/
ctellc(fd) int fd; {
int hi, lo;
if(!_mode(fd) || !_bufuse[fd]) return (-1);
if(_adjust(fd)) return (-1);
hi = lo = 0;
_seek(FROM_CUR, fd, &hi, &lo);
return (lo & 127);
}
>>> DTOI.C 370
#include "stdio.h"
/*
** dtoi -- convert signed decimal string to integer nbr
** returns field length, else ERR on error
*/
dtoi(decstr, nbr) char *decstr; int *nbr; {
int len, s;
if((*decstr)=='-') {s=1; ++decstr;} else s=0;
if((len=utoi(decstr, nbr))<0) return ERR;
if(*nbr<0) return ERR;
if(s) {*nbr = -*nbr; return ++len;} else return len;
}
>>> EXIT.C 447
#include "stdio.h"
#include "clib.h"
/*
** Close all open files and exit to DOS.
** Entry: ec = exit code.
*/
exit(ec) int ec; {
int fd; char str[4];
ec &= 255;
if(ec) {
left(itou(ec, str, 4));
fputs("Exit Code: ", stderr);
fputs(str, stderr);
fputs("\n", stderr);
}
for(fd = 0; fd < MAXFILES; ++fd) fclose(fd);
_bdos2((RETDOS<<8)|ec, NULL, NULL, NULL);
#asm
_abort: jmp _exit
public _abort
#endasm
}
>>> FCLOSE.C 336
#include "stdio.h"
#include "clib.h"
/*
** Close fd
** Entry: fd = file descriptor for file to be closed.
** Returns NULL for success, otherwise ERR
*/
extern int _status[];
fclose(fd) int fd; {
if(!_mode(fd) || _flush(fd)) return (ERR);
if(_bdos2(CLOSE<<8, fd, NULL, NULL) == -6) return (ERR);
return (_status[fd] = NULL);
}
>>> FEOF.C 214
#include "clib.h"
extern int _status[];
/*
** Test for end-of-file status.
** Entry: fd = file descriptor
** Returns non-zero if fd is at eof, else zero.
*/
feof(fd) int fd; {
return (_status[fd] & EOFBIT);
}
>>> FERROR.C 152
#include "stdio.h"
#include "clib.h"
extern _status[];
/*
** Test for error status on fd.
*/
ferror(fd) int fd; {
return (_status[fd] & ERRBIT);
}
>>> FGETC.C 1083
#include "stdio.h"
#include "clib.h"
extern int _nextc[];
/*
** Character-stream input of one character from fd.
** Entry: fd = File descriptor of pertinent file.
** Returns the next character on success, else EOF.
*/
fgetc(fd) int fd; {
int ch; /* must be int so EOF will flow through */
if(_nextc[fd] != EOF) { /* an ungotten byte pending? */
ch = _nextc[fd];
_nextc[fd] = EOF;
return (ch & 255); /* was cooked the first time */
}
while(1) {
ch = _read(fd);
if(iscons(fd)) {
switch(ch) { /* extra console cooking */
case ABORT: exit(2);
case CR: _write(CR, stderr); _write(LF, stderr); break;
case DEL: ch = RUB;
case RUB:
case WIPE: break;
default: _write(ch, stderr);
}
}
switch(ch) { /* normal cooking */
default: return (ch);
case DOSEOF: _seteof(fd); return (EOF);
case CR: return ('\n');
case LF:
}
}
}
#asm
_getc: jmp _fgetc
public _getc
#endasm
>>> FGETS.C 1659
#include "stdio.h"
#include "clib.h"
/*
** Gets an entire string (including its newline
** terminator) or size-1 characters, whichever comes
** first. The input is terminated by a null character.
** Entry: str = Pointer to destination buffer.
** size = Size of the destination buffer.
** fd = File descriptor of pertinent file.
** Returns str on success, else NULL.
*/
fgets(str, size, fd) char *str; unsigned size, fd; {
return (_gets(str, size, fd, 1));
}
/*
** Gets an entire string from stdin (excluding its newline
** terminator) or size-1 characters, whichever comes
** first. The input is terminated by a null character.
** The user buffer must be large enough to hold the data.
** Entry: str = Pointer to destination buffer.
** Returns str on success, else NULL.
*/
gets(str) char *str; {
return (_gets(str, 32767, stdin, 0));
}
_gets(str, size, fd, nl) char *str; unsigned size, fd, nl; {
int backup; char *next;
next = str;
while(--size > 0) {
switch (*next = fgetc(fd)) {
case EOF: *next = NULL;
if(next == str) return (NULL);
return (str);
case '\n': *(next + nl) = NULL;
return (str);
case RUB: if(next > str) backup = 1; else backup = 0;
goto backout;
case WIPE: backup = next - str;
backout: if(iscons(fd)) {
++size;
while(backup--) {
fputs("\b \b", stderr);
--next; ++size;
}
continue;
}
default: ++next;
}
}
*next = NULL;
return (str);
}
>>> FOPEN.C 485
#include "stdio.h"
#include "clib.h"
/*
** Open file indicated by fn.
** Entry: fn = Null-terminated DOS file name.
** mode = "a" - append
** "r" - read
** "w" - write
** "a+" - append update
** "r+" - read update
** "w+" - write update
** Returns a file descriptor on success, else NULL.
*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -