home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
BDSC
/
BDSC-1
/
STDLIB1.C
< prev
next >
Wrap
Text File
|
2000-06-30
|
9KB
|
474 lines
#include "bdscio.h"
/*
STDLIB1.C -- for BDS C v1.45 -- LZ, 11/6/81
The files STDLIB1.C and STDLIB2.C contain the source for
all functions in the DEFF.CRL library file.
Functions appearing in this source file:
fopen getc ungetc getw
fcreat putc putw
fflush fclose
atoi
strcat strcmp strcpy strlen
isalpha isupper islower isdigit
isspace toupper tolower
qsort
initw initb getval
alloc * free *
abs max min
* -- Compilation of alloc and free must be explicitly enabled by
swapping the commenting of the ALLOC_ON and ALLOC_OFF definitions
in BDSCIO.H.
*/
/*
Buffered I/O for C:
*/
#define STD_IN 0
#define STD_OUT 1
#define STD_ERR 4
#define DEV_LST 2
#define DEV_RDR 3
#define DEV_PUN 3
int fopen(filename,iobuf)
struct _buf *iobuf;
char *filename;
{
if ((iobuf -> _fd = open(filename,0))<0) return ERROR;
iobuf -> _nleft = 0;
return iobuf -> _fd;
}
int getc(iobuf)
struct _buf *iobuf;
{
int nsecs;
if (iobuf == STD_IN) return getchar();
if (iobuf == DEV_RDR) return bdos(3);
if (!iobuf->_nleft--) /* if buffer empty, fill it up first */
{
if ((nsecs = read(iobuf -> _fd, iobuf -> _buff, NSECTS)) <= 0)
return iobuf -> _nleft++;
iobuf -> _nleft = nsecs * SECSIZ - 1;
iobuf -> _nextp = iobuf -> _buff;
}
return *iobuf->_nextp++;
}
/*
Buffered "unget" a character routine. Only ONE
byte may be "ungotten" between consecutive "getc" calls.
*/
int ungetc(c, iobuf)
struct _buf *iobuf;
char c;
{
if (iobuf == STD_IN) return ungetch(c);
if ((iobuf < 7) || iobuf -> _nleft == (NSECTS * SECSIZ)) return ERROR;
*--iobuf -> _nextp = c;
iobuf -> _nleft++;
return OK;
}
int getw(iobuf)
struct _buf *iobuf;
{
int a,b;
if (((a=getc(iobuf)) >= 0) && ((b= getc(iobuf)) >=0))
return 256*b+a;
return ERROR;
}
int fcreat(name,iobuf)
char *name;
struct _buf *iobuf;
{
if ((iobuf -> _fd = creat(name)) < 0 ) return ERROR;
iobuf -> _nextp = iobuf -> _buff;
iobuf -> _nleft = (NSECTS * SECSIZ);
return iobuf -> _fd;
}
int putc(c,iobuf)
char c;
struct _buf *iobuf;
{
if (iobuf <= 4) /* handle special device codes: */
{
switch (iobuf)
{
case STD_OUT: return putchar(c); /* std output */
case DEV_LST: return (bdos(5,c)); /* list dev. */
case DEV_PUN: return (bdos(4,c)); /* to punch */
case STD_ERR: if (c == '\n') /* to std err */
bdos(2,'\r');
return bdos(2,c);
}
}
if (!iobuf -> _nleft--) /* if buffer full, flush it */
{
if ((write(iobuf -> _fd, iobuf -> _buff, NSECTS)) != NSECTS)
return ERROR;
iobuf -> _nleft = (NSECTS * SECSIZ - 1);
iobuf -> _nextp = iobuf -> _buff;
}
return *iobuf -> _nextp++ = c;
}
int putw(w,iobuf)
unsigned w;
struct _buf *iobuf;
{
if ((putc(w%256,iobuf) >=0 ) && (putc(w / 256,iobuf) >= 0))
return w;
return ERROR;
}
int fflush(iobuf)
struct _buf *iobuf;
{
int i;
if (iobuf < 4) return OK;
if (iobuf -> _nleft == (NSECTS * SECSIZ)) return OK;
i = NSECTS - iobuf->_nleft / SECSIZ;
if (write(iobuf -> _fd, iobuf -> _buff, i) != i)
return ERROR;
i = (i-1) * SECSIZ;
if (iobuf -> _nleft) {
movmem(iobuf->_buff + i, iobuf->_buff, SECSIZ);
iobuf -> _nleft += i;
iobuf -> _nextp -= i;
return seek(iobuf->_fd, -1, 1);
}
iobuf -> _nleft = (NSECTS * SECSIZ);
iobuf -> _nextp = iobuf -> _buff;
return OK;
}
int fclose(iobuf)
struct _buf *iobuf;
{
if (iobuf < 4) return OK;
return close(iobuf -> _fd);
}
/*
Some string functions
*/
int atoi(n)
char *n;
{
int val;
char c;
int sign;
val=0;
sign=1;
while ((c = *n) == '\t' || c== ' ') ++n;
if (c== '-') {sign = -1; n++;}
while ( isdigit(c = *n++)) val = val * 10 + c - '0';
return sign*val;
}
char *strcat(s1,s2)
char *s1, *s2;
{
char *temp; temp=s1;
while(*s1) s1++;
do *s1++ = *s2; while (*s2++);
return temp;
}
int strcmp(s,t)
char s[], t[];
{
int i;
i = 0;
while (s[i] == t[i])
if (s[i++] == '\0')
return 0;
return s[i] - t[i];
}
char *strcpy(s1,s2)
char *s1, *s2;
{
char *temp; temp=s1;
while (*s1++ = *s2++);
return temp;
}
int strlen(s)
char *s;
{
int len;
len=0;
while (*s++) len++;
return len;
}
/*
Some character diddling functions
*/
int isalpha(c)
char c;
{
return isupper(c) || islower(c);
}
int isupper(c)
char c;
{
return c>='A' && c<='Z';
}
int islower(c)
char c;
{
return c>='a' && c<='z';
}
int isdigit(c)
char c;
{
return c>='0' && c<='9';
}
int isspace(c)
char c;
{
return c==' ' || c=='\t' || c=='\n';
}
char toupper(c)
char c;
{
return islower(c) ? c-32 : c;
}
char tolower(c)
char c;
{
return isupper(c) ? c+32 : c;
}
/*
Other stuff...
*/
/*
This is the new qsort routine, utilizing the shell sort
technique given in the Software Tools book (by Kernighan
& Plauger.)
"Qsort" has been fixed on 4/10/81 to handle data arrays bigger
than 32K. (Ints were used instead of unsigneds in previous
versions.)
NOTE: this "qsort" function is different from the "qsort" given
in some old releases (pre 1.32) -- here, the items are sorted
in ASCENDING order. The old "qsort" sorted stuff in DESCENDING
order, and was in part responsible for the atrocious play of
the "Othello" program (it always made the WORST moves it could
find...)
*/
qsort(base, nel, width, compar)
char *base; int (*compar)();
unsigned width,nel;
{ int i, j;
unsigned gap, ngap, t1;
int jd, t2;
t1 = nel * width;
for (ngap = nel / 2; ngap > 0; ngap /= 2) {
gap = ngap * width;
t2 = gap + width;
jd = base + gap;
for (i = t2; i <= t1; i += width)
for (j = i - t2; j >= 0; j -= gap) {
if ((*compar)(base+j, jd+j) <=0) break;
_swp(width, base+j, jd+j);
}
}
}
_swp(w,a,b)
char *a,*b;
unsigned w;
{
char tmp;
while(w--) {tmp=*a; *a++=*b; *b++=tmp;}
}
/*
Initialization functions
*/
initw(var,string)
int *var;
char *string;
{
int n;
while ((n = getval(&string)) != -32760) *var++ = n;
}
initb(var,string)
char *var, *string;
{
int n;
while ((n = getval(&string)) != -32760) *var++ = n;
}
int getval(strptr)
char **strptr;
{
int n;
if (!**strptr) return -32760;
n = atoi(*strptr);
while (**strptr && *(*strptr)++ != ',');
return n;
}
/*
Storage allocation routines, taken from chapter 8 of K&R, but
simplified to ignore the storage allignment problem and not
bother with the "morecore" hack (a call to "sbrk" under CP/M is
a relatively CHEAP operation, and can be done on every call to
"alloc" without degrading efficiency.)
Note that compilation of "alloc" and "free" is disabled until
the "#define ALLOC_ON 1" statement is un-commented in the header
file ("BDSCIO.H"). This is done so that the external storage
required by alloc and free isn't declared unless the user
actually needs the alloc and free functions. As soon as BDS C
gets static variables, this kludge will go away.
*/
#ifdef ALLOC_ON /* Compilation of alloc and free is enabled only
when the ALLOC_ON symbol is #defined in BDSCIO.H */
char *alloc(nbytes)
unsigned nbytes;
{
struct _header *p, *q, *cp;
int nunits;
nunits = 1 + (nbytes + (sizeof (_base) - 1)) / sizeof (_base);
if ((q = _allocp) == NULL) {
_base._ptr = _allocp = q = &_base;
_base._size = 0;
}
for (p = q -> _ptr; ; q = p, p = p -> _ptr) {
if (p -> _size >= nunits) {
if (p -> _size == nunits)
q -> _ptr = p -> _ptr;
else {
p -> _size -= nunits;
p += p -> _size;
p -> _size = nunits;
}
_allocp = q;
return p + 1;
}
if (p == _allocp) {
if ((cp = sbrk(nunits * sizeof (_base))) == ERROR)
return NULL;
cp -> _size = nunits;
free(cp+1); /* remember: pointer arithmetic! */
p = _allocp;
}
}
}
free(ap)
struct _header *ap;
{
struct _header *p, *q;
p = ap - 1; /* No need for the cast when "ap" is a struct ptr */
for (q = _allocp; !(p > q && p < q -> _ptr); q = q -> _ptr)
if (q >= q -> _ptr && (p > q || p < q -> _ptr))
break;
if (p + p -> _size == q -> _ptr) {
p -> _size += q -> _ptr -> _size;
p -> _ptr = q -> _ptr -> _ptr;
}
else p -> _ptr = q -> _ptr;
if (q + q -> _size == p) {
q -> _size += p -> _size;
q -> _ptr = p -> _ptr;
}
else q -> _ptr = p;
_allocp = q;
}
#endif
/*
Now some really hairy functions to wrap things up:
*/
int abs(n)
{
return (n<0) ? -n : n;
}
int max(a,b)
{
return (a > b) ? a : b;
}
int min(a,b)
{
return (a <= b) ? a : b;
}