home *** CD-ROM | disk | FTP | other *** search
-
-
- #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;
- }
-