home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / C / SMALL_C / CSYSLIB.C < prev    next >
Text File  |  1987-10-04  |  8KB  |  373 lines

  1.  
  2.  
  3. /*
  4. ** CSYSLIB -- System-Level Library Functions
  5. ** Modified for MS-DOS 2 by R. Grehan
  6. */
  7.  
  8. #include stdio.h
  9. #include clib.def
  10. #define NOCCARGC    /* no argument count passing */
  11. #define DIR         /* compile directory option */
  12.  
  13. /*
  14. ****************** System Variables ********************
  15. */
  16.  
  17. int
  18.  
  19.   errno,             /* Error number holding var */
  20.   
  21.   Ucnt=1,            /* arg count for main */
  22.   Uvec[20],          /* arg vectors for main */
  23.  
  24.   Ustatus[MAXFILES] = {RDBIT, WRTBIT, RDBIT|WRTBIT},
  25.                      /* status of respective file */
  26.   Udevice[MAXFILES] = {CONSOL, CONSOL, CONSOL},
  27.                      /* non-disk device assignments */
  28.   Unextc[MAXFILES]  = {EOF, EOF, EOF},
  29.                      /* pigeonhole for ungetc bytes */
  30.   Ufd[MAXFILES] = {0, 1, 2};
  31.                      /* Map logical fd's to physical */
  32.  
  33. char
  34.  *Umemptr,           /* pointer to free memory. */
  35.   Uarg1[]="*";       /* first arg for main */
  36. /*
  37. *************** System-Level Functions *****************
  38. */
  39.  
  40. /*
  41. ** -- Process Command Line, Execute main(), and Exit to CP/M
  42. */
  43. Umain() {
  44.   Uparse();
  45.   main(Ucnt,Uvec);
  46.   exit(0);
  47.   }
  48.  
  49. /*
  50. ** Parse command line and setup argc and argv.
  51. */
  52. Uparse() {
  53.   char *count, *ptr;
  54.   count = 128;  /* Reserve bytes */
  55.   ptr = Ualloc(count+1, YES);
  56.  
  57.   count=Ugcmdtl(ptr);    /* Get command tail - null pad */
  58.  
  59.   Uvec[0]=Uarg1;                /* first arg = "*" */
  60.   while (*ptr) {
  61.     if(isspace(*ptr)) {++ptr; continue;}
  62.     switch(*ptr) {
  63.       case '<': ptr = Uredirect(ptr, "r", stdin);
  64.                 continue;
  65.       case '>': if(*(ptr+1) == '>')
  66.                      ptr = Uredirect(ptr+1, "a", stdout);
  67.                 else ptr = Uredirect(ptr,   "w", stdout);
  68.                 continue;
  69.       default:  if(Ucnt < 20) Uvec[Ucnt++] = ptr;
  70.                 ptr = Ufield(ptr);
  71.       }
  72.     }
  73.   }
  74.  
  75. Ugcmdtl(mypt) char *mypt; {
  76. #asm
  77.   MOV AH,62H  ;Get program segment prefix
  78.   INT 21H
  79.   MOV AX,DS   ;Get our segment
  80.   MOV ES,AX   ;Will be destination
  81.   MOV DS,BX   ;PSP segment is source
  82.   MOV SI,80H  ;Offset to command tail byte count
  83.   MOV CL,[SI] ;Get byte count
  84.   MOV BX,CX   ;Save for return
  85.   INC SI      ;Bump pointer
  86.   POP AX      ;Return address
  87.   POP DI      ;mypt
  88.   PUSH DI     ;Restore
  89.   PUSH AX
  90.   CLD         ;Set direction
  91.   REP MOVSB   ;Move it in
  92.   MOV BYTE PTR ES:[DI],0 ;Move in Null
  93.   MOV AX,ES   ;Restore our segment
  94.   MOV DS,AX
  95.   XOR CX,CX   ;Zero in CX
  96. #endasm
  97. }
  98. /*
  99.  
  100. ** Isolate next command-line field.
  101. */
  102. Ufield(ptr) char *ptr; {
  103.   while(*ptr) {
  104.     if(isspace(*ptr)) {
  105.       *ptr = NULL;
  106.       return (++ptr);
  107.       }
  108.     ++ptr;
  109.     }
  110.   return (ptr);
  111.   }
  112.  
  113. /*
  114. ** Redirect stdin or stdout.
  115. */
  116. Uredirect(ptr, mode, std)  char *ptr, *mode; int std; {
  117.   char *fn;
  118.   fn = ++ptr;
  119.   ptr = Ufield(ptr);
  120.   if(Uopen(fn, mode, std)==ERR) exit('R');
  121.   return (ptr);
  122.   }
  123.  
  124. /*
  125. ** ------------ File Open
  126. */
  127.  
  128. /*
  129. ** Open file on specified fd.
  130. */
  131. Uopen(fn, mode, fd) char *fn, *mode; int fd; {
  132.   int pfd;
  133.   if(!strchr("rwau", *mode)) return (ERR);
  134.   Unextc[fd] = EOF;
  135.   if(strcmp(fn,"CON:")==0) {
  136.     Udevice[fd]=CONSOL; Ustatus[fd]=RDBIT|WRTBIT; return (fd);
  137.     }
  138.   if(strcmp(fn,"LST:")==0) {
  139.     Udevice[fd]=PRINTR; Ustatus[fd]=WRTBIT; return (fd);
  140.     }
  141.   Udevice[fd] = 0;
  142.   switch(*mode) {
  143.     case 'r': {
  144.       if((pfd=Umsdos(fn,0,0,OPNFIL+RACCESS))==ERR) return (ERR);
  145.       Ustatus[fd] =  RDBIT;
  146.       Ufd[fd]=pfd;
  147.       break;
  148.       }
  149.     case 'u': {
  150.       if((pfd=Umsdos(fn,0,0,OPNFIL+RWACCESS))==ERR)
  151.          return (ERR);
  152.       Ustatus[fd] = RDBIT|WRTBIT;
  153.       Ufd[fd]=pfd;
  154.       break;
  155.      } 
  156.     case 'w': {
  157.       if((pfd=Umsdos(fn,0,0,OPNFIL+WACCESS))!=ERR) { 
  158.               Umsdos(0,0,pfd,CLOFIL);
  159.               Umsdos(fn,0,0,DELFIL); }
  160.     create:
  161.       if((pfd=Umsdos(fn,0,0,MAKFIL))==ERR) return (ERR);
  162.       Ustatus[fd] = EOFBIT|WRTBIT;
  163.       Ufd[fd]=pfd;
  164.       break;
  165.       }
  166.     default: {      /* append mode */
  167.       if((pfd=Umsdos(fn,0,0,OPNFIL+RWACCESS))==ERR) 
  168.       goto create;
  169.       Ustatus[fd] = RDBIT;
  170.       Ufd[fd]=pfd;
  171.       seek(fd, -1, -1, 2);
  172.       while(fgetc(fd)!=EOF) ;
  173.       Ustatus[fd] = EOFBIT|WRTBIT;
  174.       }
  175.     }
  176.   return (fd);
  177.   }
  178.  
  179. /*
  180. ** ------------ File Input
  181. */
  182.  
  183. /*
  184. ** Binary-stream input fd.
  185. */
  186. Uread(buff,fd,n) int fd; char *buff, *n; {
  187.   char *i;  /* Fake unsigned */
  188.   char ch;
  189.   i=n;
  190.   switch (Umode(fd)) {
  191.     default: Useterr(fd); return (EOF);
  192.     case RDBIT:
  193.     case RDBIT|WRTBIT:
  194.     }
  195.   if(Unextc[fd] != EOF) {
  196.     *buff++=Unextc[fd];
  197.     Unextc[fd] = EOF;
  198.     if((--n)==0) return(1) ;
  199.     }
  200.   switch(Udevice[fd]) {
  201.     /* PUN & LST can't occur since they are write mode */
  202.     case CONSOL: while(n--) {
  203.                  if((ch=Uconin())==FILEOF) return(EOF);
  204.                  *buff++=ch;                 
  205.                  } return(i-n);
  206.     default:
  207.          if((i=Umsdos(buff,n,Ufd[fd],RDFIL))==ERR)
  208.            return(ERR);
  209.          if(i==0) Useteof(fd);
  210.          return(i);
  211.     }
  212.   }
  213.  
  214. /*
  215. ** Console character input.
  216. */
  217. Uconin() {
  218.   int ch;
  219.   while(!(ch = Dcio(255))) ;
  220.   switch(ch) {
  221.     case ABORT: exit(0);
  222.     case    LF:
  223.     case    CR: Uconout(LF); return (Uconout(CR));
  224.     case   DEL: ch = RUB;
  225.        default: if(ch < 32) { Uconout('^'); Uconout(ch+64);}
  226.                 else Uconout(ch);
  227.                 return (ch);
  228.     }
  229.   }
  230.  
  231. /*
  232. ** Special direct keyboard input for MS-DOS
  233. */
  234. Dcio(ch) int ch; {
  235. #asm
  236.   POP SI
  237.   POP DX
  238.   PUSH DX
  239.   PUSH SI
  240.   MOV AH,6   ;Direct I/O
  241.   INT 21H
  242.   JNZ  Dcio1
  243.   XOR AL,AL  ;No char.
  244. Dcio1:
  245.   MOV BL,AL
  246.   XOR BH,BH
  247. #endasm
  248. }
  249.  
  250.  
  251. /*
  252. ** ------------ File Output
  253. */
  254.  
  255. /*
  256. ** Binary-Stream output to fd.
  257. */
  258. Uwrite(buff, fd, n) int fd; char *buff, *n; {
  259.   char *i;
  260.   i=n;
  261.   switch (Umode(fd)) {
  262.     default: Useterr(fd); return (EOF);
  263.     case WRTBIT:
  264.     case WRTBIT|RDBIT:
  265.     case WRTBIT|EOFBIT:
  266.     case WRTBIT|EOFBIT|RDBIT:
  267.     }
  268.   switch(Udevice[fd]) {
  269.     /* RDR can't occur since it is read mode */
  270.     case CONSOL: while (n--) {
  271.                  Dcio(*buff++);
  272.                  } return(i-n);
  273.     case PRINTR: while (n--) {
  274.                  Umsdos(*buff++,0,0,PRTOUT);
  275.                  } return (i-n);
  276.     default:
  277.       return(Umsdos(buff,n,Ufd[fd],WRFIL));
  278.     }
  279.   }
  280.  
  281. /*
  282. ** Console character output.
  283. */
  284. Uconout(ch) int ch; {
  285.   Dcio(ch);
  286.   return (ch);
  287.   }
  288.  
  289. /*
  290. ** ------------ Buffer Service
  291. */
  292.  
  293.  
  294. /*
  295. ** Return fd's open mode, else NULL.
  296. */
  297. Umode(fd) char *fd; {
  298.   if(fd < MAXFILES) return (Ustatus[fd]);
  299.   return (NULL);
  300.   }
  301.  
  302. /*
  303. ** Set eof status for fd and
  304. ** disable future i/o unless writing is allowed.
  305. */
  306. Useteof(fd) int fd; {
  307.   Ustatus[fd] |= EOFBIT;
  308.   }
  309.  
  310. /*
  311. ** Clear eof status for fd.
  312. */
  313. Uclreof(fd) int fd; {
  314.   Ustatus[fd] &= ~EOFBIT;
  315.   }
  316.  
  317. /*
  318. ** Set error status for fd.
  319. */
  320. Useterr(fd) int fd; {
  321.   Ustatus[fd] |= ERRBIT;
  322.   }
  323.  
  324. /*
  325. ** ------------ Memory Allocation
  326. */
  327.  
  328. /*
  329. ** Allocate n bytes of (possibly zeroed) memory.
  330. ** Entry: n = Size of the items in bytes.
  331. **    clear = "true" if clearing is desired.
  332. ** Returns the address of the allocated block of memory
  333. ** or NULL if the requested amount of space is not available.
  334. */
  335. Ualloc(n, clear) char *n; int clear; {
  336.   char *oldptr;
  337.   if(n < avail(YES)) {
  338.     if(clear) pad(Umemptr, NULL, n);
  339.     oldptr = Umemptr;
  340.     Umemptr += n;
  341.     return (oldptr);
  342.     }
  343.   return (NULL);
  344.   }
  345.  
  346. /* MS-DOS interface
  347. ** If there's an error code, we store it in errno and
  348. ** return ERR
  349. */
  350.  
  351. Umsdos(dx,cx,bx,ax) int dx,cx,bx,ax; {
  352. #asm
  353.   POP SI  ;Return address
  354.   POP AX  ;Load all the registers
  355.   POP BX
  356.   POP CX
  357.   POP DX
  358.   PUSH DX  ;Now restore them
  359.   PUSH CX
  360.   PUSH BX
  361.   PUSH AX
  362.   PUSH SI
  363.   INT 21H  ;Issue the call do DOS
  364.   JNC UMSDOS1  ;Jump if no error
  365.   MOV _ERRNO,AX
  366.   MOV AX,-2    ;ERR
  367. UMSDOS1:
  368.   MOV BX,AX
  369.   XOR CX,CX    ;Zero in CX
  370. #endasm
  371. }
  372.  
  373.