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 >
Text File  |  2000-06-30  |  9KB  |  474 lines

  1.  
  2.  
  3. #include "bdscio.h"
  4.  
  5. /*
  6.     STDLIB1.C -- for BDS C v1.45 -- LZ, 11/6/81
  7.  
  8.     The files STDLIB1.C and STDLIB2.C contain the source for
  9.     all functions in the DEFF.CRL library file.
  10.  
  11.     Functions appearing in this source file:
  12.  
  13.     fopen        getc        ungetc        getw
  14.     fcreat        putc        putw
  15.     fflush        fclose
  16.     atoi
  17.     strcat        strcmp        strcpy        strlen
  18.     isalpha        isupper        islower        isdigit
  19.     isspace        toupper        tolower
  20.     qsort
  21.     initw        initb        getval
  22.     alloc *        free *
  23.     abs        max        min
  24.  
  25.     * -- Compilation of alloc and free must be explicitly enabled by
  26.          swapping the commenting of the ALLOC_ON and ALLOC_OFF definitions
  27.          in BDSCIO.H.
  28.  
  29. */
  30.  
  31.  
  32. /*
  33.     Buffered I/O for C:
  34. */
  35.  
  36. #define STD_IN    0
  37. #define STD_OUT 1
  38. #define STD_ERR 4
  39.  
  40. #define DEV_LST 2
  41. #define DEV_RDR 3
  42. #define DEV_PUN 3
  43.  
  44.  
  45. int fopen(filename,iobuf)
  46. struct _buf *iobuf;
  47. char *filename;
  48. {
  49.     if ((iobuf -> _fd = open(filename,0))<0) return ERROR;
  50.     iobuf -> _nleft = 0;
  51.     return iobuf -> _fd;
  52. }
  53.  
  54.  
  55. int getc(iobuf)
  56. struct _buf *iobuf;
  57. {
  58.     int nsecs;
  59.     if (iobuf == STD_IN) return getchar();
  60.     if (iobuf == DEV_RDR) return bdos(3);
  61.     if (!iobuf->_nleft--)        /* if buffer empty, fill it up first */
  62.      {
  63.         if ((nsecs = read(iobuf -> _fd, iobuf -> _buff, NSECTS)) <= 0)
  64.             return iobuf -> _nleft++;
  65.         iobuf -> _nleft = nsecs * SECSIZ - 1;
  66.         iobuf -> _nextp = iobuf -> _buff;
  67.      }
  68.     return *iobuf->_nextp++;
  69. }
  70.  
  71. /*
  72.     Buffered "unget" a character routine. Only ONE
  73.     byte may be "ungotten" between consecutive "getc" calls.
  74. */
  75.  
  76. int ungetc(c, iobuf)
  77. struct _buf *iobuf;
  78. char c;
  79. {
  80.     if (iobuf == STD_IN) return ungetch(c);
  81.     if ((iobuf < 7) || iobuf -> _nleft == (NSECTS * SECSIZ)) return ERROR;
  82.     *--iobuf -> _nextp = c;
  83.     iobuf -> _nleft++;
  84.     return OK;
  85. }
  86.     
  87.  
  88. int getw(iobuf)
  89. struct _buf *iobuf;
  90. {
  91.     int a,b;    
  92.     if (((a=getc(iobuf)) >= 0) && ((b= getc(iobuf)) >=0))
  93.             return 256*b+a;
  94.     return ERROR;
  95. }
  96.  
  97.  
  98. int fcreat(name,iobuf)
  99. char *name;
  100. struct _buf *iobuf;
  101. {
  102.     if ((iobuf -> _fd = creat(name)) < 0 ) return ERROR;
  103.     iobuf -> _nextp = iobuf -> _buff;
  104.     iobuf -> _nleft = (NSECTS * SECSIZ);
  105.     return iobuf -> _fd;
  106. }
  107.  
  108.  
  109. int putc(c,iobuf)
  110. char c;
  111. struct _buf *iobuf;
  112. {
  113.     if (iobuf <= 4)            /* handle special device codes: */
  114.      {
  115.         switch (iobuf)
  116.          {
  117.             case STD_OUT: return putchar(c);  /* std output */
  118.             case DEV_LST: return (bdos(5,c)); /* list dev.  */
  119.             case DEV_PUN: return (bdos(4,c)); /* to punch   */
  120.             case STD_ERR: if (c == '\n')      /* to std err */
  121.                         bdos(2,'\r');
  122.                       return bdos(2,c);
  123.          }    
  124.      }
  125.     if (!iobuf -> _nleft--)        /*   if buffer full, flush it     */
  126.      {
  127.         if ((write(iobuf -> _fd, iobuf -> _buff, NSECTS)) != NSECTS)
  128.             return ERROR;
  129.         iobuf -> _nleft = (NSECTS * SECSIZ - 1);
  130.         iobuf -> _nextp = iobuf -> _buff;
  131.      }
  132.     return *iobuf -> _nextp++ = c;
  133. }
  134.  
  135.  
  136. int putw(w,iobuf)
  137. unsigned w;
  138. struct _buf *iobuf;
  139. {
  140.     if ((putc(w%256,iobuf) >=0 ) && (putc(w / 256,iobuf) >= 0))
  141.                 return w;
  142.     return ERROR;
  143. }
  144.  
  145.  
  146. int fflush(iobuf)
  147. struct _buf *iobuf;
  148. {
  149.     int i;
  150.     if (iobuf < 4) return OK;
  151.     if (iobuf -> _nleft == (NSECTS * SECSIZ)) return OK;
  152.  
  153.     i = NSECTS - iobuf->_nleft / SECSIZ;
  154.     if (write(iobuf -> _fd, iobuf -> _buff, i) != i)
  155.             return ERROR;
  156.     i = (i-1) * SECSIZ;
  157.  
  158.     if (iobuf -> _nleft) {
  159.         movmem(iobuf->_buff + i, iobuf->_buff, SECSIZ);
  160.         iobuf -> _nleft += i;
  161.         iobuf -> _nextp -= i;
  162.         return seek(iobuf->_fd, -1, 1);
  163.      }
  164.  
  165.     iobuf -> _nleft = (NSECTS * SECSIZ);
  166.     iobuf -> _nextp = iobuf -> _buff;
  167.     return OK;
  168. }
  169.  
  170. int fclose(iobuf)
  171. struct _buf *iobuf;
  172. {
  173.     if (iobuf < 4) return OK;
  174.     return close(iobuf -> _fd);
  175. }
  176.  
  177.  
  178. /*
  179.     Some string functions
  180. */
  181.  
  182. int atoi(n)
  183. char *n;
  184. {
  185.     int val; 
  186.     char c;
  187.     int sign;
  188.     val=0;
  189.     sign=1;
  190.     while ((c = *n) == '\t' || c== ' ') ++n;
  191.     if (c== '-') {sign = -1; n++;}
  192.     while (  isdigit(c = *n++)) val = val * 10 + c - '0';
  193.     return sign*val;
  194. }
  195.  
  196.  
  197. char *strcat(s1,s2)
  198. char *s1, *s2;
  199. {
  200.     char *temp; temp=s1;
  201.     while(*s1) s1++;
  202.     do *s1++ = *s2; while (*s2++);
  203.     return temp;
  204. }
  205.  
  206.  
  207. int strcmp(s,t)
  208. char s[], t[];
  209. {
  210.     int i;
  211.     i = 0;
  212.     while (s[i] == t[i])
  213.         if (s[i++] == '\0')
  214.             return 0;
  215.     return s[i] - t[i];
  216. }
  217.  
  218.  
  219. char *strcpy(s1,s2)
  220. char *s1, *s2;
  221. {
  222.     char *temp; temp=s1;
  223.     while (*s1++ = *s2++);
  224.     return temp;
  225. }
  226.  
  227.  
  228. int strlen(s)
  229. char *s;
  230. {
  231.     int len;
  232.     len=0;
  233.     while (*s++) len++;
  234.     return len;
  235. }
  236.  
  237.  
  238. /*
  239.     Some character diddling functions
  240. */
  241.  
  242. int isalpha(c)
  243. char c;
  244. {
  245.     return isupper(c) || islower(c);
  246. }
  247.  
  248.  
  249. int isupper(c)
  250. char c;
  251. {
  252.     return c>='A' && c<='Z';
  253. }
  254.  
  255.  
  256. int islower(c)
  257. char c;
  258. {
  259.     return c>='a' && c<='z';
  260. }
  261.  
  262.  
  263. int isdigit(c)
  264. char c;
  265. {
  266.     return c>='0' && c<='9';
  267. }
  268.  
  269.  
  270. int isspace(c)
  271. char c;
  272. {
  273.     return c==' ' || c=='\t' || c=='\n';
  274. }
  275.  
  276.  
  277. char toupper(c)
  278. char c;
  279. {
  280.     return islower(c) ? c-32 : c;
  281. }
  282.  
  283.  
  284. char tolower(c)
  285. char c;
  286. {
  287.     return isupper(c) ? c+32 : c;
  288. }
  289.  
  290.  
  291.  
  292.  
  293. /*
  294.     Other stuff...
  295. */
  296.  
  297. /*
  298.     This is the new qsort routine, utilizing the shell sort
  299.     technique given in the Software Tools book (by Kernighan 
  300.     & Plauger.)
  301.  
  302.     "Qsort" has been fixed on 4/10/81 to handle data arrays bigger
  303.     than 32K. (Ints were used instead of unsigneds in previous 
  304.     versions.)
  305.  
  306.     NOTE: this "qsort" function is different from the "qsort" given
  307.     in some old releases (pre 1.32) -- here, the items are sorted
  308.     in ASCENDING order. The old "qsort" sorted stuff in DESCENDING
  309.     order, and was in part responsible for the atrocious play of
  310.     the "Othello" program (it always made the WORST moves it could
  311.     find...) 
  312. */
  313.  
  314. qsort(base, nel, width, compar)
  315. char *base; int (*compar)();
  316. unsigned width,nel;
  317. {    int i, j;
  318.     unsigned gap, ngap, t1;
  319.     int jd, t2;
  320.     t1 = nel * width;
  321.     for (ngap = nel / 2; ngap > 0; ngap /= 2) {
  322.        gap = ngap * width;
  323.        t2 = gap + width;
  324.        jd = base + gap;
  325.        for (i = t2; i <= t1; i += width)
  326.           for (j =  i - t2; j >= 0; j -= gap) {
  327.         if ((*compar)(base+j, jd+j) <=0) break;
  328.              _swp(width, base+j, jd+j);
  329.           }
  330.     }
  331. }
  332.  
  333. _swp(w,a,b)
  334. char *a,*b;
  335. unsigned w;
  336. {
  337.     char tmp;
  338.     while(w--) {tmp=*a; *a++=*b; *b++=tmp;}
  339. }
  340.  
  341.  
  342. /*
  343.      Initialization functions
  344. */
  345.  
  346.  
  347. initw(var,string)
  348. int *var;
  349. char *string;
  350. {
  351.     int n;
  352.     while ((n = getval(&string)) != -32760) *var++ = n;
  353. }
  354.  
  355. initb(var,string)
  356. char *var, *string;
  357. {
  358.     int n;
  359.     while ((n = getval(&string)) != -32760) *var++ = n;
  360. }
  361.  
  362. int getval(strptr)
  363. char **strptr;
  364. {
  365.     int n;
  366.     if (!**strptr) return -32760;
  367.     n = atoi(*strptr);
  368.     while (**strptr && *(*strptr)++ != ',');
  369.     return n;
  370. }
  371.  
  372.  
  373.  
  374. /*
  375.     Storage allocation routines, taken from chapter 8 of K&R, but
  376.     simplified to ignore the storage allignment problem and not
  377.     bother with the "morecore" hack (a call to "sbrk" under CP/M is
  378.     a relatively CHEAP operation, and can be done on every call to
  379.     "alloc" without degrading efficiency.)
  380.  
  381.     Note that compilation of "alloc" and "free" is disabled until
  382.     the "#define ALLOC_ON 1" statement is un-commented in the header
  383.     file ("BDSCIO.H"). This is done so that the external storage
  384.     required by alloc and free isn't declared unless the user
  385.     actually needs the alloc and free functions. As soon as BDS C
  386.     gets static variables, this kludge will go away.
  387. */
  388.  
  389.  
  390. #ifdef ALLOC_ON        /* Compilation of alloc and free is enabled only
  391.                when the ALLOC_ON symbol is #defined in BDSCIO.H */
  392.  
  393. char *alloc(nbytes)
  394. unsigned nbytes;
  395. {
  396.     struct _header *p, *q, *cp;
  397.     int nunits; 
  398.     nunits = 1 + (nbytes + (sizeof (_base) - 1)) / sizeof (_base);
  399.     if ((q = _allocp) == NULL) {
  400.         _base._ptr = _allocp = q = &_base;
  401.         _base._size = 0;
  402.      }
  403.     for (p = q -> _ptr; ; q = p, p = p -> _ptr) {
  404.         if (p -> _size >= nunits) {
  405.             if (p -> _size == nunits)
  406.                 q -> _ptr = p -> _ptr;
  407.             else {
  408.                 p -> _size -= nunits;
  409.                 p += p -> _size;
  410.                 p -> _size = nunits;
  411.              }
  412.             _allocp = q;
  413.             return p + 1;
  414.          }
  415.         if (p == _allocp) {
  416.             if ((cp = sbrk(nunits * sizeof (_base))) == ERROR)
  417.                 return NULL;
  418.             cp -> _size = nunits; 
  419.             free(cp+1);    /* remember: pointer arithmetic! */
  420.             p = _allocp;
  421.         }
  422.      }
  423. }
  424.  
  425.  
  426. free(ap)
  427. struct _header *ap;
  428. {
  429.     struct _header *p, *q;
  430.  
  431.     p = ap - 1;    /* No need for the cast when "ap" is a struct ptr */
  432.  
  433.     for (q = _allocp; !(p > q && p < q -> _ptr); q = q -> _ptr)
  434.         if (q >= q -> _ptr && (p > q || p < q -> _ptr))
  435.             break;
  436.     if (p + p -> _size == q -> _ptr) {
  437.         p -> _size += q -> _ptr -> _size;
  438.         p -> _ptr = q -> _ptr -> _ptr;
  439.      }
  440.     else p -> _ptr = q -> _ptr;
  441.  
  442.     if (q + q -> _size == p) {
  443.         q -> _size += p -> _size;
  444.         q -> _ptr = p -> _ptr;
  445.      }
  446.     else q -> _ptr = p;
  447.  
  448.     _allocp = q;
  449. }
  450.  
  451. #endif
  452.  
  453.  
  454.  
  455. /*
  456.     Now some really hairy functions to wrap things up:
  457. */
  458.  
  459. int abs(n)
  460. {
  461.     return (n<0) ? -n : n;
  462. }
  463.  
  464. int max(a,b)
  465. {
  466.     return (a > b) ? a : b;
  467. }
  468.  
  469. int min(a,b)
  470. {
  471.     return (a <= b) ? a : b;
  472. }
  473.  
  474.